diff --git a/exp_reports/controller.ts b/exp_reports/controller.ts index f6b09a3b..21ec80c6 100644 --- a/exp_reports/controller.ts +++ b/exp_reports/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_reports/index.ts b/exp_reports/index.ts index 4c745977..cba7c8f1 100644 --- a/exp_reports/index.ts +++ b/exp_reports/index.ts @@ -1,5 +1,5 @@ import * as lib from "@clusterio/lib"; -import * as messages from "./messages"; +import * as messages from "./messages.js"; declare module "@clusterio/lib" { export interface ControllerConfigFields { @@ -8,37 +8,6 @@ declare module "@clusterio/lib" { } } -lib.definePermission({ - name: "exp_reports.report.get", - title: "Get Reports", - description: "Retrieve a specific report by id.", - grantByDefault: true, -}); -lib.definePermission({ - name: "exp_reports.report.list", - title: "List Reports", - description: "List the reports against every player, or against one player.", - grantByDefault: true, -}); -lib.definePermission({ - name: "exp_reports.report.subscribe", - title: "Subscribe to Report Updates", - description: "Receive updates when reports are made or deleted.", - grantByDefault: true, -}); -lib.definePermission({ - name: "exp_reports.report.create", - title: "Create Reports", - description: "Report a player.", - grantByDefault: false, -}); -lib.definePermission({ - name: "exp_reports.report.delete", - title: "Delete Reports", - description: "Delete reports made against a player.", - grantByDefault: false, -}); - export const plugin: lib.PluginDeclaration = { name: "exp_reports", title: "ExpGaming - Reports", @@ -58,9 +27,42 @@ export const plugin: lib.PluginDeclaration = { messages.ReportDeleteRequest, ], - instanceEntrypoint: "./dist/node/instance", + permissions: [ + { + name: "exp_reports.report.get", + title: "Get Reports", + description: "Retrieve a specific report by id.", + grantByDefault: true, + }, + { + name: "exp_reports.report.list", + title: "List Reports", + description: "List the reports against every player, or against one player.", + grantByDefault: true, + }, + { + name: "exp_reports.report.subscribe", + title: "Subscribe to Report Updates", + description: "Receive updates when reports are made or deleted.", + grantByDefault: true, + }, + { + name: "exp_reports.report.create", + title: "Create Reports", + description: "Report a player.", + grantByDefault: false, + }, + { + name: "exp_reports.report.delete", + title: "Delete Reports", + description: "Delete reports made against a player.", + grantByDefault: false, + }, + ], - controllerEntrypoint: "./dist/node/controller", + instanceEntrypoint: "./dist/node/instance.js", + + controllerEntrypoint: "./dist/node/controller.js", controllerConfigFields: { "exp_reports.discord_webhook_url": { title: "Discord Webhook URL", diff --git a/exp_reports/instance.ts b/exp_reports/instance.ts index bf6baf1e..61c4c38c 100644 --- a/exp_reports/instance.ts +++ b/exp_reports/instance.ts @@ -1,5 +1,5 @@ import { BaseInstancePlugin } from "@clusterio/host"; -import * as messages from "./messages"; +import * as messages from "./messages.js"; /** Sent by the lua side when a player reports another. */ export type IpcReportCreate = { diff --git a/exp_reports/messages.ts b/exp_reports/messages.ts index c59c9775..768ee269 100644 --- a/exp_reports/messages.ts +++ b/exp_reports/messages.ts @@ -1,6 +1,16 @@ import * as lib from "@clusterio/lib"; import { Type, Static } from "@sinclair/typebox"; +declare module "@clusterio/lib" { + export interface Permissions { + "exp_reports.report.get": never; + "exp_reports.report.list": never; + "exp_reports.report.subscribe": never; + "exp_reports.report.create": never; + "exp_reports.report.delete": never; + } +} + /* Data records */ diff --git a/exp_reports/package.json b/exp_reports/package.json index daef5451..3e974df2 100644 --- a/exp_reports/package.json +++ b/exp_reports/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_reports/test/controller.test.js b/exp_reports/test/controller.test.js index 62782e78..8097ee5b 100644 --- a/exp_reports/test/controller.test.js +++ b/exp_reports/test/controller.test.js @@ -1,10 +1,9 @@ -"use strict"; -const t = require("tap"); -const lib = require("@clusterio/lib"); -const { Controller, InstanceRecord } = require("@clusterio/controller"); -const { ControllerPlugin } = require("../dist/node/controller"); -const messages = require("../dist/node/messages"); -const { plugin: pluginDeclaration } = require("../dist/node/index"); +import t from "tap"; +import * as lib from "@clusterio/lib"; +import { Controller, InstanceRecord } from "@clusterio/controller"; +import { ControllerPlugin } from "../dist/node/controller.js"; +import * as messages from "../dist/node/messages.js"; +import { plugin as pluginDeclaration } from "../dist/node/index.js"; // The controller validates message classes against the link registry, and the // plugin's config fields must be defined before a ControllerConfig can set them diff --git a/exp_reports/test/instance.test.js b/exp_reports/test/instance.test.js index 6c150aa3..6fdedcc8 100644 --- a/exp_reports/test/instance.test.js +++ b/exp_reports/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 for (const Message of pluginDeclaration.messages) { diff --git a/exp_reports/test/messages.test.js b/exp_reports/test/messages.test.js index 1471eebd..f892318b 100644 --- a/exp_reports/test/messages.test.js +++ b/exp_reports/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 sampleReport = new messages.ReportRecord(7, "bob", "alice", "griefing", "EXP", 12345); diff --git a/exp_reports/test/module.test.js b/exp_reports/test/module.test.js index 7017a1e3..3ec85bcb 100644 --- a/exp_reports/test/module.test.js +++ b/exp_reports/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 ["requests.lua", "receivers.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_reports/web/components/ReportsPage.tsx b/exp_reports/web/components/ReportsPage.tsx index ce4e16ed..795e44e1 100644 --- a/exp_reports/web/components/ReportsPage.tsx +++ b/exp_reports/web/components/ReportsPage.tsx @@ -6,8 +6,8 @@ import { useColumnSearch, useTableQueryState, } from "@clusterio/web_ui"; -import { ReportCreateRequest, ReportDeleteRequest, ReportRecord } from "../../messages"; -import type { WebPlugin } from ".."; +import { ReportCreateRequest, ReportDeleteRequest, ReportRecord } from "../../messages.js"; +import { useReports } from ".."; const strcmp = new Intl.Collator(undefined, { numeric: true, sensitivity: "base" }).compare; @@ -50,8 +50,7 @@ function CreateReportButton() { function ReportsTable() { const control = useContext(ControlContext); const account = useAccount(); - const plugin = control.plugins.get("exp_reports") as WebPlugin; - const [reports, synced] = plugin.useReports(); + const [reports, synced] = useReports(); const tableState = useTableQueryState({ namespace: "report", diff --git a/exp_reports/web/index.tsx b/exp_reports/web/index.tsx index 3b9dc85d..53abedee 100644 --- a/exp_reports/web/index.tsx +++ b/exp_reports/web/index.tsx @@ -1,27 +1,27 @@ import React, { useCallback, useSyncExternalStore } from "react"; -import { BaseWebPlugin } from "@clusterio/web_ui"; +import { WebPluginContext } from "@clusterio/web_ui"; import * as lib from "@clusterio/lib"; -import * as messages from "../messages"; +import * as messages from "../messages.js"; import ReportsPage from "./components/ReportsPage"; -export class WebPlugin extends BaseWebPlugin { - reports = new lib.MapSubscriber(messages.ReportUpdatedEvent, this.control); +let reports: lib.MapSubscriber | undefined; - async init() { - this.pages = [ - { - path: "/reports", - sidebarName: "Reports", - permission: "exp_reports.report.list", - content: , - }, - ]; - } +export function useReports() { + const subscribe = useCallback((cb: () => void) => reports!.subscribe(cb), []); + return useSyncExternalStore(subscribe, () => reports!.getSnapshot()); +} - useReports() { - const subscribe = useCallback((cb: () => void) => this.reports.subscribe(cb), []); - return useSyncExternalStore(subscribe, () => this.reports.getSnapshot()); - } +export default function registerPlugin(context: WebPluginContext) { + context.control.hooks.pages.attach("exp_reports", () => [ + { + path: "/reports", + sidebarName: "Reports", + permission: "exp_reports.report.list", + content: , + }, + ]); + + reports = new lib.MapSubscriber(messages.ReportUpdatedEvent, context.control); }