From 5487976a213fc3032ae7cc9e1fc7981a7235e9e4 Mon Sep 17 00:00:00 2001 From: bbassie <17990055+bbassie@users.noreply.github.com> Date: Wed, 9 Sep 2026 17:56:01 +0000 Subject: [PATCH 1/4] Add a Node.js CI workflow that builds and tests inside clusterio The packages use workspace:^ and catalog: versions, so they only resolve inside a clusterio checkout with this repository under external_plugins. The workflow clones clusterio master, checks this repository out into external_plugins/ExpCluster, runs pnpm install (which runs every prepare script), then runs the tap suites. A last step wipes dist and runs tsc --build in each package on its own. pnpm install builds packages in dependency order, which is why the missing project references fixed in #473 went unnoticed. On the tree before #473 this step fails with the same five TS2307 errors. Co-Authored-By: Claude Fable 5.1 --- .github/workflows/node.yml | 49 ++++++++++++++++++++++++++++++++++++++ CONTRIBUTING.md | 2 +- 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/node.yml diff --git a/.github/workflows/node.yml b/.github/workflows/node.yml new file mode 100644 index 00000000..24e1fd98 --- /dev/null +++ b/.github/workflows/node.yml @@ -0,0 +1,49 @@ +name: Node.js CI + +on: + push: + pull_request: + +env: + # The packages use workspace:^ and catalog: versions, so they only resolve + # inside a clusterio checkout with this repository under external_plugins + CLUSTERIO_REPOSITORY: clusterio/clusterio + CLUSTERIO_REF: master + +jobs: + test: + runs-on: ubuntu-latest + timeout-minutes: 20 + defaults: + run: + working-directory: external_plugins/ExpCluster + steps: + - name: Checkout clusterio + uses: actions/checkout@v4 + with: + repository: ${{ env.CLUSTERIO_REPOSITORY }} + ref: ${{ env.CLUSTERIO_REF }} + - name: Checkout ExpCluster into the workspace + uses: actions/checkout@v4 + with: + path: external_plugins/ExpCluster + - uses: pnpm/action-setup@v4 + - uses: actions/setup-node@v4 + with: + node-version: lts/* + - name: Install and build the workspace + working-directory: . + run: pnpm install --no-frozen-lockfile + - name: Run tests + run: pnpm --filter "@expcluster/*" run test + - name: Build each package on its own + run: | + # pnpm install runs prepare in dependency order, which hides a missing + # project reference (#473). Building from an empty dist one package at + # a time fails unless every cross package import is referenced. + for pkg in exp_*/; do + rm -rf exp_*/dist + echo "::group::${pkg%/}" + (cd "$pkg" && pnpm exec tsc --build) + echo "::endgroup::" + done diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9fa851c4..216a5196 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -9,7 +9,7 @@ For developers wanting to add features please follow these guidelines: - Lua is checked with [emmylua](https://github.com/EmmyLuaLs/emmylua-analyzer-rust), configured by `.emmyrc.json`. Install the EmmyLua extension rather than sumnekolua / luals, and use factoriomod-debug to generate the factorio api types. Note that an inline cast must be written `--[[@as T]]`, the spaced form is not parsed. - Changes should be made on your own fork and merged into `main` through a pull request. - Each pull request should be limited to one feature or a few bug fixes and link to the related issue page. -- Pull requests are automatically linted and documentation checked. +- Pull requests are automatically linted, then built and tested against the latest clusterio `master`. - Pull requests are manually reviewed to maintain code and language quality. - New features should have the branch names: `feature/feature-name` - Bug fixes should have the branch names: `fix/bug-name` From 2048de6244c80bd3494e6913e3f28724d55ddcc5 Mon Sep 17 00:00:00 2001 From: Cooldude2606 <25043174+Cooldude2606@users.noreply.github.com> Date: Fri, 11 Sep 2026 23:41:04 +0100 Subject: [PATCH 2/4] Small changes to node ci --- .github/workflows/node.yml | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/.github/workflows/node.yml b/.github/workflows/node.yml index 24e1fd98..80d77eff 100644 --- a/.github/workflows/node.yml +++ b/.github/workflows/node.yml @@ -9,38 +9,40 @@ env: # inside a clusterio checkout with this repository under external_plugins CLUSTERIO_REPOSITORY: clusterio/clusterio CLUSTERIO_REF: master + # Node version to use for the tests. This is used by the setup-node action + NODE_VERSION: lts/* jobs: test: runs-on: ubuntu-latest - timeout-minutes: 20 + timeout-minutes: 5 defaults: run: working-directory: external_plugins/ExpCluster steps: - - name: Checkout clusterio + - name: Checkout Clusterio uses: actions/checkout@v4 with: repository: ${{ env.CLUSTERIO_REPOSITORY }} ref: ${{ env.CLUSTERIO_REF }} - - name: Checkout ExpCluster into the workspace + - name: Checkout ExpCluster uses: actions/checkout@v4 with: path: external_plugins/ExpCluster - uses: pnpm/action-setup@v4 - uses: actions/setup-node@v4 with: - node-version: lts/* - - name: Install and build the workspace + node-version: ${{ env.NODE_VERSION }} + - name: Install and build working-directory: . run: pnpm install --no-frozen-lockfile - name: Run tests run: pnpm --filter "@expcluster/*" run test - - name: Build each package on its own + - name: Run reference checks run: | - # pnpm install runs prepare in dependency order, which hides a missing - # project reference (#473). Building from an empty dist one package at - # a time fails unless every cross package import is referenced. + # pnpm install runs prepare in dependency order, which hides missing + # project references. Building from an empty dist one package at a time + # will fail unless every cross package import is referenced correctly. for pkg in exp_*/; do rm -rf exp_*/dist echo "::group::${pkg%/}" From 30f1b5ea753bab5cbecb57a5ad8bf2dc608d7db1 Mon Sep 17 00:00:00 2001 From: bbassie <17990055+bbassie@users.noreply.github.com> Date: Fri, 11 Sep 2026 23:20:29 +0000 Subject: [PATCH 3/4] Declare permissions on the plugin declaration Clusterio #988 added a permissions array to PluginDeclaration and a type level Permissions registry, and made checkPermission and the web UI hasPermission helpers take PermissionName. Move the definePermission calls of exp_groups and exp_scenario into the declaration and add the names to the registry so the web pages type check. The browser tsconfigs include index.ts so the augmentation is visible to the web bundle, matching the in-repo plugins. The exp_scenario table keeps its tuple form and derives the name union from it, so a new row is still one line. Seed role permissions are typed as PermissionName, so a typo in seed.ts is now a compile error rather than a warning at seed time. The tests register the declared permissions through registerPluginPermissions instead of importing permissions.ts for its side effect. Co-Authored-By: Claude Fable 5.1 --- exp_groups/index.ts | 236 ++++++++++++++------------- exp_groups/messages.ts | 24 +++ exp_scenario/index.ts | 48 +++--- exp_scenario/permissions.ts | 18 +- exp_scenario/seed.ts | 5 +- exp_scenario/test/controller.test.js | 6 +- exp_scenario/test/seed.test.js | 6 +- exp_scenario/tsconfig.browser.json | 2 +- 8 files changed, 192 insertions(+), 153 deletions(-) diff --git a/exp_groups/index.ts b/exp_groups/index.ts index 743f33b9..f0f8e5ce 100644 --- a/exp_groups/index.ts +++ b/exp_groups/index.ts @@ -12,123 +12,6 @@ declare module "@clusterio/lib" { } } -// Group permissions - -lib.definePermission({ - name: "exp_groups.group.get", - title: "Get Groups", - description: "Retrieve a specific Factorio permission group by ID.", - grantByDefault: true, -}); -lib.definePermission({ - name: "exp_groups.group.list", - title: "List Groups", - description: "List all Factorio permission groups.", - grantByDefault: true, -}); -lib.definePermission({ - name: "exp_groups.group.subscribe", - title: "Subscribe to Group Updates", - description: "Receive updates when Factorio permission groups change.", - grantByDefault: true, -}); -lib.definePermission({ - name: "exp_groups.group.create", - title: "Create Groups", - description: "Create new Factorio permission groups.", - grantByDefault: false, -}); -lib.definePermission({ - name: "exp_groups.group.update", - title: "Update Groups", - description: "Modify existing Factorio permission groups.", - grantByDefault: false, -}); -lib.definePermission({ - name: "exp_groups.group.delete", - title: "Delete Groups", - description: "Delete Factorio permission groups.", - grantByDefault: false, -}); - -// Assignment permissions - -lib.definePermission({ - name: "exp_groups.assignment.get", - title: "Get Assignments", - description: "Retrieve a specific manual group assignment for a player.", - grantByDefault: true, -}); -lib.definePermission({ - name: "exp_groups.assignment.list", - title: "List Assignments", - description: "List all manual group assignments.", - grantByDefault: true, -}); -lib.definePermission({ - name: "exp_groups.assignment.subscribe", - title: "Subscribe to Assignment Updates", - description: "Receive updates when manual group assignments change.", - grantByDefault: true, -}); -lib.definePermission({ - name: "exp_groups.assignment.create", - title: "Create Assignments", - description: "Manually assign players to groups, overriding role mappings.", - grantByDefault: false, -}); -lib.definePermission({ - name: "exp_groups.assignment.update", - title: "Update Assignments", - description: "Modify existing manual group assignments.", - grantByDefault: false, -}); -lib.definePermission({ - name: "exp_groups.assignment.delete", - title: "Delete Assignments", - description: "Remove manual group assignments.", - grantByDefault: false, -}); - -// Role mapping permissions - -lib.definePermission({ - name: "exp_groups.role_mapping.get", - title: "Get Role Mappings", - description: "Retrieve a specific role mapping rule.", - grantByDefault: true, -}); -lib.definePermission({ - name: "exp_groups.role_mapping.list", - title: "List Role Mappings", - description: "List all role mapping rules.", - grantByDefault: true, -}); -lib.definePermission({ - name: "exp_groups.role_mapping.subscribe", - title: "Subscribe to Role Mapping Updates", - description: "Receive updates when role mapping rules change.", - grantByDefault: true, -}); -lib.definePermission({ - name: "exp_groups.role_mapping.create", - title: "Create Role Mappings", - description: "Create rules that map user roles to Factorio permission groups.", - grantByDefault: false, -}); -lib.definePermission({ - name: "exp_groups.role_mapping.update", - title: "Update Role Mappings", - description: "Modify existing role mapping rules.", - grantByDefault: false, -}); -lib.definePermission({ - name: "exp_groups.role_mapping.delete", - title: "Delete Role Mappings", - description: "Delete role mapping rules.", - grantByDefault: false, -}); - export const plugin: lib.PluginDeclaration = { name: "exp_groups", title: "ExpGaming - Permission Groups", @@ -164,6 +47,125 @@ export const plugin: lib.PluginDeclaration = { messages.RoleMappingListRequest, ], + permissions: [ + // Group permissions + + { + name: "exp_groups.group.get", + title: "Get Groups", + description: "Retrieve a specific Factorio permission group by ID.", + grantByDefault: true, + }, + { + name: "exp_groups.group.list", + title: "List Groups", + description: "List all Factorio permission groups.", + grantByDefault: true, + }, + { + name: "exp_groups.group.subscribe", + title: "Subscribe to Group Updates", + description: "Receive updates when Factorio permission groups change.", + grantByDefault: true, + }, + { + name: "exp_groups.group.create", + title: "Create Groups", + description: "Create new Factorio permission groups.", + grantByDefault: false, + }, + { + name: "exp_groups.group.update", + title: "Update Groups", + description: "Modify existing Factorio permission groups.", + grantByDefault: false, + }, + { + name: "exp_groups.group.delete", + title: "Delete Groups", + description: "Delete Factorio permission groups.", + grantByDefault: false, + }, + + // Assignment permissions + + { + name: "exp_groups.assignment.get", + title: "Get Assignments", + description: "Retrieve a specific manual group assignment for a player.", + grantByDefault: true, + }, + { + name: "exp_groups.assignment.list", + title: "List Assignments", + description: "List all manual group assignments.", + grantByDefault: true, + }, + { + name: "exp_groups.assignment.subscribe", + title: "Subscribe to Assignment Updates", + description: "Receive updates when manual group assignments change.", + grantByDefault: true, + }, + { + name: "exp_groups.assignment.create", + title: "Create Assignments", + description: "Manually assign players to groups, overriding role mappings.", + grantByDefault: false, + }, + { + name: "exp_groups.assignment.update", + title: "Update Assignments", + description: "Modify existing manual group assignments.", + grantByDefault: false, + }, + { + name: "exp_groups.assignment.delete", + title: "Delete Assignments", + description: "Remove manual group assignments.", + grantByDefault: false, + }, + + // Role mapping permissions + + { + name: "exp_groups.role_mapping.get", + title: "Get Role Mappings", + description: "Retrieve a specific role mapping rule.", + grantByDefault: true, + }, + { + name: "exp_groups.role_mapping.list", + title: "List Role Mappings", + description: "List all role mapping rules.", + grantByDefault: true, + }, + { + name: "exp_groups.role_mapping.subscribe", + title: "Subscribe to Role Mapping Updates", + description: "Receive updates when role mapping rules change.", + grantByDefault: true, + }, + { + name: "exp_groups.role_mapping.create", + title: "Create Role Mappings", + description: "Create rules that map user roles to Factorio permission groups.", + grantByDefault: false, + }, + { + name: "exp_groups.role_mapping.update", + title: "Update Role Mappings", + description: "Modify existing role mapping rules.", + grantByDefault: false, + }, + { + name: "exp_groups.role_mapping.delete", + title: "Delete Role Mappings", + description: "Delete role mapping rules.", + grantByDefault: false, + }, + ], + instanceEntrypoint: "./dist/node/instance", instanceConfigFields: { "exp_groups.sync_mode": { diff --git a/exp_groups/messages.ts b/exp_groups/messages.ts index b0e5e986..d5191ca9 100644 --- a/exp_groups/messages.ts +++ b/exp_groups/messages.ts @@ -1,6 +1,30 @@ import * as lib from "@clusterio/lib"; import { Type, Static } from "@sinclair/typebox"; +// Declared here rather than in index.ts because the browser project cannot include index.ts, which re-exports controller.ts +declare module "@clusterio/lib" { + export interface Permissions { + "exp_groups.group.get": never; + "exp_groups.group.list": never; + "exp_groups.group.subscribe": never; + "exp_groups.group.create": never; + "exp_groups.group.update": never; + "exp_groups.group.delete": never; + "exp_groups.assignment.get": never; + "exp_groups.assignment.list": never; + "exp_groups.assignment.subscribe": never; + "exp_groups.assignment.create": never; + "exp_groups.assignment.update": never; + "exp_groups.assignment.delete": never; + "exp_groups.role_mapping.get": never; + "exp_groups.role_mapping.list": never; + "exp_groups.role_mapping.subscribe": never; + "exp_groups.role_mapping.create": never; + "exp_groups.role_mapping.update": never; + "exp_groups.role_mapping.delete": never; + } +} + /* Data records */ diff --git a/exp_scenario/index.ts b/exp_scenario/index.ts index f09c3c6f..5d04b902 100644 --- a/exp_scenario/index.ts +++ b/exp_scenario/index.ts @@ -1,29 +1,14 @@ import * as lib from "@clusterio/lib"; import * as messages from "./messages"; - -// Defines a permission for every in game action and role flag used by the scenario -import "./permissions"; - -lib.definePermission({ - name: "exp_scenario.config.view", - title: "View ExpScenario Config", - description: "View the config for all submodules of ExpScenario", -}); - -lib.definePermission({ - name: "exp_scenario.config.edit", - title: "Edit ExpScenario Config", - description: "Edit the config for all submodules of ExpScenario", -}); - -lib.definePermission({ - name: "exp_scenario.seed", - title: "Seed ExpScenario roles and groups", - description: "Create the roles and permission groups the scenario shipped with", -}); +import { permissions as scenarioPermissions, type ScenarioPermissionName } from "./permissions"; declare module "@clusterio/lib" { - + // Everything checked in game through exp_roles, plus the permissions checked on the controller + export interface Permissions extends Record { + "exp_scenario.config.view": never; + "exp_scenario.config.edit": never; + "exp_scenario.seed": never; + } } export const plugin: lib.PluginDeclaration = { @@ -37,5 +22,24 @@ export const plugin: lib.PluginDeclaration = { messages.SeedRequest, ], + permissions: [ + ...scenarioPermissions, + { + name: "exp_scenario.config.view", + title: "View ExpScenario Config", + description: "View the config for all submodules of ExpScenario", + }, + { + name: "exp_scenario.config.edit", + title: "Edit ExpScenario Config", + description: "Edit the config for all submodules of ExpScenario", + }, + { + name: "exp_scenario.seed", + title: "Seed ExpScenario roles and groups", + description: "Create the roles and permission groups the scenario shipped with", + }, + ], + webEntrypoint: "./web", }; diff --git a/exp_scenario/permissions.ts b/exp_scenario/permissions.ts index bbaafacd..5fc7aa52 100644 --- a/exp_scenario/permissions.ts +++ b/exp_scenario/permissions.ts @@ -1,4 +1,4 @@ -import * as lib from "@clusterio/lib"; +import type * as lib from "@clusterio/lib"; /** * Permissions checked by the scenario in game through exp_roles. @@ -7,9 +7,9 @@ import * as lib from "@clusterio/lib"; * underscores, see module/commands/_authorities.lua. Everything else is checked * by name at its call site. */ -type Definition = [name: string, title: string, description: string, grantByDefault?: boolean]; +type Definition = readonly [name: Name, title: string, description: string, grantByDefault?: boolean]; -const definitions: Definition[] = [ +const definitions = [ ["exp_scenario.bypass.deconstruction_log", "Deconstruction log bypass", "Be excluded from the deconstruction log."], ["exp_scenario.bypass.entity_protection", "Bypass entity protection", "Remove entities that the protection filter would block."], ["exp_scenario.bypass.nuke_protection", "Bypass nuke protection", "Use nukes without the nuke protection restrictions."], @@ -118,8 +118,12 @@ const definitions: Definition[] = [ ["exp_scenario.player.admin", "Factorio admin", "Be promoted to Factorio admin while holding a role with this permission."], ["exp_scenario.player.instant_respawn", "Instant respawn", "Respawn after two seconds instead of the default delay."], ["exp_scenario.player.spectator", "Spectator", "Remove the zoom to world noise effect, as Factorio does for spectators."], -]; +] as const satisfies readonly Definition[]; -for (const [name, title, description, grantByDefault] of definitions) { - lib.definePermission({ name, title, description, grantByDefault }); -} +/** Name of a permission defined by the scenario, added to lib.Permissions in index.ts. */ +export type ScenarioPermissionName = (typeof definitions)[number][0]; + +export const permissions = definitions.map((definition: Definition): lib.PermissionDefinition => { + const [name, title, description, grantByDefault] = definition; + return { name, title, description, grantByDefault }; +}); diff --git a/exp_scenario/seed.ts b/exp_scenario/seed.ts index 37edbd63..64b34550 100644 --- a/exp_scenario/seed.ts +++ b/exp_scenario/seed.ts @@ -1,3 +1,4 @@ +import type * as lib from "@clusterio/lib"; import { RoleColor } from "@expcluster/roles"; /** @@ -19,7 +20,7 @@ export interface SeedRole { isAdmin?: boolean; /** Name of the role whose permissions are also granted, applied recursively. */ parent?: string; - permissions: string[]; + permissions: lib.PermissionName[]; /** * Name of the seed group holders are placed in by their highest role. * Without one the holders stay in Factorio's Default group. @@ -329,7 +330,7 @@ export const seedGroups: SeedGroup[] = [ /** The permissions a seed role grants, including those of its parents. */ export function flattenSeedPermissions(role: SeedRole, roles = seedRoles) { - const permissions = new Set(); + const permissions = new Set(); const seen = new Set(); let current: SeedRole | undefined = role; while (current && !seen.has(current.name)) { diff --git a/exp_scenario/test/controller.test.js b/exp_scenario/test/controller.test.js index 18ffedc4..16206b95 100644 --- a/exp_scenario/test/controller.test.js +++ b/exp_scenario/test/controller.test.js @@ -11,8 +11,10 @@ const { ControllerPlugin: RolesPlugin } = require("@expcluster/roles/dist/node/c const { ControllerPlugin: GroupsPlugin } = require("@expcluster/permission-groups/dist/node/controller"); const { GroupRecord, GroupPermissions, RoleMappingRecord } = require("@expcluster/permission-groups"); -// Importing this defines the permissions the seed grants -require("../dist/node/permissions"); +const { plugin } = require("../dist/node/index"); + +// Registering the plugin defines the permissions the seed grants +lib.registerPluginPermissions([plugin]); // The controller validates message classes against the link registry for (const Message of [messages.SeedRequest, ...roles.plugin.messages, ...groups.plugin.messages]) { diff --git a/exp_scenario/test/seed.test.js b/exp_scenario/test/seed.test.js index 87e198a6..f1c89203 100644 --- a/exp_scenario/test/seed.test.js +++ b/exp_scenario/test/seed.test.js @@ -3,8 +3,10 @@ const t = require("tap"); const lib = require("@clusterio/lib"); const { seedRoles, seedGroups, flattenSeedPermissions } = require("../dist/node/seed"); -// Importing this defines the permissions the seed grants -require("../dist/node/permissions"); +const { plugin } = require("../dist/node/index"); + +// Registering the plugin defines the permissions the seed grants +lib.registerPluginPermissions([plugin]); t.test("seedRoles[] grant only defined permissions", t2 => { for (const role of seedRoles) { diff --git a/exp_scenario/tsconfig.browser.json b/exp_scenario/tsconfig.browser.json index 1e3889e7..b67577c5 100644 --- a/exp_scenario/tsconfig.browser.json +++ b/exp_scenario/tsconfig.browser.json @@ -1,4 +1,4 @@ { "extends": "../tsconfig.browser.json", - "include": [ "web/**/*.tsx", "web/**/*.ts", "messages.ts", "package.json" ], + "include": [ "web/**/*.tsx", "web/**/*.ts", "index.ts", "messages.ts", "permissions.ts", "package.json" ], } From 7fd66c6ac75ee37ebc9441fe68451703e44d9af6 Mon Sep 17 00:00:00 2001 From: bbassie <17990055+bbassie@users.noreply.github.com> Date: Fri, 11 Sep 2026 23:21:41 +0000 Subject: [PATCH 4/4] Migrate to ES modules Clusterio #984 converted its packages to ESM, so a CommonJS plugin can no longer import @clusterio/lib and plugin entrypoints must name the full file. Every package gets "type": "module", entrypoints and relative imports carry the .js extension, and the webpack configs become .cjs as webpack-cli loads them with require. tsconfig.node.json moves from node16 to nodenext to match clusterio, which needs it for the JSON import attributes in its sources. The tap tests and the shared test helpers use import and import.meta.dirname. The test scripts pass --type-strip-only so tap leaves lib's .ts subpath imports to Node's own type stripping, as its TypeScript loader compiled them without a default export. The lua runner resolves fengari from the test file it is given, since a bare import from the shared test directory does not reach the plugin's devDependencies. Co-Authored-By: Claude Fable 5.1 --- exp_commands/index.ts | 2 +- exp_commands/package.json | 1 + .../{webpack.config.js => webpack.config.cjs} | 0 exp_groups/controller.ts | 2 +- exp_groups/index.ts | 10 ++++---- exp_groups/instance.ts | 2 +- exp_groups/package.json | 1 + exp_groups/web/components/AssignmentForm.tsx | 2 +- .../web/components/AssignmentsTable.tsx | 2 +- exp_groups/web/components/GroupForm.tsx | 2 +- exp_groups/web/components/GroupViewPage.tsx | 2 +- exp_groups/web/components/GroupsTable.tsx | 2 +- exp_groups/web/components/RoleMappingForm.tsx | 2 +- .../web/components/RoleMappingsTable.tsx | 2 +- exp_groups/web/index.tsx | 2 +- .../{webpack.config.js => webpack.config.cjs} | 0 exp_gui/index.ts | 2 +- exp_gui/package.json | 1 + .../{webpack.config.js => webpack.config.cjs} | 0 exp_legacy/index.ts | 2 +- exp_legacy/package.json | 1 + .../{webpack.config.js => webpack.config.cjs} | 0 exp_roles/controller.ts | 2 +- exp_roles/index.ts | 10 ++++---- exp_roles/instance.ts | 2 +- exp_roles/package.json | 3 ++- exp_roles/test/controller.test.js | 11 ++++---- exp_roles/test/instance.test.js | 13 +++++----- exp_roles/test/messages.test.js | 7 +++--- exp_roles/test/module.test.js | 11 ++++---- exp_roles/web/components/RoleProperties.tsx | 2 +- exp_roles/web/index.tsx | 2 +- .../{webpack.config.js => webpack.config.cjs} | 0 exp_scenario/controller.ts | 4 +-- exp_scenario/index.ts | 8 +++--- exp_scenario/package.json | 3 ++- exp_scenario/test/controller.test.js | 25 +++++++++---------- exp_scenario/test/seed.test.js | 9 +++---- exp_scenario/web/components/Seed.tsx | 2 +- .../{webpack.config.js => webpack.config.cjs} | 0 exp_server_ups/index.ts | 2 +- exp_server_ups/package.json | 1 + .../{webpack.config.js => webpack.config.cjs} | 0 exp_util/index.ts | 2 +- exp_util/package.json | 1 + .../{webpack.config.js => webpack.config.cjs} | 0 test/common.js | 5 ++-- test/lua/runner.js | 13 +++++----- tsconfig.node.json | 2 +- 49 files changed, 91 insertions(+), 89 deletions(-) rename exp_commands/{webpack.config.js => webpack.config.cjs} (100%) rename exp_groups/{webpack.config.js => webpack.config.cjs} (100%) rename exp_gui/{webpack.config.js => webpack.config.cjs} (100%) rename exp_legacy/{webpack.config.js => webpack.config.cjs} (100%) rename exp_roles/{webpack.config.js => webpack.config.cjs} (100%) rename exp_scenario/{webpack.config.js => webpack.config.cjs} (100%) rename exp_server_ups/{webpack.config.js => webpack.config.cjs} (100%) rename exp_util/{webpack.config.js => webpack.config.cjs} (100%) diff --git a/exp_commands/index.ts b/exp_commands/index.ts index 3e788480..58d11b1f 100644 --- a/exp_commands/index.ts +++ b/exp_commands/index.ts @@ -4,5 +4,5 @@ export const plugin: lib.PluginDeclaration = { name: "exp_commands", title: "exp_commands", description: "Example Description. Plugin. Change me in index.ts", - instanceEntrypoint: "./dist/node/instance", + instanceEntrypoint: "./dist/node/instance.js", }; diff --git a/exp_commands/package.json b/exp_commands/package.json index 7628cfeb..04b5f922 100644 --- a/exp_commands/package.json +++ b/exp_commands/package.json @@ -5,6 +5,7 @@ "author": "Cooldude2606 ", "license": "MIT", "repository": "explosivegaming/ExpCluster", + "type": "module", "main": "dist/node/index.js", "scripts": { "prepare": "tsc --build && webpack-cli --env production" diff --git a/exp_commands/webpack.config.js b/exp_commands/webpack.config.cjs similarity index 100% rename from exp_commands/webpack.config.js rename to exp_commands/webpack.config.cjs diff --git a/exp_groups/controller.ts b/exp_groups/controller.ts index 14d13ef2..a6034433 100644 --- a/exp_groups/controller.ts +++ b/exp_groups/controller.ts @@ -1,6 +1,6 @@ import { BaseControllerPlugin } from "@clusterio/controller"; import * as lib from "@clusterio/lib"; -import * as messages from "./messages"; +import * as messages from "./messages.js"; import * as path from "node:path"; export class ControllerPlugin extends BaseControllerPlugin { diff --git a/exp_groups/index.ts b/exp_groups/index.ts index f0f8e5ce..c92c3e6b 100644 --- a/exp_groups/index.ts +++ b/exp_groups/index.ts @@ -1,8 +1,8 @@ import * as lib from "@clusterio/lib"; -import * as messages from "./messages"; +import * as messages from "./messages.js"; -export * from "./messages"; -export type { ControllerPlugin } from "./controller"; +export * from "./messages.js"; +export type { ControllerPlugin } from "./controller.js"; declare module "@clusterio/lib" { export interface InstanceConfigFields { @@ -166,7 +166,7 @@ export const plugin: lib.PluginDeclaration = { }, ], - instanceEntrypoint: "./dist/node/instance", + instanceEntrypoint: "./dist/node/instance.js", instanceConfigFields: { "exp_groups.sync_mode": { description: "Synchronize permission groups with the controller", @@ -176,7 +176,7 @@ export const plugin: lib.PluginDeclaration = { }, }, - controllerEntrypoint: "./dist/node/controller", + controllerEntrypoint: "./dist/node/controller.js", controllerConfigFields: { }, diff --git a/exp_groups/instance.ts b/exp_groups/instance.ts index d3ed3cc4..207b969c 100644 --- a/exp_groups/instance.ts +++ b/exp_groups/instance.ts @@ -1,6 +1,6 @@ import { BaseInstancePlugin } from "@clusterio/host"; import * as lib from "@clusterio/lib"; -import * as messages from "./messages"; +import * as messages from "./messages.js"; export type IpcGroupUpdated = { group_name: string, diff --git a/exp_groups/package.json b/exp_groups/package.json index 0bd0dae8..6e055307 100644 --- a/exp_groups/package.json +++ b/exp_groups/package.json @@ -5,6 +5,7 @@ "author": "Cooldude2606 ", "license": "MIT", "repository": "explosivegaming/ExpCluster", + "type": "module", "main": "dist/node/index.js", "scripts": { "prepare": "tsc --build && webpack-cli --env production" diff --git a/exp_groups/web/components/AssignmentForm.tsx b/exp_groups/web/components/AssignmentForm.tsx index 41a6a8f2..f20b21a2 100644 --- a/exp_groups/web/components/AssignmentForm.tsx +++ b/exp_groups/web/components/AssignmentForm.tsx @@ -2,7 +2,7 @@ import React, { useContext, useEffect } from "react"; import { Modal, Form, Select } from "antd"; import { ControlContext, useUsers } from "@clusterio/web_ui"; -import * as messages from "../../messages"; +import * as messages from "../../messages.js"; import type { WebPlugin } from ".."; export default function AssignmentForm({ open, setOpen, initial }: { diff --git a/exp_groups/web/components/AssignmentsTable.tsx b/exp_groups/web/components/AssignmentsTable.tsx index 680d9f78..f6997811 100644 --- a/exp_groups/web/components/AssignmentsTable.tsx +++ b/exp_groups/web/components/AssignmentsTable.tsx @@ -3,7 +3,7 @@ import { Table, Button, Space, Input, InputRef } from "antd"; import { EditOutlined, SearchOutlined } from "@ant-design/icons"; import { ControlContext, useAccount } from "@clusterio/web_ui"; -import { AssignmentDeleteRequest, AssignmentRecord } from "../../messages"; +import { AssignmentDeleteRequest, AssignmentRecord } from "../../messages.js"; import type { WebPlugin } from ".."; import AssignmentForm from "./AssignmentForm"; diff --git a/exp_groups/web/components/GroupForm.tsx b/exp_groups/web/components/GroupForm.tsx index 14e3aa1a..945f3c59 100644 --- a/exp_groups/web/components/GroupForm.tsx +++ b/exp_groups/web/components/GroupForm.tsx @@ -3,7 +3,7 @@ import { Modal, Form, Input, Switch } from "antd"; import { useNavigate } from "react-router-dom"; import { ControlContext } from "@clusterio/web_ui"; -import * as messages from "../../messages"; +import * as messages from "../../messages.js"; export default function GroupForm({ open, setOpen }: { open: boolean, diff --git a/exp_groups/web/components/GroupViewPage.tsx b/exp_groups/web/components/GroupViewPage.tsx index 1d5d31fe..1f5ec8ac 100644 --- a/exp_groups/web/components/GroupViewPage.tsx +++ b/exp_groups/web/components/GroupViewPage.tsx @@ -5,7 +5,7 @@ import { Button, Checkbox, Input, Space, Spin, Alert } from "antd"; import { ControlContext, useAccount, useDefaultModPack, PageLayout, PageHeader, notifyErrorHandler } from "@clusterio/web_ui"; import DeletedConfirm from "./DeleteConfirm"; -import * as messages from "../../messages"; +import * as messages from "../../messages.js"; import type { WebPlugin } from ".."; const DOMAIN_MAPPING = { diff --git a/exp_groups/web/components/GroupsTable.tsx b/exp_groups/web/components/GroupsTable.tsx index 1dc711d9..d3f6c9b9 100644 --- a/exp_groups/web/components/GroupsTable.tsx +++ b/exp_groups/web/components/GroupsTable.tsx @@ -3,7 +3,7 @@ import { Table } from "antd"; import { useNavigate } from "react-router-dom"; import { ControlContext } from "@clusterio/web_ui"; -import { GroupRecord } from "../../messages"; +import { GroupRecord } from "../../messages.js"; import type { WebPlugin } from ".."; import GroupForm from "./GroupForm"; diff --git a/exp_groups/web/components/RoleMappingForm.tsx b/exp_groups/web/components/RoleMappingForm.tsx index ee143301..59918b29 100644 --- a/exp_groups/web/components/RoleMappingForm.tsx +++ b/exp_groups/web/components/RoleMappingForm.tsx @@ -2,7 +2,7 @@ import React, { useContext, useEffect } from "react"; import { Modal, Form, Select, InputNumber, Switch, Alert } from "antd"; import { ControlContext, useRoles } from "@clusterio/web_ui"; -import { RoleMappingRecord, RoleMappingCreateRequest, RoleMappingUpdateRequest } from "../../messages"; +import { RoleMappingRecord, RoleMappingCreateRequest, RoleMappingUpdateRequest } from "../../messages.js"; import type { WebPlugin } from ".."; export default function RoleMappingForm({ open, setOpen, initial }: { diff --git a/exp_groups/web/components/RoleMappingsTable.tsx b/exp_groups/web/components/RoleMappingsTable.tsx index 05877426..ab948960 100644 --- a/exp_groups/web/components/RoleMappingsTable.tsx +++ b/exp_groups/web/components/RoleMappingsTable.tsx @@ -3,7 +3,7 @@ import { Table, Button, Space, Tag } from "antd"; import { EditOutlined } from "@ant-design/icons"; import { ControlContext, useAccount, useRoles } from "@clusterio/web_ui"; -import { RoleMappingRecord, RoleMappingDeleteRequest } from "../../messages"; +import { RoleMappingRecord, RoleMappingDeleteRequest } from "../../messages.js"; import type { WebPlugin } from ".."; import RoleMappingForm from "./RoleMappingForm"; diff --git a/exp_groups/web/index.tsx b/exp_groups/web/index.tsx index e9fbc797..5a2f24cd 100644 --- a/exp_groups/web/index.tsx +++ b/exp_groups/web/index.tsx @@ -2,7 +2,7 @@ import React, { useState, useCallback, useSyncExternalStore } from "react"; import { BaseWebPlugin, PageLayout, PageHeader, useAccount, SectionHeader } from "@clusterio/web_ui"; import { Button } from "antd"; -import * as messages from "../messages"; +import * as messages from "../messages.js"; import * as lib from "@clusterio/lib"; import GroupsTable from "./components/GroupsTable"; diff --git a/exp_groups/webpack.config.js b/exp_groups/webpack.config.cjs similarity index 100% rename from exp_groups/webpack.config.js rename to exp_groups/webpack.config.cjs diff --git a/exp_gui/index.ts b/exp_gui/index.ts index eb9596f4..b25ce074 100644 --- a/exp_gui/index.ts +++ b/exp_gui/index.ts @@ -4,5 +4,5 @@ export const plugin: lib.PluginDeclaration = { name: "exp_gui", title: "exp_gui", description: "Example Description. Plugin. Change me in index.ts", - instanceEntrypoint: "./dist/node/instance", + instanceEntrypoint: "./dist/node/instance.js", }; diff --git a/exp_gui/package.json b/exp_gui/package.json index 6679512a..5f344d11 100644 --- a/exp_gui/package.json +++ b/exp_gui/package.json @@ -5,6 +5,7 @@ "author": "Cooldude2606 ", "license": "MIT", "repository": "explosivegaming/ExpCluster", + "type": "module", "main": "dist/node/index.js", "scripts": { "prepare": "tsc --build && webpack-cli --env production" diff --git a/exp_gui/webpack.config.js b/exp_gui/webpack.config.cjs similarity index 100% rename from exp_gui/webpack.config.js rename to exp_gui/webpack.config.cjs diff --git a/exp_legacy/index.ts b/exp_legacy/index.ts index ff35fce5..c49d3201 100644 --- a/exp_legacy/index.ts +++ b/exp_legacy/index.ts @@ -4,5 +4,5 @@ export const plugin: lib.PluginDeclaration = { name: "exp_legacy", title: "exp_legacy", description: "Example Description. Plugin. Change me in index.ts", - instanceEntrypoint: "./dist/node/instance", + instanceEntrypoint: "./dist/node/instance.js", }; diff --git a/exp_legacy/package.json b/exp_legacy/package.json index f5220dc7..601368c5 100644 --- a/exp_legacy/package.json +++ b/exp_legacy/package.json @@ -5,6 +5,7 @@ "author": "Cooldude2606 ", "license": "MIT", "repository": "explosivegaming/ExpCluster", + "type": "module", "main": "dist/node/index.js", "scripts": { "prepare": "tsc --build && webpack-cli --env production" diff --git a/exp_legacy/webpack.config.js b/exp_legacy/webpack.config.cjs similarity index 100% rename from exp_legacy/webpack.config.js rename to exp_legacy/webpack.config.cjs diff --git a/exp_roles/controller.ts b/exp_roles/controller.ts index b9bf3a8b..96acc167 100644 --- a/exp_roles/controller.ts +++ b/exp_roles/controller.ts @@ -1,6 +1,6 @@ import { BaseControllerPlugin, InstanceRecord } from "@clusterio/controller"; import * as lib from "@clusterio/lib"; -import * as messages from "./messages"; +import * as messages from "./messages.js"; import * as path from "node:path"; export class ControllerPlugin extends BaseControllerPlugin { diff --git a/exp_roles/index.ts b/exp_roles/index.ts index e481fc8f..211f29c8 100644 --- a/exp_roles/index.ts +++ b/exp_roles/index.ts @@ -1,8 +1,8 @@ import * as lib from "@clusterio/lib"; -import * as messages from "./messages"; +import * as messages from "./messages.js"; -export * from "./messages"; -export type { ControllerPlugin } from "./controller"; +export * from "./messages.js"; +export type { ControllerPlugin } from "./controller.js"; declare module "@clusterio/lib" { export interface InstanceConfigFields { @@ -35,7 +35,7 @@ export const plugin: lib.PluginDeclaration = { messages.AssignmentUpdateRequest, ], - instanceEntrypoint: "./dist/node/instance", + instanceEntrypoint: "./dist/node/instance.js", instanceConfigFields: { "exp_roles.sync_mode": { description: "Synchronize in game roles with the controller", @@ -45,7 +45,7 @@ export const plugin: lib.PluginDeclaration = { }, }, - controllerEntrypoint: "./dist/node/controller", + controllerEntrypoint: "./dist/node/controller.js", controllerConfigFields: { }, diff --git a/exp_roles/instance.ts b/exp_roles/instance.ts index 208a0982..d57a5819 100644 --- a/exp_roles/instance.ts +++ b/exp_roles/instance.ts @@ -1,6 +1,6 @@ import { BaseInstancePlugin } from "@clusterio/host"; import * as lib from "@clusterio/lib"; -import * as messages from "./messages"; +import * as messages from "./messages.js"; /** Sent by the lua side when roles are changed in game. */ export type IpcAssignmentUpdate = { diff --git a/exp_roles/package.json b/exp_roles/package.json index c5f3ae57..6a09a372 100644 --- a/exp_roles/package.json +++ b/exp_roles/package.json @@ -5,10 +5,11 @@ "author": "Cooldude2606 ", "license": "MIT", "repository": "explosivegaming/ExpCluster", + "type": "module", "main": "dist/node/index.js", "scripts": { "prepare": "tsc --build && webpack-cli --env production", - "test": "tap --disable-coverage --allow-empty-coverage test/*.test.js", + "test": "tap --type-strip-only --disable-coverage --allow-empty-coverage test/*.test.js", "coverage": "tap --coverage-report=text test/*.test.js" }, "engines": { diff --git a/exp_roles/test/controller.test.js b/exp_roles/test/controller.test.js index 4e66ee48..0549c733 100644 --- a/exp_roles/test/controller.test.js +++ b/exp_roles/test/controller.test.js @@ -1,9 +1,8 @@ -"use strict"; -const t = require("tap"); -const lib = require("@clusterio/lib"); -const { Controller } = require("@clusterio/controller"); -const { ControllerPlugin } = require("../dist/node/controller"); -const messages = require("../dist/node/messages"); +import t from "tap"; +import * as lib from "@clusterio/lib"; +import { Controller } from "@clusterio/controller"; +import { ControllerPlugin } from "../dist/node/controller.js"; +import * as messages from "../dist/node/messages.js"; // The controller validates message classes against the link registry lib.Link.register(messages.RoleUpdatedEvent); diff --git a/exp_roles/test/instance.test.js b/exp_roles/test/instance.test.js index cb3db308..e0651358 100644 --- a/exp_roles/test/instance.test.js +++ b/exp_roles/test/instance.test.js @@ -1,10 +1,9 @@ -"use strict"; -const t = require("tap"); -const lib = require("@clusterio/lib"); -const { Instance } = require("@clusterio/host"); -const { InstancePlugin } = require("../dist/node/instance"); -const { plugin: pluginDeclaration } = require("../dist/node/index"); -const messages = require("../dist/node/messages"); +import t from "tap"; +import * as lib from "@clusterio/lib"; +import { Instance } from "@clusterio/host"; +import { InstancePlugin } from "../dist/node/instance.js"; +import { plugin as pluginDeclaration } from "../dist/node/index.js"; +import * as messages from "../dist/node/messages.js"; // The instance validates message classes against the link registry, and the // plugin's config fields must be defined before an InstanceConfig can set them diff --git a/exp_roles/test/messages.test.js b/exp_roles/test/messages.test.js index 8ec26550..324d0719 100644 --- a/exp_roles/test/messages.test.js +++ b/exp_roles/test/messages.test.js @@ -1,7 +1,6 @@ -"use strict"; -const t = require("tap"); -const messages = require("../dist/node/messages"); -const { testMatrix, testRoundTripJsonSerialisable } = require("../../test/common"); +import t from "tap"; +import * as messages from "../dist/node/messages.js"; +import { testMatrix, testRoundTripJsonSerialisable } from "../../test/common.js"; const fullMeta = new messages.RoleMetaRecord( 7, 3, 1, "Mod", "[Mod]", new messages.RoleColor(1, 2, 3), 3600000, true, 12345, false, diff --git a/exp_roles/test/module.test.js b/exp_roles/test/module.test.js index 2e5d4aa5..0acdfc29 100644 --- a/exp_roles/test/module.test.js +++ b/exp_roles/test/module.test.js @@ -1,14 +1,13 @@ -"use strict"; -const path = require("node:path"); -const t = require("tap"); -const { reportLuaTests } = require("../../test/lua/runner"); +import path from "node:path"; +import t from "tap"; +import { reportLuaTests } from "../../test/lua/runner.js"; -const envFile = path.join(__dirname, "module", "env.lua"); +const envFile = path.join(import.meta.dirname, "module", "env.lua"); // Each file runs in its own lua state, and each test in a fresh environment t.test("control.lua", t2 => { for (const file of ["lookup.lua", "players.lua", "assignment.lua", "sync.lua", "holders.lua"]) { - t2.test(file, t3 => reportLuaTests(t3, envFile, path.join(__dirname, "module", file))); + t2.test(file, t3 => reportLuaTests(t3, envFile, path.join(import.meta.dirname, "module", file))); } t2.end(); }); diff --git a/exp_roles/web/components/RoleProperties.tsx b/exp_roles/web/components/RoleProperties.tsx index b63ae707..53f6ca99 100644 --- a/exp_roles/web/components/RoleProperties.tsx +++ b/exp_roles/web/components/RoleProperties.tsx @@ -4,7 +4,7 @@ import { Button, Col, ColorPicker, Form, Input, InputNumber, Row, Switch, Toolti import * as lib from "@clusterio/lib"; import { ControlContext, SectionHeader, useAccount, notifyErrorHandler } from "@clusterio/web_ui"; -import { RoleColor, RoleMetaRecord, RoleMetaUpdateRequest } from "../../messages"; +import { RoleColor, RoleMetaRecord, RoleMetaUpdateRequest } from "../../messages.js"; import type { WebPlugin } from ".."; const MS_PER_HOUR = 3600000; diff --git a/exp_roles/web/index.tsx b/exp_roles/web/index.tsx index 644cd10d..36e9de1d 100644 --- a/exp_roles/web/index.tsx +++ b/exp_roles/web/index.tsx @@ -2,7 +2,7 @@ import React, { useCallback, useSyncExternalStore } from "react"; import { BaseWebPlugin } from "@clusterio/web_ui"; import * as lib from "@clusterio/lib"; -import * as messages from "../messages"; +import * as messages from "../messages.js"; import RoleProperties from "./components/RoleProperties"; diff --git a/exp_roles/webpack.config.js b/exp_roles/webpack.config.cjs similarity index 100% rename from exp_roles/webpack.config.js rename to exp_roles/webpack.config.cjs diff --git a/exp_scenario/controller.ts b/exp_scenario/controller.ts index cd04b3db..05d3303e 100644 --- a/exp_scenario/controller.ts +++ b/exp_scenario/controller.ts @@ -4,8 +4,8 @@ import { RoleMetaRecord, type ControllerPlugin as RolesPlugin } from "@expcluste import { GroupRecord, GroupPermissions, RoleMappingRecord, type ControllerPlugin as GroupsPlugin, } from "@expcluster/permission-groups"; -import * as messages from "./messages"; -import { SeedRole, SeedGroup, seedRoles, seedGroups, flattenSeedPermissions } from "./seed"; +import * as messages from "./messages.js"; +import { SeedRole, SeedGroup, seedRoles, seedGroups, flattenSeedPermissions } from "./seed.js"; export class ControllerPlugin extends BaseControllerPlugin { async init() { diff --git a/exp_scenario/index.ts b/exp_scenario/index.ts index 5d04b902..203c5721 100644 --- a/exp_scenario/index.ts +++ b/exp_scenario/index.ts @@ -1,6 +1,6 @@ import * as lib from "@clusterio/lib"; -import * as messages from "./messages"; -import { permissions as scenarioPermissions, type ScenarioPermissionName } from "./permissions"; +import * as messages from "./messages.js"; +import { permissions as scenarioPermissions, type ScenarioPermissionName } from "./permissions.js"; declare module "@clusterio/lib" { // Everything checked in game through exp_roles, plus the permissions checked on the controller @@ -15,8 +15,8 @@ export const plugin: lib.PluginDeclaration = { name: "exp_scenario", title: "exp_scenario", description: "Example Description. Plugin. Change me in index.ts", - controllerEntrypoint: "./dist/node/controller", - instanceEntrypoint: "./dist/node/instance", + controllerEntrypoint: "./dist/node/controller.js", + instanceEntrypoint: "./dist/node/instance.js", messages: [ messages.SeedRequest, diff --git a/exp_scenario/package.json b/exp_scenario/package.json index 1e4d9d65..706fef28 100644 --- a/exp_scenario/package.json +++ b/exp_scenario/package.json @@ -5,10 +5,11 @@ "author": "Cooldude2606 ", "license": "MIT", "repository": "explosivegaming/ExpCluster", + "type": "module", "main": "dist/node/index.js", "scripts": { "prepare": "tsc --build && webpack-cli --env production", - "test": "tap --disable-coverage --allow-empty-coverage test/*.test.js", + "test": "tap --type-strip-only --disable-coverage --allow-empty-coverage test/*.test.js", "coverage": "tap --coverage-report=text test/*.test.js" }, "engines": { diff --git a/exp_scenario/test/controller.test.js b/exp_scenario/test/controller.test.js index 16206b95..d7b96add 100644 --- a/exp_scenario/test/controller.test.js +++ b/exp_scenario/test/controller.test.js @@ -1,17 +1,16 @@ -"use strict"; -const t = require("tap"); -const lib = require("@clusterio/lib"); -const { Controller } = require("@clusterio/controller"); -const { ControllerPlugin } = require("../dist/node/controller"); -const messages = require("../dist/node/messages"); -const { seedRoles, seedGroups } = require("../dist/node/seed"); -const roles = require("@expcluster/roles"); -const groups = require("@expcluster/permission-groups"); -const { ControllerPlugin: RolesPlugin } = require("@expcluster/roles/dist/node/controller"); -const { ControllerPlugin: GroupsPlugin } = require("@expcluster/permission-groups/dist/node/controller"); -const { GroupRecord, GroupPermissions, RoleMappingRecord } = require("@expcluster/permission-groups"); +import t from "tap"; +import * as lib from "@clusterio/lib"; +import { Controller } from "@clusterio/controller"; +import { ControllerPlugin } from "../dist/node/controller.js"; +import * as messages from "../dist/node/messages.js"; +import { seedRoles, seedGroups } from "../dist/node/seed.js"; +import * as roles from "@expcluster/roles"; +import * as groups from "@expcluster/permission-groups"; +import { ControllerPlugin as RolesPlugin } from "@expcluster/roles/dist/node/controller.js"; +import { ControllerPlugin as GroupsPlugin } from "@expcluster/permission-groups/dist/node/controller.js"; +import { GroupRecord, GroupPermissions, RoleMappingRecord } from "@expcluster/permission-groups"; -const { plugin } = require("../dist/node/index"); +import { plugin } from "../dist/node/index.js"; // Registering the plugin defines the permissions the seed grants lib.registerPluginPermissions([plugin]); diff --git a/exp_scenario/test/seed.test.js b/exp_scenario/test/seed.test.js index f1c89203..c201409d 100644 --- a/exp_scenario/test/seed.test.js +++ b/exp_scenario/test/seed.test.js @@ -1,9 +1,8 @@ -"use strict"; -const t = require("tap"); -const lib = require("@clusterio/lib"); -const { seedRoles, seedGroups, flattenSeedPermissions } = require("../dist/node/seed"); +import t from "tap"; +import * as lib from "@clusterio/lib"; +import { seedRoles, seedGroups, flattenSeedPermissions } from "../dist/node/seed.js"; -const { plugin } = require("../dist/node/index"); +import { plugin } from "../dist/node/index.js"; // Registering the plugin defines the permissions the seed grants lib.registerPluginPermissions([plugin]); diff --git a/exp_scenario/web/components/Seed.tsx b/exp_scenario/web/components/Seed.tsx index 619d79df..8131b137 100644 --- a/exp_scenario/web/components/Seed.tsx +++ b/exp_scenario/web/components/Seed.tsx @@ -3,7 +3,7 @@ import { Button, Popconfirm } from "antd"; import { ControlContext, SectionHeader, useAccount, notifyErrorHandler } from "@clusterio/web_ui"; -import { SeedRequest } from "../../messages"; +import { SeedRequest } from "../../messages.js"; /** Button on the roles page which creates the roles and permission groups the scenario shipped with. */ export default function Seed() { diff --git a/exp_scenario/webpack.config.js b/exp_scenario/webpack.config.cjs similarity index 100% rename from exp_scenario/webpack.config.js rename to exp_scenario/webpack.config.cjs diff --git a/exp_server_ups/index.ts b/exp_server_ups/index.ts index cdfc8663..404259e9 100644 --- a/exp_server_ups/index.ts +++ b/exp_server_ups/index.ts @@ -12,7 +12,7 @@ export const plugin: lib.PluginDeclaration = { title: "ExpGaming - Server UPS", description: "Clusterio plugin providing in game server ups counter", - instanceEntrypoint: "./dist/node/instance", + instanceEntrypoint: "./dist/node/instance.js", instanceConfigFields: { "exp_server_ups.update_interval": { title: "Update Interval", diff --git a/exp_server_ups/package.json b/exp_server_ups/package.json index 25baa73f..e2a01051 100644 --- a/exp_server_ups/package.json +++ b/exp_server_ups/package.json @@ -5,6 +5,7 @@ "author": "Cooldude2606 ", "license": "MIT", "repository": "explosivegaming/ExpCluster", + "type": "module", "main": "dist/node/index.js", "scripts": { "prepare": "tsc --build && webpack-cli --env production" diff --git a/exp_server_ups/webpack.config.js b/exp_server_ups/webpack.config.cjs similarity index 100% rename from exp_server_ups/webpack.config.js rename to exp_server_ups/webpack.config.cjs diff --git a/exp_util/index.ts b/exp_util/index.ts index c169aefd..12957919 100644 --- a/exp_util/index.ts +++ b/exp_util/index.ts @@ -4,5 +4,5 @@ export const plugin: lib.PluginDeclaration = { name: "exp_util", title: "ExpGaming Module Utilities", description: "Provides extensions and overrides of base Lua library functions, and provides utility modules for improved module compatibly", - instanceEntrypoint: "./dist/node/instance", + instanceEntrypoint: "./dist/node/instance.js", }; diff --git a/exp_util/package.json b/exp_util/package.json index ec10ff5d..3dfa39e2 100644 --- a/exp_util/package.json +++ b/exp_util/package.json @@ -5,6 +5,7 @@ "author": "Cooldude2606 ", "license": "MIT", "repository": "explosivegaming/ExpCluster", + "type": "module", "main": "dist/node/index.js", "scripts": { "prepare": "tsc --build && webpack-cli --env production" diff --git a/exp_util/webpack.config.js b/exp_util/webpack.config.cjs similarity index 100% rename from exp_util/webpack.config.js rename to exp_util/webpack.config.cjs diff --git a/test/common.js b/test/common.js index bf63b030..f6c476f5 100644 --- a/test/common.js +++ b/test/common.js @@ -1,5 +1,4 @@ -"use strict"; -const { compile } = require("@clusterio/lib"); +import { compile } from "@clusterio/lib"; /** * Generate a flat array of tests from a matrix of inputs. @@ -49,7 +48,7 @@ function testRoundTripJsonSerialisable(t, Class, tests) { } } -module.exports = { +export { testMatrix, testRoundTripJsonSerialisable, }; diff --git a/test/lua/runner.js b/test/lua/runner.js index 51019609..14dbb9d0 100644 --- a/test/lua/runner.js +++ b/test/lua/runner.js @@ -1,7 +1,6 @@ -"use strict"; -const path = require("node:path"); -const fs = require("node:fs"); -const { lua, lauxlib, lualib, to_luastring, to_jsstring } = require("fengari"); +import path from "node:path"; +import fs from "node:fs"; +import { createRequire } from "node:module"; /** * Run one lua test file in its own lua state and return its results. @@ -21,6 +20,8 @@ const { lua, lauxlib, lualib, to_luastring, to_jsstring } = require("fengari"); * @returns {{ name: string, ok: boolean, detail?: string }[]} */ function runLuaTests(envFile, testFile) { + // fengari is a devDependency of the plugin whose tests run, so resolve it from there + const { lua, lauxlib, lualib, to_luastring, to_jsstring } = createRequire(testFile)("fengari"); const L = lauxlib.luaL_newstate(); lualib.luaL_openlibs(L); @@ -38,7 +39,7 @@ function runLuaTests(envFile, testFile) { }; load(envFile); - lua.lua_pushstring(L, to_luastring(__dirname)); + lua.lua_pushstring(L, to_luastring(import.meta.dirname)); call(); // The environment stays on the stack and is passed to the test chunk @@ -60,4 +61,4 @@ function reportLuaTests(t, envFile, testFile) { t.end(); } -module.exports = { runLuaTests, reportLuaTests }; +export { runLuaTests, reportLuaTests }; diff --git a/tsconfig.node.json b/tsconfig.node.json index a2e84c8b..b5f49789 100644 --- a/tsconfig.node.json +++ b/tsconfig.node.json @@ -2,7 +2,7 @@ "extends": "./tsconfig.base.json", "compilerOptions": { "lib": ["es2023"], - "module": "node16", + "module": "nodenext", "moduleResolution": "node16", "target": "es2022", "forceConsistentCasingInFileNames": true,