Migrate to ECMAScript Modules

Migrate the usage of CommonJS specific code and imports to ESM.  Roughly
summarised this:
- Changes all require() calls to import statement or expressions.
- Changes usage of module.exports to export statements.
- Replaces require.resolve with import.meta.resolve.
- Replaces conditional imports with conditional subpath imports.
- Replaces module === require.main with import.meta.main.
- Adds the full filename with extention to all relative imports.
- Changes all usage of __dirname and __filename to their import.meta
  equivalents.
- Sets "type": "module" in package.json files.
- Removes usage of "use strict".
- Adds .ts an an alias of .js for the webpack build.

Due to differences in how require and import resolves files the plugin
entrypoints will have to include the filename and extension after this
migration in order to work.
This commit is contained in:
Hornwitser committed 2026-09-11 22:43:57 +02:00
1 parent b69111dda3
commit 5dcaca4d0b
261 files changed
+1115 -1330

No files matched your search

+5 -6
View File
@@ -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();
}
+2 -2
View File
@@ -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`.
+3 -8
View File
@@ -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.
+11 -19
View File
@@ -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_<plugin_name>_<metric_nam
For metrics that are per-instance, you must define an `instance_id` label and set it accordingly, for example:
```js
const { Counter } = require("@clusterio/lib");
import { Counter } from "@clusterio/lib";
const barMetric = new Gauge(
"clusterio_foo_frobber_bar_metric", "Bar instance level",
@@ -565,7 +561,7 @@ The control entrypoint for plugins allows you to extend clustectl with your own
The creation of custom commands typically starts with defining a command tree for the plugin:
```js
const { Command, CommandTree } = require("@clusterio/lib");
import { Command, CommandTree } from "@clusterio/lib";
const fooFrobberCommands = new CommandTree({
name: "foo-frobber", description: "Foo Frobber Plugin commands"
});
@@ -574,7 +570,7 @@ const fooFrobberCommands = new CommandTree({
Then commands are added to the the plugin's command tree:
```js
const info = require("./info");
import { messages } from "./index.js";
fooFrobberCommands.add(new Command({
definition: ["frobnicate <type>", "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,
}
```
+2 -2
View File
@@ -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",
+1
View File
@@ -3,6 +3,7 @@
"private": true,
"files": [],
"packageManager": "pnpm@10.28.1+sha512.7d7dbbca9e99447b7c3bf7a73286afaaf6be99251eb9498baefa7d406892f67b879adb3a1d7e687fc4ccc1a388c7175fbaae567a26ab44d1067b54fcb0d6a316",
"type": "module",
"scripts": {
"build": "tsc --build",
"watch": "tsc --build --watch",
+9 -9
View File
@@ -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<InitializeParameters> {
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<InitializeParameters> {
}
}
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();
}
+14 -14
View File
@@ -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();
}
+1
View File
@@ -22,6 +22,7 @@
"access": "public"
},
"type": "module",
"main": "dist/node/index.js",
"scripts": {
"prepare": "tsc --build && webpack-cli --mode production",
+4 -4
View File
@@ -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";
/**
@@ -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
+7 -9
View File
@@ -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;
+36 -26
View File
@@ -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"))
+5 -5
View File
@@ -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(
+6 -6
View File
@@ -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";
/**
+3 -3
View File
@@ -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 = {
+1 -1
View File
@@ -4,7 +4,7 @@ import {
PermissionError, permissions,
} from "@clusterio/lib";
import UserRecord from "./UserRecord";
import UserRecord from "./UserRecord.js";
import { Static } from "@sinclair/typebox";
/**
+2 -2
View File
@@ -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.
+12 -11
View File
@@ -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."
);
}
+4 -4
View File
@@ -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
) {
+2 -2
View File
@@ -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);
File renamed without changes.
+16 -17
View File
@@ -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);
+1 -7
View File
@@ -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,
};
+7 -12
View File
@@ -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;
}
+1
View File
@@ -22,6 +22,7 @@
"access": "public"
},
"type": "module",
"main": "create.js",
"bin": {
"clusteriocreate": "./create.js"
+11 -13
View File
@@ -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,
};
@@ -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
@@ -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,
};
+4 -9
View File
@@ -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,
};
+4 -9
View File
@@ -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,
};
+7 -12
View File
@@ -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,
};
@@ -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,
};
@@ -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,
};
@@ -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
};
@@ -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";
@@ -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 {
+1 -1
View File
@@ -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({
+1 -1
View File
@@ -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 {
+5 -5
View File
@@ -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: {
@@ -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
@@ -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";
+6 -6
View File
@@ -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();
}
+4 -4
View File
@@ -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();
}
+1
View File
@@ -22,6 +22,7 @@
"access": "public"
},
"type": "module",
"main": "dist/node/index.js",
"scripts": {
"prepare": "tsc --build",
+11 -11
View File
@@ -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<string, BaseCtlPlugin>, yargs: Argv) {
const rootCommands = new lib.CommandTree({ name: "clusterioctl", description: "Manage cluster" });
+3 -3
View File
@@ -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: " | " });
+1 -1
View File
@@ -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({
+3 -3
View File
@@ -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: " | " });
+3 -3
View File
@@ -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);
+1 -1
View File
@@ -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({
+2 -2
View File
@@ -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);
+2 -2
View File
@@ -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: " | " });
+2 -2
View File
@@ -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: " | " });
+2 -2
View File
@@ -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: " | " });
+2 -2
View File
@@ -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: " | " });
@@ -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;
+6 -6
View File
@@ -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();
}
+7 -7
View File
@@ -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();
}
+1
View File
@@ -22,6 +22,7 @@
"access": "public"
},
"type": "module",
"main": "dist/node/index.js",
"scripts": {
"prepare": "tsc --build",
+1 -1
View File
@@ -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
+2 -2
View File
@@ -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
+8 -7
View File
@@ -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;
+6 -6
View File
@@ -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)) {
+2 -2
View File
@@ -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 {
+4 -4
View File
@@ -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+$/, ""),
+1 -1
View File
@@ -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";
/**
+1 -1
View File
@@ -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);
+8 -13
View File
@@ -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,
};
+39 -39
View File
@@ -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);
+11
View File
@@ -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": {
+8 -8
View File
@@ -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}`
);
}
+4 -4
View File
@@ -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 */
+1 -1
View File
@@ -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;
+3 -3
View File
@@ -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<void>;
+7 -7
View File
@@ -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<typeof ConfigLocation>;
+4 -4
View File
@@ -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<T> = (...args: Parameters<typeof classes.Config.fromJSON>) => T;
type configFromFile<T> = (...args: Parameters<typeof classes.Config.fromFile>) => Promise<T>;
+2 -2
View File
@@ -3,5 +3,5 @@
* @author Hornwitser
* @module lib/config
*/
export * from "./classes";
export * from "./definitions";
export * from "./classes.js";
export * from "./definitions.js";
+2 -2
View File
@@ -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",
+5 -5
View File
@@ -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";
+7 -7
View File
@@ -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({
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -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 {
+23 -23
View File
@@ -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";
+1 -1
View File
@@ -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<Message>;
export default message_validate;
+4 -4
View File
@@ -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;
+2 -2
View File
@@ -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 =
+4 -4
View File
@@ -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;
+8 -8
View File
@@ -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;
+4 -4
View File
@@ -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 {
+2 -2
View File
@@ -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 {
+3 -3
View File
@@ -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;
+3 -3
View File
@@ -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;
+2 -2
View File
@@ -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 };
+4 -4
View File
@@ -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;
+1 -1
View File
@@ -1,4 +1,4 @@
import { FactorioColor } from "./lua_tools";
import { FactorioColor } from "./lua_tools.js";
/**
* A localised string.
+1 -1
View File
@@ -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/";
+1 -1
View File
@@ -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";
Loaded 100 of 261 files, more files were not shown because too many files have changed in this diff. Show more