diff --git a/packages/create/create.js b/packages/create/create.js index 9bb12b52..44f8c892 100755 --- a/packages/create/create.js +++ b/packages/create/create.js @@ -509,77 +509,89 @@ async function copyPluginTemplateFile(src, dst, props) { } const templateData = await fs.readFile(src, "utf8"); - const outputData = templateData.replace(/\/\/ ([a-z_]*) \/\//g, (_, value) => { - if (!props.hasOwnProperty(value)) { - logger.warn(`Unknown property string (${value}) found in template file ${src}`); - return value; - } + const outputData = templateData + .replace(/\/\/ \[([a-z_]*)\] \/\/(.*?)\/\/ \[\] \/\//gs, (_, prop, content) => { + // Find and replace // [prop] //content// [] // + if (!props.hasOwnProperty(prop)) { + logger.warn(`Unknown property clause (${prop}) found in template file ${src}`); + return content; + } - return props[value]; - }); + return Boolean(props[prop]) ? content : ""; + }) + .replace(/\/\/ ([a-z_]*) \/\//g, (_, prop) => { + // Find and replace // prop // + if (!props.hasOwnProperty(prop)) { + logger.warn(`Unknown property string (${prop}) found in template file ${src}`); + return prop; + } + + return props[prop]; + }); await fs.outputFile(dst, outputData); } async function copyPluginTemplate(pluginName, templates) { logger.info(`Please wait, coping templates for ${templates.join(", ")}`); - const noTypescript = templates.includes("js"); const devDependencies = new Map(); - const dependencies = new Map(); const entryPoints = new Map(); - const prepare = []; const files = new Map(); + const prepare = []; - let templatePath = "./templates/plugin-ts"; - if (noTypescript) { - templatePath = "./templates/plugin-js"; - logger.error("Javascript only templates are not currently supported"); - return; - } + const javascriptOnly = templates.includes("js"); + const webpack = templates.includes("controller") || templates.includes("web"); - templatePath = path.resolve(__dirname, templatePath); + // 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"); - // Files includes in all templates + // Files included in all templates files.set(".gitignore", path.join(templatePath, ".gitignore")); files.set(".npmignore", path.join(templatePath, ".npmignore")); files.set("package.json", path.join(templatePath, "package.json")); - files.set("tsconfig.json", path.join(templatePath, "tsconfig.json")); - files.set("messages.ts", path.join(templatePath, "messages.ts")); - files.set("index.ts", path.join(templatePath, "index.ts")); - devDependencies.set("@types/node", "^20.4.5"); - devDependencies.set("@types/node", "^20.4.5"); - devDependencies.set("typescript", "^5.1.6"); - dependencies.set("@sinclair/typebox", "^0.30.4"); - prepare.push("tsc --build"); + files.set(`messages.${ext}`, path.join(templatePath, `messages.${ext}`)); + files.set(`index.${ext}`, path.join(templatePath, `index.${ext}`)); - if (templates.includes("controller") || templates.includes("web")) { - devDependencies.set("@clusterio/web_ui", "^2.0.0-alpha.14"); - devDependencies.set("@types/react", "^18.2.21"); + // Files and dependencies to support typescript + if (!javascriptOnly) { + if (webpack) { + devDependencies.set("@types/react", "^18.2.21"); + files.set("tsconfig.web.json", path.join(templatePath, "tsconfig.web.json")); + } + devDependencies.set("@types/node", "^20.4.5"); + devDependencies.set("typescript", "^5.1.6"); + files.set("tsconfig.json", path.join(templatePath, "tsconfig.json")); + prepare.push("tsc --build"); + } + + // Files and dependences to support webpack + if (webpack) { devDependencies.set("webpack", "^5.88.2"); devDependencies.set("webpack-cli", "^5.1.4"); devDependencies.set("webpack-merge", "^5.9.0"); + devDependencies.set("@clusterio/web_ui", "^2.0.0-alpha.14"); entryPoints.set("webEntrypoint", "./web"); prepare.push("webpack-cli --env production"); files.set("webpack.config.js", path.join(templatePath, "webpack.config.js")); - files.set("tsconfig.web.json", path.join(templatePath, "tsconfig.web.json")); - files.set("web/index.tsx", path.join(templatePath, - templates.includes("web") ? "web/plugin.tsx" : "web/no_plugin.tsx" + files.set(`web/index.${ext}x`, path.join(templatePath, + templates.includes("web") ? `web/plugin.${ext}x` : `web/no_plugin.${ext}x` )); } if (templates.includes("controller")) { entryPoints.set("controllerEntrypoint", "dist/plugin/controller"); - files.set("controller.ts", path.join(templatePath, "controller.ts")); + files.set(`controller.${ext}`, path.join(templatePath, `controller.${ext}`)); } if (templates.includes("host")) { entryPoints.set("hostEntrypoint", "dist/plugin/host"); - files.set("host.ts", path.join(templatePath, "host.ts")); + files.set(`host.${ext}`, path.join(templatePath, `host.${ext}`)); } if (templates.includes("instance")) { entryPoints.set("instanceEntrypoint", "dist/plugin/instance"); - files.set("instance.ts", path.join(templatePath, "instance.ts")); + files.set(`instance.${ext}`, path.join(templatePath, `instance.${ext}`)); } if (templates.includes("module")) { @@ -589,25 +601,30 @@ async function copyPluginTemplate(pluginName, templates) { } if (templates.includes("ctl")) { - files.set("ctl.ts", path.join(templatePath, "ctl.ts")); + entryPoints.set("ctlEntrypoint", "dist/plugin/ctl"); + files.set(`ctl.${ext}`, path.join(templatePath, `ctl.${ext}`)); } - // Props that will be replaced in the template files, found with "// prop_name //" + // Properties that will control the replacements in the templates const props = { + controller: templates.includes("controller"), + host: templates.includes("host"), + instance: templates.includes("instance"), + module: templates.includes("module"), + ctl: templates.includes("ctl"), + web: templates.includes("web"), plugin_name: pluginName, prepare: prepare .join(" && "), entry_points: [...entryPoints.entries()] .map((entry) => `${entry[0]}: "${entry[1]}",`) .join("\n\t"), - dependencies: [...dependencies.entries()] - .map((entry) => `"${entry[0]}": "${entry[1]}"`) - .join(",\n\t\t"), dev_dependencies: [...devDependencies.entries()] .map((entry) => `"${entry[0]}": "${entry[1]}",`) .join("\n\t\t"), }; + // Write all the template files const writes = []; for (let [dst, src] of files) { writes.push(copyPluginTemplateFile(src, dst, props)); diff --git a/packages/create/templates/plugin-js/.gitignore b/packages/create/templates/plugin-js/.gitignore new file mode 100644 index 00000000..1a993212 --- /dev/null +++ b/packages/create/templates/plugin-js/.gitignore @@ -0,0 +1,3 @@ +dist/ +node_modules/ +package-lock.json diff --git a/packages/create/templates/plugin-js/.npmignore b/packages/create/templates/plugin-js/.npmignore new file mode 100644 index 00000000..ebd99907 --- /dev/null +++ b/packages/create/templates/plugin-js/.npmignore @@ -0,0 +1,2 @@ +webpack.config.js +dist/web/build diff --git a/packages/create/templates/plugin-js/controller.js b/packages/create/templates/plugin-js/controller.js new file mode 100644 index 00000000..a18eda3b --- /dev/null +++ b/packages/create/templates/plugin-js/controller.js @@ -0,0 +1,47 @@ +"use strict"; +const lib = require("@clusterio/lib"); +const { BaseControllerPlugin } = require("@clusterio/controller"); +const { PluginExampleEvent, PluginExampleRequest } = require("./messages"); + +class ControllerPlugin extends BaseControllerPlugin { + async init() { + this.controller.handle(PluginExampleEvent, this.handlePluginExampleEvent.bind(this)); + this.controller.handle(PluginExampleRequest, this.handlePluginExampleRequest.bind(this)); + } + + async onControllerConfigFieldChanged(field, curr, prev) { + this.logger.info(`controller::onControllerConfigFieldChanged ${field}`); + }// [instance] // + + async onInstanceConfigFieldChanged(instance, field, curr, prev) { + this.logger.info(`controller::onInstanceConfigFieldChanged ${instance.id} ${field}`); + }// [] // + + async onSaveData() { + this.logger.info("controller::onSaveData"); + } + + async onShutdown() { + this.logger.info("controller::onShutdown"); + } + + async onPlayerEvent(instance, event) { + this.logger.info(`controller::onPlayerEvent ${instance.id} ${JSON.stringify(event)}`); + } + + async handlePluginExampleEvent(event) { + this.logger.info(JSON.stringify(event)); + } + + async handlePluginExampleRequest(request) { + this.logger.info(JSON.stringify(request)); + return { + myResponseString: request.myString, + myResponseNumbers: request.myNumberArray, + }; + } +} + +module.exports = { + ControllerPlugin, +}; diff --git a/packages/create/templates/plugin-js/ctl.js b/packages/create/templates/plugin-js/ctl.js new file mode 100644 index 00000000..5140697c --- /dev/null +++ b/packages/create/templates/plugin-js/ctl.js @@ -0,0 +1,31 @@ +"use strict"; +const { BaseCtlPlugin } = require("@clusterio/ctl"); +const { CommandTree, Command } = require("@clusterio/lib"); +const { PluginExampleEvent, PluginExampleRequest } = require("./messages"); +/* eslint-disable no-console */ + +const pluginCommands = new CommandTree({ + name: "// plugin_name //", description: "The default description I forgot to change", +}); + +pluginCommands.add(new Command({ + definition: ["my-command ", "My command description that I really should change", (yargs) => { + yargs.positional("foo", { describe: "foo is foo!", type: "string" }); + }], + handler: async function(args, control) { + const response = await control.sendTo("controller", new PluginExampleRequest(args.foo, [1, 2, 3])); + console.log(response); + console.log(args); + }, +})); + +/* eslint-enable no-console */ +class CtlPlugin extends BaseCtlPlugin { + async addCommands(rootCommand) { + rootCommand.add(pluginCommands); + } +} + +module.exports = { + CtlPlugin, +}; diff --git a/packages/create/templates/plugin-js/host.js b/packages/create/templates/plugin-js/host.js new file mode 100644 index 00000000..2aed38b9 --- /dev/null +++ b/packages/create/templates/plugin-js/host.js @@ -0,0 +1,35 @@ +"use strict"; +const lib = require("@clusterio/lib"); +const { BaseHostPlugin } = require("@clusterio/host"); +const { PluginExampleEvent, PluginExampleRequest } = require("./messages"); + +class HostPlugin extends BaseHostPlugin { + async init() { + this.host.handle(PluginExampleEvent, this.handlePluginExampleEvent.bind(this)); + this.host.handle(PluginExampleRequest, this.handlePluginExampleRequest.bind(this)); + } + + async onHostConfigFieldChanged(field, curr, prev) { + this.logger.info(`host::onInstanceConfigFieldChanged ${field}`); + } + + async onShutdown() { + this.logger.info("host::onShutdown"); + } + + async handlePluginExampleEvent(event) { + this.logger.info(JSON.stringify(event)); + } + + async handlePluginExampleRequest(request) { + this.logger.info(JSON.stringify(request)); + return { + myResponseString: request.myString, + myResponseNumbers: request.myNumberArray, + }; + } +} + +module.exports = { + HostPlugin, +}; diff --git a/packages/create/templates/plugin-js/index.js b/packages/create/templates/plugin-js/index.js new file mode 100644 index 00000000..32507df4 --- /dev/null +++ b/packages/create/templates/plugin-js/index.js @@ -0,0 +1,65 @@ +"use strict"; +const lib = require("@clusterio/lib"); + +const { PluginExampleEvent, PluginExampleRequest } = require("./messages"); + +lib.definePermission({ + name: "// plugin_name //.example.permission.event", + title: "Example permission event", + description: "My plugin's example permission that I forgot to remove", +}); + +lib.definePermission({ + name: "// plugin_name //.example.permission.request", + title: "Example permission request", + description: "My plugin's example permission that I forgot to remove", +});// [web] // + +lib.definePermission({ + name: "// plugin_name //.page.view", + title: "Example page view permission", + description: "My plugin's example page permission that I forgot to remove", +});// [] // + +const plugin = { + name: "// plugin_name //", + title: "// plugin_name //", + description: "I didn't update my description", + // entry_points // + // [controller] // + controlConfigFields: { + "// plugin_name //.myControllerField": { + title: "My Controller Field", + description: "This should be removed", + type: "string", + initialValue: "Remove Me", + }, + },// [] //// [host] // + hostConfigFields: { + "// plugin_name //.myHostField": { + title: "My Host Field", + description: "This should be removed", + type: "string", + initialValue: "Remove Me", + }, + },// [] //// [instance] // + instanceConfigFields: { + "// plugin_name //.myInstanceField": { + title: "My Instance Field", + description: "This should be removed", + type: "string", + initialValue: "Remove Me", + }, + },// [] // + + messages: [ + PluginExampleEvent, + PluginExampleRequest, + ], +}; + +module.exports = { + plugin, + PluginExampleEvent, + PluginExampleRequest, +}; diff --git a/packages/create/templates/plugin-js/instance.js b/packages/create/templates/plugin-js/instance.js new file mode 100644 index 00000000..2a7020ef --- /dev/null +++ b/packages/create/templates/plugin-js/instance.js @@ -0,0 +1,43 @@ +"use strict"; +const lib = require("@clusterio/lib"); +const { BaseInstancePlugin } = require("@clusterio/host"); +const { PluginExampleEvent, PluginExampleRequest } = require("./messages"); + +class InstancePlugin extends BaseInstancePlugin { + async init() { + this.instance.handle(PluginExampleEvent, this.handlePluginExampleEvent.bind(this)); + this.instance.handle(PluginExampleRequest, this.handlePluginExampleRequest.bind(this)); + } + + async onInstanceConfigFieldChanged(field, curr, prev) { + this.logger.info(`instance::onInstanceConfigFieldChanged ${field}`); + } + + async onStart() { + this.logger.info("instance::onStart"); + } + + async onStop() { + this.logger.info("instance::onStop"); + } + + async onPlayerEvent(event) { + this.logger.info(`onPlayerEvent::onPlayerEvent ${JSON.stringify(event)}`); + } + + async handlePluginExampleEvent(event) { + this.logger.info(JSON.stringify(event)); + } + + async handlePluginExampleRequest(request) { + this.logger.info(JSON.stringify(request)); + return { + myResponseString: request.myString, + myResponseNumbers: request.myNumberArray, + }; + } +} + +module.exports = { + InstancePlugin, +}; diff --git a/packages/create/templates/plugin-js/messages.js b/packages/create/templates/plugin-js/messages.js new file mode 100644 index 00000000..126934e5 --- /dev/null +++ b/packages/create/templates/plugin-js/messages.js @@ -0,0 +1,57 @@ +"use strict"; +const { plainJson, jsonArray, JsonBoolean, JsonNumber, JsonString, StringEnum } = require("@clusterio/lib"); +const { Type, Static } = require("@sinclair/typebox"); + +class PluginExampleEvent { + static type = "event"; + static src = ["host", "control"]; + static dst = ["controller", "host", "instance"]; + static plugin = "// plugin_name //"; + static permission = "// plugin_name //.example.permission.event"; + + constructor(myString, myNumberArray) { + this.myString = myString; + this.myNumberArray = myNumberArray; + } + + static jsonSchema = Type.Object({ + "myString": Type.String(), + "myNumberArray": Type.Array(Type.Number()), + }); + + static fromJson(json) { + return new PluginExampleEvent(json.myString, json.myNumberArray); + } +} + +class PluginExampleRequest { + static type = "request"; + static src = ["host", "control"]; + static dst = ["controller", "host", "instance"]; + static plugin = "// plugin_name //"; + static permission = "// plugin_name //.example.permission.request"; + + constructor(myString, myNumberArray) { + this.myString = myString; + this.myNumberArray = myNumberArray; + } + + static jsonSchema = Type.Object({ + "myString": Type.String(), + "myNumberArray": Type.Array(Type.Number()), + }); + + static fromJson(json) { + return new PluginExampleEvent(json.myString, json.myNumberArray); + } + + static Response = plainJson(Type.Object({ + "myResponseString": Type.String(), + "myResponseNumbers": Type.Array(Type.Number()), + })); +} + +module.exports = { + PluginExampleEvent, + PluginExampleRequest, +}; diff --git a/packages/create/templates/plugin-js/module/control.lua b/packages/create/templates/plugin-js/module/control.lua new file mode 100644 index 00000000..ab32acd6 --- /dev/null +++ b/packages/create/templates/plugin-js/module/control.lua @@ -0,0 +1,24 @@ +local clusterio_api = require("modules/clusterio/api") + +local MyModule = { + events = {}, + on_nth_tick = {}, +} + +function MyModule.foo() + game.print("foo") +end + +MyModule.events[clusterio_api.events.on_server_startup] = function(event) + game.print(game.table_to_json(event)) +end + +MyModule.events[defines.events.on_player_crafted_item] = function(event) + game.print(game.table_to_json(event)) +end + +MyModule.on_nth_tick[300] = function() + game.print(game.tick) +end + +return MyModule diff --git a/packages/create/templates/plugin-js/module/module.json b/packages/create/templates/plugin-js/module/module.json new file mode 100644 index 00000000..1edcac37 --- /dev/null +++ b/packages/create/templates/plugin-js/module/module.json @@ -0,0 +1,12 @@ +{ + "name": "// plugin_name //", + "load": [ + "control.lua" + ], + "require": [ + + ], + "dependencies": [ + + ] +} diff --git a/packages/create/templates/plugin-js/module/module_exports.lua b/packages/create/templates/plugin-js/module/module_exports.lua new file mode 100644 index 00000000..cc0c5632 --- /dev/null +++ b/packages/create/templates/plugin-js/module/module_exports.lua @@ -0,0 +1,2 @@ + +return require("./control") diff --git a/packages/create/templates/plugin-js/package.json b/packages/create/templates/plugin-js/package.json new file mode 100644 index 00000000..627f1431 --- /dev/null +++ b/packages/create/templates/plugin-js/package.json @@ -0,0 +1,29 @@ +{ + "name": "// plugin_name //", + "version": "0.1.0", + "description": "", + "main": "index.js", + "scripts": { + "prepare": "// prepare //" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@clusterio/lib": "^2.0.0-alpha.14" + }, + "devDependencies": { + // dev_dependencies // + "@clusterio/lib": "^2.0.0-alpha.14" + }, + "dependencies": { + "@sinclair/typebox": "^0.30.4" + }, + "publishConfig": { + "access": "public" + }, + "keywords": [ + "clusterio", + "factorio" + ] +} diff --git a/packages/create/templates/plugin-js/web/no_plugin.jsx b/packages/create/templates/plugin-js/web/no_plugin.jsx new file mode 100644 index 00000000..e69de29b diff --git a/packages/create/templates/plugin-js/web/plugin.jsx b/packages/create/templates/plugin-js/web/plugin.jsx new file mode 100644 index 00000000..dd0c2acd --- /dev/null +++ b/packages/create/templates/plugin-js/web/plugin.jsx @@ -0,0 +1,49 @@ +const { useContext, useEffect, useState } = require("react"); +// const { } = require("antd"); + +const { + BaseWebPlugin, PageLayout, Control, ControlContext, notifyErrorHandler, +} = require("@clusterio/web_ui"); + +const lib = require("@clusterio/lib"); +const { PluginExampleEvent, PluginExampleRequest } = require("../messages"); + +function MyTemplatePage() { + let control = useContext(ControlContext); + + return +

// plugin_name //

+
; +} + +class WebPlugin extends BaseWebPlugin { + async init() { + this.pages = [ + { + path: "/// plugin_name //", + sidebarName: "// plugin_name //", + permission: "// plugin_name //.page.view", + content: , + }, + ]; + + this.control.handle(PluginExampleEvent, this.handlePluginExampleEvent.bind(this)); + this.control.handle(PluginExampleRequest, this.handlePluginExampleRequest.bind(this)); + } + + async handlePluginExampleEvent(event) { + this.logger.info(JSON.stringify(event)); + } + + async handlePluginExampleRequest(request) { + this.logger.info(JSON.stringify(request)); + return { + myResponseString: request.myString, + myResponseNumbers: request.myNumberArray, + }; + } +} + +module.exports = { + WebPlugin, +} diff --git a/packages/create/templates/plugin-js/webpack.config.js b/packages/create/templates/plugin-js/webpack.config.js new file mode 100644 index 00000000..3d43cfbd --- /dev/null +++ b/packages/create/templates/plugin-js/webpack.config.js @@ -0,0 +1,28 @@ +"use strict"; +const path = require("path"); +const webpack = require("webpack"); +const { merge } = require("webpack-merge"); + +const common = require("@clusterio/web_ui/webpack.common"); + +module.exports = (env = {}) => merge(common(env), { + context: __dirname, + entry: "./web/index.jsx", + output: { + path: path.resolve(__dirname, "dist", "web"), + }, + plugins: [ + new webpack.container.ModuleFederationPlugin({ + name: "// plugin_name //", + library: { type: "var", name: "plugin_// plugin_name //" }, + exposes: { + "./": "./info.js", + "./package.json": "./package.json", + }, + shared: { + "@clusterio/lib": { import: false }, + "@clusterio/web_ui": { import: false }, + }, + }), + ], +}); diff --git a/packages/create/templates/plugin-ts/.gitignore b/packages/create/templates/plugin-ts/.gitignore index 1eae0cf6..1a993212 100644 --- a/packages/create/templates/plugin-ts/.gitignore +++ b/packages/create/templates/plugin-ts/.gitignore @@ -1,2 +1,3 @@ dist/ node_modules/ +package-lock.json diff --git a/packages/create/templates/plugin-ts/controller.ts b/packages/create/templates/plugin-ts/controller.ts index ee6d56b7..e24dfca5 100644 --- a/packages/create/templates/plugin-ts/controller.ts +++ b/packages/create/templates/plugin-ts/controller.ts @@ -10,11 +10,11 @@ export class ControllerPlugin extends BaseControllerPlugin { async onControllerConfigFieldChanged(field: string, curr: unknown, prev: unknown) { this.logger.info(`controller::onControllerConfigFieldChanged ${field}`); - } + }// [instance] // async onInstanceConfigFieldChanged(instance: InstanceInfo, field: string, curr: unknown, prev: unknown) { this.logger.info(`controller::onInstanceConfigFieldChanged ${instance.id} ${field}`); - } + }// [] // async onSaveData() { this.logger.info("controller::onSaveData"); diff --git a/packages/create/templates/plugin-ts/ctl.ts b/packages/create/templates/plugin-ts/ctl.ts index adbc0d05..db6b9c1b 100644 --- a/packages/create/templates/plugin-ts/ctl.ts +++ b/packages/create/templates/plugin-ts/ctl.ts @@ -13,7 +13,8 @@ pluginCommands.add(new Command({ yargs.positional("foo", { describe: "foo is foo!", type: "string" }); }], handler: async function(args: { foo: string }, control: Control) { - await control.sendTo("controller", new PluginExampleEvent(args.foo, [1, 2, 3])); + const response = await control.sendTo("controller", new PluginExampleRequest(args.foo, [1, 2, 3])); + console.log(response); console.log(args); }, })); diff --git a/packages/create/templates/plugin-ts/index.ts b/packages/create/templates/plugin-ts/index.ts index 2ecceb6a..48371429 100644 --- a/packages/create/templates/plugin-ts/index.ts +++ b/packages/create/templates/plugin-ts/index.ts @@ -12,13 +12,56 @@ lib.definePermission({ name: "// plugin_name //.example.permission.request", title: "Example permission request", description: "My plugin's example permission that I forgot to remove", -}); +});// [web] // + +lib.definePermission({ + name: "// plugin_name //.page.view", + title: "Example page view permission", + description: "My plugin's example page permission that I forgot to remove", +});// [] // + +declare module "@clusterio/lib" {// [controller] // + export interface ControllerConfigFields { + "// plugin_name //.myControllerField": string; + }// [] //// [host] // + export interface HostConfigFields { + "// plugin_name //.myHostField": string; + }// [] //// [instance] // + export interface InstanceConfigFields { + "// plugin_name //.myInstanceField": string; + }// [] // +} export const plugin: lib.PluginDeclaration = { name: "// plugin_name //", title: "// plugin_name //", description: "I didn't update my description", // entry_points // + // [controller] // + controlConfigFields: { + "// plugin_name //.myControllerField": { + title: "My Controller Field", + description: "This should be removed", + type: "string", + initialValue: "Remove Me", + }, + },// [] //// [host] // + hostConfigFields: { + "// plugin_name //.myHostField": { + title: "My Host Field", + description: "This should be removed", + type: "string", + initialValue: "Remove Me", + }, + },// [] //// [instance] // + instanceConfigFields: { + "// plugin_name //.myInstanceField": { + title: "My Instance Field", + description: "This should be removed", + type: "string", + initialValue: "Remove Me", + }, + },// [] // messages: [ PluginExampleEvent, diff --git a/packages/create/templates/plugin-ts/messages.ts b/packages/create/templates/plugin-ts/messages.ts index d357e31e..2dec80e6 100644 --- a/packages/create/templates/plugin-ts/messages.ts +++ b/packages/create/templates/plugin-ts/messages.ts @@ -5,7 +5,7 @@ export class PluginExampleEvent { declare ["constructor"]: typeof PluginExampleEvent; static type = "event" as const; static src = ["host", "control"] as const; - static dst = ["controller", "host"] as const; + static dst = ["controller", "host", "instance"] as const; static plugin = "// plugin_name //" as const; static permission = "// plugin_name //.example.permission.event"; @@ -29,7 +29,7 @@ export class PluginExampleRequest { declare ["constructor"]: typeof PluginExampleRequest; static type = "request" as const; static src = ["host", "control"] as const; - static dst = ["controller", "host"] as const; + static dst = ["controller", "host", "instance"] as const; static plugin = "// plugin_name //" as const; static permission = "// plugin_name //.example.permission.request"; diff --git a/packages/create/templates/plugin-ts/package.json b/packages/create/templates/plugin-ts/package.json index 9f542eb8..f1a25265 100644 --- a/packages/create/templates/plugin-ts/package.json +++ b/packages/create/templates/plugin-ts/package.json @@ -16,10 +16,14 @@ // dev_dependencies // "@clusterio/lib": "^2.0.0-alpha.14" }, + "dependencies": { + "@sinclair/typebox": "^0.30.4" + }, "publishConfig": { "access": "public" }, - "dependencies": { - // dependencies // - } + "keywords": [ + "clusterio", + "factorio" + ] } diff --git a/packages/create/templates/plugin-ts/webpack.config.js b/packages/create/templates/plugin-ts/webpack.config.js index 85da4267..81e247eb 100644 --- a/packages/create/templates/plugin-ts/webpack.config.js +++ b/packages/create/templates/plugin-ts/webpack.config.js @@ -14,7 +14,7 @@ module.exports = (env = {}) => merge(common(env), { plugins: [ new webpack.container.ModuleFederationPlugin({ name: "// plugin_name //", - library: { type: "var", name: "plugin___plugin_name__" }, + library: { type: "var", name: "plugin_// plugin_name //" }, exposes: { "./": "./index.ts", "./package.json": "./package.json",