diff --git a/clean.js b/clean.js index f657c54f..51bc9f47 100644 --- a/clean.js +++ b/clean.js @@ -6,12 +6,11 @@ * clean-all: Removes all build, test, and execution artifacts. Including cluster config and logs! */ -"use strict"; -const path = require("path"); -const fs = require("node:fs/promises"); -const yargs = require("yargs"); +import path from "node:path"; +import fs from "node:fs/promises"; +import yargs from "yargs"; -const npmPackage = require("./package.json"); +import npmPackage from "./package.json" with { type: "json" }; const workspaces = npmPackage.workspaces .map(p => p.slice(0, -2)) .filter(p => !p.includes("external_plugins")); @@ -116,6 +115,6 @@ async function main() { } // Run main if started from command line -if (module === require.main) { +if (import.meta.main) { main(); } diff --git a/docs/contributing.md b/docs/contributing.md index 1ae0d1d2..62dc3c71 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -229,8 +229,8 @@ Files containing and exporting a single class should be named the same as the cl Relative imports in lib package are prefixed with lib to make them easier to distinguish, as the names tend to be very generic. E.g.: - const libLink = require("./link"); - const libLuaTools = require("./lua_tools"); + import libLink from "./link"; + import libLuaTools from "./lua_tools"; Note that no sub-modules of the lib package is imported directly from the outside of it with the exception of `build_mod`. diff --git a/docs/devs/json-serialisable-classes.md b/docs/devs/json-serialisable-classes.md index ca152c2a..24715bd4 100644 --- a/docs/devs/json-serialisable-classes.md +++ b/docs/devs/json-serialisable-classes.md @@ -14,7 +14,7 @@ See the following example code for a hypothetical `Data` class with a single pro * A Data class example * @alias module:Data */ -class Data { +export class Data { /** @type {string} */ member = "foo"; @@ -41,8 +41,6 @@ class Data { return json; } } - -module.exports = Data; ``` Serialising an instance of `Data` for JSON is as simple as doing `serialised = JSON.stringify(data)` as the `toJSON` method is automatically called by `JSON.stringify` to create a suitable object. @@ -53,14 +51,13 @@ For example a class holding a data property with an instance of the Data class f ```js // Composed.js -"use strict"; -const Data = require("./Data"); +import Data from "./Data"; /** * Composed data class example * @alias module:Data */ -class Composed { +export class Composed { /** @type {module:Data|undefined} */ data; @@ -83,8 +80,6 @@ class Composed { // toJSON is optional and not needed for this particular class } - -module.exports = Composed; ``` It's easy to create a new instance of Composed by calling `new Composed(new Data("spam"))` and serialising to and from JSON is the same as for Data. diff --git a/docs/writing-plugins.md b/docs/writing-plugins.md index fb80fef8..f86e9582 100644 --- a/docs/writing-plugins.md +++ b/docs/writing-plugins.md @@ -48,12 +48,12 @@ By default the main entrypoint is the `index.js` file, but this may be changed b Here's an example of `index.js`: ```js -module.exports.plugin = { +export const plugin = { name: "foo_frobber", title: "Foo Frobber", description: "Does advanced frobnication", - instanceEntrypoint: "instance", - controllerEntrypoint: "controller", + instanceEntrypoint: "instance.js", + controllerEntrypoint: "controller.js", messages: { /* See below */ }, @@ -117,9 +117,9 @@ The plugin class should derive from its respective base class defined in `lib/pl For example, to define a ControllerPlugin class the following code can be used: ```js -const { BaseControllerPlugin } = require("@clusterio/controller"); +import { BaseControllerPlugin } from "@clusterio/controller"; -class ControllerPlugin extends BaseControllerPlugin { +export class ControllerPlugin extends BaseControllerPlugin { async init() { this.foo = 42; await this.startFrobnication(); @@ -127,10 +127,6 @@ class ControllerPlugin extends BaseControllerPlugin { // ... } - -module.exports = { - ControllerPlugin, -} ``` For the instance plugin it's exactly the same except "Controller" is replaced with "Instance", for host plugins "Host" is used and for the clusterioctl plugin "Ctl" is used. @@ -525,7 +521,7 @@ In its simplest form collecting data from plugins consists of defining the metri For example: ```js -const { Counter } = require("@clusterio/lib"); +import { Counter } from "@clusterio/lib"; const fooMetric = new Counter( "clusterio_foo_frobber_foo_metric", "Measures the level of foo", @@ -541,7 +537,7 @@ It's recommended that plugin metrics follow `clusterio__", "Do frobnications", (yargs) => { @@ -600,15 +596,11 @@ Note that messages sent from clusterioctl needs to have `"control-controller"` a To have the command tree become part of clusterioctl it needs to be added to the rootCommand tree in `addCommands` callback of the Ctl plugin: ```js -const { BaseCtlPlugin } = require("@clusterio/ctl"); +import { BaseCtlPlugin } from "@clusterio/ctl"; -class CtlPlugin extends BaseCtlPlugin { +export class CtlPlugin extends BaseCtlPlugin { async addCommands(rootCommand) { rootCommand.add(fooFrobberCommands); } } - -module.exports = { - CtlPlugin, -} ``` diff --git a/eslint.config.mjs b/eslint.config.mjs index d7b7e8e2..8fc661f1 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -418,7 +418,7 @@ export default defineConfig([{ ...globals.mocha, }, - sourceType: "commonjs", + sourceType: "module", parserOptions: {}, }, @@ -489,7 +489,7 @@ export default defineConfig([{ "node/shebang": "off", }, }, { - files: ["packages/create/templates/**/*.{t,j}s?(x)"], + files: ["packages/create/templates/**/*.?(c){t,j}s?(x)"], "rules": { "node/no-missing-require": "off", diff --git a/package.json b/package.json index dc551a8c..972d08c9 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,7 @@ "private": true, "files": [], "packageManager": "pnpm@10.28.1+sha512.7d7dbbca9e99447b7c3bf7a73286afaaf6be99251eb9498baefa7d406892f67b879adb3a1d7e687fc4ccc1a388c7175fbaae567a26ab44d1067b54fcb0d6a316", + "type": "module", "scripts": { "build": "tsc --build", "watch": "tsc --build --watch", diff --git a/packages/controller/controller.ts b/packages/controller/controller.ts index 9787bab6..4c344ba9 100644 --- a/packages/controller/controller.ts +++ b/packages/controller/controller.ts @@ -27,12 +27,12 @@ import jwt from "jsonwebtoken"; // homebrew modules import * as lib from "@clusterio/lib"; -const { ConsoleTransport, levels, logger } = lib; +import { ConsoleTransport, levels, logger } from "@clusterio/lib"; -import Controller from "./src/Controller"; -import UserManager from "./src/UserManager"; -import UserRecord from "./src/UserRecord"; -import { version } from "./package.json"; +import Controller from "./src/Controller.js"; +import UserManager from "./src/UserManager.js"; +import UserRecord from "./src/UserRecord.js"; +import packageConfig from "./package.json" with { type: "json" }; // globals let controller: Controller; @@ -216,7 +216,7 @@ async function handleCopyStaticCommand( pluginInfos: lib.PluginNodeEnvInfo[], ) { await fs.cp( - path.join(__dirname, "..", "web", "static"), + path.join(import.meta.dirname, "..", "web", "static"), args.target, { recursive: true, @@ -377,7 +377,7 @@ async function initialize(): Promise { let command = args._[0]; let shouldRun = false; if (command === "run") { - logger.info(`Starting Clusterio controller ${version}`); + logger.info(`Starting Clusterio controller ${packageConfig.version}`); if (args.recovery) { logger.warn("Controller recovery mode enabled. Some features will be disabled."); } @@ -426,7 +426,7 @@ async function initialize(): Promise { } } - controllerConfig.set("controller.version", version); // Allows tracking last loaded version + controllerConfig.set("controller.version", packageConfig.version); // Allows tracking last loaded version if (!controllerConfig.get("controller.auth_secret")) { logger.info("Generating new controller authentication secret"); @@ -537,6 +537,6 @@ ${err.stack}` }); } -if (module === require.main) { +if (import.meta.main) { bootstrap(); } diff --git a/packages/controller/index.ts b/packages/controller/index.ts index 4e7b2b63..82b2cbad 100644 --- a/packages/controller/index.ts +++ b/packages/controller/index.ts @@ -1,17 +1,17 @@ -import { bootstrap } from "./controller"; -export { default as Controller } from "./src/Controller"; -export { default as ControllerRouter } from "./src/ControllerRouter"; -export { default as ControlConnection } from "./src/ControlConnection"; -export { default as HostConnection } from "./src/HostConnection"; -export { default as InstanceRecord } from "./src/InstanceRecord"; -export { default as InstanceManager } from "./src/InstanceManager"; -export { default as HostRecord } from "./src/HostRecord"; -export { default as BaseControllerPlugin } from "./src/BaseControllerPlugin"; -export { default as UserManager } from "./src/UserManager"; -export { default as UserRecord } from "./src/UserRecord"; -export { default as User } from "./src/User"; -export { default as WsServer } from "./src/WsServer"; +import { bootstrap } from "./controller.js"; +export { default as Controller } from "./src/Controller.js"; +export { default as ControllerRouter } from "./src/ControllerRouter.js"; +export { default as ControlConnection } from "./src/ControlConnection.js"; +export { default as HostConnection } from "./src/HostConnection.js"; +export { default as InstanceRecord } from "./src/InstanceRecord.js"; +export { default as InstanceManager } from "./src/InstanceManager.js"; +export { default as HostRecord } from "./src/HostRecord.js"; +export { default as BaseControllerPlugin } from "./src/BaseControllerPlugin.js"; +export { default as UserManager } from "./src/UserManager.js"; +export { default as UserRecord } from "./src/UserRecord.js"; +export { default as User } from "./src/User.js"; +export { default as WsServer } from "./src/WsServer.js"; -if (module === require.main) { +if (import.meta.main) { bootstrap(); } diff --git a/packages/controller/package.json b/packages/controller/package.json index cc070c83..0ff9fda0 100644 --- a/packages/controller/package.json +++ b/packages/controller/package.json @@ -22,6 +22,7 @@ "access": "public" }, + "type": "module", "main": "dist/node/index.js", "scripts": { "prepare": "tsc --build && webpack-cli --mode production", diff --git a/packages/controller/src/BaseConnection.ts b/packages/controller/src/BaseConnection.ts index 76949eb8..b04c1946 100644 --- a/packages/controller/src/BaseConnection.ts +++ b/packages/controller/src/BaseConnection.ts @@ -1,12 +1,12 @@ import path from "path"; import fs from "node:fs/promises"; -import type Controller from "./Controller"; -import type WsServerConnector from "./WsServerConnector"; +import type Controller from "./Controller.js"; +import type WsServerConnector from "./WsServerConnector.js"; import * as lib from "@clusterio/lib"; -const { logger } = lib; -import * as routes from "./routes"; +import { logger } from "@clusterio/lib"; +import * as routes from "./routes.js"; /** diff --git a/packages/controller/src/BaseControllerPlugin.ts b/packages/controller/src/BaseControllerPlugin.ts index 7b052b42..6f4c579c 100644 --- a/packages/controller/src/BaseControllerPlugin.ts +++ b/packages/controller/src/BaseControllerPlugin.ts @@ -2,10 +2,10 @@ import type { CollectorResult, Event, InstanceStatus, Logger, ModPack, ModInfo, PlayerEvent, PluginNodeEnvInfo, } from "@clusterio/lib"; -import type Controller from "./Controller"; -import type InstanceRecord from "./InstanceRecord"; -import type ControlConnection from "./ControlConnection"; -import type HostConnection from "./HostConnection"; +import type Controller from "./Controller.js"; +import type InstanceRecord from "./InstanceRecord.js"; +import type ControlConnection from "./ControlConnection.js"; +import type HostConnection from "./HostConnection.js"; /** * Base class for controller plugins diff --git a/packages/controller/src/ControlConnection.ts b/packages/controller/src/ControlConnection.ts index c9c9f8b0..63e2d667 100644 --- a/packages/controller/src/ControlConnection.ts +++ b/packages/controller/src/ControlConnection.ts @@ -1,15 +1,15 @@ -import type WsServerConnector from "./WsServerConnector"; +import type WsServerConnector from "./WsServerConnector.js"; import events from "events"; import * as lib from "@clusterio/lib"; -const { logFilter, logger } = lib; +import { logFilter, logger } from "@clusterio/lib"; -import BaseConnection from "./BaseConnection"; -import User from "./User"; -import UserRecord from "./UserRecord"; -import * as routes from "./routes"; -import Controller from "./Controller"; +import BaseConnection from "./BaseConnection.js"; +import User from "./User.js"; +import UserRecord from "./UserRecord.js"; +import * as routes from "./routes.js"; +import Controller from "./Controller.js"; const strcmp = new Intl.Collator(undefined, { numeric: true, sensitivity: "base" }).compare; @@ -1325,5 +1325,3 @@ export default class ControlConnection extends BaseConnection { this._controller.debugEvents.on("message", this.ws_dumper); } } - -module.exports = ControlConnection; diff --git a/packages/controller/src/Controller.ts b/packages/controller/src/Controller.ts index d9362ff7..7c7aa18b 100644 --- a/packages/controller/src/Controller.ts +++ b/packages/controller/src/Controller.ts @@ -1,6 +1,6 @@ import type winston from "winston"; import { BlockList, type AddressInfo, isIPv4, isIPv6 } from "net"; -import type { ControllerArgs } from "../controller"; +import type { ControllerArgs } from "../controller.js"; import express, { type Request, type Response, type NextFunction, type Application } from "express"; import type { Static } from "@sinclair/typebox"; import finalhandler from "finalhandler"; @@ -14,22 +14,23 @@ import jwt from "jsonwebtoken"; import path from "path"; import semver from "semver"; import stream from "stream"; +import { fileURLToPath, pathToFileURL } from "node:url"; import * as lib from "@clusterio/lib"; -const { logger, Summary, Gauge } = lib; +import { logger, Summary, Gauge } from "@clusterio/lib"; -import HttpCloser from "./HttpCloser"; -import InstanceRecord from "./InstanceRecord"; -import * as metrics from "./metrics"; -import * as routes from "./routes"; -import User from "./User"; -import UserRecord from "./UserRecord"; -import UserManager from "./UserManager"; -import WsServer from "./WsServer"; -import HostRecord from "./HostRecord"; -import BaseControllerPlugin from "./BaseControllerPlugin"; -import ControllerRouter from "./ControllerRouter"; -import InstanceManager from "./InstanceManager"; +import HttpCloser from "./HttpCloser.js"; +import InstanceRecord from "./InstanceRecord.js"; +import * as metrics from "./metrics.js"; +import * as routes from "./routes.js"; +import User from "./User.js"; +import UserRecord from "./UserRecord.js"; +import UserManager from "./UserManager.js"; +import WsServer from "./WsServer.js"; +import HostRecord from "./HostRecord.js"; +import BaseControllerPlugin from "./BaseControllerPlugin.js"; +import ControllerRouter from "./ControllerRouter.js"; +import InstanceManager from "./InstanceManager.js"; const endpointDurationSummary = new Summary( "clusterio_controller_http_endpoint_duration_seconds", @@ -345,7 +346,7 @@ export default class Controller { // Start webpack development server if enabled if (args.dev || args.devPlugin) { - this._startDevServer(args); + await this._startDevServer(args); } this.config.on("fieldChanged", (field, curr, prev) => { @@ -383,7 +384,7 @@ export default class Controller { Controller.addAppRoutes(this.app, this.pluginInfos); if (!args.dev) { - let manifestPath = path.join(__dirname, "..", "..", "web", "manifest.json"); + let manifestPath = path.join(import.meta.dirname, "..", "..", "web", "manifest.json"); let manifest = await Controller.loadJsonObject(manifestPath); if (!manifest["main.js"]) { @@ -458,12 +459,13 @@ export default class Controller { async _startDevServer(args: ControllerArgs) { logger.warn("Webpack development mode enabled"); - const webpack = require("webpack"); - const webpackDevMiddleware = require("webpack-dev-middleware"); + const webpack = (await import("webpack")).default; + const webpackDevMiddleware = (await import("webpack-dev-middleware")).default; const webpackConfigs = []; if (args.dev) { - webpackConfigs.push(require("../../../webpack.config")({})); // Path outside of build + // @ts-expect-error this file is run from a different folder + webpackConfigs.push((await import("../../../webpack.config.cjs")).default({})); // Path outside of build } if (args.devPlugin) { let devPlugins = new Map(); @@ -472,7 +474,10 @@ export default class Controller { if (!info) { throw new lib.StartupError(`No plugin named ${name}`); } - let config = require(path.posix.join(info.requirePath, "webpack.config"))({}); + const webpackConfig = path.posix.join(info.requirePath, "webpack.config.cjs"); + let config = (await import( + path.isAbsolute(webpackConfig) ? pathToFileURL(webpackConfig).href : webpackConfig + )).default({}); devPlugins.set(name, webpackConfigs.length); webpackConfigs.push(config); } @@ -627,7 +632,9 @@ export default class Controller { try { // First check the clusterio version const runningVersion = this.config.get("controller.version"); - const packageJsonPath = require.resolve("@clusterio/controller/package.json"); + const packageJsonPath = fileURLToPath( + import.meta.resolve("@clusterio/controller/package.json"), + ); const packageJson = JSON.parse(await fs.readFile(packageJsonPath, "utf8")); if (runningVersion !== packageJson.version) { this.config.restartRequired = true; @@ -651,7 +658,7 @@ export default class Controller { } } } catch (err: any) { - logger.warn(`Failed to read package json for ${packageName}:\n${err.stack ?? err.message}`); + logger.warn(`Failed to read package.json for ${packageName}:\n${err.stack ?? err.message}`); } return false; @@ -660,7 +667,7 @@ export default class Controller { async checkRestartDowngrade() { try { const runningVersion = this.config.get("controller.version"); - const packageJsonPath = require.resolve("@clusterio/controller/package.json"); + const packageJsonPath = fileURLToPath(import.meta.resolve("@clusterio/controller/package.json")); const packageJson = JSON.parse(await fs.readFile(packageJsonPath, "utf8")); const installedVersion = packageJson.version; @@ -901,7 +908,7 @@ export default class Controller { // Set folder to serve static content from (the website) const staticOptions = { immutable: true, maxAge: 1000 * 86400 * 365 }; app.use("/static", - express.static(path.join(__dirname, "..", "..", "web", "static"), staticOptions) + express.static(path.join(import.meta.dirname, "..", "..", "web", "static"), staticOptions) ); app.use("/static", express.static("static", staticOptions)); // Used for data export files @@ -1124,7 +1131,7 @@ export default class Controller { for (let pluginInfo of this.pluginInfos) { try { let manifestPath = path.posix.join(pluginInfo.requirePath, "dist", "web", "manifest.json"); - pluginInfo.manifest = await Controller.loadJsonObject(require.resolve(manifestPath), true); + pluginInfo.manifest = await Controller.loadJsonObject(import.meta.resolve(manifestPath), true); } catch (err) { logger.warn(`Unable to load dist/web/manifest.json for plugin ${pluginInfo.name}`); } @@ -1241,7 +1248,10 @@ export default class Controller { } mainBundle = routes.stripStaticPrefix(mainBundle); - fs.readFile(path.join(__dirname, "..", "..", "..", "web", "index.html"), "utf8").then((content) => { + fs.readFile( + path.join(import.meta.dirname, "..", "..", "..", "web", "index.html"), + "utf8", + ).then((content) => { res.type("text/html"); res.send(content .replace(/__CLUSTER_NAME__/g, res.app.locals.controller.config.get("controller.name")) diff --git a/packages/controller/src/ControllerRouter.ts b/packages/controller/src/ControllerRouter.ts index 4072c941..4b90abb8 100644 --- a/packages/controller/src/ControllerRouter.ts +++ b/packages/controller/src/ControllerRouter.ts @@ -1,10 +1,10 @@ -import type Controller from "./Controller"; -import type BaseConnection from "./BaseConnection"; +import type Controller from "./Controller.js"; +import type BaseConnection from "./BaseConnection.js"; import * as lib from "@clusterio/lib"; -import HostConnection from "./HostConnection"; -import ControlConnection from "./ControlConnection"; -const { logger } = lib; +import { logger } from "@clusterio/lib"; +import HostConnection from "./HostConnection.js"; +import ControlConnection from "./ControlConnection.js"; export default class ControllerRouter { constructor( diff --git a/packages/controller/src/HostConnection.ts b/packages/controller/src/HostConnection.ts index e7132925..c368f8c8 100644 --- a/packages/controller/src/HostConnection.ts +++ b/packages/controller/src/HostConnection.ts @@ -1,12 +1,12 @@ -import type Controller from "./Controller"; -import type WsServerConnector from "./WsServerConnector"; +import type Controller from "./Controller.js"; +import type WsServerConnector from "./WsServerConnector.js"; import * as lib from "@clusterio/lib"; -const { logger } = lib; +import { logger } from "@clusterio/lib"; -import BaseConnection from "./BaseConnection"; -import InstanceRecord from "./InstanceRecord"; -import HostRecord from "./HostRecord"; +import BaseConnection from "./BaseConnection.js"; +import InstanceRecord from "./InstanceRecord.js"; +import HostRecord from "./HostRecord.js"; /** diff --git a/packages/controller/src/InstanceManager.ts b/packages/controller/src/InstanceManager.ts index e1cf1941..51292dc6 100644 --- a/packages/controller/src/InstanceManager.ts +++ b/packages/controller/src/InstanceManager.ts @@ -1,8 +1,8 @@ import * as lib from "@clusterio/lib"; -import type Controller from "./Controller"; -import type HostConnection from "./HostConnection"; -import InstanceRecord from "./InstanceRecord"; +import type Controller from "./Controller.js"; +import type HostConnection from "./HostConnection.js"; +import InstanceRecord from "./InstanceRecord.js"; export default class InstanceManager { private static readonly DefaultFactorioSettings = { diff --git a/packages/controller/src/User.ts b/packages/controller/src/User.ts index d82202a1..c4fe115f 100644 --- a/packages/controller/src/User.ts +++ b/packages/controller/src/User.ts @@ -4,7 +4,7 @@ import { PermissionError, permissions, } from "@clusterio/lib"; -import UserRecord from "./UserRecord"; +import UserRecord from "./UserRecord.js"; import { Static } from "@sinclair/typebox"; /** diff --git a/packages/controller/src/UserManager.ts b/packages/controller/src/UserManager.ts index 0b4861b8..60649e5f 100644 --- a/packages/controller/src/UserManager.ts +++ b/packages/controller/src/UserManager.ts @@ -3,8 +3,8 @@ import jwt from "jsonwebtoken"; import * as lib from "@clusterio/lib"; -import User from "./User"; -import UserRecord from "./UserRecord"; +import User from "./User.js"; +import UserRecord from "./UserRecord.js"; /** * Access layer for users on the controller. diff --git a/packages/controller/src/WsServer.ts b/packages/controller/src/WsServer.ts index c2b33c81..f6293b84 100644 --- a/packages/controller/src/WsServer.ts +++ b/packages/controller/src/WsServer.ts @@ -1,18 +1,18 @@ import type { IncomingMessage } from "http"; import type { Duplex } from "stream"; -import type Controller from "./Controller"; +import type Controller from "./Controller.js"; import jwt from "jsonwebtoken"; import WebSocket, { WebSocketServer } from "ws"; import * as lib from "@clusterio/lib"; -const { logger } = lib; +import { logger } from "@clusterio/lib"; -import ControlConnection from "./ControlConnection"; -import HostConnection from "./HostConnection"; -import WsServerConnector from "./WsServerConnector"; +import ControlConnection from "./ControlConnection.js"; +import HostConnection from "./HostConnection.js"; +import WsServerConnector from "./WsServerConnector.js"; -import { version as packageVersion } from "../package.json"; +import packageConfig from "../package.json" with { type: "json" }; const wsMessageCounter = new lib.Counter( "clusterio_controller_websocket_message_total", @@ -45,12 +45,12 @@ export default class WsServer { sessionAud: string = `session-${Date.now()}`; nextSessionId: number = 1; nextControlId: number = 1; - wss: WebSocket.Server; + wss: WebSocketServer; constructor(controller: Controller) { this.controller = controller; - this.wss = new WebSocket.Server({ + this.wss = new WebSocketServer({ noServer: true, path: "/api/socket", }); @@ -139,7 +139,7 @@ export default class WsServer { loadedPlugins[name] = plugin.info.version; } - socket.send(JSON.stringify(new lib.MessageHello(new lib.HelloData(packageVersion, loadedPlugins)))); + socket.send(JSON.stringify(new lib.MessageHello(new lib.HelloData(packageConfig.version, loadedPlugins)))); this.attachHandler(socket, req); } @@ -287,10 +287,11 @@ ${err.stack}` logger.info( `WsServer | registered host ${data.id} using version ${data.version}` ); - if (data.version !== packageVersion) { + if (data.version !== packageConfig.version) { logger.warn( `Host ${data.id} connected using version ${data.version} which does not match the ` + - `version of the controller is currently running (${packageVersion}). It may not work as expected.` + `version of the controller is currently running (${packageConfig.version}). ` + + "It may not work as expected." ); } diff --git a/packages/controller/src/WsServerConnector.ts b/packages/controller/src/WsServerConnector.ts index 403feeb6..7277f8c3 100644 --- a/packages/controller/src/WsServerConnector.ts +++ b/packages/controller/src/WsServerConnector.ts @@ -1,10 +1,10 @@ -import type WebSocket from "ws"; +import { type WebSocket } from "ws"; import events from "events"; import assert from "assert/strict"; import * as lib from "@clusterio/lib"; -const { logger } = lib; +import { logger } from "@clusterio/lib"; /** @@ -49,7 +49,7 @@ export default class WsServerConnector extends lib.WebSocketBaseConnector { * @param account - account data to provide to control connection */ ready( - socket: WebSocket.WebSocket, + socket: WebSocket, src: lib.Address, sessionToken: string, account: lib.AccountDetails | undefined @@ -80,7 +80,7 @@ export default class WsServerConnector extends lib.WebSocketBaseConnector { * @param lastSeq - The last message the client received. */ continue( - socket: WebSocket.WebSocket, + socket: WebSocket, lastSeq: number ) { diff --git a/packages/controller/src/routes.ts b/packages/controller/src/routes.ts index f99d729f..5e522583 100644 --- a/packages/controller/src/routes.ts +++ b/packages/controller/src/routes.ts @@ -1,5 +1,5 @@ import type { Application, Request, Response } from "express"; -import Controller from "./Controller"; +import Controller from "./Controller.js"; import busboy from "busboy"; import crypto from "crypto"; @@ -12,7 +12,7 @@ import nodeStream from "stream"; import util from "util"; import * as lib from "@clusterio/lib"; -const { logger } = lib; +import { logger } from "@clusterio/lib"; const finished = util.promisify(nodeStream.finished); diff --git a/packages/controller/webpack.config.js b/packages/controller/webpack.config.cjs similarity index 100% rename from packages/controller/webpack.config.js rename to packages/controller/webpack.config.cjs diff --git a/packages/create/create.js b/packages/create/create.js index 1fc26b6f..457dae2b 100755 --- a/packages/create/create.js +++ b/packages/create/create.js @@ -1,20 +1,19 @@ #!/usr/bin/env node -"use strict"; -const child_process = require("child_process"); -const fs = require("node:fs/promises"); -const inquirer = require("inquirer"); -const os = require("os"); -const path = require("path"); -const stream = require("stream"); -const util = require("util"); -const yargs = require("yargs"); +import child_process from "node:child_process"; +import fs from "node:fs/promises"; +import inquirer from "inquirer"; +import os from "node:os"; +import path from "node:path"; +import stream from "node:stream"; +import util from "node:util"; +import yargs from "yargs"; -const { levels, logger, setLogLevel } = require("./logging"); -const { copyPluginTemplates } = require("./template"); +import { levels, logger, setLogLevel } from "./logging.js"; +import { copyPluginTemplates } from "./template.js"; let dev = false; const scriptExt = process.platform === "win32" ? ".cmd" : ""; -const { escapeArg } = require("./escape_arg"); +import { escapeArg } from "./escape_arg.js"; // I hate this, there is a bug with rl.close on windows that was meant to have been fixed in Node14.4 // See nodejs/node#21771 and nodejs/node#30701 for the apparent fix that was applied @@ -147,21 +146,21 @@ async function execFile(cmd, args) { async function execController(args) { if (dev) { - return await execFile("node", [path.join(__dirname, "..", "controller"), ...args]); + return await execFile("node", [path.join(import.meta.dirname, "..", "controller"), ...args]); } return await execFile(path.join("node_modules", ".bin", `clusteriocontroller${scriptExt}`), args); } async function execHost(args) { if (dev) { - return await execFile("node", [path.join(__dirname, "..", "host"), ...args]); + return await execFile("node", [path.join(import.meta.dirname, "..", "host"), ...args]); } return await execFile(path.join("node_modules", ".bin", `clusteriohost${scriptExt}`), args); } async function execCtl(args) { if (dev) { - return await execFile("node", [path.join(__dirname, "..", "ctl"), ...args]); + return await execFile("node", [path.join(import.meta.dirname, "..", "ctl"), ...args]); } return await execFile(path.join("node_modules", ".bin", `clusterioctl${scriptExt}`), args); } @@ -408,7 +407,7 @@ async function installClusterio(mode, plugins) { for (let plugin of plugins) { if (!pluginList.has(plugin)) { - let pluginInfo = require(require.resolve(plugin, { paths: [process.cwd()] })).plugin; + let pluginInfo = (await import(plugin)).plugin; pluginList.set(pluginInfo.name, plugin); } } @@ -900,7 +899,7 @@ async function main() { /* eslint-enable no-console */ } -if (module === require.main) { +if (import.meta.main) { main().catch(err => { if (err instanceof InstallError) { logger.error(err.message); diff --git a/packages/create/escape_arg.js b/packages/create/escape_arg.js index 3767ae82..b194c75f 100644 --- a/packages/create/escape_arg.js +++ b/packages/create/escape_arg.js @@ -1,6 +1,4 @@ -"use strict"; - -function escapeArg(arg) { +export function escapeArg(arg) { // When shell: true is used execFile does not escaping of arguments, they are // simply joined by space and then passed to the shell. @@ -56,7 +54,3 @@ function escapeArg(arg) { } return `"${arg.replace(/[$`"\\]/g, "\\$&")}"`; } - -module.exports = { - escapeArg, -}; diff --git a/packages/create/logging.js b/packages/create/logging.js index 265dd8e1..9954b666 100644 --- a/packages/create/logging.js +++ b/packages/create/logging.js @@ -1,8 +1,7 @@ /* eslint-disable no-console */ -"use strict"; -const chalk = require("chalk"); +import chalk from "chalk"; -const levels = Object.freeze({ +export const levels = Object.freeze({ fatal: 0, error: 1, warn: 2, @@ -11,7 +10,7 @@ const levels = Object.freeze({ verbose: 6, }); -const colors = { +export const colors = { fatal: "inverse red", error: "bold redBright", warn: "bold yellowBright", @@ -21,7 +20,7 @@ const colors = { }; let maxLogLevel = levels.info; -const logger = {}; +export const logger = {}; for (let [name, level] of Object.entries(levels)) { // eslint-disable-next-line no-loop-func logger[name] = message => { @@ -42,10 +41,6 @@ for (let [name, level] of Object.entries(levels)) { }; } -module.exports = { - colors, - levels, - setLogLevel: (level) => { maxLogLevel = level; }, - logger, -}; - +export function setLogLevel(level) { + maxLogLevel = level; +} diff --git a/packages/create/package.json b/packages/create/package.json index aa0bfd24..601defa0 100644 --- a/packages/create/package.json +++ b/packages/create/package.json @@ -22,6 +22,7 @@ "access": "public" }, + "type": "module", "main": "create.js", "bin": { "clusteriocreate": "./create.js" diff --git a/packages/create/template.js b/packages/create/template.js index e878a42a..99505d70 100644 --- a/packages/create/template.js +++ b/packages/create/template.js @@ -1,9 +1,8 @@ -"use strict"; -const { logger } = require("./logging"); -const fs = require("node:fs/promises"); -const path = require("path"); +import { logger } from "./logging.js"; +import fs from "node:fs/promises"; +import path from "node:path"; -const _package = require("./package.json"); +import _package from "./package.json" with { type: "json" }; async function copyTemplateFile(src, dst, properties) { logger.verbose(`Writing ${dst} from template ${src}`); @@ -79,7 +78,7 @@ async function copyTemplateFile(src, dst, properties) { } } -async function copyPluginTemplates(pluginName, templates) { +export async function copyPluginTemplates(pluginName, templates) { logger.info(`Please wait, coping templates for ${templates.join(", ")}`); const files = new Map(); const prepare = []; @@ -96,8 +95,11 @@ async function copyPluginTemplates(pluginName, templates) { // Get the file extension and path to the templates const ext = javascriptOnly ? "js" : "ts"; - const templatePath = path.resolve(__dirname, javascriptOnly ? "./templates/plugin-js" : "./templates/plugin-ts"); - const commonPath = path.resolve(__dirname, "./templates/common"); + const templatePath = path.resolve( + import.meta.dirname, + javascriptOnly ? "./templates/plugin-js" : "./templates/plugin-ts" + ); + const commonPath = path.resolve(import.meta.dirname, "./templates/common"); // Files included in all templates files.set(".gitignore", path.join(commonPath, "template.gitignore")); @@ -119,7 +121,7 @@ async function copyPluginTemplates(pluginName, templates) { // Files and dependences to support webpack if (webpack) { prepare.push("webpack-cli --mode production"); - files.set("webpack.config.js", path.join(commonPath, "webpack.config.js")); + files.set("webpack.config.cjs", path.join(commonPath, "webpack.config.cjs")); if (templates.includes("web")) { files.set(`web/index.${ext}x`, path.join(templatePath, `web/plugin.${ext}x`)); pluginContexts += 1; @@ -202,7 +204,3 @@ async function copyPluginTemplates(pluginName, templates) { await Promise.all(writes); logger.info("Successfully wrote all template files"); } - -module.exports = { - copyPluginTemplates, -}; diff --git a/packages/create/templates/common/package.json b/packages/create/templates/common/package.json index 0e01b9d7..7169e2aa 100644 --- a/packages/create/templates/common/package.json +++ b/packages/create/templates/common/package.json @@ -2,6 +2,7 @@ "name": "__plugin_name__", "version": "0.1.0", "description": "Example Description. Package. Change me in package.json", + "type": "module", //%if typescript "main": "dist/node/index.js", //%endif diff --git a/packages/create/templates/common/webpack.config.js b/packages/create/templates/common/webpack.config.cjs similarity index 100% rename from packages/create/templates/common/webpack.config.js rename to packages/create/templates/common/webpack.config.cjs diff --git a/packages/create/templates/plugin-js/controller.js b/packages/create/templates/plugin-js/controller.js index fae78fdc..4efb047d 100644 --- a/packages/create/templates/plugin-js/controller.js +++ b/packages/create/templates/plugin-js/controller.js @@ -1,19 +1,18 @@ -"use strict"; -const lib = require("@clusterio/lib"); -const { BaseControllerPlugin } = require("@clusterio/controller"); +import * as lib from "@clusterio/lib"; +import { BaseControllerPlugin } from "@clusterio/controller"; //%if multi_context // Messages requires multi context -const { +import { PluginExampleEvent, PluginExampleRequest, //%endif //%if controller & web // Subscribing requires web content and the controller ExampleSubscribableUpdate, ExampleSubscribableValue, //%endif //%if multi_context // Messages requires multi context -} = require("./messages"); +} from "./messages.js"; //%endif -class ControllerPlugin extends BaseControllerPlugin { +export class ControllerPlugin extends BaseControllerPlugin { //%if controller & web // Subscribing requires web content and the controller exampleDatabase; storageDirty = false; @@ -79,7 +78,3 @@ class ControllerPlugin extends BaseControllerPlugin { } //%endif } - -module.exports = { - ControllerPlugin, -}; diff --git a/packages/create/templates/plugin-js/ctl.js b/packages/create/templates/plugin-js/ctl.js index 95e886b9..03377b92 100644 --- a/packages/create/templates/plugin-js/ctl.js +++ b/packages/create/templates/plugin-js/ctl.js @@ -1,8 +1,7 @@ -"use strict"; -const { BaseCtlPlugin } = require("@clusterio/ctl"); -const { CommandTree, Command } = require("@clusterio/lib"); +import { BaseCtlPlugin } from "@clusterio/ctl"; +import { CommandTree, Command } from "@clusterio/lib"; //%// We do not check for multi context here because it doesn't make sense to have a ctl without messages -const { PluginExampleEvent, PluginExampleRequest } = require("./messages"); +import { PluginExampleEvent, PluginExampleRequest } from "./messages.js"; /* eslint-disable no-console */ const pluginCommands = new CommandTree({ @@ -21,12 +20,8 @@ pluginCommands.add(new Command({ })); /* eslint-enable no-console */ -class CtlPlugin extends BaseCtlPlugin { +export class CtlPlugin extends BaseCtlPlugin { async addCommands(rootCommand) { rootCommand.add(pluginCommands); } } - -module.exports = { - CtlPlugin, -}; diff --git a/packages/create/templates/plugin-js/host.js b/packages/create/templates/plugin-js/host.js index c1e1468d..6675acff 100644 --- a/packages/create/templates/plugin-js/host.js +++ b/packages/create/templates/plugin-js/host.js @@ -1,11 +1,10 @@ -"use strict"; -const lib = require("@clusterio/lib"); -const { BaseHostPlugin } = require("@clusterio/host"); +import * as lib from "@clusterio/lib"; +import { BaseHostPlugin } from "@clusterio/host"; //%if multi_context -const { PluginExampleEvent, PluginExampleRequest } = require("./messages"); +import { PluginExampleEvent, PluginExampleRequest } from "./messages.js"; //%endif -class HostPlugin extends BaseHostPlugin { +export class HostPlugin extends BaseHostPlugin { //%if multi_context async init() { this.host.handle(PluginExampleEvent, this.handlePluginExampleEvent.bind(this)); @@ -35,7 +34,3 @@ class HostPlugin extends BaseHostPlugin { } //%endif } - -module.exports = { - HostPlugin, -}; diff --git a/packages/create/templates/plugin-js/index.js b/packages/create/templates/plugin-js/index.js index d773d4c4..932b460d 100644 --- a/packages/create/templates/plugin-js/index.js +++ b/packages/create/templates/plugin-js/index.js @@ -1,7 +1,6 @@ -"use strict"; -const lib = require("@clusterio/lib"); +import * as lib from "@clusterio/lib"; //%if multi_context -const Messages = require("./messages"); +import Messages from "./messages.js"; lib.definePermission({ name: "__plugin_name__.example.permission.event", @@ -36,7 +35,7 @@ lib.definePermission({ }); //%endif -const plugin = { +export const plugin = { name: "__plugin_name__", title: "__plugin_name__", description: "Example Description. Plugin. Change me in index.js", @@ -44,7 +43,7 @@ const plugin = { //%endif //%if controller - controllerEntrypoint: "./dist/node/controller", + controllerEntrypoint: "./dist/node/controller.js", //%endif //%if controller & config controllerConfigFields: { @@ -60,7 +59,7 @@ const plugin = { //%endif //%if host - hostEntrypoint: "./dist/node/host", + hostEntrypoint: "./dist/node/host.js", //%endif //%if host & config hostConfigFields: { @@ -76,7 +75,7 @@ const plugin = { //%endif //%if instance | module // Modules load an empty instance plugin - instanceEntrypoint: "./dist/node/instance", + instanceEntrypoint: "./dist/node/instance.js", //%endif //%if instance & config instanceConfigFields: { @@ -92,7 +91,7 @@ const plugin = { //%endif //%if ctl - ctlEntrypoint: "./dist/node/ctl", + ctlEntrypoint: "./dist/node/ctl.js", //%endif //%if ctl & config controlConfigFields: { @@ -124,7 +123,3 @@ const plugin = { ], //%endif }; - -module.exports = { - plugin, -}; diff --git a/packages/create/templates/plugin-js/instance.js b/packages/create/templates/plugin-js/instance.js index 41175938..8049e468 100644 --- a/packages/create/templates/plugin-js/instance.js +++ b/packages/create/templates/plugin-js/instance.js @@ -1,11 +1,10 @@ -"use strict"; -const lib = require("@clusterio/lib"); -const { BaseInstancePlugin } = require("@clusterio/host"); +import * as lib from "@clusterio/lib"; +import { BaseInstancePlugin } from "@clusterio/host"; //%if multi_context -const { PluginExampleEvent, PluginExampleRequest } = require("./messages"); +import { PluginExampleEvent, PluginExampleRequest } from "./messages.js"; //%endif -class InstancePlugin extends BaseInstancePlugin { +export class InstancePlugin extends BaseInstancePlugin { //%if multi_context | module async init() { //%if multi_context @@ -68,7 +67,3 @@ class InstancePlugin extends BaseInstancePlugin { } //%endif } - -module.exports = { - InstancePlugin, -}; diff --git a/packages/create/templates/plugin-js/instance_empty.js b/packages/create/templates/plugin-js/instance_empty.js index 177f9952..cf4f0b68 100644 --- a/packages/create/templates/plugin-js/instance_empty.js +++ b/packages/create/templates/plugin-js/instance_empty.js @@ -1,11 +1,6 @@ -"use strict"; -const { BaseInstancePlugin } = require("@clusterio/host"); +import { BaseInstancePlugin } from "@clusterio/host"; -class InstancePlugin extends BaseInstancePlugin { +export class InstancePlugin extends BaseInstancePlugin { // This class is empty because an instance plugin must be defined for a module to be injected // This requirement may change in the future to allow for standalone modules } - -module.exports = { - InstancePlugin, -}; diff --git a/packages/create/templates/plugin-js/messages.js b/packages/create/templates/plugin-js/messages.js index aaffd9f6..296856ea 100644 --- a/packages/create/templates/plugin-js/messages.js +++ b/packages/create/templates/plugin-js/messages.js @@ -1,8 +1,7 @@ -"use strict"; -const { plainJson, jsonArray, JsonBoolean, JsonNumber, JsonString, StringEnum } = require("@clusterio/lib"); -const { Type } = require("@sinclair/typebox"); +import { plainJson, jsonArray, JsonBoolean, JsonNumber, JsonString, StringEnum } from "@clusterio/lib"; +import { Type } from "@sinclair/typebox"; -class PluginExampleEvent { +export class PluginExampleEvent { static type = "event"; static src = ["host", "control"]; static dst = ["controller", "host", "instance"]; @@ -24,7 +23,7 @@ class PluginExampleEvent { } } -class PluginExampleRequest { +export class PluginExampleRequest { static type = "request"; static src = ["host", "control"]; static dst = ["controller", "host", "instance"]; @@ -52,7 +51,7 @@ class PluginExampleRequest { } //%if controller & web // Subscribing requires web content and the controller -class ExampleSubscribableValue { +export class ExampleSubscribableValue { constructor(id, updatedAtMs, isDeleted) { this.id = id; this.updatedAtMs = updatedAtMs; @@ -70,7 +69,7 @@ class ExampleSubscribableValue { } } -class ExampleSubscribableUpdate { +export class ExampleSubscribableUpdate { static type = "event"; static src = "controller"; static dst = "control"; @@ -90,12 +89,3 @@ class ExampleSubscribableUpdate { } } //%endif - -module.exports = { - PluginExampleEvent, - PluginExampleRequest, -//%if controller & web // Subscribing requires web content and the controller - ExampleSubscribableValue, - ExampleSubscribableUpdate, -//%endif -}; diff --git a/packages/create/templates/plugin-js/web/plugin.jsx b/packages/create/templates/plugin-js/web/plugin.jsx index 4aa14c85..48f90cf9 100644 --- a/packages/create/templates/plugin-js/web/plugin.jsx +++ b/packages/create/templates/plugin-js/web/plugin.jsx @@ -21,7 +21,7 @@ import { ExampleSubscribableUpdate, ExampleSubscribableValue, //%endif //%if multi_context // Messages requires multi context -} from "../messages"; +} from "../messages.js"; //%endif import * as lib from "@clusterio/lib"; diff --git a/packages/create/templates/plugin-ts/controller.ts b/packages/create/templates/plugin-ts/controller.ts index 59fb296d..f69e5b72 100644 --- a/packages/create/templates/plugin-ts/controller.ts +++ b/packages/create/templates/plugin-ts/controller.ts @@ -9,7 +9,7 @@ import { ExampleSubscribableUpdate, ExampleSubscribableValue, //%endif //%if multi_context // Messages requires multi context -} from "./messages"; +} from "./messages.js"; //%endif export class ControllerPlugin extends BaseControllerPlugin { diff --git a/packages/create/templates/plugin-ts/ctl.ts b/packages/create/templates/plugin-ts/ctl.ts index dc0fa01b..0a42aa8a 100644 --- a/packages/create/templates/plugin-ts/ctl.ts +++ b/packages/create/templates/plugin-ts/ctl.ts @@ -1,7 +1,7 @@ import { BaseCtlPlugin, type Control } from "@clusterio/ctl"; import { CommandTree, Command } from "@clusterio/lib"; //%// We do not check for multi context here because it doesn't make sense to have a ctl without messages -import { PluginExampleEvent, PluginExampleRequest } from "./messages"; +import { PluginExampleEvent, PluginExampleRequest } from "./messages.js"; /* eslint-disable no-console */ const pluginCommands = new CommandTree({ diff --git a/packages/create/templates/plugin-ts/host.ts b/packages/create/templates/plugin-ts/host.ts index 9a395988..ed31b4e5 100644 --- a/packages/create/templates/plugin-ts/host.ts +++ b/packages/create/templates/plugin-ts/host.ts @@ -1,7 +1,7 @@ import * as lib from "@clusterio/lib"; import { BaseHostPlugin } from "@clusterio/host"; //%if multi_context -import { PluginExampleEvent, PluginExampleRequest } from "./messages"; +import { PluginExampleEvent, PluginExampleRequest } from "./messages.js"; //%endif export class HostPlugin extends BaseHostPlugin { diff --git a/packages/create/templates/plugin-ts/index.ts b/packages/create/templates/plugin-ts/index.ts index 539a66bc..8027808b 100644 --- a/packages/create/templates/plugin-ts/index.ts +++ b/packages/create/templates/plugin-ts/index.ts @@ -1,6 +1,6 @@ import * as lib from "@clusterio/lib"; //%if multi_context -import * as Messages from "./messages"; +import * as Messages from "./messages.js"; lib.definePermission({ name: "__plugin_name__.example.permission.event", @@ -71,7 +71,7 @@ export const plugin: lib.PluginDeclaration = { //%endif //%if controller - controllerEntrypoint: "./dist/node/controller", + controllerEntrypoint: "./dist/node/controller.js", //%endif //%if controller & config controllerConfigFields: { @@ -87,7 +87,7 @@ export const plugin: lib.PluginDeclaration = { //%endif //%if host - hostEntrypoint: "./dist/node/host", + hostEntrypoint: "./dist/node/host.js", //%endif //%if host & config hostConfigFields: { @@ -103,7 +103,7 @@ export const plugin: lib.PluginDeclaration = { //%endif //%if instance | module // Modules load an empty instance plugin - instanceEntrypoint: "./dist/node/instance", + instanceEntrypoint: "./dist/node/instance.js", //%endif //%if instance & config instanceConfigFields: { @@ -119,7 +119,7 @@ export const plugin: lib.PluginDeclaration = { //%endif //%if ctl - ctlEntrypoint: "./dist/node/ctl", + ctlEntrypoint: "./dist/node/ctl.js", //%endif //%if ctl & config controlConfigFields: { diff --git a/packages/create/templates/plugin-ts/instance.ts b/packages/create/templates/plugin-ts/instance.ts index 133efa6f..9f3cf81d 100644 --- a/packages/create/templates/plugin-ts/instance.ts +++ b/packages/create/templates/plugin-ts/instance.ts @@ -1,7 +1,7 @@ import * as lib from "@clusterio/lib"; import { BaseInstancePlugin } from "@clusterio/host"; //%if multi_context -import { PluginExampleEvent, PluginExampleRequest } from "./messages"; +import { PluginExampleEvent, PluginExampleRequest } from "./messages.js"; //%endif //%if module diff --git a/packages/create/templates/plugin-ts/web/plugin.tsx b/packages/create/templates/plugin-ts/web/plugin.tsx index 40d1ca9b..3584a098 100644 --- a/packages/create/templates/plugin-ts/web/plugin.tsx +++ b/packages/create/templates/plugin-ts/web/plugin.tsx @@ -21,7 +21,7 @@ import { ExampleSubscribableUpdate, ExampleSubscribableValue, //%endif //%if multi_context // Messages requires multi context -} from "../messages"; +} from "../messages.js"; //%endif import * as lib from "@clusterio/lib"; diff --git a/packages/ctl/ctl.ts b/packages/ctl/ctl.ts index 926db7e0..b3141d5f 100755 --- a/packages/ctl/ctl.ts +++ b/packages/ctl/ctl.ts @@ -7,16 +7,16 @@ import fs from "node:fs/promises"; import yargs, { type Argv } from "yargs"; import path from "path"; -import { version } from "./package.json"; +import packageConfig from "./package.json" with { type: "json" }; import { strict as assert } from "assert"; // Reduce startup time by lazy compiling schemas. -(global as any).lazySchemaCompilation = true; +import "./src/set_lazy_schema_compliation.js"; import * as lib from "@clusterio/lib"; import { ConsoleTransport, levels, logger } from "@clusterio/lib"; -import * as commands from "./src/commands"; -import BaseCtlPlugin from "./src/BaseCtlPlugin"; +import * as commands from "./src/commands.js"; +import BaseCtlPlugin from "./src/BaseCtlPlugin.js"; /** @@ -37,7 +37,7 @@ class ControlConnector extends lib.WebSocketClientConnector { new lib.MessageRegisterControl( new lib.RegisterControlData( this._token, - version, + packageConfig.version, ) ) ); @@ -377,6 +377,6 @@ ${err.stack}` }); } -if (module === require.main) { +if (import.meta.main) { bootstrap(); } diff --git a/packages/ctl/index.ts b/packages/ctl/index.ts index 54bd5f27..0852c19b 100644 --- a/packages/ctl/index.ts +++ b/packages/ctl/index.ts @@ -1,7 +1,7 @@ -import { bootstrap } from "./ctl"; -export * from "./ctl"; -export { default as BaseCtlPlugin } from "./src/BaseCtlPlugin"; +import { bootstrap } from "./ctl.js"; +export * from "./ctl.js"; +export { default as BaseCtlPlugin } from "./src/BaseCtlPlugin.js"; -if (module === require.main) { +if (import.meta.main) { bootstrap(); } diff --git a/packages/ctl/package.json b/packages/ctl/package.json index 96d18c33..04f1373b 100644 --- a/packages/ctl/package.json +++ b/packages/ctl/package.json @@ -22,6 +22,7 @@ "access": "public" }, + "type": "module", "main": "dist/node/index.js", "scripts": { "prepare": "tsc --build", diff --git a/packages/ctl/src/commands.ts b/packages/ctl/src/commands.ts index ffb46193..5e31a507 100644 --- a/packages/ctl/src/commands.ts +++ b/packages/ctl/src/commands.ts @@ -1,17 +1,17 @@ import type { Argv } from "yargs"; import * as lib from "@clusterio/lib"; -import type BaseCtlPlugin from "./BaseCtlPlugin"; -import { controllerCommands } from "./commands_controller"; -import { hostCommands } from "./commands_host"; -import { instanceCommands } from "./commands_instance"; -import { modPackCommands } from "./commands_mod_pack"; -import { modCommands } from "./commands_mod"; -import { permissionCommands } from "./commands_permission"; -import { roleCommands } from "./commands_role"; -import { userCommands } from "./commands_user"; -import { logCommands } from "./commands_log"; -import { debugCommands } from "./commands_debug"; +import type BaseCtlPlugin from "./BaseCtlPlugin.js"; +import { controllerCommands } from "./commands_controller.js"; +import { hostCommands } from "./commands_host.js"; +import { instanceCommands } from "./commands_instance.js"; +import { modPackCommands } from "./commands_mod_pack.js"; +import { modCommands } from "./commands_mod.js"; +import { permissionCommands } from "./commands_permission.js"; +import { roleCommands } from "./commands_role.js"; +import { userCommands } from "./commands_user.js"; +import { logCommands } from "./commands_log.js"; +import { debugCommands } from "./commands_debug.js"; export async function registerCommands(ctlPlugins: Map, yargs: Argv) { const rootCommands = new lib.CommandTree({ name: "clusterioctl", description: "Manage cluster" }); diff --git a/packages/ctl/src/commands_controller.ts b/packages/ctl/src/commands_controller.ts index fbdde7a4..4bfbd41e 100644 --- a/packages/ctl/src/commands_controller.ts +++ b/packages/ctl/src/commands_controller.ts @@ -5,9 +5,9 @@ import os from "os"; import child_process from "child_process"; import * as lib from "@clusterio/lib"; -import type { Control } from "../ctl"; -import { print } from "./command_ops"; -import { serializedConfigToString, getEditor, configToKeyVal } from "./config_ops"; +import type { Control } from "../ctl.js"; +import { print } from "./command_ops.js"; +import { serializedConfigToString, getEditor, configToKeyVal } from "./config_ops.js"; const asTable = asTableModule.configure({ delimiter: " | " }); diff --git a/packages/ctl/src/commands_debug.ts b/packages/ctl/src/commands_debug.ts index af991afc..c69e9298 100644 --- a/packages/ctl/src/commands_debug.ts +++ b/packages/ctl/src/commands_debug.ts @@ -1,5 +1,5 @@ import * as lib from "@clusterio/lib"; -import type { Control } from "../ctl"; +import type { Control } from "../ctl.js"; export const debugCommands = new lib.CommandTree({ name: "debug", description: "Debugging utilities" }); debugCommands.add(new lib.Command({ diff --git a/packages/ctl/src/commands_host.ts b/packages/ctl/src/commands_host.ts index c44db2fe..fc269e3b 100644 --- a/packages/ctl/src/commands_host.ts +++ b/packages/ctl/src/commands_host.ts @@ -6,9 +6,9 @@ import child_process from "child_process"; import * as lib from "@clusterio/lib"; import { logger } from "@clusterio/lib"; -import type { Control } from "../ctl"; -import { print } from "./command_ops"; -import { serializedConfigToString, getEditor, configToKeyVal } from "./config_ops"; +import type { Control } from "../ctl.js"; +import { print } from "./command_ops.js"; +import { serializedConfigToString, getEditor, configToKeyVal } from "./config_ops.js"; const asTable = asTableModule.configure({ delimiter: " | " }); diff --git a/packages/ctl/src/commands_instance.ts b/packages/ctl/src/commands_instance.ts index 173451b4..8451d56c 100644 --- a/packages/ctl/src/commands_instance.ts +++ b/packages/ctl/src/commands_instance.ts @@ -9,9 +9,9 @@ import util from "util"; import * as lib from "@clusterio/lib"; import { logger } from "@clusterio/lib"; -import type { Control } from "../ctl"; -import { print } from "./command_ops"; -import { serializedConfigToString, getEditor, configToKeyVal } from "./config_ops"; +import type { Control } from "../ctl.js"; +import { print } from "./command_ops.js"; +import { serializedConfigToString, getEditor, configToKeyVal } from "./config_ops.js"; const asTable = asTableModule.configure({ delimiter: " | " }); const finished = util.promisify(stream.finished); diff --git a/packages/ctl/src/commands_log.ts b/packages/ctl/src/commands_log.ts index c121b3bc..4cce13a3 100644 --- a/packages/ctl/src/commands_log.ts +++ b/packages/ctl/src/commands_log.ts @@ -2,7 +2,7 @@ import winston from "winston"; import * as lib from "@clusterio/lib"; import { ConsoleTransport, levels, logger } from "@clusterio/lib"; -import type { Control } from "../ctl"; +import type { Control } from "../ctl.js"; export const logCommands = new lib.CommandTree({ name: "log", description: "Log inspection" }); logCommands.add(new lib.Command({ diff --git a/packages/ctl/src/commands_mod.ts b/packages/ctl/src/commands_mod.ts index 83f8873a..778ead86 100644 --- a/packages/ctl/src/commands_mod.ts +++ b/packages/ctl/src/commands_mod.ts @@ -7,8 +7,8 @@ import util from "util"; import * as lib from "@clusterio/lib"; import { logger } from "@clusterio/lib"; -import type { Control } from "../ctl"; -import { print } from "./command_ops"; +import type { Control } from "../ctl.js"; +import { print } from "./command_ops.js"; const asTable = asTableModule.configure({ delimiter: " | " }); const finished = util.promisify(stream.finished); diff --git a/packages/ctl/src/commands_mod_pack.ts b/packages/ctl/src/commands_mod_pack.ts index a4af8a90..6c88679f 100644 --- a/packages/ctl/src/commands_mod_pack.ts +++ b/packages/ctl/src/commands_mod_pack.ts @@ -2,8 +2,8 @@ import asTableModule from "as-table"; import * as lib from "@clusterio/lib"; import { logger } from "@clusterio/lib"; -import type { Control } from "../ctl"; -import { print } from "./command_ops"; +import type { Control } from "../ctl.js"; +import { print } from "./command_ops.js"; const asTable = asTableModule.configure({ delimiter: " | " }); diff --git a/packages/ctl/src/commands_permission.ts b/packages/ctl/src/commands_permission.ts index 94d2fbe4..0094314b 100644 --- a/packages/ctl/src/commands_permission.ts +++ b/packages/ctl/src/commands_permission.ts @@ -1,8 +1,8 @@ import asTableModule from "as-table"; import * as lib from "@clusterio/lib"; -import type { Control } from "../ctl"; -import { print } from "./command_ops"; +import type { Control } from "../ctl.js"; +import { print } from "./command_ops.js"; const asTable = asTableModule.configure({ delimiter: " | " }); diff --git a/packages/ctl/src/commands_role.ts b/packages/ctl/src/commands_role.ts index ae99188d..e1707255 100644 --- a/packages/ctl/src/commands_role.ts +++ b/packages/ctl/src/commands_role.ts @@ -2,8 +2,8 @@ import asTableModule from "as-table"; import * as lib from "@clusterio/lib"; import { logger } from "@clusterio/lib"; -import type { Control } from "../ctl"; -import { print } from "./command_ops"; +import type { Control } from "../ctl.js"; +import { print } from "./command_ops.js"; const asTable = asTableModule.configure({ delimiter: " | " }); diff --git a/packages/ctl/src/commands_user.ts b/packages/ctl/src/commands_user.ts index 37887013..1f8817f6 100644 --- a/packages/ctl/src/commands_user.ts +++ b/packages/ctl/src/commands_user.ts @@ -3,8 +3,8 @@ import asTableModule from "as-table"; import path from "path"; import * as lib from "@clusterio/lib"; -import type { Control } from "../ctl"; -import { print } from "./command_ops"; +import type { Control } from "../ctl.js"; +import { print } from "./command_ops.js"; const asTable = asTableModule.configure({ delimiter: " | " }); diff --git a/packages/ctl/src/set_lazy_schema_compliation.ts b/packages/ctl/src/set_lazy_schema_compliation.ts new file mode 100644 index 00000000..f5ff3418 --- /dev/null +++ b/packages/ctl/src/set_lazy_schema_compliation.ts @@ -0,0 +1,3 @@ +// This needs to be a separate file due to ECMAScript Modules evaluating code in +// imported modules before any code in the file that imports it. +(global as any).lazySchemaCompilation = true; diff --git a/packages/host/host.ts b/packages/host/host.ts index 91aeace5..a1f9a9b8 100755 --- a/packages/host/host.ts +++ b/packages/host/host.ts @@ -15,7 +15,7 @@ import fs from "node:fs/promises"; import path from "path"; import yargs from "yargs"; -import { version } from "./package.json"; +import packageConfig from "./package.json" with { type: "json" }; import winston from "winston"; import "winston-daily-rotate-file"; @@ -23,7 +23,7 @@ import "winston-daily-rotate-file"; import * as lib from "@clusterio/lib"; import { ConsoleTransport, levels, logger } from "@clusterio/lib"; -import Host from "./src/Host"; +import Host from "./src/Host.js"; let host: Host | undefined; @@ -69,7 +69,7 @@ export class HostConnector extends lib.WebSocketClientConnector { new lib.MessageRegisterHost( new lib.RegisterHostData( this.hostConfig.get("host.controller_token"), - version, + packageConfig.version, this.hostConfig.get("host.id"), plugins, ) @@ -145,7 +145,7 @@ async function startHost() { let command = args._[0]; if (command === "run") { - logger.info(`Starting Clusterio host ${version}`); + logger.info(`Starting Clusterio host ${packageConfig.version}`); if (args.recovery) { logger.warn("Host recovery mode enabled. Some features will be disabled."); } @@ -187,7 +187,7 @@ async function startHost() { } } - hostConfig.set("host.version", version); // Allows tracking last loaded version + hostConfig.set("host.version", packageConfig.version); // Allows tracking last loaded version if (command === "config") { await lib.handleConfigCommand(args, hostConfig, hostConfigLock); @@ -308,6 +308,6 @@ ${err.stack}` }); } -if (module === require.main) { +if (import.meta.main) { bootstrap(); } diff --git a/packages/host/index.ts b/packages/host/index.ts index f39ce536..75ef3560 100644 --- a/packages/host/index.ts +++ b/packages/host/index.ts @@ -1,10 +1,10 @@ -import { bootstrap } from "./host"; -export { default as BaseHostPlugin } from "./src/BaseHostPlugin"; -export { default as BaseInstancePlugin } from "./src/BaseInstancePlugin"; -export { default as Host, HostRouter } from "./src/Host"; -export { default as Instance } from "./src/Instance"; -export { default as InstanceConnection } from "./src/InstanceConnection"; +import { bootstrap } from "./host.js"; +export { default as BaseHostPlugin } from "./src/BaseHostPlugin.js"; +export { default as BaseInstancePlugin } from "./src/BaseInstancePlugin.js"; +export { default as Host, HostRouter } from "./src/Host.js"; +export { default as Instance } from "./src/Instance.js"; +export { default as InstanceConnection } from "./src/InstanceConnection.js"; -if (module === require.main) { +if (import.meta.main) { bootstrap(); } diff --git a/packages/host/package.json b/packages/host/package.json index e80c6082..542caa42 100644 --- a/packages/host/package.json +++ b/packages/host/package.json @@ -22,6 +22,7 @@ "access": "public" }, + "type": "module", "main": "dist/node/index.js", "scripts": { "prepare": "tsc --build", diff --git a/packages/host/src/BaseHostPlugin.ts b/packages/host/src/BaseHostPlugin.ts index 131da3db..d85f741a 100644 --- a/packages/host/src/BaseHostPlugin.ts +++ b/packages/host/src/BaseHostPlugin.ts @@ -1,7 +1,7 @@ import type { CollectorResult, Logger, ParsedFactorioOutput, PlayerEvent, PluginNodeEnvInfo, } from "@clusterio/lib"; -import type Host from "./Host"; +import type Host from "./Host.js"; /** * Base class for host plugins diff --git a/packages/host/src/BaseInstancePlugin.ts b/packages/host/src/BaseInstancePlugin.ts index 515af1ad..97d9efda 100644 --- a/packages/host/src/BaseInstancePlugin.ts +++ b/packages/host/src/BaseInstancePlugin.ts @@ -1,8 +1,8 @@ import type { CollectorResult, Logger, ParsedFactorioOutput, PlayerEvent, PluginNodeEnvInfo, } from "@clusterio/lib"; -import type Instance from "./Instance"; -import type Host from "./Host"; +import type Instance from "./Instance.js"; +import type Host from "./Host.js"; /** * Base class for instance plugins diff --git a/packages/host/src/Host.ts b/packages/host/src/Host.ts index 7cae0ce6..1af79a92 100644 --- a/packages/host/src/Host.ts +++ b/packages/host/src/Host.ts @@ -5,16 +5,17 @@ import pidusage from "pidusage"; import semver from "semver"; import setBlocking from "set-blocking"; import stream from "stream"; +import { fileURLToPath } from "node:url"; import util from "util"; // internal libraries import * as lib from "@clusterio/lib"; import { logger } from "@clusterio/lib"; -import type { HostConnector } from "../host"; -import Instance from "./Instance"; -import InstanceConnection from "./InstanceConnection"; -import BaseHostPlugin from "./BaseHostPlugin"; +import type { HostConnector } from "../host.js"; +import Instance from "./Instance.js"; +import InstanceConnection from "./InstanceConnection.js"; +import BaseHostPlugin from "./BaseHostPlugin.js"; const finished = util.promisify(stream.finished); @@ -859,7 +860,7 @@ export default class Host extends lib.Link { try { // First check the clusterio version const runningVersion = this.config.get("host.version"); - const packageJsonPath = require.resolve("@clusterio/host/package.json"); + const packageJsonPath = fileURLToPath(import.meta.resolve("@clusterio/host/package.json")); const packageJson = JSON.parse(await fs.readFile(packageJsonPath, "utf8")); if (runningVersion !== packageJson.version) { this.config.restartRequired = true; @@ -883,7 +884,7 @@ export default class Host extends lib.Link { } } } catch (err: any) { - logger.warn(`Failed to read package json for ${packageName}:\n${err.stack ?? err.message}`); + logger.warn(`Failed to read package.json for ${packageName}:\n${err.stack ?? err.message}`); } return false; @@ -892,7 +893,7 @@ export default class Host extends lib.Link { async checkRestartDowngrade() { try { const runningVersion = this.config.get("host.version"); - const packageJsonPath = require.resolve("@clusterio/host/package.json"); + const packageJsonPath = fileURLToPath(import.meta.resolve("@clusterio/host/package.json")); const packageJson = JSON.parse(await fs.readFile(packageJsonPath, "utf8")); const installedVersion = packageJson.version; diff --git a/packages/host/src/Instance.ts b/packages/host/src/Instance.ts index 3e45f04d..755c7364 100644 --- a/packages/host/src/Instance.ts +++ b/packages/host/src/Instance.ts @@ -9,11 +9,11 @@ const execAsync = util.promisify(exec); // internal libraries import * as lib from "@clusterio/lib"; -import { FactorioServer } from "./server"; -import { SaveModule, patch } from "./patch"; -import { exportData } from "./export"; -import type Host from "./Host"; -import BaseInstancePlugin from "./BaseInstancePlugin"; +import { FactorioServer } from "./server.js"; +import { SaveModule, patch } from "./patch.js"; +import { exportData } from "./export.js"; +import type Host from "./Host.js"; +import BaseInstancePlugin from "./BaseInstancePlugin.js"; const scriptCommands = [ "/cheat", "/editor", @@ -963,7 +963,7 @@ end`.replace(/\r?\n/g, " "); // Find stand alone modules to load // XXX for now only the included clusterio module is loaded - let modulesDirectory = path.join(__dirname, "..", "..", "..", "modules"); + let modulesDirectory = path.join(import.meta.dirname, "..", "..", "..", "modules"); for (let entry of await fs.readdir(modulesDirectory, { withFileTypes: true })) { if (entry.isDirectory()) { if (modules.has(entry.name)) { diff --git a/packages/host/src/InstanceConnection.ts b/packages/host/src/InstanceConnection.ts index e9f01053..5ae602be 100644 --- a/packages/host/src/InstanceConnection.ts +++ b/packages/host/src/InstanceConnection.ts @@ -1,6 +1,6 @@ import * as lib from "@clusterio/lib"; -import type Host from "./Host"; -import type Instance from "./Instance"; +import type Host from "./Host.js"; +import type Instance from "./Instance.js"; export default class InstanceConnection extends lib.Link { diff --git a/packages/host/src/export.ts b/packages/host/src/export.ts index 198ffb0a..e8986af2 100644 --- a/packages/host/src/export.ts +++ b/packages/host/src/export.ts @@ -5,9 +5,9 @@ import { Jimp, JimpMime, type JimpInstance } from "jimp"; import JSZip from "jszip"; import * as lib from "@clusterio/lib"; -import * as libBuildMod from "@clusterio/lib/dist/node/build_mod"; -import type { FactorioServer } from "./server"; -import { definesPrototypesFallback } from "./export_fallback"; +import * as libBuildMod from "@clusterio/lib/dist/node/build_mod.js"; +import type { FactorioServer } from "./server.js"; +import { definesPrototypesFallback } from "./export_fallback.js"; interface SimpleIconSpecification { icons?: never; @@ -56,7 +56,7 @@ async function generateExportMod(server: FactorioServer) { clean: false, build: true, pack: true, - sourceDir: path.join(__dirname, "..", "..", "..", "lua", "export"), + sourceDir: path.join(import.meta.dirname, "..", "..", "..", "lua", "export"), outputDir: server.writePath("mods"), bumpPatch: false, factorioVersion: server.version?.replace(/\.\d+$/, ""), diff --git a/packages/host/src/patch.ts b/packages/host/src/patch.ts index c94f5ce1..af89e6b0 100644 --- a/packages/host/src/patch.ts +++ b/packages/host/src/patch.ts @@ -9,7 +9,7 @@ import { Type, Static } from "@sinclair/typebox"; import * as lib from "@clusterio/lib"; -import BaseInstancePlugin from "./BaseInstancePlugin"; +import BaseInstancePlugin from "./BaseInstancePlugin.js"; /** diff --git a/packages/lib/browser.ts b/packages/lib/browser.ts index 1d7bc9c9..624196fb 100644 --- a/packages/lib/browser.ts +++ b/packages/lib/browser.ts @@ -17,7 +17,7 @@ export * from "./src/subscriptions"; export { default as ExponentialBackoff } from "./src/ExponentialBackoff"; export { default as RateLimiter } from "./src/RateLimiter"; export { default as ValueCache } from "./src/ValueCache"; -export { default as isDeepStrictEqual } from "./src/is_deep_strict_equal"; +export { default as isDeepStrictEqual } from "#is_deep_strict_equal"; import { checkSingletonImport } from "./src/check_singleton_import"; checkSingletonImport(import.meta.url); diff --git a/packages/lib/build_mod.js b/packages/lib/build_mod.js index d89c5dfb..d25ae4ba 100644 --- a/packages/lib/build_mod.js +++ b/packages/lib/build_mod.js @@ -1,11 +1,10 @@ /* eslint-disable no-console */ -"use strict"; -const fs = require("node:fs/promises"); -const JSZip = require("jszip"); -const path = require("path"); -const stream = require("stream"); -const util = require("util"); -const yargs = require("yargs"); +import fs from "node:fs/promises"; +import JSZip from "jszip"; +import path from "node:path"; +import stream from "node:stream"; +import util from "node:util"; +import yargs from "yargs"; const finished = util.promisify(stream.finished); @@ -79,7 +78,7 @@ async function buildMod(args, info, modName) { } } -async function build(args) { +export async function build(args) { let info = JSON.parse(await fs.readFile(path.join(args.sourceDir, "info.json"))); if (args.factorioVersion) { @@ -150,10 +149,6 @@ async function main() { await build(args); } -if (module === require.main) { +if (import.meta.main) { main().catch(err => { console.log(err); }); } - -module.exports = { - build, -}; diff --git a/packages/lib/index.ts b/packages/lib/index.ts index 48ed7462..116f289c 100644 --- a/packages/lib/index.ts +++ b/packages/lib/index.ts @@ -2,44 +2,44 @@ * Shared library for Clusterio * @module lib */ -export * from "./build_mod"; -export * from "./src/api"; -export * from "./src/command"; -export * from "./src/config"; -export * from "./src/data"; -export * from "./src/database"; -export * from "./src/errors"; -export * from "./src/export"; -export * from "./src/external"; -export * from "./src/factorio"; -export * from "./src/file_ops"; -export * from "./src/hash"; -export * from "./src/helpers"; -export * from "./src/ini"; -export * from "./src/link"; -export * from "./src/logging"; -export * from "./src/logging_utils"; -export * from "./src/lua_tools"; -export * from "./src/permissions"; -export * from "./src/plugin"; -export * from "./src/plugin_loader"; -export * from "./src/prometheus"; -export * from "./src/schema"; -export * from "./src/shared_commands"; -export * from "./src/stream"; -export * from "./src/system_collectors"; -export * from "./src/zip_ops"; -export * from "./src/subscriptions"; -export * from "./src/datastore"; -export * from "./src/load_plugin_list"; -export * from "./src/rce_ops"; -export * from "./src/LockFile"; +export * from "./build_mod.js"; +export * from "./src/api.js"; +export * from "./src/command.js"; +export * from "./src/config/index.js"; +export * from "./src/data/index.js"; +export * from "./src/database.js"; +export * from "./src/errors.js"; +export * from "./src/export.js"; +export * from "./src/external/index.js"; +export * from "./src/factorio/index.js"; +export * from "./src/file_ops.js"; +export * from "./src/hash.js"; +export * from "./src/helpers.js"; +export * from "./src/ini.js"; +export * from "./src/link/index.js"; +export * from "./src/logging.js"; +export * from "./src/logging_utils.js"; +export * from "./src/lua_tools.js"; +export * from "./src/permissions.js"; +export * from "./src/plugin.js"; +export * from "./src/plugin_loader.js"; +export * from "./src/prometheus.js"; +export * from "./src/schema.js"; +export * from "./src/shared_commands.js"; +export * from "./src/stream.js"; +export * from "./src/system_collectors.js"; +export * from "./src/zip_ops.js"; +export * from "./src/subscriptions.js"; +export * from "./src/datastore.js"; +export * from "./src/load_plugin_list.js"; +export * from "./src/rce_ops.js"; +export * from "./src/LockFile.js"; -export { default as ExponentialBackoff } from "./src/ExponentialBackoff"; -export { default as ModStore } from "./src/ModStore"; -export { default as RateLimiter } from "./src/RateLimiter"; -export { default as ValueCache } from "./src/ValueCache"; -export { default as isDeepStrictEqual } from "./src/is_deep_strict_equal"; +export { default as ExponentialBackoff } from "./src/ExponentialBackoff.js"; +export { default as ModStore } from "./src/ModStore.js"; +export { default as RateLimiter } from "./src/RateLimiter.js"; +export { default as ValueCache } from "./src/ValueCache.js"; +export { default as isDeepStrictEqual } from "#is_deep_strict_equal"; -import { checkSingletonImport } from "./src/check_singleton_import"; -checkSingletonImport(__filename); +import { checkSingletonImport } from "./src/check_singleton_import.js"; +checkSingletonImport(import.meta.filename); diff --git a/packages/lib/package.json b/packages/lib/package.json index 4da29bf8..8cc7bcb7 100644 --- a/packages/lib/package.json +++ b/packages/lib/package.json @@ -22,6 +22,17 @@ "access": "public" }, + "type": "module", + "imports": { + "#WebSocket": { + "node": "./src/link/WebSocket.node.ts", + "import": "./src/link/WebSocket.browser.ts" + }, + "#is_deep_strict_equal": { + "node": "./src/is_deep_strict_equal.node.ts", + "import": "./src/is_deep_strict_equal.browser.ts" + } + }, "browser": "browser.ts", "main": "dist/node/index.js", "scripts": { diff --git a/packages/lib/scripts/compile_validator.js b/packages/lib/scripts/compile_validator.js index 47bcee1e..7c1d932d 100644 --- a/packages/lib/scripts/compile_validator.js +++ b/packages/lib/scripts/compile_validator.js @@ -1,15 +1,14 @@ -"use strict"; -const fs = require("node:fs"); -const path = require("path"); -const Ajv = require("ajv"); -const standaloneCode = require("ajv/dist/standalone").default; +import fs from "node:fs"; +import path from "node:path"; +import Ajv from "ajv"; +import standaloneCode from "ajv/dist/standalone/index.js"; /* eslint-disable node/no-sync */ // Provide an empty file for message_core to load -fs.writeFileSync(path.join(__dirname, "../dist/node/src/data/message_validate.js"), ""); +fs.writeFileSync(path.join(import.meta.dirname, "../dist/node/src/data/message_validate.js"), "export default {};"); -const { Message } = require("../dist/node/src/data/messages_core"); +const { Message } = await import("../dist/node/src/data/messages_core.js"); const ajv = new Ajv({ allowUnionTypes: true, @@ -18,13 +17,14 @@ const ajv = new Ajv({ verbose: true, code: { source: true, + esm: true, }, }); const validate = ajv.compile(Message.jsonSchema); let moduleCode = standaloneCode(ajv, validate); function write(output) { fs.writeFileSync( - path.join(__dirname, output), + path.join(import.meta.dirname, output), `// generated by scripts/compile_validator.js\n// @ts-nocheck\n/* eslint-disable */\n${moduleCode}` ); } diff --git a/packages/lib/src/ModStore.ts b/packages/lib/src/ModStore.ts index 625ae253..999157f3 100644 --- a/packages/lib/src/ModStore.ts +++ b/packages/lib/src/ModStore.ts @@ -2,10 +2,10 @@ import fs from "node:fs/promises"; import path from "path"; import events from "events"; import { Static } from "@sinclair/typebox"; -import { logger } from "./logging"; -import { downloadFile, safeOutputFile } from "./file_ops"; -import { ModPortalReleaseSchema, ModPortalDetailsSchema, ModNameVersionPair } from "./data/messages_mod"; -import { ModInfo, ModPack, MajorMinorVersion, ModVersionEquality, SourceVersion } from "./data"; +import { logger } from "./logging.js"; +import { downloadFile, safeOutputFile } from "./file_ops.js"; +import { ModPortalReleaseSchema, ModPortalDetailsSchema, ModNameVersionPair } from "./data/messages_mod.js"; +import { ModInfo, ModPack, MajorMinorVersion, ModVersionEquality, SourceVersion } from "./data/index.js"; export interface ModStoreEvents { /** A stored mod was created, updated or deleted */ diff --git a/packages/lib/src/check_singleton_import.ts b/packages/lib/src/check_singleton_import.ts index 6a734128..a238fbe8 100644 --- a/packages/lib/src/check_singleton_import.ts +++ b/packages/lib/src/check_singleton_import.ts @@ -1,4 +1,4 @@ -import { InstallationError } from "./errors"; +import { InstallationError } from "./errors.js"; declare global { // eslint-disable-next-line vars-on-top var _clusterioLibImportedFrom: string; diff --git a/packages/lib/src/command.ts b/packages/lib/src/command.ts index 2a55c22e..bf910262 100644 --- a/packages/lib/src/command.ts +++ b/packages/lib/src/command.ts @@ -6,9 +6,9 @@ * @author Hornwitser * @module lib/command */ -import * as libData from "./data"; -import * as libErrors from "./errors"; -import type { Link } from "./link"; +import * as libData from "./data/index.js"; +import * as libErrors from "./errors.js"; +import type { Link } from "./link/index.js"; import type { Argv } from "yargs"; export type CommandHandler = (args: any, control: any) => Promise; diff --git a/packages/lib/src/config/classes.ts b/packages/lib/src/config/classes.ts index d982f174..6ca54746 100644 --- a/packages/lib/src/config/classes.ts +++ b/packages/lib/src/config/classes.ts @@ -3,13 +3,13 @@ import { Type, Static } from "@sinclair/typebox"; import * as fs from "node:fs/promises"; import events from "events"; -import isDeepStrictEqual from "../is_deep_strict_equal"; -import { basicType } from "../helpers"; -import * as libSchema from "../schema"; -import { StringEnum } from "../data/composites"; -import { safeOutputFile } from "../file_ops"; -import * as validators from "./validators"; -import { RequestError } from "../errors"; +import isDeepStrictEqual from "#is_deep_strict_equal"; +import { basicType } from "../helpers.js"; +import * as libSchema from "../schema.js"; +import { StringEnum } from "../data/composites.js"; +import { safeOutputFile } from "../file_ops.js"; +import * as validators from "./validators.js"; +import { RequestError } from "../errors.js"; const ConfigLocation = StringEnum(["controller", "host", "control"]); export type ConfigLocation = Static; diff --git a/packages/lib/src/config/definitions.ts b/packages/lib/src/config/definitions.ts index 8510c280..0f109141 100644 --- a/packages/lib/src/config/definitions.ts +++ b/packages/lib/src/config/definitions.ts @@ -1,9 +1,9 @@ // Core definitions for the configuration system -import * as classes from "./classes"; -import * as validators from "./validators"; -import type { PluginNodeEnvInfo, PluginWebpackEnvInfo } from "../plugin"; +import * as classes from "./classes.js"; +import * as validators from "./validators.js"; +import type { PluginNodeEnvInfo, PluginWebpackEnvInfo } from "../plugin.js"; import { Static } from "@sinclair/typebox"; -import { isTargetVersion } from "../data/version"; +import { isTargetVersion } from "../data/version.js"; type configFromJSON = (...args: Parameters) => T; type configFromFile = (...args: Parameters) => Promise; diff --git a/packages/lib/src/config/index.ts b/packages/lib/src/config/index.ts index a111da14..0614402f 100644 --- a/packages/lib/src/config/index.ts +++ b/packages/lib/src/config/index.ts @@ -3,5 +3,5 @@ * @author Hornwitser * @module lib/config */ -export * from "./classes"; -export * from "./definitions"; +export * from "./classes.js"; +export * from "./definitions.js"; diff --git a/packages/lib/src/data/InstanceDetails.ts b/packages/lib/src/data/InstanceDetails.ts index 04c1a686..adf0b9d8 100644 --- a/packages/lib/src/data/InstanceDetails.ts +++ b/packages/lib/src/data/InstanceDetails.ts @@ -1,6 +1,6 @@ import { Static, Type } from "@sinclair/typebox"; -import { StringEnum } from "./composites"; -import { TargetVersion, TargetVersionSchema } from "./version"; +import { StringEnum } from "./composites.js"; +import { TargetVersion, TargetVersionSchema } from "./version.js"; export const InstanceStatus = StringEnum([ "unknown", diff --git a/packages/lib/src/data/ModInfo.ts b/packages/lib/src/data/ModInfo.ts index 3205e2aa..dc702d91 100644 --- a/packages/lib/src/data/ModInfo.ts +++ b/packages/lib/src/data/ModInfo.ts @@ -2,16 +2,16 @@ import fs from "node:fs/promises"; import JSZip from "jszip"; import { Type, Static } from "@sinclair/typebox"; -import * as libHash from "../hash"; -import * as libSchema from "../schema"; -import { findRoot } from "../zip_ops"; -import { ModRecord } from "./ModPack"; +import * as libHash from "../hash.js"; +import * as libSchema from "../schema.js"; +import { findRoot } from "../zip_ops.js"; +import { ModRecord } from "./ModPack.js"; import { MajorMinorVersion, MajorMinorVersionSchema, normaliseMajorMinorVersion, integerMajorMinorVersion, SourceVersion, SourceVersionSchema, isSourceVersion, normaliseSourceVersion, integerSourceVersion, ModVersionEquality, -} from "./version"; +} from "./version.js"; type ModDependencyType = "incompatible" | "optional" | "hidden" | "unordered" | "required" | "recommended"; diff --git a/packages/lib/src/data/ModPack.ts b/packages/lib/src/data/ModPack.ts index 33251845..29458422 100644 --- a/packages/lib/src/data/ModPack.ts +++ b/packages/lib/src/data/ModPack.ts @@ -1,19 +1,19 @@ import zlib from "zlib"; import { Type, Static } from "@sinclair/typebox"; -import * as libSchema from "../schema"; -import * as libLuaTools from "../lua_tools"; +import * as libSchema from "../schema.js"; +import * as libLuaTools from "../lua_tools.js"; -import ExportManifest from "./ExportManifest"; -import type { ExportSettings } from "../export"; -import type { Logger } from "../logging"; +import ExportManifest from "./ExportManifest.js"; +import type { ExportSettings } from "../export.js"; +import type { Logger } from "../logging.js"; -import ModInfo, { ModDependencyUnsatisfiedReason } from "./ModInfo"; +import ModInfo, { ModDependencyUnsatisfiedReason } from "./ModInfo.js"; import { PartialVersion, PartialVersionSchema, integerPartialVersion, SourceVersion, SourceVersionSchema, normaliseFullVersion, integerSourceVersion, -} from "./version"; +} from "./version.js"; export const ModSettingColor = Type.Object({ diff --git a/packages/lib/src/data/ModuleInfo.ts b/packages/lib/src/data/ModuleInfo.ts index 968a456e..8c43fc0b 100644 --- a/packages/lib/src/data/ModuleInfo.ts +++ b/packages/lib/src/data/ModuleInfo.ts @@ -1,5 +1,5 @@ import { Type, Static } from "@sinclair/typebox"; -import { compile } from "../schema"; +import { compile } from "../schema.js"; /** * Information about a module stored in its module.json file diff --git a/packages/lib/src/data/Role.ts b/packages/lib/src/data/Role.ts index 19fb17e7..954d5def 100644 --- a/packages/lib/src/data/Role.ts +++ b/packages/lib/src/data/Role.ts @@ -1,5 +1,5 @@ import { Static, Type } from "@sinclair/typebox"; -import { permissions as globalPermissions } from "../permissions"; +import { permissions as globalPermissions } from "../permissions.js"; interface RoleCollection { get(id: number): Role; diff --git a/packages/lib/src/data/UserDetails.ts b/packages/lib/src/data/UserDetails.ts index 5a99dfed..28a1646a 100644 --- a/packages/lib/src/data/UserDetails.ts +++ b/packages/lib/src/data/UserDetails.ts @@ -1,6 +1,6 @@ import { Static, Type } from "@sinclair/typebox"; -import PlayerStats from "./PlayerStats"; +import PlayerStats from "./PlayerStats.js"; /** Represents a user in the cluster */ export default class UserDetails { diff --git a/packages/lib/src/data/index.ts b/packages/lib/src/data/index.ts index a8ca8a96..ff473748 100644 --- a/packages/lib/src/data/index.ts +++ b/packages/lib/src/data/index.ts @@ -3,26 +3,26 @@ * @module lib/data * @author Hornwitser */ -export { default as ExportManifest } from "./ExportManifest"; -export { default as ModInfo, ModDependency } from "./ModInfo"; -export { ModSettingColor, getInstalledModUpdates, applyModRecordAdvisories } from "./ModPack"; -export type { ModSetting, ModRecord, ModRecordAdvisory } from "./ModPack"; -export { default as ModPack } from "./ModPack"; -export { default as ModuleInfo } from "./ModuleInfo"; -export { default as Permission } from "./Permission"; -export { default as PlayerStats } from "./PlayerStats"; -export { default as Role } from "./Role"; -export { default as InstanceDetails, InstanceStatus } from "./InstanceDetails"; -export { default as HostDetails } from "./HostDetails"; -export { default as UserDetails } from "./UserDetails"; -export type { IUser } from "./UserDetails"; -export * from "./composites"; -export * from "./messages_core"; -export * from "./messages_controller"; -export * from "./messages_host"; -export * from "./messages_instance"; -export * from "./messages_mod"; -export * from "./messages_user"; -export * from "./messages_role"; -export * from "./messages_plugin"; -export * from "./version"; +export { default as ExportManifest } from "./ExportManifest.js"; +export { default as ModInfo, ModDependency } from "./ModInfo.js"; +export { ModSettingColor, getInstalledModUpdates, applyModRecordAdvisories } from "./ModPack.js"; +export type { ModSetting, ModRecord, ModRecordAdvisory } from "./ModPack.js"; +export { default as ModPack } from "./ModPack.js"; +export { default as ModuleInfo } from "./ModuleInfo.js"; +export { default as Permission } from "./Permission.js"; +export { default as PlayerStats } from "./PlayerStats.js"; +export { default as Role } from "./Role.js"; +export { default as InstanceDetails, InstanceStatus } from "./InstanceDetails.js"; +export { default as HostDetails } from "./HostDetails.js"; +export { default as UserDetails } from "./UserDetails.js"; +export type { IUser } from "./UserDetails.js"; +export * from "./composites.js"; +export * from "./messages_core.js"; +export * from "./messages_controller.js"; +export * from "./messages_host.js"; +export * from "./messages_instance.js"; +export * from "./messages_mod.js"; +export * from "./messages_user.js"; +export * from "./messages_role.js"; +export * from "./messages_plugin.js"; +export * from "./version.js"; diff --git a/packages/lib/src/data/message_validate.d.ts b/packages/lib/src/data/message_validate.d.ts index d9ec5838..bbb3d8b3 100644 --- a/packages/lib/src/data/message_validate.d.ts +++ b/packages/lib/src/data/message_validate.d.ts @@ -1,4 +1,4 @@ import type { ValidateFunction } from "ajv"; -import type { Message } from "./messages_core"; +import type { Message } from "./messages_core.js"; const message_validate: ValidateFunction; export default message_validate; diff --git a/packages/lib/src/data/messages_controller.ts b/packages/lib/src/data/messages_controller.ts index 9075cfb9..25ca7789 100644 --- a/packages/lib/src/data/messages_controller.ts +++ b/packages/lib/src/data/messages_controller.ts @@ -1,8 +1,8 @@ import { Type, Static } from "@sinclair/typebox"; -import { JsonString, StringEnum, StringKey, plainJson } from "./composites"; -import { levels } from "../logging"; -import { ControllerConfig, HostConfig } from "../config"; -import { ExternalFactorioVersionSchema, LatestReleasesSchema } from "../external"; +import { JsonString, StringEnum, StringKey, plainJson } from "./composites.js"; +import { levels } from "../logging.js"; +import { ControllerConfig, HostConfig } from "../config/index.js"; +import { ExternalFactorioVersionSchema, LatestReleasesSchema } from "../external/index.js"; export class ControllerStopRequest { declare ["constructor"]: typeof ControllerStopRequest; diff --git a/packages/lib/src/data/messages_core.ts b/packages/lib/src/data/messages_core.ts index c4145a47..ff391b21 100644 --- a/packages/lib/src/data/messages_core.ts +++ b/packages/lib/src/data/messages_core.ts @@ -1,8 +1,8 @@ // Note: Run compile_validator script after making changes to this file. import { TSchema, Type, Static } from "@sinclair/typebox"; -import messageValidate from "./message_validate"; // generated file -import { StringEnum } from "./composites"; +import messageValidate from "./message_validate.js"; // generated file +import { StringEnum } from "./composites.js"; export type AddressType = "controller" | "host" | "instance" | "control" | "broadcast"; export type AddressShorthand = diff --git a/packages/lib/src/data/messages_host.ts b/packages/lib/src/data/messages_host.ts index e707d856..aa4edbc9 100644 --- a/packages/lib/src/data/messages_host.ts +++ b/packages/lib/src/data/messages_host.ts @@ -1,8 +1,8 @@ import { Type, Static } from "@sinclair/typebox"; -import { jsonArray, plainJson, StringEnum } from "./composites"; -import { CollectorResultSerialized } from "../prometheus"; -import { HostConfig } from "../config/definitions"; -import HostDetails from "./HostDetails"; +import { jsonArray, plainJson, StringEnum } from "./composites.js"; +import { CollectorResultSerialized } from "../prometheus.js"; +import { HostConfig } from "../config/definitions.js"; +import HostDetails from "./HostDetails.js"; export class HostStopRequest { declare ["constructor"]: typeof HostStopRequest; diff --git a/packages/lib/src/data/messages_instance.ts b/packages/lib/src/data/messages_instance.ts index 51bcd0db..d107632c 100644 --- a/packages/lib/src/data/messages_instance.ts +++ b/packages/lib/src/data/messages_instance.ts @@ -1,12 +1,12 @@ import { Type, Static } from "@sinclair/typebox"; -import PlayerStats from "./PlayerStats"; -import { JsonString, StringEnum, jsonArray, plainJson } from "./composites"; -import { InstanceConfig } from "../config"; -import type { IUser } from "./UserDetails"; -import type { MessageRequest } from "./messages_core"; -import { CollectorResultSerialized } from "../prometheus"; -import { TargetVersion, TargetVersionSchema, PartialVersion, PartialVersionSchema } from "./version"; -import InstanceDetails, { InstanceStatus } from "./InstanceDetails"; +import PlayerStats from "./PlayerStats.js"; +import { JsonString, StringEnum, jsonArray, plainJson } from "./composites.js"; +import { InstanceConfig } from "../config/index.js"; +import type { IUser } from "./UserDetails.js"; +import type { MessageRequest } from "./messages_core.js"; +import { CollectorResultSerialized } from "../prometheus.js"; +import { TargetVersion, TargetVersionSchema, PartialVersion, PartialVersionSchema } from "./version.js"; +import InstanceDetails, { InstanceStatus } from "./InstanceDetails.js"; export class InstanceDetailsGetRequest { declare ["constructor"]: typeof InstanceDetailsGetRequest; diff --git a/packages/lib/src/data/messages_mod.ts b/packages/lib/src/data/messages_mod.ts index 4d5a09e3..5d26fc78 100644 --- a/packages/lib/src/data/messages_mod.ts +++ b/packages/lib/src/data/messages_mod.ts @@ -1,13 +1,13 @@ import { Type, Static } from "@sinclair/typebox"; -import ModInfo, { ModDependency } from "./ModInfo"; -import ModPack from "./ModPack"; -import { JsonString, jsonArray } from "./composites"; +import ModInfo, { ModDependency } from "./ModInfo.js"; +import ModPack from "./ModPack.js"; +import { JsonString, jsonArray } from "./composites.js"; import { MajorMinorVersion, MajorMinorVersionSchema, normaliseMajorMinorVersion, SourceVersion, SourceVersionSchema, ModVersionEquality, -} from "./version"; +} from "./version.js"; export class ModPackGetRequest { diff --git a/packages/lib/src/data/messages_plugin.ts b/packages/lib/src/data/messages_plugin.ts index edbe7664..2c2a114c 100644 --- a/packages/lib/src/data/messages_plugin.ts +++ b/packages/lib/src/data/messages_plugin.ts @@ -1,6 +1,6 @@ import { Type, Static } from "@sinclair/typebox"; -import { jsonArray } from "./composites"; -import { PluginNodeEnvInfo } from "../plugin"; +import { jsonArray } from "./composites.js"; +import { PluginNodeEnvInfo } from "../plugin.js"; /* This is similar to other plugin definitions but with lots removed */ export class PluginDetails { diff --git a/packages/lib/src/data/messages_role.ts b/packages/lib/src/data/messages_role.ts index 423c1d65..1a3986cb 100644 --- a/packages/lib/src/data/messages_role.ts +++ b/packages/lib/src/data/messages_role.ts @@ -1,7 +1,7 @@ import { Type, Static } from "@sinclair/typebox"; -import { JsonNumber, jsonArray } from "./composites"; -import Permission from "./Permission"; -import Role from "./Role"; +import { JsonNumber, jsonArray } from "./composites.js"; +import Permission from "./Permission.js"; +import Role from "./Role.js"; export class PermissionListRequest { declare ["constructor"]: typeof PermissionListRequest; diff --git a/packages/lib/src/data/messages_user.ts b/packages/lib/src/data/messages_user.ts index 2c73d8be..2de27c19 100644 --- a/packages/lib/src/data/messages_user.ts +++ b/packages/lib/src/data/messages_user.ts @@ -1,7 +1,7 @@ import { Type, Static } from "@sinclair/typebox"; -import UserDetails, { IUser } from "./UserDetails"; -import { StringEnum, jsonArray, plainJson } from "./composites"; -import { MessageRequest } from "./messages_core"; +import UserDetails, { IUser } from "./UserDetails.js"; +import { StringEnum, jsonArray, plainJson } from "./composites.js"; +import { MessageRequest } from "./messages_core.js"; export class UserGetRequest { declare ["constructor"]: typeof UserGetRequest; diff --git a/packages/lib/src/database.ts b/packages/lib/src/database.ts index 81ea71ac..1e94d298 100644 --- a/packages/lib/src/database.ts +++ b/packages/lib/src/database.ts @@ -6,8 +6,8 @@ */ import fs from "node:fs/promises"; -import * as libFileOps from "./file_ops"; -import { basicType } from "./helpers"; +import * as libFileOps from "./file_ops.js"; +import { basicType } from "./helpers.js"; export type ItemCountWithQuality = { [quality: string]: number }; diff --git a/packages/lib/src/datastore.ts b/packages/lib/src/datastore.ts index ed5113d9..23c294e0 100644 --- a/packages/lib/src/datastore.ts +++ b/packages/lib/src/datastore.ts @@ -2,10 +2,10 @@ import path from "path"; import fs from "node:fs/promises"; import { EventEmitter } from "events"; -import { safeOutputFile } from "./file_ops"; -import { SubscribableValue } from "./subscriptions"; -import { logger } from "./logging"; -import { ControllerConfig } from "./config"; +import { safeOutputFile } from "./file_ops.js"; +import { SubscribableValue } from "./subscriptions.js"; +import { logger } from "./logging.js"; +import { ControllerConfig } from "./config/index.js"; type DatastoreKey = string | number; type DatastoreValue = string | number | boolean | object; diff --git a/packages/lib/src/export.ts b/packages/lib/src/export.ts index 10f06089..2ae9eb3f 100644 --- a/packages/lib/src/export.ts +++ b/packages/lib/src/export.ts @@ -1,4 +1,4 @@ -import { FactorioColor } from "./lua_tools"; +import { FactorioColor } from "./lua_tools.js"; /** * A localised string. diff --git a/packages/lib/src/external/FactorioVersions.ts b/packages/lib/src/external/FactorioVersions.ts index 86360b39..ae1f2e39 100644 --- a/packages/lib/src/external/FactorioVersions.ts +++ b/packages/lib/src/external/FactorioVersions.ts @@ -1,5 +1,5 @@ import { Static, Type } from "@sinclair/typebox"; -import { FullVersionSchema, integerFullVersion, isFullVersion } from "../data/version"; +import { FullVersionSchema, integerFullVersion, isFullVersion } from "../data/version.js"; const ARCHIVE_URL = "https://factorio.com/download/archive/"; diff --git a/packages/lib/src/external/LatestReleases.ts b/packages/lib/src/external/LatestReleases.ts index 91a0f322..885565ae 100644 --- a/packages/lib/src/external/LatestReleases.ts +++ b/packages/lib/src/external/LatestReleases.ts @@ -1,5 +1,5 @@ import { Static, Type } from "@sinclair/typebox"; -import { FullVersion, FullVersionSchema } from "../data/version"; +import { FullVersion, FullVersionSchema } from "../data/version.js"; const LATEST_RELEASES_URL = "https://factorio.com/api/latest-releases"; diff --git a/packages/lib/src/external/index.ts b/packages/lib/src/external/index.ts index 0bd258c4..0bf27ace 100644 --- a/packages/lib/src/external/index.ts +++ b/packages/lib/src/external/index.ts @@ -2,5 +2,5 @@ * Library for interfacing with external apis * @module lib/external */ -export * from "./FactorioVersions"; -export * from "./LatestReleases"; +export * from "./FactorioVersions.js"; +export * from "./LatestReleases.js"; diff --git a/packages/lib/src/factorio/index.ts b/packages/lib/src/factorio/index.ts index 72335610..dbf0e1bf 100644 --- a/packages/lib/src/factorio/index.ts +++ b/packages/lib/src/factorio/index.ts @@ -3,4 +3,4 @@ * @module lib/factorio * @author Hornwitser */ -export * from "./exchange_string"; +export * from "./exchange_string.js"; diff --git a/packages/lib/src/file_ops.ts b/packages/lib/src/file_ops.ts index 55d2bda7..b8899406 100644 --- a/packages/lib/src/file_ops.ts +++ b/packages/lib/src/file_ops.ts @@ -7,7 +7,7 @@ import fs from "node:fs/promises"; import path from "path"; import stream from "stream"; -import { redactUrl } from "./helpers"; +import { redactUrl } from "./helpers.js"; /** diff --git a/packages/lib/src/helpers.ts b/packages/lib/src/helpers.ts index b14d8e2a..dbbf2f26 100644 --- a/packages/lib/src/helpers.ts +++ b/packages/lib/src/helpers.ts @@ -3,7 +3,7 @@ * @module lib/helpers */ -import type { Logger } from "./logging"; +import type { Logger } from "./logging.js"; import setBlocking from "set-blocking"; /** diff --git a/packages/lib/src/is_deep_strict_equal.browser.ts b/packages/lib/src/is_deep_strict_equal.browser.ts new file mode 100644 index 00000000..9fdd65d2 --- /dev/null +++ b/packages/lib/src/is_deep_strict_equal.browser.ts @@ -0,0 +1 @@ +export { default } from "fast-deep-equal/es6/index.js"; diff --git a/packages/lib/src/is_deep_strict_equal.d.ts b/packages/lib/src/is_deep_strict_equal.d.ts deleted file mode 100644 index 3ec0532c..00000000 --- a/packages/lib/src/is_deep_strict_equal.d.ts +++ /dev/null @@ -1 +0,0 @@ -export default function isDeepStrictEqual(a: any, b: any): boolean; diff --git a/packages/lib/src/is_deep_strict_equal.js b/packages/lib/src/is_deep_strict_equal.js deleted file mode 100644 index 0f695078..00000000 --- a/packages/lib/src/is_deep_strict_equal.js +++ /dev/null @@ -1,9 +0,0 @@ - -"use strict"; - -if (process.env.APP_ENV === "browser") { - - module.exports = require("fast-deep-equal/es6"); -} else { - module.exports = require("util").isDeepStrictEqual; -} diff --git a/packages/lib/src/is_deep_strict_equal.node.ts b/packages/lib/src/is_deep_strict_equal.node.ts new file mode 100644 index 00000000..4714580c --- /dev/null +++ b/packages/lib/src/is_deep_strict_equal.node.ts @@ -0,0 +1 @@ +export { isDeepStrictEqual as default } from "util"; diff --git a/packages/lib/src/link/WebSocket.browser.ts b/packages/lib/src/link/WebSocket.browser.ts new file mode 100644 index 00000000..a1444375 --- /dev/null +++ b/packages/lib/src/link/WebSocket.browser.ts @@ -0,0 +1,2 @@ +const NativeWebSocket = WebSocket; +export { NativeWebSocket as WebSocket }; diff --git a/packages/lib/src/link/WebSocket.d.ts b/packages/lib/src/link/WebSocket.d.ts deleted file mode 100644 index c44f2672..00000000 --- a/packages/lib/src/link/WebSocket.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import ws = require("ws"); -export = ws; diff --git a/packages/lib/src/link/WebSocket.js b/packages/lib/src/link/WebSocket.js deleted file mode 100644 index 06879e25..00000000 --- a/packages/lib/src/link/WebSocket.js +++ /dev/null @@ -1,3 +0,0 @@ -"use strict"; - -module.exports = process.env.APP_ENV === "browser" ? window.WebSocket : require("ws"); diff --git a/packages/lib/src/link/WebSocket.node.ts b/packages/lib/src/link/WebSocket.node.ts new file mode 100644 index 00000000..64683e43 --- /dev/null +++ b/packages/lib/src/link/WebSocket.node.ts @@ -0,0 +1 @@ +export { WebSocket } from "ws"; diff --git a/packages/lib/src/link/connectors.ts b/packages/lib/src/link/connectors.ts index ebed9978..8ce84f8f 100644 --- a/packages/lib/src/link/connectors.ts +++ b/packages/lib/src/link/connectors.ts @@ -2,12 +2,12 @@ import { strict as assert } from "assert"; import events from "events"; -import WebSocket from "./WebSocket"; -import * as libData from "../data"; -import * as libErrors from "../errors"; -import { logger } from "../logging"; -import ExponentialBackoff from "../ExponentialBackoff"; -import type { Request, Event } from "./link"; +import { WebSocket } from "#WebSocket"; +import * as libData from "../data/index.js"; +import * as libErrors from "../errors.js"; +import { logger } from "../logging.js"; +import ExponentialBackoff from "../ExponentialBackoff.js"; +import type { Request, Event } from "./link.js"; /** * Numbered codes describing why a connection was closed @@ -151,7 +151,7 @@ type WebSocketBaseConnectorEvents = { "drop": [], }; -export type WebSocketClusterio = WebSocket.WebSocket & { +export type WebSocketClusterio = WebSocket & { clusterio_ignore_dump?: boolean; }; @@ -275,7 +275,9 @@ export abstract class WebSocketBaseConnector< if (process.env.APP_ENV === "browser") { this._socket!.close(ConnectionClosed.Timeout, "Heartbeat timeout"); } else { - this._socket!.terminate(); + // This is only available in node, but the typechecking doesn't + // detect that this code is unreachable in the browser build. + (this._socket! as any).terminate(); } } else { @@ -635,7 +637,7 @@ export abstract class WebSocketClientConnector extends WebSocketBaseConnector { + this._socket!.onerror = ((event: { error?: any, message?: string, }) => { // It's assumed that close is always called by ws let code = !event.error ? "" : `, code: ${event.error.code}`; let message = `Connector | Socket error: ${event.message || "unknown error"}${code}`; @@ -657,7 +659,8 @@ export abstract class WebSocketClientConnector extends WebSocketBaseConnector { logger.verbose("Connector | Open"); diff --git a/packages/lib/src/link/index.ts b/packages/lib/src/link/index.ts index d48297e3..e45a6550 100644 --- a/packages/lib/src/link/index.ts +++ b/packages/lib/src/link/index.ts @@ -3,5 +3,5 @@ * @module lib/link * @author Hornwitser */ -export * from "./link"; -export * from "./connectors"; +export * from "./link.js"; +export * from "./connectors.js"; diff --git a/packages/lib/src/link/link.ts b/packages/lib/src/link/link.ts index c4c8fa9b..80973177 100644 --- a/packages/lib/src/link/link.ts +++ b/packages/lib/src/link/link.ts @@ -1,15 +1,15 @@ // Implementation of Link class -import * as libData from "../data"; -import * as libErrors from "../errors"; -import { logger } from "../logging"; -import * as libSchema from "../schema"; -import { dataClasses } from "./messages"; -import { BaseConnector, WebSocketBaseConnector } from "./connectors"; +import * as libData from "../data/index.js"; +import * as libErrors from "../errors.js"; +import { logger } from "../logging.js"; +import * as libSchema from "../schema.js"; +import { dataClasses } from "./messages.js"; +import { BaseConnector, WebSocketBaseConnector } from "./connectors.js"; import { strict as assert } from "assert"; -import type { PluginNodeEnvInfo, PluginWebpackEnvInfo } from "../plugin"; +import type { PluginNodeEnvInfo, PluginWebpackEnvInfo } from "../plugin.js"; import type { AddressType, JSONDeserialisable, MessageRoutable, MessageRequest, MessageEvent, IUser, -} from "../data"; +} from "../data/index.js"; export interface Request { constructor: Partial>> & { diff --git a/packages/lib/src/link/messages.ts b/packages/lib/src/link/messages.ts index 1db48338..dbdac526 100644 --- a/packages/lib/src/link/messages.ts +++ b/packages/lib/src/link/messages.ts @@ -1,13 +1,13 @@ -import * as core from "../data/messages_core"; -import * as controller from "../data/messages_controller"; -import * as host from "../data/messages_host"; -import * as instance from "../data/messages_instance"; -import * as mod from "../data/messages_mod"; -import * as user from "../data/messages_user"; -import * as role from "../data/messages_role"; -import * as plugin from "../data/messages_plugin"; -import * as subscriptions from "../subscriptions"; -import type { RequestClass, EventClass } from "./link"; +import * as core from "../data/messages_core.js"; +import * as controller from "../data/messages_controller.js"; +import * as host from "../data/messages_host.js"; +import * as instance from "../data/messages_instance.js"; +import * as mod from "../data/messages_mod.js"; +import * as user from "../data/messages_user.js"; +import * as role from "../data/messages_role.js"; +import * as plugin from "../data/messages_plugin.js"; +import * as subscriptions from "../subscriptions.js"; +import type { RequestClass, EventClass } from "./link.js"; /** * Event and Request payloads registered with the Link class. Used to decode diff --git a/packages/lib/src/load_plugin_list.ts b/packages/lib/src/load_plugin_list.ts index 8d4d1689..d91977e2 100644 --- a/packages/lib/src/load_plugin_list.ts +++ b/packages/lib/src/load_plugin_list.ts @@ -1,8 +1,8 @@ import fs from "node:fs/promises"; import { createRequire } from "node:module"; import path from "path"; -import { logger } from "./logging"; -import * as libFileOps from "./file_ops"; +import { logger } from "./logging.js"; +import * as libFileOps from "./file_ops.js"; import vm from "vm"; /** @@ -67,6 +67,7 @@ async function findLocalPlugins(pluginList: Map): Promise 0; } +const require = createRequire(import.meta.url); function getPluginName(requireSpec: string) { const context = vm.createContext({ require: require, pluginInfo: null }); const code = `pluginInfo = require(${JSON.stringify(requireSpec)}).plugin;`; diff --git a/packages/lib/src/logging_utils.ts b/packages/lib/src/logging_utils.ts index eebb1c2e..2a02f57d 100644 --- a/packages/lib/src/logging_utils.ts +++ b/packages/lib/src/logging_utils.ts @@ -14,12 +14,12 @@ import Transport from "winston-transport"; import { LEVEL, MESSAGE } from "triple-beam"; import chalk from "chalk"; -import * as libData from "./data"; -import * as libErrors from "./errors"; -import * as libFileOps from "./file_ops"; -import { type LogFilter, levels, logFilter, logger } from "./logging"; -import * as libStream from "./stream"; -import type { Link } from "./link"; +import * as libData from "./data/index.js"; +import * as libErrors from "./errors.js"; +import * as libFileOps from "./file_ops.js"; +import { type LogFilter, levels, logFilter, logger } from "./logging.js"; +import * as libStream from "./stream.js"; +import type { Link } from "./link/index.js"; const finished = util.promisify(stream.finished); diff --git a/packages/lib/src/permissions.ts b/packages/lib/src/permissions.ts index ce1bb44c..b7ef91a9 100644 --- a/packages/lib/src/permissions.ts +++ b/packages/lib/src/permissions.ts @@ -6,7 +6,7 @@ * @author Hornwitser * @module lib/users */ -import { Permission } from "./data"; +import { Permission } from "./data/index.js"; export const permissions = new Map(); diff --git a/packages/lib/src/plugin.ts b/packages/lib/src/plugin.ts index 456cde2a..b5060561 100644 --- a/packages/lib/src/plugin.ts +++ b/packages/lib/src/plugin.ts @@ -2,10 +2,10 @@ * Plugin interfaces and utilities. * @module lib/plugin */ -import * as libHelpers from "./helpers"; -import type { Logger } from "./logging"; -import type { FieldDefinition } from "./config"; -import type { PlayerStats } from "./data"; +import * as libHelpers from "./helpers.js"; +import type { Logger } from "./logging.js"; +import type { FieldDefinition } from "./config/index.js"; +import type { PlayerStats } from "./data/index.js"; export const PluginFeatureFlags = [ diff --git a/packages/lib/src/plugin_loader.ts b/packages/lib/src/plugin_loader.ts index 31ec7a03..7578e0f7 100644 --- a/packages/lib/src/plugin_loader.ts +++ b/packages/lib/src/plugin_loader.ts @@ -5,9 +5,10 @@ */ import path from "path"; import fs from "node:fs/promises"; -import * as libErrors from "./errors"; -import * as libPlugin from "./plugin"; -import { logger } from "./logging"; +import { fileURLToPath, pathToFileURL } from "node:url"; +import * as libErrors from "./errors.js"; +import * as libPlugin from "./plugin.js"; +import { logger } from "./logging.js"; /** @@ -32,7 +33,9 @@ export async function loadPluginInfos(pluginList: Map) { try { const absolute = path.isAbsolute(pluginPath); const packageImport = path.posix.join(pluginPath, "package.json"); - packagePath = require.resolve(packageImport); + packagePath = fileURLToPath(import.meta.resolve( + absolute ? pathToFileURL(packageImport).href : packageImport + )); await fs.access(packagePath, fs.constants.F_OK); } catch (err) { let errMsg = `Plugin path ${pluginPath} does not exist`; @@ -46,8 +49,10 @@ export async function loadPluginInfos(pluginList: Map) { } try { - pluginInfo = require(pluginPath).plugin; - pluginPackage = require(packagePath); + pluginPackage = (await import(pathToFileURL(packagePath).href, { with: { type: "json" }})).default; + pluginInfo = (await import( + pathToFileURL(path.posix.join(pluginPath, pluginPackage.main ?? "index.js")).href + )).plugin; } catch (err: any) { if (err.code === "InstallationError") { throw err; @@ -89,7 +94,7 @@ export async function loadPluginClass className: string, pluginClass: Class, ): Promise { - let entrypoint = require(requirePath); + let entrypoint = await import(pathToFileURL(requirePath).href); if (!entrypoint[className]) { throw new libErrors.PluginError(pluginName, new Error(`Expected ${requirePath} to export a class named ${className}`) diff --git a/packages/lib/src/prometheus.ts b/packages/lib/src/prometheus.ts index 84999093..89082788 100644 --- a/packages/lib/src/prometheus.ts +++ b/packages/lib/src/prometheus.ts @@ -12,7 +12,7 @@ * the listed interfaces for more information. * * @example - * const { Counter, exposition } = require("@clusterio/lib"); + * import { Counter, exposition } from "@clusterio/lib"; * * // Collectors are by default registered to the default collector regitry. * const totalRequests = new Counter( @@ -27,7 +27,8 @@ * * // Code handling the /metrics HTTP request, here shown for express * // but any http framework may be used - * const app = require("express")(); + * import express from "express"; + * const app = express(); * async function getMetrics(req, res) { * // By default exposition uses the default collector registry * let text = await exposition(); @@ -39,7 +40,7 @@ * @module lib/prometheus */ import { Type, Static } from "@sinclair/typebox"; -import { StringEnum } from "./data/composites"; +import { StringEnum } from "./data/composites.js"; /** * Result from collecting a {@link Collector} @@ -1669,7 +1670,8 @@ async function* expositionLines( * express.js. * * @example - * const app = require("express")(); + * import express from "express"; + * const app = express(); * async function getMetrics(req, res) { * // By default exposition uses the default collector registry * let text = await exposition(); diff --git a/packages/lib/src/rce_ops.ts b/packages/lib/src/rce_ops.ts index b5ad5be5..92f32adc 100644 --- a/packages/lib/src/rce_ops.ts +++ b/packages/lib/src/rce_ops.ts @@ -1,15 +1,15 @@ import util from "util"; import path from "path"; import { exec } from "child_process"; -import { logger } from "./logging"; -import { RequestError } from "./errors"; -import { PluginNodeEnvInfo } from "./plugin"; +import { logger } from "./logging.js"; +import { RequestError } from "./errors.js"; +import { PluginNodeEnvInfo } from "./plugin.js"; const execAsync = util.promisify(exec); function isDev() { // dev: /packages/lib/dist/src/rce_ops.js // prod: /node_modules/@clusterio/lib/dist/src/rce_ops.js - return __dirname.split(path.sep).at(-5) === "packages"; // opposed to "@clusterio" + return import.meta.dirname.split(path.sep).at(-5) === "packages"; // opposed to "@clusterio" } async function logExec(cmd: string) { diff --git a/packages/lib/src/schema.ts b/packages/lib/src/schema.ts index c783a3c9..4224086b 100644 --- a/packages/lib/src/schema.ts +++ b/packages/lib/src/schema.ts @@ -2,7 +2,7 @@ * JSON schemas used for validating link messages * @module lib/schema */ -import Ajv, { JSONSchemaType, ValidateFunction } from "ajv"; +import { Ajv, JSONSchemaType, ValidateFunction } from "ajv"; const ajv = new Ajv({ // These are duplicated in scripts/compile_validator allowUnionTypes: true, diff --git a/packages/lib/src/shared_commands.ts b/packages/lib/src/shared_commands.ts index d9f6eb09..654f0d90 100644 --- a/packages/lib/src/shared_commands.ts +++ b/packages/lib/src/shared_commands.ts @@ -4,11 +4,12 @@ */ import path from "path"; -import * as libConfig from "./config"; -import * as libFileOps from "./file_ops"; -import { logger } from "./logging"; -import * as libHelpers from "./helpers"; -import { LockFile } from "./LockFile"; +import * as libConfig from "./config/index.js"; +import * as libFileOps from "./file_ops.js"; +import { logger } from "./logging.js"; +import * as libHelpers from "./helpers.js"; +import { LockFile } from "./LockFile.js"; +import { pathToFileURL } from "url"; function print(...content: any[]) { @@ -59,8 +60,13 @@ export async function handlePluginCommand( let pluginInfo: { name: string }; try { - - pluginInfo = require(pluginPath).plugin; + const pluginPackage = (await import( + pathToFileURL(path.posix.join(pluginPath, "package.json")).href, + { with: { type: "json" }}, + )).default; + pluginInfo = (await import( + pathToFileURL(path.posix.join(pluginPath, pluginPackage.main ?? "index.js")).href + )).plugin; } catch (err: any) { logger.error(`Unable to import plugin info from ${args.path}:\n${err.stack}`); process.exitCode = 1; diff --git a/packages/lib/src/subscriptions.ts b/packages/lib/src/subscriptions.ts index 1b3311b6..4324f53e 100644 --- a/packages/lib/src/subscriptions.ts +++ b/packages/lib/src/subscriptions.ts @@ -1,9 +1,9 @@ import { Type, Static } from "@sinclair/typebox"; -import { Link, Event, EventClass, RequestHandler, WebSocketBaseConnector } from "./link"; -import { Address, MessageRequest, IUser, JsonBoolean, StringEnum, AccountDetails } from "./data"; -import isDeepStrictEqual from "./is_deep_strict_equal"; -import { RequestError } from "./errors"; -import { logger } from "./logging"; +import { Link, Event, EventClass, RequestHandler, WebSocketBaseConnector } from "./link/index.js"; +import { Address, MessageRequest, IUser, JsonBoolean, StringEnum } from "./data/index.js"; +import isDeepStrictEqual from "#is_deep_strict_equal"; +import { RequestError } from "./errors.js"; +import { logger } from "./logging.js"; export type SubscriptionRequestHandler = RequestHandler | null>; export type EventSubscriberCallback = (event: T | null, synced: boolean) => void diff --git a/packages/lib/src/system_collectors.ts b/packages/lib/src/system_collectors.ts index adadc0ad..6132dfe2 100644 --- a/packages/lib/src/system_collectors.ts +++ b/packages/lib/src/system_collectors.ts @@ -1,8 +1,8 @@ import fs from "node:fs/promises"; import os from "os"; import util from "util"; -import { Gauge } from "./prometheus"; -import { SystemInfo } from "./data"; +import { Gauge } from "./prometheus.js"; +import { SystemInfo } from "./data/index.js"; function filterCpuModel() { const model = os.cpus()[0].model; diff --git a/packages/lib/tsconfig.browser.json b/packages/lib/tsconfig.browser.json index 8a87bca4..f90faa99 100644 --- a/packages/lib/tsconfig.browser.json +++ b/packages/lib/tsconfig.browser.json @@ -15,6 +15,7 @@ "./src/helpers.ts", "./src/hash.ts", "./src/ini.ts", + "./src/is_deep_strict_equal.browser.ts", "./src/link/*.ts", "./src/lua_tools.ts", "./src/logging.ts", diff --git a/packages/lib/tsconfig.node.json b/packages/lib/tsconfig.node.json index ef6ccd30..983999cb 100644 --- a/packages/lib/tsconfig.node.json +++ b/packages/lib/tsconfig.node.json @@ -1,6 +1,7 @@ { "extends": "../../tsconfig.node.json", "include": ["index.ts", "build_mod.js", "src/**/*.ts", "src/**/*.js"], + "exclude": ["src/**/*.browser.ts"], "compilerOptions": { "allowJs": true, }, diff --git a/packages/web_ui/webpack.common.js b/packages/web_ui/webpack.common.js index 26545081..2ae834ab 100644 --- a/packages/web_ui/webpack.common.js +++ b/packages/web_ui/webpack.common.js @@ -141,6 +141,9 @@ module.exports = (env = {}, argv = {}) => ({ }, resolve: { extensions: [".js", ".ts", ".json", ".jsx", ".tsx"], + extensionAlias: { + ".js": [".ts", ".js"], + }, fallback: { "crypto": false, "fs": false, diff --git a/plugins/global_chat/control.ts b/plugins/global_chat/control.ts index 3b6534ba..ff4f5068 100644 --- a/plugins/global_chat/control.ts +++ b/plugins/global_chat/control.ts @@ -1,6 +1,6 @@ import { CommandTree, Command } from "@clusterio/lib"; import { BaseCtlPlugin } from "@clusterio/ctl"; -import { ChatEvent } from "./messages"; +import { ChatEvent } from "./messages.js"; const globalChatCommands = new CommandTree({ name: "global-chat", description: "Global Chat plugin commands", diff --git a/plugins/global_chat/index.ts b/plugins/global_chat/index.ts index a02d5cfd..dee12820 100644 --- a/plugins/global_chat/index.ts +++ b/plugins/global_chat/index.ts @@ -1,13 +1,13 @@ import type * as lib from "@clusterio/lib"; -import { ChatEvent } from "./messages"; +import { ChatEvent } from "./messages.js"; export const plugin: lib.PluginDeclaration = { name: "global_chat", title: "Global Chat", description: "Forwards chat between instances.", - instanceEntrypoint: "dist/node/instance", - ctlEntrypoint: "dist/node/control", + instanceEntrypoint: "dist/node/instance.js", + ctlEntrypoint: "dist/node/control.js", features: [ "ScriptCommands", diff --git a/plugins/global_chat/instance.ts b/plugins/global_chat/instance.ts index 2a3fa4e6..22cf1dda 100644 --- a/plugins/global_chat/instance.ts +++ b/plugins/global_chat/instance.ts @@ -1,6 +1,6 @@ import * as lib from "@clusterio/lib"; import { BaseInstancePlugin } from "@clusterio/host"; -import { ChatEvent } from "./messages"; +import { ChatEvent } from "./messages.js"; /** * Removes server-specific tags from messages. diff --git a/plugins/global_chat/package.json b/plugins/global_chat/package.json index c33bba72..1b259dbb 100644 --- a/plugins/global_chat/package.json +++ b/plugins/global_chat/package.json @@ -23,6 +23,7 @@ "access": "public" }, + "type": "module", "main": "dist/node/index.js", "scripts": { "prepare": "tsc --build && webpack-cli --mode production", diff --git a/plugins/global_chat/test/plugin.js b/plugins/global_chat/test/plugin.js index 6436dc16..0b3b1a1e 100644 --- a/plugins/global_chat/test/plugin.js +++ b/plugins/global_chat/test/plugin.js @@ -1,13 +1,10 @@ -"use strict"; -const assert = require("assert").strict; -const lib = require("@clusterio/lib"); - -const mock = require("../../../test/mock"); -const lines = require("../../../test/lib/factorio/lines"); -const instance = require("../dist/node/instance"); -const info = require("../dist/node/index").plugin; -const { ChatEvent } = require("../dist/node/messages"); +import assert from "node:assert/strict"; +import * as mock from "../../../test/mock.js"; +import * as lines from "../../../test/lib/factorio/lines.js"; +import * as instance from "../dist/node/instance.js"; +import { plugin as info } from "../dist/node/index.js"; +import { ChatEvent } from "../dist/node/messages.js"; describe("global_chat plugin", function() { describe("removeTags()", function() { diff --git a/plugins/global_chat/webpack.config.js b/plugins/global_chat/webpack.config.cjs similarity index 100% rename from plugins/global_chat/webpack.config.js rename to plugins/global_chat/webpack.config.cjs diff --git a/plugins/inventory_sync/controller.ts b/plugins/inventory_sync/controller.ts index 19df1451..6bd7fa10 100644 --- a/plugins/inventory_sync/controller.ts +++ b/plugins/inventory_sync/controller.ts @@ -1,10 +1,10 @@ import { BaseControllerPlugin, type InstanceRecord } from "@clusterio/controller"; -import type { IpcPlayerData } from "./messages"; +import type { IpcPlayerData } from "./messages.js"; import fs from "node:fs/promises"; import path from "path"; import * as lib from "@clusterio/lib"; -import * as msg from "./messages"; +import * as msg from "./messages.js"; async function loadDatabase(config: lib.ControllerConfig, logger: lib.Logger) { let itemsPath = path.resolve(config.get("controller.database_directory"), "inventories.json"); diff --git a/plugins/inventory_sync/index.ts b/plugins/inventory_sync/index.ts index f38ec669..dc78621b 100644 --- a/plugins/inventory_sync/index.ts +++ b/plugins/inventory_sync/index.ts @@ -1,5 +1,5 @@ import * as lib from "@clusterio/lib"; -import * as messages from "./messages"; +import * as messages from "./messages.js"; declare module "@clusterio/lib" { export interface InstanceConfigFields { @@ -22,7 +22,7 @@ export const plugin: lib.PluginDeclaration = { title: "Inventory sync", description: "Synchronizes players inventories between instances", - instanceEntrypoint: "dist/node/instance", + instanceEntrypoint: "dist/node/instance.js", instanceConfigFields: { "inventory_sync.rcon_chunk_size": { title: "Rcon inventory chunk size", @@ -33,7 +33,7 @@ export const plugin: lib.PluginDeclaration = { }, }, - controllerEntrypoint: "dist/node/controller", + controllerEntrypoint: "dist/node/controller.js", controllerConfigFields: { "inventory_sync.player_lock_timeout": { title: "Player Lock Timeout", diff --git a/plugins/inventory_sync/instance.ts b/plugins/inventory_sync/instance.ts index c831e8fd..bc05d896 100644 --- a/plugins/inventory_sync/instance.ts +++ b/plugins/inventory_sync/instance.ts @@ -2,7 +2,7 @@ import * as lib from "@clusterio/lib"; import { BaseInstancePlugin } from "@clusterio/host"; import { AcquireRequest, AcquireResponse, ReleaseRequest, UploadRequest, DownloadRequest, DownloadResponse, IpcPlayerData, -} from "./messages"; +} from "./messages.js"; type IpcPlayerName = { player_name: string diff --git a/plugins/inventory_sync/package.json b/plugins/inventory_sync/package.json index 14c093a0..035df1ac 100644 --- a/plugins/inventory_sync/package.json +++ b/plugins/inventory_sync/package.json @@ -23,6 +23,7 @@ "access": "public" }, + "type": "module", "main": "dist/node/index.js", "scripts": { "prepare": "tsc --build && webpack-cli --mode production", diff --git a/plugins/inventory_sync/web/index.tsx b/plugins/inventory_sync/web/index.tsx index f17184e3..21aef86b 100644 --- a/plugins/inventory_sync/web/index.tsx +++ b/plugins/inventory_sync/web/index.tsx @@ -1,7 +1,7 @@ import React, { useContext, useEffect, useState } from "react"; import { BaseWebPlugin, PageLayout, PageHeader, ControlContext } from "@clusterio/web_ui"; -import { DatabaseStatsRequest, DatabaseStatsResponse } from "../messages"; +import { DatabaseStatsRequest, DatabaseStatsResponse } from "../messages.js"; import "./style.css"; diff --git a/plugins/inventory_sync/webpack.config.js b/plugins/inventory_sync/webpack.config.cjs similarity index 100% rename from plugins/inventory_sync/webpack.config.js rename to plugins/inventory_sync/webpack.config.cjs diff --git a/plugins/player_auth/controller.ts b/plugins/player_auth/controller.ts index 02e9c25a..19dcce81 100644 --- a/plugins/player_auth/controller.ts +++ b/plugins/player_auth/controller.ts @@ -4,11 +4,10 @@ import util from "util"; import jwt from "jsonwebtoken"; import { Static } from "@sinclair/typebox"; -import * as lib from "@clusterio/lib"; import { BaseControllerPlugin } from "@clusterio/controller"; -const { basicType } = lib; +import { basicType, RequestError } from "@clusterio/lib"; -import { FetchPlayerCodeRequest, PlayerAuthServer, SetVerifyCodeRequest } from "./messages"; +import { FetchPlayerCodeRequest, PlayerAuthServer, SetVerifyCodeRequest } from "./messages.js"; async function generateCode(length: number): Promise { @@ -207,7 +206,7 @@ export class ControllerPlugin extends BaseControllerPlugin { let entry = this.players.get(player); if (!entry || entry.expiresMs < Date.now()) { - throw new lib.RequestError("invalid player"); + throw new RequestError("invalid player"); } entry.verifyCode = verifyCode; diff --git a/plugins/player_auth/index.ts b/plugins/player_auth/index.ts index f8d860b1..f4f5d6aa 100644 --- a/plugins/player_auth/index.ts +++ b/plugins/player_auth/index.ts @@ -1,5 +1,5 @@ import * as lib from "@clusterio/lib"; -import * as messages from "./messages"; +import * as messages from "./messages.js"; declare module "@clusterio/lib" { export interface InstanceConfigFields { @@ -16,8 +16,8 @@ export const plugin: lib.PluginDeclaration = { name: "player_auth", title: "Player Auth", description: "Provides authentication to the cluster via logging into a Factorio server.", - controllerEntrypoint: "dist/node/controller", - instanceEntrypoint: "dist/node/instance", + controllerEntrypoint: "dist/node/controller.js", + instanceEntrypoint: "dist/node/instance.js", webEntrypoint: "./web", controllerConfigFields: { "player_auth.code_length": { diff --git a/plugins/player_auth/instance.ts b/plugins/player_auth/instance.ts index 780dd1a3..58be8518 100644 --- a/plugins/player_auth/instance.ts +++ b/plugins/player_auth/instance.ts @@ -1,6 +1,6 @@ import { BaseInstancePlugin } from "@clusterio/host"; -import { FetchPlayerCodeRequest, SetVerifyCodeRequest } from "./messages"; +import { FetchPlayerCodeRequest, SetVerifyCodeRequest } from "./messages.js"; type IpcPlayerAuth = { type: "open_dialog", diff --git a/plugins/player_auth/package.json b/plugins/player_auth/package.json index e674f239..20b174a5 100644 --- a/plugins/player_auth/package.json +++ b/plugins/player_auth/package.json @@ -23,6 +23,7 @@ "access": "public" }, + "type": "module", "main": "dist/node/index.js", "scripts": { "prepare": "tsc --build && webpack-cli --mode production", diff --git a/plugins/player_auth/test/plugin.js b/plugins/player_auth/test/plugin.js index 35d21e54..590af809 100644 --- a/plugins/player_auth/test/plugin.js +++ b/plugins/player_auth/test/plugin.js @@ -1,15 +1,14 @@ -"use strict"; -const assert = require("assert").strict; -const jwt = require("jsonwebtoken"); +import assert from "node:assert/strict"; +import jwt from "jsonwebtoken"; -const mock = require("../../../test/mock"); +import * as mock from "../../../test/mock.js"; -const controller = require("../dist/node/controller"); -const instance = require("../dist/node/instance"); -const info = require("../dist/node/index").plugin; -const { FetchPlayerCodeRequest, SetVerifyCodeRequest, PlayerAuthServer } = require("../dist/node/messages"); -const { testRoundTripJsonSerialisable, testMatrix } = require("../../../test/common"); -const lib = require("@clusterio/lib"); +import * as controller from "../dist/node/controller.js"; +import * as instance from "../dist/node/instance.js"; +import { plugin as info } from "../dist/node/index.js"; +import { FetchPlayerCodeRequest, SetVerifyCodeRequest, PlayerAuthServer } from "../dist/node/messages.js"; +import { testRoundTripJsonSerialisable, testMatrix } from "../../../test/common.js"; +import * as lib from "@clusterio/lib"; function postJSON(url, body) { diff --git a/plugins/player_auth/web/index.tsx b/plugins/player_auth/web/index.tsx index 1c5cd20a..17cb7531 100644 --- a/plugins/player_auth/web/index.tsx +++ b/plugins/player_auth/web/index.tsx @@ -3,7 +3,7 @@ import React, { useEffect, useState } from "react"; import { BaseWebPlugin, notifyErrorHandler } from "@clusterio/web_ui"; import { Alert, Button, Form, Input, Modal, Space, Spin, Typography } from "antd"; -import { PlayerAuthServer } from "../messages"; +import { PlayerAuthServer } from "../messages.js"; import "./style.css"; const { Paragraph, Text } = Typography; diff --git a/plugins/player_auth/webpack.config.js b/plugins/player_auth/webpack.config.cjs similarity index 100% rename from plugins/player_auth/webpack.config.js rename to plugins/player_auth/webpack.config.cjs diff --git a/plugins/research_sync/controller.ts b/plugins/research_sync/controller.ts index 498e2a45..954e5f70 100644 --- a/plugins/research_sync/controller.ts +++ b/plugins/research_sync/controller.ts @@ -4,7 +4,7 @@ import { BaseControllerPlugin } from "@clusterio/controller"; import { Static } from "@sinclair/typebox"; import * as lib from "@clusterio/lib"; -const { RateLimiter } = lib; +import { RateLimiter } from "@clusterio/lib"; import { ContributionEvent, @@ -13,7 +13,7 @@ import { TechnologySync, SyncTechnologiesRequest, TechnologyProgress, -} from "./messages"; +} from "./messages.js"; type Technology = { level: number, diff --git a/plugins/research_sync/index.ts b/plugins/research_sync/index.ts index 85afabdc..33a0967a 100644 --- a/plugins/research_sync/index.ts +++ b/plugins/research_sync/index.ts @@ -1,13 +1,13 @@ import type * as lib from "@clusterio/lib"; -import * as messages from "./messages"; +import * as messages from "./messages.js"; export const plugin: lib.PluginDeclaration = { name: "research_sync", title: "Research Sync", description: "Synchronises technology research progress between instances.", - instanceEntrypoint: "dist/node/instance", - controllerEntrypoint: "dist/node/controller", + instanceEntrypoint: "dist/node/instance.js", + controllerEntrypoint: "dist/node/controller.js", features: [ "SavePatching", diff --git a/plugins/research_sync/instance.ts b/plugins/research_sync/instance.ts index 5ce28907..5e254d86 100644 --- a/plugins/research_sync/instance.ts +++ b/plugins/research_sync/instance.ts @@ -6,7 +6,7 @@ import { FinishedEvent, TechnologySync, SyncTechnologiesRequest, -} from "./messages"; +} from "./messages.js"; // ./module/sync.lua type IpcContribution = { diff --git a/plugins/research_sync/package.json b/plugins/research_sync/package.json index b21ebf5f..2f3ef9ea 100644 --- a/plugins/research_sync/package.json +++ b/plugins/research_sync/package.json @@ -23,6 +23,7 @@ "access": "public" }, + "type": "module", "main": "dist/node/index.js", "scripts": { "prepare": "tsc --build && webpack-cli --mode production", diff --git a/plugins/research_sync/test/missing.js b/plugins/research_sync/test/missing.js index ae16e8f1..4d585e2b 100644 --- a/plugins/research_sync/test/missing.js +++ b/plugins/research_sync/test/missing.js @@ -1,6 +1,5 @@ // These are libraries that does not have any units test, they are // required here in order to track coverage for them. -"use strict"; -require("../dist/node/instance"); -require("../dist/node/controller"); +import "../dist/node/instance.js"; +import "../dist/node/controller.js"; diff --git a/plugins/research_sync/webpack.config.js b/plugins/research_sync/webpack.config.cjs similarity index 100% rename from plugins/research_sync/webpack.config.js rename to plugins/research_sync/webpack.config.cjs diff --git a/plugins/statistics_exporter/index.ts b/plugins/statistics_exporter/index.ts index 6e769973..f9a38150 100644 --- a/plugins/statistics_exporter/index.ts +++ b/plugins/statistics_exporter/index.ts @@ -12,7 +12,7 @@ export const plugin: lib.PluginDeclaration = { description: "Provides in-game item/fluid production, builds, kills, and pollution "+ "statistics to the cluster's Prometheus endpoint.", - instanceEntrypoint: "dist/node/instance", + instanceEntrypoint: "dist/node/instance.js", instanceConfigFields: { "statistics_exporter.command_timeout": { title: "Command Timeout", diff --git a/plugins/statistics_exporter/instance.ts b/plugins/statistics_exporter/instance.ts index c76bf1f0..82382ada 100644 --- a/plugins/statistics_exporter/instance.ts +++ b/plugins/statistics_exporter/instance.ts @@ -1,7 +1,7 @@ import * as lib from "@clusterio/lib"; import { BaseInstancePlugin } from "@clusterio/host"; -const { Gauge } = lib; +import { Gauge } from "@clusterio/lib"; type IpcStats = { game_tick: number, diff --git a/plugins/statistics_exporter/package.json b/plugins/statistics_exporter/package.json index 68c2a4a0..5ca2bb5a 100644 --- a/plugins/statistics_exporter/package.json +++ b/plugins/statistics_exporter/package.json @@ -23,6 +23,7 @@ "access": "public" }, + "type": "module", "main": "dist/node/index.js", "scripts": { "prepare": "tsc --build && webpack-cli --mode production", diff --git a/plugins/statistics_exporter/test/plugin.js b/plugins/statistics_exporter/test/plugin.js index 6c0393e1..49f1439e 100644 --- a/plugins/statistics_exporter/test/plugin.js +++ b/plugins/statistics_exporter/test/plugin.js @@ -1,9 +1,8 @@ -"use strict"; -const assert = require("assert").strict; +import assert from "node:assert/strict"; -const mock = require("../../../test/mock"); -const instance = require("../dist/node/instance"); -const info = require("../dist/node/index").plugin; +import * as mock from "../../../test/mock.js"; +import * as instance from "../dist/node/instance.js"; +import { plugin as info } from "../dist/node/index.js"; describe("statistics_exporter plugin", function() { diff --git a/plugins/statistics_exporter/webpack.config.js b/plugins/statistics_exporter/webpack.config.cjs similarity index 100% rename from plugins/statistics_exporter/webpack.config.js rename to plugins/statistics_exporter/webpack.config.cjs diff --git a/plugins/subspace_storage/controller.ts b/plugins/subspace_storage/controller.ts index 4630d1a5..32f990cc 100644 --- a/plugins/subspace_storage/controller.ts +++ b/plugins/subspace_storage/controller.ts @@ -4,10 +4,10 @@ import fs from "node:fs/promises"; import path from "path"; import * as lib from "@clusterio/lib"; -const { Counter, Gauge } = lib; +import { Counter, Gauge } from "@clusterio/lib"; -import * as routes from "./routes"; -import * as dole from "./dole"; +import * as routes from "./routes.js"; +import * as dole from "./dole.js"; import { Item, @@ -16,7 +16,7 @@ import { GetStorageRequest, UpdateStorageEvent, SetStorageSubscriptionRequest, -} from "./messages"; +} from "./messages.js"; const exportCounter = new Counter( diff --git a/plugins/subspace_storage/dole.ts b/plugins/subspace_storage/dole.ts index 4060f424..f01f20e9 100644 --- a/plugins/subspace_storage/dole.ts +++ b/plugins/subspace_storage/dole.ts @@ -1,7 +1,7 @@ -import * as doleNN from "./dole_nn_base"; +import * as doleNN from "./dole_nn_base.js"; import * as lib from "@clusterio/lib"; -const { Gauge } = lib; +import { Gauge } from "@clusterio/lib"; const prometheusNNDoleGauge = new Gauge( diff --git a/plugins/subspace_storage/index.ts b/plugins/subspace_storage/index.ts index 300c8895..00cb5914 100644 --- a/plugins/subspace_storage/index.ts +++ b/plugins/subspace_storage/index.ts @@ -1,5 +1,5 @@ import * as lib from "@clusterio/lib"; -import * as messages from "./messages"; +import * as messages from "./messages.js"; declare module "@clusterio/lib" { export interface ControllerConfigFields { @@ -22,7 +22,7 @@ export const plugin: lib.PluginDeclaration = { name: "subspace_storage", title: "Subspace Storage", description: "Provides shared storage across instances for the Subspace Storage mod", - instanceEntrypoint: "dist/node/instance", + instanceEntrypoint: "dist/node/instance.js", instanceConfigFields: { "subspace_storage.log_item_transfers": { title: "Log Item Transfers", @@ -32,7 +32,7 @@ export const plugin: lib.PluginDeclaration = { }, }, - controllerEntrypoint: "dist/node/controller", + controllerEntrypoint: "dist/node/controller.js", controllerConfigFields: { "subspace_storage.division_method": { title: "Division Method", diff --git a/plugins/subspace_storage/instance.ts b/plugins/subspace_storage/instance.ts index 4de15afb..87ab957f 100644 --- a/plugins/subspace_storage/instance.ts +++ b/plugins/subspace_storage/instance.ts @@ -7,7 +7,7 @@ import { GetStorageRequest, UpdateStorageEvent, Item, -} from "./messages"; +} from "./messages.js"; type IpcItems = [name: string, count: number, quality: string][]; diff --git a/plugins/subspace_storage/package.json b/plugins/subspace_storage/package.json index 3b77dec0..7a7c2582 100644 --- a/plugins/subspace_storage/package.json +++ b/plugins/subspace_storage/package.json @@ -23,6 +23,7 @@ "access": "public" }, + "type": "module", "main": "dist/node/index.js", "scripts": { "prepare": "tsc --build && webpack-cli --mode production", diff --git a/plugins/subspace_storage/test/missing.js b/plugins/subspace_storage/test/missing.js index ab3009d7..e01532ac 100644 --- a/plugins/subspace_storage/test/missing.js +++ b/plugins/subspace_storage/test/missing.js @@ -1,8 +1,7 @@ // These are libraries that does not have any units test, they are // required here in order to track coverage for them. -"use strict"; -require("../dist/node/instance"); -require("../dist/node/controller"); -require("../dist/node/dole"); -require("../dist/node/dole_nn_base"); +import "../dist/node/instance.js"; +import "../dist/node/controller.js"; +import "../dist/node/dole.js"; +import "../dist/node/dole_nn_base.js"; diff --git a/plugins/subspace_storage/test/routes.js b/plugins/subspace_storage/test/routes.js index fc4aac5b..3d8b0afd 100644 --- a/plugins/subspace_storage/test/routes.js +++ b/plugins/subspace_storage/test/routes.js @@ -1,8 +1,7 @@ -"use strict"; -const assert = require("assert").strict; +import assert from "node:assert/strict"; -const routes = require("../dist/node/routes"); -const { get } = require("../../../test/integration"); +import * as routes from "../dist/node/routes.js"; +import { get } from "../../../test/integration/index.js"; describe("subspace_storage endpoints", function() { diff --git a/plugins/subspace_storage/web/index.tsx b/plugins/subspace_storage/web/index.tsx index 2ead807c..2b91ca61 100644 --- a/plugins/subspace_storage/web/index.tsx +++ b/plugins/subspace_storage/web/index.tsx @@ -6,7 +6,7 @@ import { useExportLocale, useExportPrototypeMetadata, useDefaultModPack, FactorioIcon, useTableQueryState, useColumnSearch, } from "@clusterio/web_ui"; -import { GetStorageRequest, Item, SetStorageSubscriptionRequest, UpdateStorageEvent } from "../messages"; +import { GetStorageRequest, Item, SetStorageSubscriptionRequest, UpdateStorageEvent } from "../messages.js"; import "./style.css"; diff --git a/plugins/subspace_storage/webpack.config.js b/plugins/subspace_storage/webpack.config.cjs similarity index 100% rename from plugins/subspace_storage/webpack.config.js rename to plugins/subspace_storage/webpack.config.cjs diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index f22b099c..949418cc 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -11,7 +11,7 @@ catalog: '@types/express': ^4.17.17 '@types/finalhandler': ^1.2.0 '@types/jsonwebtoken': ^9.0.9 - '@types/node': ^20.17.19 + '@types/node': ^22.20.1 '@types/react': ^18.3.18 '@types/set-blocking': ^2.0.0 '@types/ws': ^8.5.14 @@ -38,4 +38,7 @@ catalogMode: strict linkWorkspacePackages: true +onlyBuiltDependencies: + - '@swc/core' + shellEmulator: true diff --git a/publish.js b/publish.js index 80c81a7c..90aaabaf 100644 --- a/publish.js +++ b/publish.js @@ -2,10 +2,9 @@ * Publish any mods that need to be published */ -"use strict"; -const FormData = require("form-data"); -const fs = require("node:fs/promises"); -const yargs = require("yargs"); +import FormData from "form-data"; +import fs from "node:fs/promises"; +import yargs from "yargs"; let DRY = false; @@ -129,6 +128,6 @@ async function main() { } // Run main if started from command line -if (module === require.main) { +if (import.meta.main) { main(); } diff --git a/scripts/version-compat-test.js b/scripts/version-compat-test.js index d4055900..1e7c9250 100644 --- a/scripts/version-compat-test.js +++ b/scripts/version-compat-test.js @@ -19,16 +19,16 @@ * The repository must be built (pnpm run build) before running with a local side. */ "use strict"; -const child_process = require("child_process"); -const events = require("events"); -const fs = require("fs/promises"); -const path = require("path"); -const readline = require("readline"); -const util = require("util"); +import child_process from "node:child_process"; +import events from "node:events"; +import fs from "node:fs/promises"; +import path from "node:path"; +import readline from "node:readline"; +import util from "node:util"; const execFile = util.promisify(child_process.execFile); -const repoRoot = path.join(__dirname, ".."); +const repoRoot = path.join(import.meta.dirname, ".."); const workDir = path.join(repoRoot, "temp", "compat-test"); const controllerDir = path.join(workDir, "controller"); const hostDir = path.join(workDir, "host"); diff --git a/test/common.js b/test/common.js index eb75a3f2..b35116d9 100644 --- a/test/common.js +++ b/test/common.js @@ -1,6 +1,5 @@ -"use strict"; -const assert = require("assert").strict; -const { compile } = require("@clusterio/lib"); +import assert from "node:assert/strict"; +import { compile } from "@clusterio/lib"; /** * Generate a flat array of tests from a matrix of inputs. @@ -10,7 +9,7 @@ const { compile } = require("@clusterio/lib"); * @returns {Array<{ [K in keyof T]: T[K][number] }>} * An array of tuples, each containing one value from each input array. */ -function testMatrix(...arrays) { +export function testMatrix(...arrays) { return arrays.reduce((acc, curr) => acc.flatMap(a => curr.map(b => [...a, b])), [[]]); } @@ -21,7 +20,7 @@ function testMatrix(...arrays) { * @param {{new(...args: T): object}} Class - The class which has toJSON and fromJSON methods. * @param {T[]} tests - The tests inputs to pass to the class constructor. */ -function testRoundTripJsonSerialisable(Class, tests) { +export function testRoundTripJsonSerialisable(Class, tests) { const validate = compile(Class.jsonSchema); for (const test of tests) { const original = new Class(...test); @@ -34,8 +33,3 @@ function testRoundTripJsonSerialisable(Class, tests) { } } } - -module.exports = { - testMatrix, - testRoundTripJsonSerialisable, -}; diff --git a/test/controller/BaseControllerPlugin.js b/test/controller/BaseControllerPlugin.js index b4dda949..0ff45811 100644 --- a/test/controller/BaseControllerPlugin.js +++ b/test/controller/BaseControllerPlugin.js @@ -1,6 +1,5 @@ -"use strict"; -const mock = require("../mock"); -const controller = require("@clusterio/controller"); +import * as mock from "../mock.js"; +import * as controller from "@clusterio/controller"; describe("controller/src/BaseControllerPlugin", function() { describe("class BaseControllerPlugin", function() { diff --git a/test/controller/ControlConnection.test.js b/test/controller/ControlConnection.test.js index 90483a08..2ad0db9d 100644 --- a/test/controller/ControlConnection.test.js +++ b/test/controller/ControlConnection.test.js @@ -1,6 +1,5 @@ -"use strict"; -const assert = require("assert").strict; -const { ControlConnection } = require("@clusterio/controller"); +import assert from "node:assert/strict"; +import { ControlConnection } from "@clusterio/controller"; describe("controller/src/ControlConnection", function() { describe(".handleControllerRestartRequest()", function() { diff --git a/test/controller/Controller.js b/test/controller/Controller.js index 6054854a..d2f014ca 100644 --- a/test/controller/Controller.js +++ b/test/controller/Controller.js @@ -1,17 +1,16 @@ -"use strict"; -const path = require("node:path"); -const assert = require("assert").strict; -const { Controller, HostRecord, InstanceRecord, UserRecord } = require("@clusterio/controller"); -const { EventEmitter } = require("stream"); -const events = require("node:events"); -const http = require("node:http"); -const express = require("express"); +import path from "node:path"; +import assert from "node:assert/strict"; +import { Controller, HostRecord, InstanceRecord, UserRecord } from "@clusterio/controller"; +import events, { EventEmitter } from "node:events"; +import http from "node:http"; +import express from "express"; +import { fileURLToPath } from "node:url"; -const { +import { ControllerConfig, Address, RequestError, InstanceConfig, SystemInfo, Role, ModPack, addPluginConfigFields, -} = require("@clusterio/lib"); +} from "@clusterio/lib"; class MockEvent {} @@ -33,10 +32,12 @@ class MockInstanceConfig extends EventEmitter { } describe("controller/src/Controller", function() { - describe("class Controller", function() { + describe("class Controller", async function() { /** @type {Controller} */ let controller, mockInstanceConfig; - const controllerVersion = require("@clusterio/controller/package.json").version; + const controllerVersion = ( + await import("@clusterio/controller/package.json", { with: { type: "json" }}) + ).default.version; before(async function() { const controllerConfig = new ControllerConfig("controller", { "controller.version": controllerVersion }); controller = new Controller({}, [], controllerConfig); @@ -245,7 +246,7 @@ describe("controller/src/Controller", function() { controller.config.restartRequired = false; controller.pluginInfos[0] = { name: "restart_test", - packagePath: require.resolve("@clusterio/controller/package.json"), + packagePath: fileURLToPath(import.meta.resolve("@clusterio/controller/package.json")), version: controllerVersion, }; }); diff --git a/test/controller/ControllerUser.js b/test/controller/ControllerUser.js index 12f789c3..8897e474 100644 --- a/test/controller/ControllerUser.js +++ b/test/controller/ControllerUser.js @@ -1,7 +1,6 @@ -"use strict"; -const assert = require("assert").strict; -const lib = require("@clusterio/lib"); -const { User } = require("@clusterio/controller"); +import assert from "node:assert/strict"; +import * as lib from "@clusterio/lib"; +import { User } from "@clusterio/controller"; describe("controller/src/User", function() { describe("class User", function() { diff --git a/test/controller/HostRecord.test.js b/test/controller/HostRecord.test.js index 60ca74de..687497e4 100644 --- a/test/controller/HostRecord.test.js +++ b/test/controller/HostRecord.test.js @@ -1,9 +1,8 @@ -"use strict"; -const assert = require("assert").strict; -const { HostDetails } = require("@clusterio/lib"); -const { HostRecord } = require("@clusterio/controller"); +import assert from "node:assert/strict"; +import { HostDetails } from "@clusterio/lib"; +import { HostRecord } from "@clusterio/controller"; -const { testMatrix, testRoundTripJsonSerialisable } = require("../common"); +import { testMatrix, testRoundTripJsonSerialisable } from "../common.js"; describe("controller/HostRecord", function () { const samplePlugins = new Map([ diff --git a/test/controller/HttpCloser.js b/test/controller/HttpCloser.js index d7bcadd4..f072d051 100644 --- a/test/controller/HttpCloser.js +++ b/test/controller/HttpCloser.js @@ -1,12 +1,11 @@ -"use strict"; -const assert = require("assert").strict; -const fs = require("node:fs/promises"); -const http = require("http"); -const https = require("https"); -const util = require("util"); -const events = require("node:events"); +import assert from "node:assert/strict"; +import fs from "node:fs/promises"; +import http from "node:http"; +import https from "node:https"; +import util from "node:util"; +import events from "node:events"; -const HttpCloser = require("@clusterio/controller/dist/node/src/HttpCloser").default; +import HttpCloser from "@clusterio/controller/dist/node/src/HttpCloser.js"; // Time to wait during async operations to ensure they happened in order. const tick = 20; diff --git a/test/controller/InstanceManager.test.js b/test/controller/InstanceManager.test.js index 312cb402..59e05063 100644 --- a/test/controller/InstanceManager.test.js +++ b/test/controller/InstanceManager.test.js @@ -1,8 +1,7 @@ -"use strict"; -const assert = require("assert").strict; -const lib = require("@clusterio/lib"); +import assert from "node:assert/strict"; +import * as lib from "@clusterio/lib"; -const { Controller, InstanceRecord, InstanceManager } = require("@clusterio/controller"); +import { Controller, InstanceRecord, InstanceManager } from "@clusterio/controller"; describe("controller/InstanceManager", function () { /** @type {Controller} */ diff --git a/test/controller/InstanceRecord.test.js b/test/controller/InstanceRecord.test.js index c3c169c5..7b496bad 100644 --- a/test/controller/InstanceRecord.test.js +++ b/test/controller/InstanceRecord.test.js @@ -1,9 +1,8 @@ -"use strict"; -const assert = require("assert").strict; -const lib = require("@clusterio/lib"); -const { InstanceRecord } = require("@clusterio/controller"); +import assert from "node:assert/strict"; +import * as lib from "@clusterio/lib"; +import { InstanceRecord } from "@clusterio/controller"; -const { testMatrix, testRoundTripJsonSerialisable } = require("../common"); +import { testMatrix, testRoundTripJsonSerialisable } from "../common.js"; describe("controller/InstanceRecord", function () { /** @type {lib.InstanceConfig} */ diff --git a/test/controller/User.test.js b/test/controller/User.test.js index cf605280..a04bbdc0 100644 --- a/test/controller/User.test.js +++ b/test/controller/User.test.js @@ -1,7 +1,6 @@ -"use strict"; -const assert = require("assert").strict; -const { Role, SubscribableDatastore } = require("@clusterio/lib"); -const { User } = require("@clusterio/controller"); +import assert from "node:assert/strict"; +import { Role, SubscribableDatastore } from "@clusterio/lib"; +import { User } from "@clusterio/controller"; describe("controller/User", function () { /** @type {SubscribableDatastore} */ diff --git a/test/controller/UserManager.test.js b/test/controller/UserManager.test.js index 8312c3b7..5005875e 100644 --- a/test/controller/UserManager.test.js +++ b/test/controller/UserManager.test.js @@ -1,10 +1,9 @@ -"use strict"; -const path = require("path"); -const fs = require("node:fs/promises"); -const assert = require("assert").strict; -const jwt = require("jsonwebtoken"); -const { Role, SubscribableDatastore, ControllerConfig } = require("@clusterio/lib"); -const { UserRecord, UserManager } = require("@clusterio/controller"); +import path from "node:path"; +import fs from "node:fs/promises"; +import assert from "node:assert/strict"; +import jwt from "jsonwebtoken"; +import { Role, SubscribableDatastore, ControllerConfig } from "@clusterio/lib"; +import { UserRecord, UserManager } from "@clusterio/controller"; const TEMP_DIR = path.join("temp", "test", "UserManager"); diff --git a/test/controller/UserRecord.test.js b/test/controller/UserRecord.test.js index fe7c6ccb..c4e2eee9 100644 --- a/test/controller/UserRecord.test.js +++ b/test/controller/UserRecord.test.js @@ -1,9 +1,8 @@ -"use strict"; -const assert = require("assert").strict; -const { UserDetails, PlayerStats } = require("@clusterio/lib"); -const { UserRecord } = require("@clusterio/controller"); +import assert from "node:assert/strict"; +import { UserDetails, PlayerStats } from "@clusterio/lib"; +import { UserRecord } from "@clusterio/controller"; -const { testMatrix, testRoundTripJsonSerialisable } = require("../common"); +import { testMatrix, testRoundTripJsonSerialisable } from "../common.js"; describe("controller/UserRecord", function () { it("should be round trip serialisable", function () { diff --git a/test/controller/WsServer.js b/test/controller/WsServer.js index 7501ec59..3b97fe40 100644 --- a/test/controller/WsServer.js +++ b/test/controller/WsServer.js @@ -1,7 +1,6 @@ -"use strict"; -const assert = require("assert").strict; -const { Controller, WsServer } = require("@clusterio/controller"); -const { ControllerConfig } = require("@clusterio/lib"); +import assert from "node:assert/strict"; +import { Controller, WsServer } from "@clusterio/controller"; +import { ControllerConfig } from "@clusterio/lib"; describe("controller/src/WsServer", function() { describe("class WsServer", function() { diff --git a/test/controller/routes.js b/test/controller/routes.js index 5087e97b..5e764214 100644 --- a/test/controller/routes.js +++ b/test/controller/routes.js @@ -1,12 +1,11 @@ -"use strict"; -const assert = require("assert").strict; -const events = require("events"); -const FormData = require("form-data"); -const http = require("http"); +import assert from "node:assert/strict"; +import events from "node:events"; +import FormData from "form-data"; +import http from "node:http"; -const { wait } = require("@clusterio/lib"); -const routes = require("@clusterio/controller/dist/node/src/routes"); -const mock = require("../mock"); +import { wait } from "@clusterio/lib"; +import * as routes from "@clusterio/controller/dist/node/src/routes.js"; +import * as mock from "../mock.js"; describe("controller/src/routes", function() { let controller; diff --git a/test/create/echo_args.js b/test/create/echo_args.js index 1319b1cf..ecc1f2a1 100644 --- a/test/create/echo_args.js +++ b/test/create/echo_args.js @@ -1,4 +1,3 @@ -"use strict"; -if (module === require.main) { +if (import.meta.main) { process.stdout.write(JSON.stringify(process.argv.slice(2))); } diff --git a/test/create/escape_arg.js b/test/create/escape_arg.js index 593b1a3f..e9fcdf5f 100644 --- a/test/create/escape_arg.js +++ b/test/create/escape_arg.js @@ -1,17 +1,16 @@ -"use strict"; -const child_process = require("child_process"); -const util = require("util"); -const assert = require("assert").strict; -const path = require("path"); +import child_process from "node:child_process"; +import util from "node:util"; +import assert from "node:assert/strict"; +import path from "node:path"; -const { escapeArg } = require("../../packages/create/escape_arg"); +import { escapeArg } from "../../packages/create/escape_arg.js"; const execFile = util.promisify(child_process.execFile); async function exec(file, args) { const command = [file, ...args.map(escapeArg)].join(" "); const { stdout, stderr } = await execFile( command, - { shell: true, cwd: __dirname, env: { ...process.env, pct: "%"} } + { shell: true, cwd: import.meta.dirname, env: { ...process.env, pct: "%"} } ); return { stdout: JSON.parse(stdout), stderr }; } diff --git a/test/file/test_plugin/control.js b/test/file/test_plugin/control.js index 25a80a0c..6f903c05 100644 --- a/test/file/test_plugin/control.js +++ b/test/file/test_plugin/control.js @@ -1,6 +1,5 @@ -"use strict"; -const { Command, CommandTree } = require("@clusterio/lib"); -const { BaseCtlPlugin } = require("@clusterio/ctl"); +import { Command, CommandTree } from "@clusterio/lib"; +import { BaseCtlPlugin } from "@clusterio/ctl"; const testPluginCommands = new CommandTree({ name: "test-plugin", description: "Test plugin commands", @@ -15,12 +14,8 @@ testPluginCommands.add(new Command({ }, })); -class CtlPlugin extends BaseCtlPlugin { +export class CtlPlugin extends BaseCtlPlugin { async addCommands(rootCommand) { rootCommand.add(testPluginCommands); } } - -module.exports = { - CtlPlugin, -}; diff --git a/test/file/test_plugin/controller.js b/test/file/test_plugin/controller.js index 01988f39..2764aed2 100644 --- a/test/file/test_plugin/controller.js +++ b/test/file/test_plugin/controller.js @@ -1,9 +1,8 @@ -"use strict"; -const { BaseControllerPlugin } = require("@clusterio/controller"); +import { BaseControllerPlugin } from "@clusterio/controller"; -const { ControllerEcho, HostEcho } = require("./messages"); +import { ControllerEcho, HostEcho } from "./messages.js"; -class ControllerPlugin extends BaseControllerPlugin { +export class ControllerPlugin extends BaseControllerPlugin { async init() { this.logger.info("test_plugin controller loaded"); this.controller.handle(ControllerEcho, this.handleControllerEcho.bind(this)); @@ -15,7 +14,3 @@ class ControllerPlugin extends BaseControllerPlugin { return request.text; } } - -module.exports = { - ControllerPlugin, -}; diff --git a/test/file/test_plugin/host.js b/test/file/test_plugin/host.js index ca6a3bad..648d8c95 100644 --- a/test/file/test_plugin/host.js +++ b/test/file/test_plugin/host.js @@ -1,9 +1,8 @@ -"use strict"; -const { BaseHostPlugin } = require("@clusterio/host"); +import { BaseHostPlugin } from "@clusterio/host"; -const { HostEcho, HostEchoReceived } = require("./messages"); +import { HostEcho, HostEchoReceived } from "./messages.js"; -class HostPlugin extends BaseHostPlugin { +export class HostPlugin extends BaseHostPlugin { async init() { this.logger.info("test_plugin host loaded"); this.receivedEchoes = new Set(); @@ -20,7 +19,3 @@ class HostPlugin extends BaseHostPlugin { return this.receivedEchoes.has(request.text); } } - -module.exports = { - HostPlugin, -}; diff --git a/test/file/test_plugin/index.js b/test/file/test_plugin/index.js index 7938c45b..de9f64e2 100644 --- a/test/file/test_plugin/index.js +++ b/test/file/test_plugin/index.js @@ -1,24 +1,21 @@ -"use strict"; // Plugin exercising the plugin system in the integration tests, see #342. // Written as plain JavaScript so that it does not need to be built. -const { ControllerEcho, HostEcho, HostEchoReceived } = require("./messages"); +import { ControllerEcho, HostEcho, HostEchoReceived } from "./messages.js"; -module.exports = { - plugin: { - name: "test_plugin", - title: "Test Plugin", - description: "Plugin used to test the plugin system.", +export const plugin = { + name: "test_plugin", + title: "Test Plugin", + description: "Plugin used to test the plugin system.", - controllerEntrypoint: "controller", - hostEntrypoint: "host", - instanceEntrypoint: "instance", - ctlEntrypoint: "control", + controllerEntrypoint: "controller.js", + hostEntrypoint: "host.js", + instanceEntrypoint: "instance.js", + ctlEntrypoint: "control.js", - messages: [ - ControllerEcho, - HostEcho, - HostEchoReceived, - ], - }, + messages: [ + ControllerEcho, + HostEcho, + HostEchoReceived, + ], }; diff --git a/test/file/test_plugin/instance.js b/test/file/test_plugin/instance.js index 5296c026..61ec4c5f 100644 --- a/test/file/test_plugin/instance.js +++ b/test/file/test_plugin/instance.js @@ -1,12 +1,7 @@ -"use strict"; -const { BaseInstancePlugin } = require("@clusterio/host"); +import { BaseInstancePlugin } from "@clusterio/host"; -class InstancePlugin extends BaseInstancePlugin { +export class InstancePlugin extends BaseInstancePlugin { async init() { this.logger.info("test_plugin instance loaded"); } } - -module.exports = { - InstancePlugin, -}; diff --git a/test/file/test_plugin/messages.js b/test/file/test_plugin/messages.js index be98c2c4..59baf5af 100644 --- a/test/file/test_plugin/messages.js +++ b/test/file/test_plugin/messages.js @@ -1,9 +1,8 @@ -"use strict"; -const { JsonBoolean, JsonString } = require("@clusterio/lib"); +import { JsonBoolean, JsonString } from "@clusterio/lib"; // Sent from ctl to the controller, which answers with the text it was given // and broadcasts a HostEcho to the hosts. -class ControllerEcho { +export class ControllerEcho { static type = "request"; static src = "control"; static dst = "controller"; @@ -21,7 +20,7 @@ class ControllerEcho { } // Broadcast from the controller to the hosts by broadcastEventToHosts. -class HostEcho { +export class HostEcho { static type = "event"; static src = "controller"; static dst = "host"; @@ -39,7 +38,7 @@ class HostEcho { // Sent from ctl to a host, which answers with whether it received the given // text via a HostEcho. -class HostEchoReceived { +export class HostEchoReceived { static type = "request"; static src = "control"; static dst = "host"; @@ -55,9 +54,3 @@ class HostEchoReceived { toJSON() { return this.text; } static fromJSON(json) { return new this(json); } } - -module.exports = { - ControllerEcho, - HostEcho, - HostEchoReceived, -}; diff --git a/test/file/test_plugin/package.json b/test/file/test_plugin/package.json index 16079ed7..d3a552d8 100644 --- a/test/file/test_plugin/package.json +++ b/test/file/test_plugin/package.json @@ -3,6 +3,7 @@ "version": "0.0.1", "description": "Plugin used to test the plugin system, see #342", "private": true, + "type": "module", "main": "index.js", "keywords": [ "clusterio-plugin" diff --git a/test/host.js b/test/host.js index 5fb6ab5f..4fafc52e 100644 --- a/test/host.js +++ b/test/host.js @@ -1,12 +1,11 @@ -"use strict"; -const assert = require("assert").strict; -const path = require("path"); +import assert from "node:assert/strict"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; -const lib = require("@clusterio/lib"); -const Host = require("@clusterio/host/dist/node/src/Host").default; -const Instance = require("@clusterio/host/dist/node/src/Instance").default; -const { _discoverInstances } = require("@clusterio/host/dist/node/src/Host"); -const { HostConnector } = require("@clusterio/host/dist/node/host"); +import * as lib from "@clusterio/lib"; +import Host, { _discoverInstances } from "@clusterio/host/dist/node/src/Host.js"; +import Instance from "@clusterio/host/dist/node/src/Instance.js"; +import { HostConnector } from "@clusterio/host/dist/node/host.js"; describe("Host testing", function() { describe("discoverInstances()", function() { @@ -116,9 +115,11 @@ describe("Host testing", function() { ]); }); }); - describe(".checkRestartRequired()", function() { + describe(".checkRestartRequired()", async function() { let host; - const hostVersion = require("@clusterio/host/package.json").version; + const hostVersion = ( + await import("@clusterio/host/package.json", { with: { type: "json" }}) + ).default.version; before(function() { lib.addPluginConfigFields([{ name: "restart_test", hostEntrypoint: "host.js" }]); }); @@ -126,7 +127,7 @@ describe("Host testing", function() { // This can be used more generally, but i did not want to interfere with handleSyncUserListsEvent const pluginInfos = [{ name: "restart_test", - packagePath: require.resolve("@clusterio/host/package.json"), + packagePath: fileURLToPath(import.meta.resolve("@clusterio/host/package.json")), version: hostVersion, }]; const hostConfig = new lib.HostConfig("host", { "host.version": hostVersion }); @@ -177,9 +178,11 @@ describe("Host testing", function() { assert.equal(host.config.restartRequired, true); }); }); - describe(".checkRestartDowngrade()", function() { + describe(".checkRestartDowngrade()", async function() { let host; - const hostVersion = require("@clusterio/host/package.json").version; + const hostVersion = ( + await import("@clusterio/host/package.json", { with: { type: "json" }}) + ).default.version; beforeEach(function() { const hostConfig = new lib.HostConfig("host", { "host.version": hostVersion }); const hostConnector = new HostConnector(hostConfig, []); diff --git a/test/host/BaseHostPlugin.js b/test/host/BaseHostPlugin.js index a2e15739..0394f166 100644 --- a/test/host/BaseHostPlugin.js +++ b/test/host/BaseHostPlugin.js @@ -1,8 +1,6 @@ -"use strict"; -const assert = require("assert").strict; -const mock = require("../mock"); +import * as mock from "../mock.js"; -const host = require("@clusterio/host"); +import * as host from "@clusterio/host"; describe("host/src/BaseHostPlugin", function() { describe("class BaseHostPlugin", function() { diff --git a/test/host/BaseInstancePlugin.js b/test/host/BaseInstancePlugin.js index 20e077a2..71b6d252 100644 --- a/test/host/BaseInstancePlugin.js +++ b/test/host/BaseInstancePlugin.js @@ -1,8 +1,7 @@ -"use strict"; -const assert = require("assert").strict; -const mock = require("../mock"); +import assert from "node:assert/strict"; +import * as mock from "../mock.js"; -const host = require("@clusterio/host"); +import * as host from "@clusterio/host"; describe("host/src/BaseInstancePlugin", function() { describe("class BaseInstancePlugin", function() { diff --git a/test/host/Instance.js b/test/host/Instance.js index 8dd66f49..52623700 100644 --- a/test/host/Instance.js +++ b/test/host/Instance.js @@ -1,11 +1,10 @@ -"use strict"; -const assert = require("assert").strict; -const path = require("path"); +import assert from "node:assert/strict"; +import path from "node:path"; -const lib = require("@clusterio/lib"); -const { PlayerStats, wait } = lib; -const Instance = require("@clusterio/host/dist/node/src/Instance").default; -const { MockConnector, MockServer } = require("../mock"); +import * as lib from "@clusterio/lib"; +import { PlayerStats, wait } from "@clusterio/lib"; +import Instance from "@clusterio/host/dist/node/src/Instance.js"; +import { MockConnector, MockServer } from "../mock.js"; const addr = lib.Address.fromShorthand; diff --git a/test/host/export.js b/test/host/export.js index c806c316..a9131584 100644 --- a/test/host/export.js +++ b/test/host/export.js @@ -1,9 +1,8 @@ -"use strict"; -const assert = require("assert").strict; -const path = require("path"); +import assert from "node:assert/strict"; +import path from "node:path"; -const { FactorioServer } = require("@clusterio/host/dist/node/src/server"); -const { _exportLocale } = require("@clusterio/host/dist/node/src/export"); +import { FactorioServer } from "@clusterio/host/dist/node/src/server.js"; +import { _exportLocale } from "@clusterio/host/dist/node/src/export.js"; describe("host/src/export", function() { diff --git a/test/host/patch.js b/test/host/patch.js index 3df1ca5e..1e11aaca 100644 --- a/test/host/patch.js +++ b/test/host/patch.js @@ -1,11 +1,10 @@ -"use strict"; -const assert = require("assert").strict; -const fs = require("node:fs/promises"); -const JSZip = require("jszip"); -const path = require("path"); +import assert from "node:assert/strict"; +import fs from "node:fs/promises"; +import JSZip from "jszip"; +import path from "node:path"; -const lib = require("@clusterio/lib"); -const patch = require("@clusterio/host/dist/node/src/patch"); +import * as lib from "@clusterio/lib"; +import * as patch from "@clusterio/host/dist/node/src/patch.js"; describe("host/patch", function() { diff --git a/test/host/server.js b/test/host/server.js index a18e6058..60a0e681 100644 --- a/test/host/server.js +++ b/test/host/server.js @@ -1,14 +1,12 @@ -"use strict"; -const assert = require("assert").strict; -const events = require("events"); -const fs = require("node:fs/promises"); -const path = require("path"); +import assert from "node:assert/strict"; +import events from "node:events"; +import fs from "node:fs/promises"; +import path from "node:path"; -const hostServer = require("@clusterio/host/dist/node/src/server"); -const lib = require("@clusterio/lib"); -const { wait } = lib; -const { testLines } = require("../lib/factorio/lines"); -const { slowTest, externalTest } = require("../integration"); +import * as hostServer from "@clusterio/host/dist/node/src/server.js"; +import { Link, wait } from "@clusterio/lib"; +import { testLines } from "../lib/factorio/lines.js"; +import { slowTest, externalTest } from "../integration/index.js"; describe("host/server", function() { @@ -326,7 +324,7 @@ describe("host/server", function() { static jsonSchema = { type: "number" }; static fromJSON(json) { return new this(json); } } - let eventFromJSON = lib.Link.eventFromJSON(NumberEvent, "NumberEvent"); + let eventFromJSON = Link.eventFromJSON(NumberEvent, "NumberEvent"); ipcServer.handle("bad_event", async () => { eventFromJSON("not a number"); }); ipcServer.emit("ipc-bad_event", {}); await new Promise(resolve => setImmediate(resolve)); diff --git a/test/integration/clusterio.js b/test/integration/clusterio.js index 26d8dfa9..7ef99463 100644 --- a/test/integration/clusterio.js +++ b/test/integration/clusterio.js @@ -1,22 +1,21 @@ -"use strict"; -const assert = require("assert").strict; -const fs = require("node:fs/promises"); -const jwt = require("jsonwebtoken"); -const path = require("path"); -const events = require("events"); +import assert from "node:assert/strict"; +import fs from "node:fs/promises"; +import jwt from "jsonwebtoken"; +import path from "node:path"; +import events from "node:events"; -const lib = require("@clusterio/lib"); -const libBuildMod = require("@clusterio/lib/build_mod"); -const { wait } = lib; +import * as lib from "@clusterio/lib"; +import { wait } from "@clusterio/lib"; +import * as libBuildMod from "@clusterio/lib/build_mod.js"; -const testStrings = require("../lib/factorio/test_strings"); -const { +import * as testStrings from "../lib/factorio/test_strings.js"; +import { TestControl, TestControlConnector, url, controlToken, slowTest, execCtl, execCtlProcess, execController, execHost, sendRcon, getControl, spawnNode, instancesDir, factorioDir, databaseDir, controllerConfigPath, requiresFactorio, hasFactorio, -} = require("./index"); -const { ControllerEcho, HostEchoReceived } = require("../file/test_plugin/messages"); +} from "./index.js"; +import { ControllerEcho, HostEchoReceived } from "../file/test_plugin/messages.js"; /** @returns {Promise>} */ diff --git a/test/integration/create.js b/test/integration/create.js index 74784c11..1375fa29 100644 --- a/test/integration/create.js +++ b/test/integration/create.js @@ -1,11 +1,10 @@ -"use strict"; -const assert = require("assert").strict; -const fs = require("node:fs/promises"); -const jwt = require("jsonwebtoken"); -const path = require("path"); -const events = require("events"); -const child_process = require("child_process"); -const util = require("util"); +import assert from "node:assert/strict"; +import fs from "node:fs/promises"; +import jwt from "jsonwebtoken"; +import path from "node:path"; +import events from "node:events"; +import child_process from "node:child_process"; +import util from "node:util"; const cwd = path.join("temp", "test_integration"); diff --git a/test/integration/export.js b/test/integration/export.js index 45169e09..6555801a 100644 --- a/test/integration/export.js +++ b/test/integration/export.js @@ -1,11 +1,10 @@ -"use strict"; -const assert = require("assert").strict; -const path = require("path"); +import assert from "node:assert/strict"; +import path from "node:path"; -const { _exportLocale } = require("@clusterio/host/dist/node/src/export"); -const { FactorioServer } = require("@clusterio/host/dist/node/src/server"); +import { _exportLocale } from "@clusterio/host/dist/node/src/export.js"; +import { FactorioServer } from "@clusterio/host/dist/node/src/server.js"; -const { factorioDir, requiresFactorio } = require("./index"); +import { factorioDir, requiresFactorio } from "./index.js"; describe("Integration of lib/factorio/export", function() { diff --git a/test/integration/index.js b/test/integration/index.js index 2b81631a..2c6910db 100644 --- a/test/integration/index.js +++ b/test/integration/index.js @@ -1,27 +1,26 @@ /* eslint-disable no-console */ -"use strict"; -const path = require("path"); -const fs = require("node:fs/promises"); -const { readFileSync } = require("node:fs"); -const child_process = require("child_process"); -const jwt = require("jsonwebtoken"); -const util = require("util"); -const events = require("events"); +import path from "node:path"; +import fs from "node:fs/promises"; +import { readFileSync } from "node:fs"; +import child_process from "node:child_process"; +import jwt from "jsonwebtoken"; +import util from "node:util"; +import events from "node:events"; -const lib = require("@clusterio/lib"); -const { LineSplitter, ConsoleTransport, logger } = lib; +import * as lib from "@clusterio/lib"; +import { LineSplitter, ConsoleTransport, logger } from "@clusterio/lib"; -const { selectTargetCommand, initialize: initializeCtl } = require("@clusterio/ctl"); -const { _listFactorioVersions } = require("@clusterio/host/dist/node/src/server"); +import { selectTargetCommand, initialize as initializeCtl } from "@clusterio/ctl"; +import { _listFactorioVersions } from "@clusterio/host/dist/node/src/server.js"; // Make sure permissions from plugins are loaded -require("../../plugins/global_chat/dist/node/index"); -require("../../plugins/player_auth/dist/node/index"); -require("../../plugins/research_sync/dist/node/index"); -require("../../plugins/statistics_exporter/dist/node/index"); -require("../../plugins/subspace_storage/dist/node/index"); +import "../../plugins/global_chat/dist/node/index.js"; +import "../../plugins/player_auth/dist/node/index.js"; +import "../../plugins/research_sync/dist/node/index.js"; +import "../../plugins/statistics_exporter/dist/node/index.js"; +import "../../plugins/subspace_storage/dist/node/index.js"; -class TestControl extends lib.Link { +export class TestControl extends lib.Link { constructor(connector, subscribe = true) { super(connector); this.hostUpdates = []; @@ -93,7 +92,7 @@ class TestControl extends lib.Link { } } -class TestControlConnector extends lib.WebSocketClientConnector { +export class TestControlConnector extends lib.WebSocketClientConnector { register() { this.sendHandshake( new lib.MessageRegisterControl( @@ -105,7 +104,7 @@ class TestControlConnector extends lib.WebSocketClientConnector { } } -class TestHostConnector extends lib.WebSocketClientConnector { +export class TestHostConnector extends lib.WebSocketClientConnector { register() { this.sendHandshake( new lib.MessageRegisterHost( @@ -119,7 +118,7 @@ class TestHostConnector extends lib.WebSocketClientConnector { } // Mark that this test takes a lot of time, or depends on a test that takes a lot of time. -function slowTest(test) { +export function slowTest(test) { if (process.env.FAST_TEST) { test.skip(); @@ -129,7 +128,7 @@ function slowTest(test) { } // Mark that this test depends on an external API and may be slow or flaky. -function externalTest(test) { +export function externalTest(test) { if (process.env.NO_EXTERNAL_TEST) { test.skip(); } @@ -138,7 +137,7 @@ function externalTest(test) { } // Mark that this test or suite of tests requires a factorio install to run. -function requiresFactorio(testOrSuite) { +export function requiresFactorio(testOrSuite) { if (testOrSuite.skip) { if (!haveFactorioInstall) { testOrSuite.skip(); @@ -152,11 +151,11 @@ function requiresFactorio(testOrSuite) { } } -function hasFactorio() { +export function hasFactorio() { return haveFactorioInstall; } -async function get(urlPath) { +export async function get(urlPath) { const url = new URL("https://localhost:4443"); url.pathname = urlPath; let res = await fetch(url); @@ -191,16 +190,16 @@ let haveFactorioInstall; const baseHostConfig = loadJSON("config-host.json"); -let url = "https://localhost:4443/"; -let controlToken = jwt.sign({ aud: "user", user: "test" }, Buffer.from("TestSecretDoNotUse", "base64")); -let instancesDir = path.join("temp", "test", "instances"); -let modsDir = path.join("temp", "test", "mods"); -let databaseDir = path.join("temp", "test", "database"); -let factorioDir = getFactorioDir(baseHostConfig); +export let url = "https://localhost:4443/"; +export let controlToken = jwt.sign({ aud: "user", user: "test" }, Buffer.from("TestSecretDoNotUse", "base64")); +export let instancesDir = path.join("temp", "test", "instances"); +export let modsDir = path.join("temp", "test", "mods"); +export let databaseDir = path.join("temp", "test", "database"); +export let factorioDir = getFactorioDir(baseHostConfig); let pluginListPath = path.join("temp", "test", "plugin-list.json"); -let controllerConfigPath = path.join("temp", "test", "config-controller.json"); -let hostConfigPath = path.join("temp", "test", "config-host.json"); -let controlConfigPath = path.join("temp", "test", "config-control.json"); +export let controllerConfigPath = path.join("temp", "test", "config-controller.json"); +export let hostConfigPath = path.join("temp", "test", "config-host.json"); +export let controlConfigPath = path.join("temp", "test", "config-control.json"); function childOptions(options) { return { @@ -210,29 +209,29 @@ function childOptions(options) { }; } -function exec(command, options = {}) { +export function exec(command, options = {}) { // Uncomment to show commands run in tests // console.log(command); return util.promisify(child_process.exec)(command, childOptions(options)); } -function execController(...args) { +export function execController(...args) { args[0] = `node --enable-source-maps ../../packages/controller ${args[0]}`; return exec(...args); } -function execHost(...args) { +export function execHost(...args) { args[0] = `node --enable-source-maps ../../packages/host ${args[0]}`; return exec(...args); } -function execCtlProcess(...args) { +export function execCtlProcess(...args) { args[0] = `node --enable-source-maps ../../packages/ctl ${args[0]}`; return exec(...args); } let inExecCtl = false; -async function execCtl(command) { +export async function execCtl(command) { inExecCtl = true; process.chdir("temp/test"); try { @@ -257,16 +256,16 @@ afterEach(function() { } }); -async function sendRcon(instanceId, command) { +export async function sendRcon(instanceId, command) { return await control.sendTo({ instanceId }, new lib.InstanceSendRconRequest(command)); } -function getControl() { +export function getControl() { return control; } /** @returns {Promise} */ -function spawn(name, cmd, waitFor, options = {}) { +export function spawn(name, cmd, waitFor, options = {}) { const silent = process.env.SILENT_TEST; const bootstrap = !controllerProcess || !hostProcess; @@ -303,7 +302,7 @@ function spawn(name, cmd, waitFor, options = {}) { }); } -function spawnNode(name, cmd, waitFor, options) { +export function spawnNode(name, cmd, waitFor, options) { return spawn(name, `node --enable-source-maps ${cmd}`, waitFor, options); } @@ -437,34 +436,3 @@ process.on("exit", () => { if (hostProcess) { hostProcess.kill(); } if (controllerProcess) { controllerProcess.kill(); } }); - - -module.exports = { - TestControl, - TestControlConnector, - TestHostConnector, - execController, - execCtlProcess, - slowTest, - externalTest, - requiresFactorio, - get, - exec, - execCtl, - execHost, - sendRcon, - getControl, - spawn, - spawnNode, - - url, - controlToken, - instancesDir, - modsDir, - databaseDir, - factorioDir, - hasFactorio, - controllerConfigPath, - hostConfigPath, - controlConfigPath, -}; diff --git a/test/integration/instance.js b/test/integration/instance.js index 56f150b7..8bcdec7d 100644 --- a/test/integration/instance.js +++ b/test/integration/instance.js @@ -1,14 +1,13 @@ -"use strict"; -const path = require("path"); -const assert = require("assert").strict; -const lib = require("@clusterio/lib"); -const fs = require("node:fs/promises"); +import path from "node:path"; +import assert from "node:assert/strict"; +import * as lib from "@clusterio/lib"; +import fs from "node:fs/promises"; -const { testMatrix } = require("../common"); -const { +import { testMatrix } from "../common.js"; +import { slowTest, exec, execCtl, execCtlProcess, sendRcon, getControl, requiresFactorio, hasFactorio, instancesDir, -} = require("./index"); +} from "./index.js"; const instId = 48; const instName = "Integration"; diff --git a/test/integration/link.js b/test/integration/link.js index 01483b86..d45a28ca 100644 --- a/test/integration/link.js +++ b/test/integration/link.js @@ -1,11 +1,9 @@ -"use strict"; -const assert = require("assert").strict; -const events = require("events"); -const fs = require("node:fs/promises"); -const jwt = require("jsonwebtoken"); +import assert from "node:assert/strict"; +import events from "node:events"; +import jwt from "jsonwebtoken"; -const { TestControlConnector, TestHostConnector, TestControl, get, exec, url, slowTest } = require("./index"); -const { ConnectionClosed, ProtocolError, PolicyViolation, AuthenticationFailed } = require("@clusterio/lib"); +import { TestControlConnector, TestHostConnector, TestControl, get, exec, url, slowTest } from "./index.js"; +import { ConnectionClosed, ProtocolError, PolicyViolation, AuthenticationFailed } from "@clusterio/lib"; let token = jwt.sign({ aud: "user", user: "test" }, Buffer.from("TestSecretDoNotUse", "base64")); let tokenHost = jwt.sign({ aud: "host", host: 0 }, Buffer.from("TestSecretDoNotUse", "base64")); diff --git a/test/integration/patch.js b/test/integration/patch.js index a4323e79..d222ff6d 100644 --- a/test/integration/patch.js +++ b/test/integration/patch.js @@ -1,17 +1,16 @@ -"use strict"; -const assert = require("assert").strict; -const fs = require("node:fs/promises"); -const JSZip = require("jszip"); -const path = require("path"); +import assert from "node:assert/strict"; +import fs from "node:fs/promises"; +import JSZip from "jszip"; +import path from "node:path"; -const { patch, SaveModule } = require("@clusterio/host/dist/node/src/patch"); -const lib = require("@clusterio/lib"); +import { patch, SaveModule } from "@clusterio/host/dist/node/src/patch.js"; +import * as lib from "@clusterio/lib"; -const { slowTest } = require("./index"); +import { slowTest } from "./index.js"; // The server integration test is required to run before this one -require("./server"); +import "./server.js"; describe("Integration of lib/factorio/patch", function() { describe("patch()", function() { diff --git a/test/integration/routing.js b/test/integration/routing.js index 2f40745a..3aa2a9c9 100644 --- a/test/integration/routing.js +++ b/test/integration/routing.js @@ -1,12 +1,11 @@ -"use strict"; -const assert = require("assert").strict; +import assert from "node:assert/strict"; -const lib = require("@clusterio/lib"); -const { Host, Instance, InstanceConnection } = require("@clusterio/host"); -const { ControlConnection, Controller, HostConnection, InstanceRecord } = require("@clusterio/controller"); +import * as lib from "@clusterio/lib"; +import { Host, Instance, InstanceConnection } from "@clusterio/host"; +import { ControlConnection, Controller, HostConnection, InstanceRecord } from "@clusterio/controller"; // Although there are no imports, the file has side-effects such as "before" which can effect tests -require("./index"); +import "./index.js"; const addr = lib.Address.fromShorthand; diff --git a/test/integration/server.js b/test/integration/server.js index 8c8a711d..f0e08c30 100644 --- a/test/integration/server.js +++ b/test/integration/server.js @@ -1,15 +1,14 @@ -"use strict"; -const assert = require("assert").strict; -const events = require("events"); -const fs = require("node:fs/promises"); -const path = require("path"); +import assert from "node:assert/strict"; +import events from "node:events"; +import fs from "node:fs/promises"; +import path from "node:path"; -const lib = require("@clusterio/lib"); -const { InstanceManager } = require("@clusterio/controller"); -const { FactorioServer, _getFactorioVersion } = require("@clusterio/host/dist/node/src/server"); -const { logger } = lib; +import * as lib from "@clusterio/lib"; +import { InstanceManager } from "@clusterio/controller"; +import { FactorioServer, _getFactorioVersion } from "@clusterio/host/dist/node/src/server.js"; +import { logger } from "@clusterio/lib"; -const { slowTest, factorioDir, requiresFactorio } = require("./index"); +import { slowTest, factorioDir, requiresFactorio } from "./index.js"; describe("Integration of host/src/server", function() { diff --git a/test/lib/ExponentialBackoff.js b/test/lib/ExponentialBackoff.js index 5949deb2..431024ad 100644 --- a/test/lib/ExponentialBackoff.js +++ b/test/lib/ExponentialBackoff.js @@ -1,7 +1,6 @@ -"use strict"; -const assert = require("assert").strict; +import assert from "node:assert/strict"; -const { ExponentialBackoff } = require("@clusterio/lib"); +import { ExponentialBackoff } from "@clusterio/lib"; describe("lib/ExponentialBackoff", function() { describe("class ExponentialBackoff", function() { diff --git a/test/lib/LockFile.test.js b/test/lib/LockFile.test.js index f0903132..a4e25f4e 100644 --- a/test/lib/LockFile.test.js +++ b/test/lib/LockFile.test.js @@ -1,10 +1,9 @@ /* eslint-disable node/no-sync */ -"use strict"; -const assert = require("assert").strict; -const fs = require("node:fs/promises"); -const path = require("path"); +import assert from "node:assert/strict"; +import fs from "node:fs/promises"; +import path from "node:path"; -const { LockFile } = require("@clusterio/lib"); +import { LockFile } from "@clusterio/lib"; const baseDir = path.join("temp", "test", "lock_file"); diff --git a/test/lib/ModStore.test.js b/test/lib/ModStore.test.js index b329d185..32e88e5e 100644 --- a/test/lib/ModStore.test.js +++ b/test/lib/ModStore.test.js @@ -1,15 +1,14 @@ -"use strict"; -const assert = require("assert").strict; -const path = require("path"); -const fs = require("node:fs/promises"); -const stream = require("node:stream"); -const JSZip = require("jszip"); // Added for creating mock zips +import assert from "node:assert/strict"; +import path from "node:path"; +import fs from "node:fs/promises"; +import stream from "node:stream"; +import JSZip from "jszip"; // Added for creating mock zips // Capture native fetch before any potential mocks are applied const nativeFetch = global.fetch; -const { ModStore, ModInfo, ModVersionEquality } = require("@clusterio/lib"); // Adjust path based on compiled output -const { externalTest } = require("../integration"); +import { ModStore, ModInfo, ModVersionEquality } from "@clusterio/lib"; // Adjust path based on compiled output +import { externalTest } from "../integration/index.js"; const MODS_DIR = path.join("temp", "test", "mod_store", "mods"); const CACHE_FILE = path.join(MODS_DIR, "mod-info-cache.json"); diff --git a/test/lib/RateLimiter.js b/test/lib/RateLimiter.js index f778d869..bc2611d0 100644 --- a/test/lib/RateLimiter.js +++ b/test/lib/RateLimiter.js @@ -1,7 +1,6 @@ -"use strict"; -const assert = require("assert").strict; +import assert from "node:assert/strict"; -const { RateLimiter, wait } = require("@clusterio/lib"); +import { RateLimiter, wait } from "@clusterio/lib"; describe("lib/RateLimiter", function() { diff --git a/test/lib/ValueCache.test.js b/test/lib/ValueCache.test.js index b75094c3..e0ee6890 100644 --- a/test/lib/ValueCache.test.js +++ b/test/lib/ValueCache.test.js @@ -1,5 +1,5 @@ -const assert = require("assert").strict; -const { ValueCache, wait } = require("@clusterio/lib"); +import assert from "node:assert/strict"; +import { ValueCache, wait } from "@clusterio/lib"; describe("ValueCache", function () { describe("constructor", function () { diff --git a/test/lib/check_singleton_import.test.js b/test/lib/check_singleton_import.test.js index c4af4938..4df9f2ba 100644 --- a/test/lib/check_singleton_import.test.js +++ b/test/lib/check_singleton_import.test.js @@ -1,12 +1,12 @@ -const assert = require("assert").strict; -const { checkSingletonImport } = require("@clusterio/lib/dist/node/src/check_singleton_import"); +import assert from "node:assert/strict"; +import { checkSingletonImport } from "@clusterio/lib/dist/node/src/check_singleton_import.js"; // Import lib so it sets the global indicating lib has been imported. -require("@clusterio/lib"); +import "@clusterio/lib"; describe("lib/check_singleton_import", function() { it("Should throw an installation error if called twice", function() { assert.throws( - () => checkSingletonImport(__filename), + () => checkSingletonImport(import.meta.filename), { message: /Attempt to import duplicate copy of @clusterio\/lib/, code: "InstallationError", diff --git a/test/lib/command.js b/test/lib/command.js index 86e299c6..f294a105 100644 --- a/test/lib/command.js +++ b/test/lib/command.js @@ -1,8 +1,7 @@ -"use strict"; -const assert = require("assert").strict; +import assert from "node:assert/strict"; -const lib = require("@clusterio/lib"); -const mock = require("../mock"); +import * as lib from "@clusterio/lib"; +import * as mock from "../mock.js"; const addr = lib.Address.fromShorthand; diff --git a/test/lib/config/classes.js b/test/lib/config/classes.js index 40e8cbb4..17ed8100 100644 --- a/test/lib/config/classes.js +++ b/test/lib/config/classes.js @@ -1,8 +1,7 @@ -"use strict"; -const lib = require("@clusterio/lib"); -const fs = require("node:fs/promises"); -const path = require("path"); -const assert = require("assert").strict; +import * as lib from "@clusterio/lib"; +import fs from "node:fs/promises"; +import path from "node:path"; +import assert from "node:assert/strict"; const CA = lib.ConfigAccess; diff --git a/test/lib/config/migrations.js b/test/lib/config/migrations.js index cb88c6d7..26dc6b03 100644 --- a/test/lib/config/migrations.js +++ b/test/lib/config/migrations.js @@ -1,6 +1,5 @@ -"use strict"; -const lib = require("@clusterio/lib"); -const assert = require("assert").strict; +import * as lib from "@clusterio/lib"; +import assert from "node:assert/strict"; // Each migration test should indicate which version introduced the migration diff --git a/test/lib/config/validators.test.js b/test/lib/config/validators.test.js index a8cdf907..be8b867d 100644 --- a/test/lib/config/validators.test.js +++ b/test/lib/config/validators.test.js @@ -1,8 +1,7 @@ -"use strict"; -const assert = require("assert").strict; -const lib = require("@clusterio/lib"); +import assert from "node:assert/strict"; +import * as lib from "@clusterio/lib"; const validators = lib.Config.validators; -const { ControllerConfig, HostConfig, InstanceConfig, ControlConfig } = lib; +import { ControllerConfig, HostConfig, InstanceConfig, ControlConfig } from "@clusterio/lib"; describe("lib/config/validators", function() { describe("all", function() { diff --git a/test/lib/data/HostDetails.test.js b/test/lib/data/HostDetails.test.js index 5c9405b3..3084718b 100644 --- a/test/lib/data/HostDetails.test.js +++ b/test/lib/data/HostDetails.test.js @@ -1,8 +1,7 @@ -"use strict"; -const assert = require("assert").strict; -const { HostDetails } = require("@clusterio/lib"); +import assert from "node:assert/strict"; +import { HostDetails } from "@clusterio/lib"; -const { testMatrix, testRoundTripJsonSerialisable } = require("../../common"); +import { testMatrix, testRoundTripJsonSerialisable } from "../../common.js"; describe("lib/data/HostDetails", function () { diff --git a/test/lib/data/InstanceDetails.test.js b/test/lib/data/InstanceDetails.test.js index cb949c18..95058653 100644 --- a/test/lib/data/InstanceDetails.test.js +++ b/test/lib/data/InstanceDetails.test.js @@ -1,8 +1,7 @@ -"use strict"; -const assert = require("assert").strict; -const { InstanceDetails } = require("@clusterio/lib"); +import assert from "node:assert/strict"; +import { InstanceDetails } from "@clusterio/lib"; -const { testMatrix, testRoundTripJsonSerialisable } = require("../../common"); +import { testMatrix, testRoundTripJsonSerialisable } from "../../common.js"; describe("lib/data/InstanceDetails", function () { diff --git a/test/lib/data/ModInfo.js b/test/lib/data/ModInfo.js index a90a5e4d..68926e4a 100644 --- a/test/lib/data/ModInfo.js +++ b/test/lib/data/ModInfo.js @@ -1,13 +1,12 @@ -"use strict"; -const assert = require("assert").strict; -const fs = require("node:fs/promises"); -const path = require("path"); +import assert from "node:assert/strict"; +import fs from "node:fs/promises"; +import path from "node:path"; -const lib = require("@clusterio/lib"); -const libBuildMod = require("@clusterio/lib/build_mod"); -const { ModInfo, ModDependency } = lib; +import * as lib from "@clusterio/lib"; +import * as libBuildMod from "@clusterio/lib/build_mod.js"; +import { ModInfo, ModDependency } from "@clusterio/lib"; -const { testMatrix, testRoundTripJsonSerialisable } = require("../../common"); +import { testMatrix, testRoundTripJsonSerialisable } from "../../common.js"; describe("lib/data/ModInfo", function() { describe("class ModDependency", function() { diff --git a/test/lib/data/ModPack.js b/test/lib/data/ModPack.js index b813374b..ec21817a 100644 --- a/test/lib/data/ModPack.js +++ b/test/lib/data/ModPack.js @@ -1,9 +1,8 @@ -"use strict"; -const assert = require("assert").strict; -const zlib = require("zlib"); +import assert from "node:assert/strict"; +import zlib from "node:zlib"; -const lib = require("@clusterio/lib"); -const { ModInfo, ModPack, getInstalledModUpdates, applyModRecordAdvisories } = lib; +import * as lib from "@clusterio/lib"; +import { ModInfo, ModPack, getInstalledModUpdates, applyModRecordAdvisories } from "@clusterio/lib"; describe("lib/data/ModPack", function() { diff --git a/test/lib/data/Role.test.js b/test/lib/data/Role.test.js index c0f0d06c..bc908152 100644 --- a/test/lib/data/Role.test.js +++ b/test/lib/data/Role.test.js @@ -1,6 +1,5 @@ -"use strict"; -const assert = require("assert").strict; -const lib = require("@clusterio/lib"); +import assert from "node:assert/strict"; +import * as lib from "@clusterio/lib"; describe("lib/data/Role", function() { let defaultPermissions; diff --git a/test/lib/data/SystemInfo.js b/test/lib/data/SystemInfo.js index 7ee0b74f..d94cc406 100644 --- a/test/lib/data/SystemInfo.js +++ b/test/lib/data/SystemInfo.js @@ -1,8 +1,6 @@ -"use strict"; -const assert = require("assert").strict; +import assert from "node:assert/strict"; -const lib = require("@clusterio/lib"); -const { SystemInfo } = lib; +import { SystemInfo } from "@clusterio/lib"; describe("lib/data/SystemInfo", function() { diff --git a/test/lib/data/UserDetails.test.js b/test/lib/data/UserDetails.test.js index e155c4df..fa9b45ba 100644 --- a/test/lib/data/UserDetails.test.js +++ b/test/lib/data/UserDetails.test.js @@ -1,8 +1,7 @@ -"use strict"; -const assert = require("assert").strict; -const { UserDetails, PlayerStats } = require("@clusterio/lib"); +import assert from "node:assert/strict"; +import { UserDetails, PlayerStats } from "@clusterio/lib"; -const { testMatrix, testRoundTripJsonSerialisable } = require("../../common"); +import { testMatrix, testRoundTripJsonSerialisable } from "../../common.js"; describe("lib/data/UserDetails", function () { it("should be round trip serialisable", function () { diff --git a/test/lib/data/messages_core.js b/test/lib/data/messages_core.js index 2e06c673..461f913d 100644 --- a/test/lib/data/messages_core.js +++ b/test/lib/data/messages_core.js @@ -1,7 +1,5 @@ -"use strict"; -const assert = require("assert").strict; -const lib = require("@clusterio/lib"); -const { Address } = lib; +import assert from "node:assert/strict"; +import { Address } from "@clusterio/lib"; describe("lib/data/messages_core", function() { describe("class Address", function() { diff --git a/test/lib/data/version.test.js b/test/lib/data/version.test.js index 92bba3e9..ed43ca96 100644 --- a/test/lib/data/version.test.js +++ b/test/lib/data/version.test.js @@ -1,8 +1,7 @@ -"use strict"; -const assert = require("assert").strict; -const lib = require("@clusterio/lib"); +import assert from "node:assert/strict"; +import * as lib from "@clusterio/lib"; -const { testMatrix, testRoundTripJsonSerialisable } = require("../../common"); +import { testMatrix, testRoundTripJsonSerialisable } from "../../common.js"; describe("lib/data/version", function() { describe("isVersionEquality()", function() { diff --git a/test/lib/database.js b/test/lib/database.js index 4f01c942..b134eab5 100644 --- a/test/lib/database.js +++ b/test/lib/database.js @@ -1,9 +1,8 @@ -"use strict"; -const assert = require("assert").strict; -const fs = require("node:fs/promises"); -const path = require("path"); +import assert from "node:assert/strict"; +import fs from "node:fs/promises"; +import path from "node:path"; -const lib = require("@clusterio/lib"); +import * as lib from "@clusterio/lib"; describe("lib/database", function() { describe("mapToObject()", function() { diff --git a/test/lib/datastore.js b/test/lib/datastore.js index 40a97ead..b4dc5cee 100644 --- a/test/lib/datastore.js +++ b/test/lib/datastore.js @@ -1,9 +1,8 @@ -"use strict"; -const events = require("events"); -const assert = require("assert").strict; -const lib = require("@clusterio/lib"); -const fs = require("node:fs/promises"); -const path = require("path"); +import events from "node:events"; +import assert from "node:assert/strict"; +import * as lib from "@clusterio/lib"; +import fs from "node:fs/promises"; +import path from "node:path"; class MockDatastoreProvider extends lib.DatastoreProvider { constructor() { diff --git a/test/lib/errors.js b/test/lib/errors.js index 5692d0a2..1cb4d296 100644 --- a/test/lib/errors.js +++ b/test/lib/errors.js @@ -1,7 +1,6 @@ -"use strict"; -const assert = require("assert").strict; +import assert from "node:assert/strict"; -const lib = require("@clusterio/lib"); +import * as lib from "@clusterio/lib"; describe("lib/errors", function() { describe("class InvalidMessage", function() { diff --git a/test/lib/external/FactorioVersions.test.js b/test/lib/external/FactorioVersions.test.js index b92d03a7..f63554d9 100644 --- a/test/lib/external/FactorioVersions.test.js +++ b/test/lib/external/FactorioVersions.test.js @@ -1,8 +1,8 @@ -const assert = require("assert").strict; -const { readFile } = require("node:fs/promises"); +import assert from "node:assert/strict"; +import { readFile } from "node:fs/promises"; -const { fetchFactorioVersions } = require("@clusterio/lib"); -const { slowTest, externalTest } = require("../../integration"); +import { fetchFactorioVersions } from "@clusterio/lib"; +import { slowTest, externalTest } from "../../integration/index.js"; describe("FactorioVersions", function() { describe("fetchFactorioVersions", function() { diff --git a/test/lib/external/LatestReleases.test.js b/test/lib/external/LatestReleases.test.js index 4fb79eff..686b6b52 100644 --- a/test/lib/external/LatestReleases.test.js +++ b/test/lib/external/LatestReleases.test.js @@ -1,7 +1,7 @@ -const assert = require("assert").strict; +import assert from "node:assert/strict"; -const { fetchLatestReleases, resolveReleaseChannel } = require("@clusterio/lib"); -const { slowTest, externalTest } = require("../../integration"); +import { fetchLatestReleases, resolveReleaseChannel } from "@clusterio/lib"; +import { slowTest, externalTest } from "../../integration/index.js"; describe("LatestReleases", function() { describe("fetchLatestReleases", function() { diff --git a/test/lib/factorio/exchange_string.js b/test/lib/factorio/exchange_string.js index eaea8458..9ea118dc 100644 --- a/test/lib/factorio/exchange_string.js +++ b/test/lib/factorio/exchange_string.js @@ -1,11 +1,10 @@ -"use strict"; -const assert = require("assert").strict; -const zlib = require("zlib"); +import assert from "node:assert/strict"; +import zlib from "node:zlib"; -const lib = require("@clusterio/lib"); +import * as lib from "@clusterio/lib"; -const testStrings = require("./test_strings"); -const testSettings = require("./test_settings"); +import * as testStrings from "./test_strings.js"; +import * as testSettings from "./test_settings.js"; // Simple linear congruential random number generator diff --git a/test/lib/factorio/lines.js b/test/lib/factorio/lines.js index f520c742..498150d6 100644 --- a/test/lib/factorio/lines.js +++ b/test/lib/factorio/lines.js @@ -1,7 +1,5 @@ // Lines for testing the factorio output - -"use strict"; -let testLines = new Map([ +export const testLines = new Map([ [ " 1.306 Info RemoteCommandProcessor.cpp:131: Starting RCON interface at port 4000", { @@ -219,7 +217,3 @@ let testLines = new Map([ }, ], ]); - -module.exports = { - testLines, -}; diff --git a/test/lib/factorio/test_settings.js b/test/lib/factorio/test_settings.js index fea7eb77..c1d397f4 100644 --- a/test/lib/factorio/test_settings.js +++ b/test/lib/factorio/test_settings.js @@ -1,6 +1,5 @@ -"use strict"; -const default_map_gen_settings = { +export const default_map_gen_settings = { autoplace_controls: { "coal": { frequency: 1, size: 1, richness: 1 }, "copper-ore": { frequency: 1, size: 1, richness: 1 }, @@ -37,7 +36,7 @@ const default_map_gen_settings = { water: 1, }; -const default_map_settings = { +export const default_map_settings = { pollution: { enabled: true, diffusion_ratio: 0.02, @@ -140,7 +139,7 @@ const default_map_settings = { }, }; -const modified_map_gen_settings = { +export const modified_map_gen_settings = { autoplace_controls: { "coal": { frequency: 1, size: 1, richness: 1 }, "copper-ore": { frequency: 0.5, size: 1, richness: 1 }, @@ -196,7 +195,7 @@ const modified_map_gen_settings = { water: 0.3333333432674408, }; -const modified_map_settings = { +export const modified_map_settings = { pollution: { enabled: true, diffusion_ratio: 0.02, @@ -299,7 +298,7 @@ const modified_map_settings = { }, }; -const modified_v2_map_gen_settings = { +export const modified_v2_map_gen_settings = { autoplace_controls: { "coal": { frequency: 1, size: 1, richness: 1 }, "copper-ore": { frequency: 0.5, size: 1, richness: 1 }, @@ -362,7 +361,7 @@ const modified_v2_map_gen_settings = { territory_settings: null, }; -const modified_v2_map_settings = { +export const modified_v2_map_settings = { pollution: { enabled: true, diffusion_ratio: 0.02, @@ -467,7 +466,7 @@ const modified_v2_map_settings = { }, }; -const modified_v2_1_map_gen_settings = { +export const modified_v2_1_map_gen_settings = { "autoplace_controls": { "coal": { "frequency": 1, "size": 1, "richness": 1 }, "copper-ore": { "frequency": 0.5, "size": 1, "richness": 1 }, @@ -516,7 +515,7 @@ const modified_v2_1_map_gen_settings = { "territory_settings": null, }; -const modified_v2_1_map_settings = { +export const modified_v2_1_map_settings = { "pollution": { "enabled": true, "diffusion_ratio": 0.02, @@ -615,7 +614,7 @@ const modified_v2_1_map_settings = { }, }; -const modified_v2_1_13_map_settings = { +export const modified_v2_1_13_map_settings = { ...modified_v2_1_map_settings, "enemy_expansion": { ...modified_v2_1_map_settings.enemy_expansion, @@ -623,7 +622,7 @@ const modified_v2_1_13_map_settings = { }, }; -const modified_space_age_map_gen_settings = { +export const modified_space_age_map_gen_settings = { autoplace_controls: { "aquilo_crude_oil": { frequency: 1, size: 1, richness: 1 }, "calcite": { frequency: 1, size: 1, richness: 1 }, @@ -701,16 +700,3 @@ const modified_space_age_map_gen_settings = { no_enemies_mode: false, territory_settings: null, }; - -module.exports = { - default_map_gen_settings, - default_map_settings, - modified_map_gen_settings, - modified_map_settings, - modified_v2_map_gen_settings, - modified_v2_map_settings, - modified_v2_1_map_gen_settings, - modified_v2_1_map_settings, - modified_v2_1_13_map_settings, - modified_space_age_map_gen_settings, -}; diff --git a/test/lib/factorio/test_strings.js b/test/lib/factorio/test_strings.js index eebad109..331993e9 100644 --- a/test/lib/factorio/test_strings.js +++ b/test/lib/factorio/test_strings.js @@ -1,7 +1,6 @@ -"use strict"; // Exchange strings for testing with -const default_ = ` +export default ` >>>eNpjZGBkUGQAgwZ7EOZgSc5PzIHxQJgrOb+gILVIN78oFVmYM 7moNCVVNz8TVXFqXmpupW5SYjGKYo7Movw8dBNYi0vy81BFSopSU 4uRRbhLixLzMktz0fUyMF5imubZ0CLHAML/6xkU/v8HYSDrAdAvI @@ -14,7 +13,7 @@ MPlQMQJEAG2EO4yRgjTod+B0UEeJiuJUALUb8SA7IYUhA9Pwqw9j GQ/mkMwIwLZH2giKg5YooELZGEKnHjBDHcNMDwvsMN4DvMdGJlBD JCqL0AxCA8kAzMKQgs4gIObmQEBgGmjrO/lHgDxa6G4<<<`; -const modified = ` +export const modified = ` >>>eNp1UzFs00AUvZ8mbRIEypCBSlCCyFAhOQqBKULxlQUxMCCxgnCc S2rh2On5LAgMZOjAgISEurQLXSmCBTGwRWKhEkgIJraiMgBiaGmFOiC FO5/PsUz6pfv+9/6/99+/kwEBOo2k6c83NhrZtOkaNkIDXa286fZ6hG @@ -31,7 +30,7 @@ jnh3gmXQRElVwYyxI8x4FMqOzsu4edrKK6hNZ5wU7V9G+ufEFL+7yHi cySQMp7wDHnRsBW571ORGn6fH2fUDj/FwV0iUbXPMbmTP7akkt8ChiL /BPceEs3j1M3iz71/ObT9tA==<<<`; -const modified_v2 = ` +export const modified_v2 = ` >>>eNp1Uz9oU0EY/y5N2iRWzRCFitSAGURIjNEpSN7VRRwcBFeJl5dL +ujLe+3de9XoYIYODoogXdrFrlZ0EQe3gIsFBdHJrVIHBYdWi3QQ4l3 u3csz1Q++7333+31/75IYAJwRCpNx0yU2QNfQmjbd+XnKCi6jgg/hlM @@ -49,7 +48,7 @@ Ln6IET6h2alhiMgvQ3SGxnDDDd32daT/yCD5fQ8R3WMEyeN/PENaNmy E5utYOI24z/cT+oQf48FdgozaFZg6qX+1KqW+GYyy4qNZgFNY/0IAHj RI5Q/27QvL<<<`; -const modified_v2_1 = ` +export const modified_v2_1 = ` >>>eNp1U89rE0EUftM0NYlVc4iCIjWHHkRICNFTkezoRTx4ELxKnGwm unSz087uVlsP5uDBg1CQXvSiVyt6EY9CwIu9if4DlXqwt1aK9CDEeZm dyZrgg/f49nu/37BTQCAPGYDZaVcwH6DnGC24YmmJy4qQHAAsnXdl3O @@ -65,7 +64,7 @@ JYkZplFakZG9jCkjt5gyQ4nHFv3qqTPmsjWiYeiVKOkP57RB9xB0Dvk X9skPmJ46b3GGNscC4FCtiwbc3PTPrUX46YL/qSDp8BMOqAJI8C+u/S peyl8e7GC3Ce2le3AIs019Y//gU3lOV1<<<`; -const modified_space_age = ` +export const modified_space_age = ` >>>eNp1VEFoE0EUnUkb27TWBomFSqkBexAhMVZPRbJbL+LBg+BV1slm kgzd7LYzs9HYgz304EEQpJf2Yq9W9CIevBW8WFAQPXmr1IOCh1aL9CD UmZ2dzW4aB2by972Z9//7MyQFALggJpjIogWfOJ5lU7+KLY84ACwZeg @@ -86,7 +85,7 @@ Gx0+5gy4RUpPimXd3JJg0hSVAZVaD42oXlGs+OdLeL8NIjXUO043NJp 38bydxUydeQi4j66kCmzxzUMyYTVaPneF1Uj+vlxQH+ZT82gl0Du2he Y+lJ/JEpK/WZNmBM/mgXgnKlfCACLzljjH+s/hYo=<<<`; -const modified_v2_1_13 = ` +export const modified_v2_1_13 = ` >>>eNp1U89rE0EUftMmNYm15hAFRWoOPYiQEKKgFMmOXsSDB0HwJHGy mejSzU47u1utHszBgwdBkF70olcrehHvAS/2JvUfqNSDvbVSpAehzsv sTNYEH7zHt9/7/YadAAIzSmE64wrmA/QcowVXLC5yWRGSA4Cl866M27 @@ -101,12 +100,3 @@ JYkZpmFakZGd1AkjtxhSQjYziizPKvHmmTPmUDWuYoiVKOgP57RB9yS 0Dvo1NMEfJJWw1i+YLmuywM1C1jwbPKaGnjffEMETl1yE9Qxu/9C7rp u3nVP+RQebGLpzeY4SxwbkUKGDDtjU/J9P3/nrIfNHXdPAWgFF7JHkZ 0L+YLmXPjcc3XoAz1D69BVjk1sULxb83nuUA<<<`; - -module.exports = { - default: default_, - modified, - modified_v2, - modified_v2_1, - modified_v2_1_13, - modified_space_age, -}; diff --git a/test/lib/file_ops.js b/test/lib/file_ops.js index 581cff94..036544a4 100644 --- a/test/lib/file_ops.js +++ b/test/lib/file_ops.js @@ -1,11 +1,10 @@ -"use strict"; -const assert = require("assert").strict; -const fs = require("node:fs/promises"); -const http = require("node:http"); -const path = require("path"); -const util = require("node:util"); +import assert from "node:assert/strict"; +import fs from "node:fs/promises"; +import http from "node:http"; +import path from "node:path"; +import util from "node:util"; -const lib = require("@clusterio/lib"); +import * as lib from "@clusterio/lib"; describe("lib/file_ops", function() { let baseDir = path.join("temp", "test", "file_ops"); diff --git a/test/lib/hash.js b/test/lib/hash.js index 726c45eb..6ee9dc74 100644 --- a/test/lib/hash.js +++ b/test/lib/hash.js @@ -1,9 +1,8 @@ -"use strict"; -const assert = require("assert").strict; -const fs = require("node:fs/promises"); -const path = require("path"); +import assert from "node:assert/strict"; +import fs from "node:fs/promises"; +import path from "node:path"; -const lib = require("@clusterio/lib"); +import * as lib from "@clusterio/lib"; describe("lib/hash", function() { diff --git a/test/lib/helpers.js b/test/lib/helpers.js index 27486882..2517ab6a 100644 --- a/test/lib/helpers.js +++ b/test/lib/helpers.js @@ -1,8 +1,7 @@ -"use strict"; -const assert = require("assert").strict; +import assert from "node:assert/strict"; const hrtime = process.hrtime.bigint; -const lib = require("@clusterio/lib"); +import * as lib from "@clusterio/lib"; describe("lib/helpers", function() { diff --git a/test/lib/ini.js b/test/lib/ini.js index b600df7c..7c1e57e0 100644 --- a/test/lib/ini.js +++ b/test/lib/ini.js @@ -1,7 +1,6 @@ -"use strict"; -const assert = require("assert").strict; -const fs = require("node:fs/promises"); -const lib = require("@clusterio/lib"); +import assert from "node:assert/strict"; +import fs from "node:fs/promises"; +import * as lib from "@clusterio/lib"; describe("lib/ini", function() { describe("parse()", function() { diff --git a/test/lib/link/connector.js b/test/lib/link/connector.js index bbfbf39c..851b9e78 100644 --- a/test/lib/link/connector.js +++ b/test/lib/link/connector.js @@ -1,9 +1,8 @@ -"use strict"; -const assert = require("assert").strict; -const events = require("events"); +import assert from "node:assert/strict"; +import events from "node:events"; -const mock = require("../../mock"); -const lib = require("@clusterio/lib"); +import * as mock from "../../mock.js"; +import * as lib from "@clusterio/lib"; describe("lib/link/connectors", function() { diff --git a/test/lib/link/link.js b/test/lib/link/link.js index 112ae492..b6bec464 100644 --- a/test/lib/link/link.js +++ b/test/lib/link/link.js @@ -1,9 +1,8 @@ -"use strict"; -const assert = require("assert").strict; -const events = require("events"); +import assert from "node:assert/strict"; +import events from "node:events"; -const lib = require("@clusterio/lib"); -const mock = require("../../mock"); +import * as lib from "@clusterio/lib"; +import * as mock from "../../mock.js"; const addr = lib.Address.fromShorthand; diff --git a/test/lib/logging_utils.js b/test/lib/logging_utils.js index 919714e7..ba159555 100644 --- a/test/lib/logging_utils.js +++ b/test/lib/logging_utils.js @@ -1,10 +1,9 @@ -"use strict"; -const assert = require("assert").strict; -const fs = require("node:fs/promises"); -const path = require("path"); +import assert from "node:assert/strict"; +import fs from "node:fs/promises"; +import path from "node:path"; -const { testLines } = require("./factorio/lines"); -const lib = require("@clusterio/lib"); +import { testLines } from "./factorio/lines.js"; +import * as lib from "@clusterio/lib"; describe("lib/logging_utils.js", function() { diff --git a/test/lib/lua_tools.js b/test/lib/lua_tools.js index 8b70b274..64c49e80 100644 --- a/test/lib/lua_tools.js +++ b/test/lib/lua_tools.js @@ -1,7 +1,6 @@ -"use strict"; -const assert = require("assert").strict; +import assert from "node:assert/strict"; -const lib = require("@clusterio/lib"); +import * as lib from "@clusterio/lib"; describe("lib/lua_tools", function() { diff --git a/test/lib/plugin.js b/test/lib/plugin.js index 30587b30..b9fd11ac 100644 --- a/test/lib/plugin.js +++ b/test/lib/plugin.js @@ -1,8 +1,7 @@ -"use strict"; -const assert = require("assert").strict; +import assert from "node:assert/strict"; -const mock = require("../mock"); -const lib = require("@clusterio/lib"); +import * as mock from "../mock.js"; +import * as lib from "@clusterio/lib"; describe("lib/plugin", function() { diff --git a/test/lib/plugin_loader.js b/test/lib/plugin_loader.js index 58281988..9d4b3ef2 100644 --- a/test/lib/plugin_loader.js +++ b/test/lib/plugin_loader.js @@ -1,10 +1,10 @@ -"use strict"; -const assert = require("assert").strict; -const fs = require("node:fs/promises"); -const path = require("path"); +import assert from "node:assert/strict"; +import fs from "node:fs/promises"; +import path from "node:path"; +import { pathToFileURL } from "node:url"; -const lib = require("@clusterio/lib"); -const { BaseControllerPlugin } = require("@clusterio/controller"); +import * as lib from "@clusterio/lib"; +import { BaseControllerPlugin } from "@clusterio/controller"; describe("lib/plugin_loader", function() { @@ -19,7 +19,7 @@ describe("lib/plugin_loader", function() { await fs.mkdir(pluginPath, { recursive: true }); await fs.writeFile( path.join(pluginPath, "index.js"), - `module.exports.plugin = { name: "${infoName}" };` + `export const plugin = { name: "${infoName}" };` ); await fs.writeFile( path.join(pluginPath, "package.json"), @@ -56,7 +56,7 @@ describe("lib/plugin_loader", function() { it("should reject on broken plugin", async function() { let brokenMessage; try { - require(path.resolve(brokenPlugin)); + await import(pathToFileURL(path.resolve(path.join(brokenPlugin, "index.js")))); } catch (err) { brokenMessage = err.message; } @@ -84,7 +84,7 @@ describe("lib/plugin_loader", function() { await writeEntrypoint(missingClass, ""); await writeEntrypoint( - wrongParentClass, "class ControllerPlugin {}\n module.exports = { ControllerPlugin };\n" + wrongParentClass, "export class ControllerPlugin {};\n" ); }); it("should throw if class is missing from entrypoint", async function() { @@ -92,13 +92,13 @@ describe("lib/plugin_loader", function() { await assert.rejects( lib.loadPluginClass( "test", - path.posix.join(requirePath, "controller"), + path.posix.join(requirePath, "controller.js"), "ControllerPlugin", BaseControllerPlugin, ), { message: - `PluginError: Expected ${path.posix.join(requirePath, "controller")} ` + + `PluginError: Expected ${path.posix.join(requirePath, "controller.js")} ` + "to export a class named ControllerPlugin", } ); @@ -108,14 +108,14 @@ describe("lib/plugin_loader", function() { await assert.rejects( lib.loadPluginClass( "test", - path.posix.join(requirePath, "controller"), + path.posix.join(requirePath, "controller.js"), "ControllerPlugin", BaseControllerPlugin, ), { message: "PluginError: Expected ControllerPlugin exported from " + - `${path.posix.join(requirePath, "controller")} to be a subclass of BaseControllerPlugin`, + `${path.posix.join(requirePath, "controller.js")} to be a subclass of BaseControllerPlugin`, } ); }); @@ -152,7 +152,7 @@ describe("lib/plugin_loader", function() { await fs.mkdir(pluginPath, { recursive: true }); await fs.writeFile( path.join(pluginPath, "index.js"), - `module.exports.plugin = { name: "${name}" };` + `export const plugin = { name: "${name}" };` ); await fs.writeFile( path.join(pluginPath, "package.json"), @@ -195,7 +195,7 @@ describe("lib/plugin_loader", function() { await fs.mkdir(path.join(deepPluginPath, "dist")); await fs.writeFile( path.join(deepPluginPath, "dist", "index.js"), - 'module.exports.plugin = { name: "deep" };' + 'export const plugin = { name: "deep" };' ); // Create an npm module that is not a plugin diff --git a/test/lib/prometheus.js b/test/lib/prometheus.js index 8ef24147..0dcc4d93 100644 --- a/test/lib/prometheus.js +++ b/test/lib/prometheus.js @@ -1,7 +1,6 @@ -"use strict"; -const assert = require("assert").strict; +import assert from "node:assert/strict"; -const prometheus = require("@clusterio/lib"); +import * as prometheus from "@clusterio/lib"; describe("lib/prometheus", function() { diff --git a/test/lib/rce_ops.js b/test/lib/rce_ops.js index c5b272b7..dc3c56d3 100644 --- a/test/lib/rce_ops.js +++ b/test/lib/rce_ops.js @@ -1,6 +1,5 @@ -"use strict"; -const assert = require("assert").strict; -const lib = require("@clusterio/lib"); +import assert from "node:assert/strict"; +import * as lib from "@clusterio/lib"; describe("rce_ops", function() { describe("updatePackage", function() { diff --git a/test/lib/stream.js b/test/lib/stream.js index 144e7c06..09b8ee43 100644 --- a/test/lib/stream.js +++ b/test/lib/stream.js @@ -1,11 +1,10 @@ -"use strict"; -const assert = require("assert").strict; -const fs = require("node:fs/promises"); -const path = require("path"); -const stream = require("stream"); -const util = require("util"); +import assert from "node:assert/strict"; +import fs from "node:fs/promises"; +import path from "node:path"; +import stream from "node:stream"; +import util from "node:util"; -const lib = require("@clusterio/lib"); +import * as lib from "@clusterio/lib"; const finished = util.promisify(stream.finished); diff --git a/test/lib/subscriptions.test.js b/test/lib/subscriptions.test.js index bd556487..97e7f943 100644 --- a/test/lib/subscriptions.test.js +++ b/test/lib/subscriptions.test.js @@ -1,9 +1,8 @@ -"use strict"; -const events = require("events"); -const assert = require("assert").strict; -const lib = require("@clusterio/lib"); -const { MockController, MockConnector, MockControl } = require("../mock"); -const { testMatrix, testRoundTripJsonSerialisable } = require("../common"); +import events from "node:events"; +import assert from "node:assert/strict"; +import * as lib from "@clusterio/lib"; +import { MockController, MockConnector, MockControl } from "../mock.js"; +import { testMatrix, testRoundTripJsonSerialisable } from "../common.js"; const addr = lib.Address.fromShorthand; diff --git a/test/lib/users.js b/test/lib/users.js index bb636191..344f304d 100644 --- a/test/lib/users.js +++ b/test/lib/users.js @@ -1,6 +1,5 @@ -"use strict"; -const assert = require("assert").strict; -const lib = require("@clusterio/lib"); +import assert from "node:assert/strict"; +import * as lib from "@clusterio/lib"; describe("lib/users", function() { diff --git a/test/lib/zip_ops.js b/test/lib/zip_ops.js index f9227021..99739d82 100644 --- a/test/lib/zip_ops.js +++ b/test/lib/zip_ops.js @@ -1,8 +1,7 @@ -"use strict"; -const assert = require("assert").strict; -const JSZip = require("jszip"); +import assert from "node:assert/strict"; +import JSZip from "jszip"; -const { findRoot } = require("@clusterio/lib"); +import { findRoot } from "@clusterio/lib"; describe("lib/factorio", function() { diff --git a/test/manual/test_settings_mod_pack.js b/test/manual/test_settings_mod_pack.js index fe2a699f..ae4e4110 100644 --- a/test/manual/test_settings_mod_pack.js +++ b/test/manual/test_settings_mod_pack.js @@ -1,5 +1,4 @@ -"use strict"; -const { ModPack } = require("@clusterio/lib"); +import { ModPack } from "@clusterio/lib"; const pack = new ModPack(); pack.name = "test-settings"; diff --git a/test/messages/controller.test.js b/test/messages/controller.test.js index de74d61c..d876a60c 100644 --- a/test/messages/controller.test.js +++ b/test/messages/controller.test.js @@ -1,12 +1,11 @@ -"use strict"; -const assert = require("assert").strict; -const fs = require("node:fs/promises"); -const os = require("node:os"); -const path = require("node:path"); -const lib = require("@clusterio/lib"); +import assert from "node:assert/strict"; +import fs from "node:fs/promises"; +import os from "node:os"; +import path from "node:path"; +import * as lib from "@clusterio/lib"; -const { Controller, ControlConnection } = require("@clusterio/controller"); -const { testMatrix, testRoundTripJsonSerialisable } = require("../common"); +import { Controller, ControlConnection } from "@clusterio/controller"; +import { testMatrix, testRoundTripJsonSerialisable } from "../common.js"; describe("messages/controller", function() { /** @type {Controller} */ diff --git a/test/messages/host.test.js b/test/messages/host.test.js index 285d37c4..fe40256a 100644 --- a/test/messages/host.test.js +++ b/test/messages/host.test.js @@ -1,9 +1,8 @@ -"use strict"; -const assert = require("assert").strict; -const lib = require("@clusterio/lib"); +import assert from "node:assert/strict"; +import * as lib from "@clusterio/lib"; -const { Host } = require("@clusterio/host"); -const { testMatrix, testRoundTripJsonSerialisable } = require("../common"); +import { Host } from "@clusterio/host"; +import { testMatrix, testRoundTripJsonSerialisable } from "../common.js"; describe("messages/host", function() { /** @type {Host} */ diff --git a/test/messages/mod.test.js b/test/messages/mod.test.js index 09d56512..7a80b2eb 100644 --- a/test/messages/mod.test.js +++ b/test/messages/mod.test.js @@ -1,13 +1,12 @@ -"use strict"; -const assert = require("assert").strict; +import assert from "node:assert/strict"; -const lib = require("@clusterio/lib"); -const { ModDependencyResolveRequest, ModDependency, ModInfo } = lib; +import * as lib from "@clusterio/lib"; +import { ModDependencyResolveRequest, ModDependency, ModInfo } from "@clusterio/lib"; -const { testMatrix, testRoundTripJsonSerialisable } = require("../common"); +import { testMatrix, testRoundTripJsonSerialisable } from "../common.js"; -const { Controller, ControlConnection } = require("@clusterio/controller"); -const { externalTest } = require("../integration"); +import { Controller, ControlConnection } from "@clusterio/controller"; +import { externalTest } from "../integration/index.js"; describe("messages/mod", function() { /** @type {Controller} */ diff --git a/test/messages/plugin.test.js b/test/messages/plugin.test.js index e2c7d9d8..7935cd3c 100644 --- a/test/messages/plugin.test.js +++ b/test/messages/plugin.test.js @@ -1,9 +1,8 @@ -"use strict"; -const assert = require("assert").strict; -const lib = require("@clusterio/lib"); +import assert from "node:assert/strict"; +import * as lib from "@clusterio/lib"; -const { Controller, ControlConnection } = require("@clusterio/controller"); -const { Host } = require("@clusterio/host"); +import { Controller, ControlConnection } from "@clusterio/controller"; +import { Host } from "@clusterio/host"; describe("messages/plugin", function() { /** @type {Host} */ diff --git a/test/mock.js b/test/mock.js index 7cb9901f..1efdc3a5 100644 --- a/test/mock.js +++ b/test/mock.js @@ -1,14 +1,13 @@ -"use strict"; -const events = require("events"); -const http = require("http"); -const express = require("express"); +import events from "node:events"; +import http from "node:http"; +import express from "express"; -const lib = require("@clusterio/lib"); -const { User, UserManager, UserRecord, InstanceManager } = require("@clusterio/controller"); +import * as lib from "@clusterio/lib"; +import { User, UserManager, UserRecord, InstanceManager } from "@clusterio/controller"; const addr = lib.Address.fromShorthand; -class MockLogger { +export class MockLogger { child() { return this; } fatal() { } @@ -26,7 +25,7 @@ class MockLogger { verbose() { } } -class MockSocket { +export class MockSocket { constructor() { this.sentMessages = []; this.events = new Map(); @@ -66,7 +65,7 @@ class MockSocket { } } -class MockConnector extends lib.BaseConnector { +export class MockConnector extends lib.BaseConnector { constructor(src, dst) { super(src, dst); @@ -86,7 +85,7 @@ class MockConnector extends lib.BaseConnector { } } -class MockServer extends events.EventEmitter { +export class MockServer extends events.EventEmitter { constructor() { super(); this.reset(); @@ -116,7 +115,7 @@ class MockServer extends events.EventEmitter { } } -class MockInstance extends lib.Link { +export class MockInstance extends lib.Link { constructor() { super(new MockConnector(addr({ instanceId: 7357 }), addr({ hostId: 1 }))); this.logger = new MockLogger(); @@ -144,15 +143,15 @@ class MockInstance extends lib.Link { } } -class MockHost extends lib.Link { +export class MockHost extends lib.Link { constructor() { super(new MockConnector(addr({ hostId: 1 }), addr("controller"))); } } -class MockControl extends lib.Link { } +export class MockControl extends lib.Link { } -class MockController { +export class MockController { constructor() { this.app = express(); this.app.locals.controller = this; @@ -224,7 +223,7 @@ class MockController { } } -async function createControllerPlugin(ControllerPluginClass, info) { +export async function createControllerPlugin(ControllerPluginClass, info) { let controller = new MockController(); let metrics = {}; let logger = new MockLogger(); @@ -233,25 +232,10 @@ async function createControllerPlugin(ControllerPluginClass, info) { return plugin; } -async function createInstancePlugin(InstancePluginClass, info) { +export async function createInstancePlugin(InstancePluginClass, info) { let instance = new MockInstance(); let host = new MockHost(); let plugin = new InstancePluginClass(info, instance, host); await plugin.init(); return plugin; } - - -module.exports = { - MockLogger, - MockSocket, - MockConnector, - MockServer, - MockInstance, - MockHost, - MockControl, - MockController, - - createControllerPlugin, - createInstancePlugin, -};