omegga 1.18.1 → 1.19.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -3
- package/dist/cli/auth.js +18 -27
- package/dist/cli/auth.js.map +1 -1
- package/dist/cli/plugin.js +7 -7
- package/dist/cli/plugin.js.map +1 -1
- package/dist/cli/terminal.js +15 -0
- package/dist/cli/terminal.js.map +1 -1
- package/dist/config/index.js +40 -1
- package/dist/config/index.js.map +1 -1
- package/dist/config/types.js +23 -0
- package/dist/config/types.js.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/logger.js +59 -3
- package/dist/logger.js.map +1 -1
- package/dist/main.js +8 -0
- package/dist/main.js.map +1 -1
- package/dist/omegga/plugin/plugin_jsonrpc_stdio.js +9 -1
- package/dist/omegga/plugin/plugin_jsonrpc_stdio.js.map +1 -1
- package/dist/omegga/plugin/plugin_node_safe.js +3 -0
- package/dist/omegga/plugin/plugin_node_safe.js.map +1 -1
- package/dist/softconfig.js +14 -0
- package/dist/softconfig.js.map +1 -1
- package/dist/util/logfile.js +188 -0
- package/dist/util/logfile.js.map +1 -0
- package/dist/webserver/backend/index.js +4 -2
- package/dist/webserver/backend/index.js.map +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -140,7 +140,7 @@ pages under `docs/api` are generated from the JSDoc in `src/`; run
|
|
|
140
140
|
1. **Bump**: Bump `version` in `package.json` and sync the lockfile with
|
|
141
141
|
`npm i --package-lock-only`.
|
|
142
142
|
2. **Changelog**: Move the `## Latest` entries in `CHANGELOG.md` under a
|
|
143
|
-
`## <version> - <date>` heading.
|
|
143
|
+
`## <version> - <date>` heading. Preview with `just notes`
|
|
144
144
|
3. **Pterodactyl**: Point the pinned image in `docker/pterodactyl/egg-omegga.json` at the new
|
|
145
145
|
`<major>.<minor>`. Releases only move `latest`, `<major>`, and
|
|
146
146
|
`<major>.<minor>`, so a pin left on the previous minor is frozen on an
|
|
@@ -148,5 +148,11 @@ pages under `docs/api` are generated from the JSDoc in `src/`; run
|
|
|
148
148
|
panel.
|
|
149
149
|
4. **Linters**: `just check`
|
|
150
150
|
5. **Commit**: Ensure everything is pushed
|
|
151
|
-
6. **
|
|
152
|
-
7. **
|
|
151
|
+
6. **Tag**: `just tag` pushes `v<version>` and builds the ghcr image and npm releases
|
|
152
|
+
7. **Approve the npm release**: A developer with npm access must do the following:
|
|
153
|
+
|
|
154
|
+
```sh
|
|
155
|
+
npm stage list omegga # find the stage-id
|
|
156
|
+
npm stage download <id> # optional, inspect the tarball before approving
|
|
157
|
+
npm stage approve <id> # prompts for an OTP, then publishes
|
|
158
|
+
```
|
package/dist/cli/auth.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
|
|
3
|
+
const logger = require("../logger.js");
|
|
3
4
|
const softconfig = require("../softconfig.js");
|
|
4
5
|
const auth = require("../omegga/auth.js");
|
|
5
6
|
const env = require("../util/env.js");
|
|
@@ -10,12 +11,10 @@ const path = require("node:path");
|
|
|
10
11
|
const prompts = require("prompts");
|
|
11
12
|
const AUTH_PATH = path.join(softconfig.default.CONFIG_HOME, softconfig.default.CONFIG_AUTH_DIR);
|
|
12
13
|
function failNonInteractive() {
|
|
13
|
-
|
|
14
|
-
"!>".red,
|
|
14
|
+
logger.default.errorp(
|
|
15
15
|
"No stored auth files and no hosting token, and there is no terminal to prompt on"
|
|
16
16
|
);
|
|
17
|
-
|
|
18
|
-
"!>".red,
|
|
17
|
+
logger.default.errorp(
|
|
19
18
|
"Generate a hosting token at https://brickadia.com/account/tokens, then set",
|
|
20
19
|
"BRICKADIA_TOKEN".yellow,
|
|
21
20
|
"or",
|
|
@@ -25,12 +24,7 @@ function failNonInteractive() {
|
|
|
25
24
|
return false;
|
|
26
25
|
}
|
|
27
26
|
async function credentialPrompt() {
|
|
28
|
-
|
|
29
|
-
">>".green,
|
|
30
|
-
"Enter",
|
|
31
|
-
"Brickadia".green.underline,
|
|
32
|
-
"credentials (not stored)"
|
|
33
|
-
);
|
|
27
|
+
logger.default.logp("Enter", "Brickadia".green.underline, "credentials (not stored)");
|
|
34
28
|
const response = await prompts([
|
|
35
29
|
{
|
|
36
30
|
type: "text",
|
|
@@ -68,7 +62,7 @@ async function authFromPrompt({
|
|
|
68
62
|
]
|
|
69
63
|
});
|
|
70
64
|
if (!authType) {
|
|
71
|
-
|
|
65
|
+
logger.default.errorp("No authentication method selected");
|
|
72
66
|
return false;
|
|
73
67
|
}
|
|
74
68
|
if (authType === "token") {
|
|
@@ -79,23 +73,20 @@ async function authFromPrompt({
|
|
|
79
73
|
validate: (value) => value ? true : "Token is required"
|
|
80
74
|
});
|
|
81
75
|
if (!token) {
|
|
82
|
-
|
|
76
|
+
logger.default.errorp("Hosting token is required");
|
|
83
77
|
return false;
|
|
84
78
|
}
|
|
85
79
|
try {
|
|
86
|
-
|
|
80
|
+
logger.default.logp("Storing hosting token...");
|
|
87
81
|
fs.writeFileSync(softconfig.default.GLOBAL_TOKEN, token.trim());
|
|
88
82
|
} catch (err) {
|
|
89
|
-
|
|
83
|
+
logger.default.errorp("Error writing hosting token to config\n", err);
|
|
90
84
|
return false;
|
|
91
85
|
}
|
|
92
86
|
return true;
|
|
93
87
|
}
|
|
94
88
|
if (isSteam) {
|
|
95
|
-
|
|
96
|
-
"!>".red,
|
|
97
|
-
"Launching with steam requires a hosting token right now."
|
|
98
|
-
);
|
|
89
|
+
logger.default.errorp("Launching with steam requires a hosting token right now.");
|
|
99
90
|
return false;
|
|
100
91
|
}
|
|
101
92
|
}
|
|
@@ -104,17 +95,17 @@ async function authFromPrompt({
|
|
|
104
95
|
try {
|
|
105
96
|
[email, password] = await credentialPrompt();
|
|
106
97
|
} catch (err) {
|
|
107
|
-
|
|
98
|
+
logger.default.errorp("Error prompting credentials\n", err);
|
|
108
99
|
return false;
|
|
109
100
|
}
|
|
110
101
|
}
|
|
111
102
|
if (!email || !password) {
|
|
112
|
-
|
|
103
|
+
logger.default.errorp("Email and password are required");
|
|
113
104
|
return false;
|
|
114
105
|
}
|
|
115
|
-
|
|
106
|
+
logger.default.logp("Generating auth tokens...");
|
|
116
107
|
const timeout = setTimeout(() => {
|
|
117
|
-
|
|
108
|
+
logger.default.logp("Probably also installing the game...");
|
|
118
109
|
}, 1e4);
|
|
119
110
|
try {
|
|
120
111
|
files = await auth.genAuthFiles(email, password, {
|
|
@@ -127,15 +118,15 @@ async function authFromPrompt({
|
|
|
127
118
|
clearTimeout(timeout);
|
|
128
119
|
} catch (err) {
|
|
129
120
|
clearTimeout(timeout);
|
|
130
|
-
|
|
121
|
+
logger.default.errorp("Error generating tokens:", err);
|
|
131
122
|
return false;
|
|
132
123
|
}
|
|
133
124
|
if (!files) {
|
|
134
|
-
|
|
125
|
+
logger.default.errorp("Authentication Failed");
|
|
135
126
|
return;
|
|
136
127
|
}
|
|
137
128
|
try {
|
|
138
|
-
|
|
129
|
+
logger.default.logp("Storing auth tokens...");
|
|
139
130
|
const authPath = path.join(
|
|
140
131
|
softconfig.default.CONFIG_HOME,
|
|
141
132
|
savedDir && savedDir !== softconfig.default.CONFIG_SAVED_DIR ? savedDir : "",
|
|
@@ -144,10 +135,10 @@ async function authFromPrompt({
|
|
|
144
135
|
file.mkdir(authPath);
|
|
145
136
|
auth.writeAuthFiles(authPath, files);
|
|
146
137
|
} catch (err) {
|
|
147
|
-
|
|
138
|
+
logger.default.errorp("Error writing tokens to config\n", err);
|
|
148
139
|
return false;
|
|
149
140
|
}
|
|
150
|
-
|
|
141
|
+
logger.default.logp("Auth tokens successfully generated!");
|
|
151
142
|
return true;
|
|
152
143
|
}
|
|
153
144
|
function authExists(dir) {
|
package/dist/cli/auth.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sources":["../../src/cli/auth.ts"],"sourcesContent":["import soft from '@/softconfig';\nimport { genAuthFiles, writeAuthFiles } from '@omegga/auth';\nimport { isNonInteractive } from '@util/env';\nimport * as file from '@util/file';\nimport 'colors';\nimport fs, { existsSync } from 'node:fs';\nimport path from 'node:path';\nimport prompts from 'prompts';\n\nexport const AUTH_PATH = path.join(soft.CONFIG_HOME, soft.CONFIG_AUTH_DIR);\n\n/**\n * Refuse to authenticate rather than opening a prompt nothing can answer.\n *\n * Reaching a prompt on such a host is worse than failing: omegga blocks\n * before it logs anything a supervisor recognises as a start, so the failure\n * shows up as a startup timeout with no cause in the log.\n */\nfunction failNonInteractive() {\n
|
|
1
|
+
{"version":3,"file":"auth.js","sources":["../../src/cli/auth.ts"],"sourcesContent":["import Logger from '@/logger';\nimport soft from '@/softconfig';\nimport { genAuthFiles, writeAuthFiles } from '@omegga/auth';\nimport { isNonInteractive } from '@util/env';\nimport * as file from '@util/file';\nimport 'colors';\nimport fs, { existsSync } from 'node:fs';\nimport path from 'node:path';\nimport prompts from 'prompts';\n\nexport const AUTH_PATH = path.join(soft.CONFIG_HOME, soft.CONFIG_AUTH_DIR);\n\n/**\n * Refuse to authenticate rather than opening a prompt nothing can answer.\n *\n * Reaching a prompt on such a host is worse than failing: omegga blocks\n * before it logs anything a supervisor recognises as a start, so the failure\n * shows up as a startup timeout with no cause in the log.\n */\nfunction failNonInteractive() {\n Logger.errorp(\n 'No stored auth files and no hosting token, and there is no terminal to prompt on',\n );\n Logger.errorp(\n 'Generate a hosting token at https://brickadia.com/account/tokens, then set',\n 'BRICKADIA_TOKEN'.yellow,\n 'or',\n 'credentials.token'.yellow,\n 'in omegga-config.yml',\n );\n return false;\n}\n\n// async function to prompt for credentials\nasync function credentialPrompt() {\n Logger.logp('Enter', 'Brickadia'.green.underline, 'credentials (not stored)');\n\n const response = await prompts([\n {\n type: 'text',\n name: 'email',\n message: 'Email',\n },\n {\n type: 'password',\n name: 'password',\n message: 'Password',\n },\n ]);\n\n return [response.email, response.password];\n}\n\nasync function authFromPrompt({\n email,\n password,\n debug = false,\n isSteam,\n branch,\n authDir,\n savedDir,\n launchArgs,\n}: {\n email?: string | null;\n password?: string | null;\n debug?: boolean;\n isSteam?: boolean;\n branch?: string;\n authDir?: string;\n savedDir?: string;\n launchArgs?: string;\n}) {\n let files: Record<string, Buffer> | null;\n\n if (isSteam || !email || !password) {\n if (isNonInteractive()) return failNonInteractive();\n\n // Prompt user to pick to select username/password or Auth Token\n const { authType } = await prompts({\n type: 'select',\n name: 'authType',\n message: 'Select authentication method',\n choices: [\n { title: 'Hosting Token', value: 'token' },\n { title: 'Username/Password', value: 'credentials' },\n ],\n });\n\n if (!authType) {\n Logger.errorp('No authentication method selected');\n return false;\n }\n\n if (authType === 'token') {\n // Prompt for hosting token\n const { token } = await prompts({\n type: 'password',\n name: 'token',\n message:\n 'Paste your server hosting token (generate one at https://brickadia.com/account/tokens)',\n validate: value => (value ? true : 'Token is required'),\n });\n\n if (!token) {\n Logger.errorp('Hosting token is required');\n return false;\n }\n\n // Write to global token file\n try {\n Logger.logp('Storing hosting token...');\n fs.writeFileSync(soft.GLOBAL_TOKEN, token.trim());\n } catch (err) {\n Logger.errorp('Error writing hosting token to config\\n', err);\n return false;\n }\n\n return true;\n }\n\n if (isSteam) {\n Logger.errorp('Launching with steam requires a hosting token right now.');\n return false;\n }\n\n // Non-steam password auth is handled below\n }\n\n if (!email || !password || !isSteam) {\n if (isNonInteractive()) return failNonInteractive();\n\n // prompt for user credentials\n try {\n [email, password] = await credentialPrompt();\n } catch (err) {\n Logger.errorp('Error prompting credentials\\n', err);\n return false;\n }\n }\n\n if (!email || !password) {\n Logger.errorp('Email and password are required');\n return false;\n }\n\n // generate auth tokens\n Logger.logp('Generating auth tokens...');\n const timeout = setTimeout(() => {\n Logger.logp('Probably also installing the game...');\n }, 10000);\n try {\n files = await genAuthFiles(email, password, {\n debug,\n branch,\n authDir,\n savedDir,\n launchArgs,\n });\n clearTimeout(timeout);\n } catch (err) {\n clearTimeout(timeout);\n Logger.errorp('Error generating tokens:', err);\n return false;\n }\n\n if (!files) {\n Logger.errorp('Authentication Failed');\n return;\n }\n\n // save the tokens to the config path (will be copied when omegga starts)\n try {\n Logger.logp('Storing auth tokens...');\n const authPath = path.join(\n soft.CONFIG_HOME,\n savedDir && savedDir !== soft.CONFIG_SAVED_DIR ? savedDir : '',\n authDir ?? soft.CONFIG_AUTH_DIR,\n );\n file.mkdir(authPath);\n writeAuthFiles(authPath, files);\n } catch (err) {\n Logger.errorp('Error writing tokens to config\\n', err);\n return false;\n }\n\n Logger.logp('Auth tokens successfully generated!');\n return true;\n}\n\n// check if auth files exist\nfunction authExists(dir?: string) {\n return soft.BRICKADIA_AUTH_FILES.every(f =>\n fs.existsSync(path.join(dir ?? AUTH_PATH, f)),\n );\n}\n\n// delete auth files stored in config\n// delete auth files stored in config\nfunction deleteAuthFiles(dir?: string) {\n const isConfigHome = dir && dir.startsWith(soft.CONFIG_HOME);\n // will not delete files outside of the config home\n if (dir && !isConfigHome) return;\n file.rmdir(dir ?? AUTH_PATH);\n\n // Remove the global auth token\n if (existsSync(soft.GLOBAL_TOKEN)) {\n fs.unlinkSync(soft.GLOBAL_TOKEN);\n }\n}\n\nexport function getGlobalToken() {\n if (!fs.existsSync(soft.GLOBAL_TOKEN)) return null;\n return fs.readFileSync(soft.GLOBAL_TOKEN, 'utf-8').trim();\n}\n\nexport const prompt = authFromPrompt;\nexport const exists = authExists;\nexport const clean = deleteAuthFiles;\n\nexport default {\n AUTH_PATH,\n prompt,\n exists,\n clean,\n getGlobalToken,\n};\n"],"names":["soft","Logger","isNonInteractive","genAuthFiles","file.mkdir","writeAuthFiles","file.rmdir","existsSync"],"mappings":"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"}
|
package/dist/cli/plugin.js
CHANGED
|
@@ -64,7 +64,7 @@ const plg = (plugin2, ...args) => {
|
|
|
64
64
|
needsNL = false;
|
|
65
65
|
console.log();
|
|
66
66
|
}
|
|
67
|
-
|
|
67
|
+
logger.default.log(plugin2.name, ">>".green, ...args);
|
|
68
68
|
};
|
|
69
69
|
const plgLog = (plugin2, ...args) => {
|
|
70
70
|
if (logger.default.VERBOSE) plg(plugin2, ...args);
|
|
@@ -80,28 +80,28 @@ const plgWarn = (plugin2, ...args) => {
|
|
|
80
80
|
needsNL = false;
|
|
81
81
|
console.warn();
|
|
82
82
|
}
|
|
83
|
-
|
|
83
|
+
logger.default.warn(plugin2.name, "W>".yellow, ...args);
|
|
84
84
|
};
|
|
85
85
|
const plgErr = (plugin2, ...args) => {
|
|
86
86
|
if (needsNL) {
|
|
87
87
|
needsNL = false;
|
|
88
88
|
console.error();
|
|
89
89
|
}
|
|
90
|
-
|
|
90
|
+
logger.default.error(plugin2.name, "!>".red, ...args);
|
|
91
91
|
};
|
|
92
92
|
const err = (...args) => {
|
|
93
93
|
if (needsNL) {
|
|
94
94
|
needsNL = false;
|
|
95
95
|
console.error();
|
|
96
96
|
}
|
|
97
|
-
|
|
97
|
+
logger.default.errorp(...args);
|
|
98
98
|
};
|
|
99
99
|
const log = (...args) => {
|
|
100
100
|
if (needsNL) {
|
|
101
101
|
needsNL = false;
|
|
102
102
|
console.log();
|
|
103
103
|
}
|
|
104
|
-
|
|
104
|
+
logger.default.logp(...args);
|
|
105
105
|
};
|
|
106
106
|
const verboseLog = (...args) => {
|
|
107
107
|
if (!logger.default.VERBOSE) return;
|
|
@@ -109,7 +109,7 @@ const verboseLog = (...args) => {
|
|
|
109
109
|
needsNL = false;
|
|
110
110
|
console.log();
|
|
111
111
|
}
|
|
112
|
-
|
|
112
|
+
logger.default.verbose(...args);
|
|
113
113
|
};
|
|
114
114
|
function checkPlugin(omeggaPath, plugin2) {
|
|
115
115
|
const pluginPath = path.join(omeggaPath, softconfig.default.PLUGIN_PATH, plugin2.name);
|
|
@@ -176,7 +176,7 @@ async function install(plugins, _options) {
|
|
|
176
176
|
try {
|
|
177
177
|
name = path.parse(transformed.url).name.replace(/^omegga-/, "");
|
|
178
178
|
} catch {
|
|
179
|
-
|
|
179
|
+
err("Error parsing name from url", transformed.url);
|
|
180
180
|
break;
|
|
181
181
|
}
|
|
182
182
|
}
|
package/dist/cli/plugin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.js","sources":["../../src/cli/plugin.ts"],"sourcesContent":["import Logger from '@/logger';\nimport soft from '@/softconfig';\nimport * as config from '@config';\nimport { PluginLoader } from '@omegga/plugin';\nimport { getPluginGit } from '@cli/plugin/git';\nimport { exec as execNonPromise } from 'node:child_process';\nimport 'colors';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport prompts from 'prompts';\nimport semver from 'semver';\nimport { promisify } from 'node:util';\nimport { VERSION } from '@/version';\n\nconst exec = promisify(execNonPromise);\n\nconst MAIN_BRANCHES = ['master', 'main'];\n\n// get the working directory for omegga\nfunction getWorkDir() {\n // default working directory is the one specified in config\n let workDir = config.store.get('defaultOmegga');\n verboseLog('Using working directory', workDir.yellow);\n\n // if there's a config in the current directory, use that one instead\n if (config.find('.')) workDir = '.';\n\n const confFile = config.find(workDir);\n\n return confFile\n ? path.resolve(process.cwd(), path.dirname(confFile))\n : undefined;\n}\n\ninterface IPlugin {\n name?: string;\n type: string | 'raw';\n url: string;\n}\n\ninterface IInstalledPlugin {\n name: string;\n path?: string;\n}\n\ninterface ITransformer {\n pattern: RegExp;\n fn(match: Record<string, string>): IPlugin;\n}\n\nconst PLUGIN_TYPES = ['safe', 'safe-ts', 'unsafe', 'rust', 'rpc'];\ntype PluginType = (typeof PLUGIN_TYPES)[number];\n\n// plugin url transformers\nconst transformers: ITransformer[] = [\n {\n // github transformer\n pattern: /^gh:(?<owner>[^/]+)\\/(?<repo>[^/]+)$/,\n fn: ({ owner, repo }) => ({\n type: 'short',\n name: repo,\n url: `https://github.com/${owner}/omegga-${repo}`,\n }),\n },\n {\n // gitlab transformer\n pattern: /^gl:(?<owner>[^/]+)\\/(?<repo>[^/]+)$/,\n fn: ({ owner, repo }) => ({\n type: 'short',\n name: repo,\n url: `https://gitlab.com/${owner}/omegga-${repo}`,\n }),\n },\n];\n\n// convert a shortened url into a full length one\nconst transformUrl = (url: string): IPlugin => {\n for (const t of transformers) {\n const match = url.match(t.pattern);\n if (match?.groups) return t.fn(match.groups);\n }\n return { type: 'raw', url };\n};\n\nlet needsNL = false;\n\n// rewrite a console line\nconst rewriteLine = (...args: unknown[]) => {\n // stdout has no cursor controls when omegga is piped or run in a container\n if (process.stdout.isTTY) {\n process.stdout.clearLine(0);\n process.stdout.cursorTo(0);\n }\n process.stdout.write(args.join(' '));\n needsNL = true;\n};\n\n// logging helper functions\nconst plg = (plugin: IPlugin | IInstalledPlugin, ...args: unknown[]) => {\n if (needsNL) {\n needsNL = false;\n console.log();\n }\n console.log(plugin.name, '>>'.green, ...args);\n};\nconst plgLog = (plugin: IPlugin | IInstalledPlugin, ...args: unknown[]) => {\n if (Logger.VERBOSE) plg(plugin, ...args);\n else\n rewriteLine(\n plugin.name ?? ('url' in plugin ? plugin.url : ''),\n '>>'.green,\n ...args,\n );\n};\nconst plgWarn = (plugin: IPlugin | IInstalledPlugin, ...args: unknown[]) => {\n if (needsNL) {\n needsNL = false;\n console.warn();\n }\n console.warn(plugin.name, 'W>'.yellow, ...args);\n};\nconst plgErr = (plugin: IPlugin | IInstalledPlugin, ...args: unknown[]) => {\n if (needsNL) {\n needsNL = false;\n console.error();\n }\n console.error(plugin.name, '!>'.red, ...args);\n};\n\nconst err = (...args: unknown[]) => {\n if (needsNL) {\n needsNL = false;\n console.error();\n }\n console.error('!>'.red, ...args);\n};\nconst log = (...args: unknown[]) => {\n if (needsNL) {\n needsNL = false;\n console.log();\n }\n console.log('>>'.green, ...args);\n};\nconst verboseLog = (...args: unknown[]) => {\n if (!Logger.VERBOSE) return;\n if (needsNL) {\n needsNL = false;\n console.log();\n }\n console.log('V>'.magenta, ...args);\n};\n\nfunction checkPlugin(\n omeggaPath: string,\n plugin: (IPlugin & { name: string }) | IInstalledPlugin,\n) {\n const pluginPath = path.join(omeggaPath, soft.PLUGIN_PATH, plugin.name);\n\n // check for the plugin file, whatever it's called\n if (fs.existsSync(path.join(pluginPath, soft.PLUGIN_FILE))) {\n if (needsNL) {\n console.log();\n needsNL = false;\n }\n plgLog(plugin, 'Checking plugin file...');\n let data;\n try {\n data = JSON.parse(\n fs.readFileSync(path.join(pluginPath, soft.PLUGIN_FILE), 'utf8'),\n );\n } catch (e) {\n plgErr(plugin, 'Error reading plugin file', e);\n return false;\n }\n\n // make sure this plugin version is okay.\n // in the future, this may include deprecation warnings and format changes\n if (data.formatVersion !== 1) {\n plgWarn(\n plugin,\n 'WARNING - Plugin file has invalid',\n 'formatVersion'.yellow + '. Expected',\n '1'.yellow,\n );\n return;\n }\n\n // check the omeggaVersion field of the plugin file\n if (!data.omeggaVersion || !semver.validRange(data.omeggaVersion)) {\n plgWarn(\n plugin,\n 'WARNING - Plugin file has invalid',\n 'omeggaVersion'.yellow + '. Expected semver expression',\n );\n return false;\n } else if (!semver.satisfies(VERSION, data.omeggaVersion)) {\n plgWarn(\n plugin,\n `WARNING - Plugin is not made for this version of omegga (${VERSION.yellow} vs ${data.omeggaVersion.yellow})`,\n );\n return false;\n }\n\n plgLog(plugin, 'Plugin file', 'OK'.green);\n return true;\n }\n\n // no plugin file, no problem!\n plgWarn(\n plugin,\n `WARNING - Plugin is missing plugin file (${soft.PLUGIN_FILE}), this may be a problem in future versions`,\n );\n return true;\n}\n\n// install plugins from a list of plugins\nexport async function install(plugins: string[], _options: unknown) {\n const omeggaPath = getWorkDir();\n if (!omeggaPath)\n return err(\n 'Not an omegga directory, run ',\n 'omegga init'.yellow,\n 'to setup one.',\n );\n\n log('Attempting to install', (plugins.length + '').yellow, 'plugins...');\n\n for (const pluginUrl of plugins) {\n const transformed = transformUrl(pluginUrl);\n\n // if the plugin wasn't transformed, try to extract its name from the git url\n let name = transformed.name;\n if (!name) {\n try {\n name = path.parse(transformed.url).name.replace(/^omegga-/, '');\n } catch {\n console.error('!>'.red, 'Error parsing name from url', transformed.url);\n break;\n }\n }\n const plugin = { ...transformed, name };\n\n log(\n 'Installing plugin',\n plugin.name.yellow,\n 'from',\n plugin.url.yellow + '...',\n );\n\n // plugin absolute path\n const pluginPath = path.join(omeggaPath, soft.PLUGIN_PATH, plugin.name);\n\n // check if plugin already exists\n // TODO: if force is passed in, remove the old directory\n if (\n fs.existsSync(pluginPath) &&\n fs.existsSync(path.join(pluginPath, 'doc.json'))\n ) {\n plgErr(\n plugin,\n 'Directory already exists! Try',\n ('omegga update ' + plugin.name).yellow,\n 'or check for plugin name collisions',\n );\n continue;\n }\n\n if (!fs.existsSync(pluginPath)) {\n // create plugin local directory\n try {\n fs.mkdirSync(pluginPath, { recursive: true });\n } catch (e) {\n plgErr(plugin, 'Error creating plugin directory', e);\n }\n }\n\n // clone the plugin from git\n try {\n const git = getPluginGit();\n plgLog(plugin, 'Cloning...');\n await git.clone(plugin.url, pluginPath);\n } catch (e) {\n plgErr(plugin, 'Error cloning plugin', e);\n }\n\n // check for the plugin file for issues\n // TODO: if force is passed in, ignore the plugin check\n if (!checkPlugin(omeggaPath, plugin)) continue;\n\n const postInstallPath = path.join(pluginPath, soft.PLUGIN_POSTINSTALL);\n if (fs.existsSync(postInstallPath)) {\n plgLog(plugin, 'Running post install script...');\n try {\n verboseLog('Changing permission of', postInstallPath);\n fs.chmodSync(postInstallPath, '0755');\n verboseLog('Executing bash file');\n const { stdout, stderr } = await exec(postInstallPath, {\n cwd: pluginPath,\n shell: 'bash',\n });\n\n if (stderr.length) plgErr(plugin, stderr);\n\n verboseLog(stdout);\n } catch (e) {\n plgErr(plugin, 'Error running post install script:', e);\n }\n }\n }\n}\nexport async function update(pluginsNames: string[], _options: unknown) {\n const omeggaPath = getWorkDir();\n if (!omeggaPath)\n return err(\n 'Not an omegga directory, run ',\n 'omegga init'.yellow,\n 'to setup one.',\n );\n\n const git = getPluginGit();\n const pluginFolder = path.join(omeggaPath, soft.PLUGIN_PATH);\n\n // if no plugins are passed in, use every plugin in the plugins folder\n if (pluginsNames.length === 0) {\n pluginsNames = fs.readdirSync(pluginFolder);\n }\n\n const plugins: (IInstalledPlugin & { path: string })[] = pluginsNames\n .map(dir => path.join(pluginFolder, dir))\n // every plugin must be a directory git can update\n .filter(\n dir =>\n fs.existsSync(dir) &&\n fs.lstatSync(dir).isDirectory() &&\n fs.existsSync(path.join(dir, '.git')),\n )\n .map(dir => ({ name: path.basename(dir), path: dir }));\n\n if (plugins.length === 0) {\n log('Found no plugins that can be updated');\n return;\n }\n\n log('Checking', (plugins.length + '').yellow, 'plugins for updates...');\n\n // list of plugins that will be updated\n const pluginsToUpdate: (IInstalledPlugin & { path: string })[] = [];\n\n for (const plugin of plugins) {\n if (needsNL) {\n console.log();\n needsNL = false;\n }\n plgLog(plugin, 'Checking...');\n\n try {\n // local edits are someone's work in progress, and an update would eat them\n if (await git.isDirty(plugin.path)) {\n plgErr(plugin, 'Detected uncommitted changes - ignoring');\n continue;\n }\n\n const branch = await git.currentBranch(plugin.path);\n if (!branch || !MAIN_BRANCHES.includes(branch)) {\n plgErr(plugin, 'Not on a main branch - ignoring');\n continue;\n }\n\n plgLog(plugin, 'Fetching...');\n await git.fetch(plugin.path);\n\n const upstream = await git.compareUpstream(plugin.path);\n if (!upstream) {\n plgErr(plugin, 'No upstream branch - ignoring');\n continue;\n }\n\n // local developers, publish your code please!!! :)\n if (upstream.ahead) {\n plgErr(plugin, 'Detected plugin is ahead - ignoring');\n continue;\n }\n\n if (!upstream.behind) {\n plgLog(plugin, 'Already up-to-date!'.green);\n continue;\n }\n\n plgLog(plugin, 'Update available');\n pluginsToUpdate.push(plugin);\n } catch (e) {\n plgErr(plugin, 'Error', e);\n }\n }\n\n if (pluginsToUpdate.length === 0) {\n log('All plugins are currently up-to-date');\n return;\n }\n\n log('Updating', (pluginsToUpdate.length + '').yellow, 'plugins...');\n let updates = 0;\n\n for (const plugin of pluginsToUpdate) {\n if (needsNL) {\n console.log();\n needsNL = false;\n }\n\n // the commit to fall back to when the new code turns out to be unusable\n let previous: string;\n try {\n previous = await git.headSha(plugin.path);\n } catch (e) {\n plgErr(plugin, 'Error reading current commit', e);\n continue;\n }\n\n try {\n plgLog(plugin, 'Pulling update...');\n await git.fastForward(plugin.path);\n\n plgLog(plugin, 'Checking plugin versions...');\n if (!checkPlugin(omeggaPath, plugin)) {\n throw 'Incompatible';\n }\n\n const postInstallPath = path.join(plugin.path, soft.PLUGIN_POSTINSTALL);\n if (fs.existsSync(postInstallPath)) {\n plgLog(plugin, 'Running post install script...');\n try {\n fs.chmodSync(postInstallPath, '0755');\n const { stdout, stderr } = await exec(postInstallPath, {\n cwd: plugin.path,\n shell: 'bash',\n });\n\n if (stderr.length) plgErr(plugin, stderr);\n\n verboseLog(stdout);\n } catch (e) {\n plgErr(plugin, 'Error running post install script:', e);\n }\n }\n\n plgLog(plugin, 'Updated!'.green);\n updates++;\n } catch (e) {\n plgErr(plugin, 'Error updating plugin', e);\n try {\n plgWarn(plugin, 'Rolling back to', previous.slice(0, 8).yellow);\n await git.resetTo(plugin.path, previous);\n } catch (rollback) {\n plgErr(plugin, 'Error rolling back', rollback);\n }\n }\n }\n\n log('Updated', (updates + '').yellow, 'plugins!');\n}\n\nexport async function check(pluginNames: string[], _options: unknown) {\n const omeggaPath = getWorkDir();\n if (!omeggaPath)\n return err(\n 'Not an omegga directory, run ',\n 'omegga init'.yellow,\n 'to setup one.',\n );\n\n const pluginFolder = path.join(omeggaPath, soft.PLUGIN_PATH);\n\n // if no plugins are passed in, use every plugin in the plugins folder\n if (pluginNames.length === 0) {\n pluginNames = fs.readdirSync(pluginFolder);\n }\n\n const plugins: IInstalledPlugin[] = pluginNames\n .map(dir => path.join(pluginFolder, dir))\n // every plugin must be in a directory\n .filter(\n dir =>\n fs.existsSync(dir) &&\n fs.lstatSync(dir).isDirectory() &&\n fs.existsSync(path.join(dir, '.git')),\n )\n .map(dir => ({ name: path.basename(dir) }));\n\n if (plugins.length === 0) {\n log('Found no plugins that can be checked');\n return;\n }\n\n log(\n 'Checking',\n (plugins.length + '').yellow,\n 'plugins for valid plugin files',\n );\n\n for (const plugin of plugins) {\n // a plugin copied in by hand is still a plugin worth checking, so this\n // does not care whether the directory came from git\n plugin.path = path.join(pluginFolder, plugin.name);\n checkPlugin(omeggaPath, plugin);\n }\n console.log();\n}\n\nconst EXECUTABLES = ['setup.sh', 'omegga_plugin'];\n\nasync function init() {\n const { author, ...response } = await prompts([\n {\n type: 'text',\n name: 'name',\n message: 'What would you like to ' + 'name'.yellow + ' your plugin?',\n validate: value =>\n value.match(/^[\\w-_]+$/) ? true : 'Invalid plugin name!',\n },\n {\n type: 'select',\n name: 'type',\n message:\n 'What ' + 'type'.yellow + ' of plugin would you like to initialize?',\n choices: [\n { title: 'safe ' + '(default)'.italic, value: 'safe' },\n { title: 'unsafe', value: 'unsafe' },\n { title: 'rust', value: 'rust' },\n { title: 'rpc', value: 'rpc' },\n ],\n },\n {\n type: prev => (prev === 'safe' ? 'confirm' : null),\n name: 'ts',\n message:\n 'Would you like to use ' + 'TypeScript'.yellow + ' in your plugin?',\n initial: false,\n },\n {\n type: 'text',\n name: 'author',\n message: 'Who is the ' + 'author'.yellow + ' of this plugin?',\n },\n ]);\n\n const name = response.name;\n const type: PluginType =\n response.type === 'safe' && response.ts ? 'safe-ts' : response.type;\n\n if (!PLUGIN_TYPES.includes(type)) {\n err('Invalid plugin type', type.red, '!');\n process.exit(1);\n }\n\n let dest: string;\n if (!config.find('.')) {\n log(\n 'Warning:'.yellow,\n 'This is not an omegga installation, initializing here instead...',\n );\n dest = `./${name}`;\n } else {\n dest = `./plugins/${name}`;\n if (!fs.existsSync('./plugins')) fs.mkdirSync('./plugins');\n }\n\n if (fs.existsSync(dest)) {\n err('A directory already exists at the desired plugin location.');\n process.exit(1);\n }\n\n log('Initializing new', type.yellow, 'plugin', name.cyan, '...');\n\n const templateData: Record<string, string> = {\n name,\n author: author ?? 'AUTHOR',\n omeggaVersion: VERSION,\n };\n\n const copyAndRender = async (src: string, dest: string) => {\n const stats = fs.statSync(src);\n // remove .rename suffix from files\n dest = dest.replace(/\\.rename$/, '');\n if (stats.isDirectory()) {\n await fs.promises.mkdir(dest);\n const contents = await fs.promises.readdir(src);\n for (const child of contents)\n await copyAndRender(path.join(src, child), path.join(dest, child));\n } else {\n // copy and render the file\n const data = (await fs.promises.readFile(src)).toString();\n const mode = EXECUTABLES.includes(path.basename(dest)) ? 0o755 : 0o644;\n\n await fs.promises.writeFile(\n dest,\n data.replace(/{{(\\w+)}}/g, (_, p) => templateData[p] ?? `{{${p}}}`),\n { mode },\n );\n }\n };\n\n const src = path.join(__dirname, `../../templates/${type}`);\n\n verboseLog('Copying and rendering template...');\n await copyAndRender(src, dest);\n\n verboseLog('Starting a repo in the new plugin directory ...');\n try {\n await getPluginGit().init(dest);\n } catch (e) {\n log('Warning: could not start a git repo here.'.yellow, e);\n }\n\n if (fs.existsSync(path.join(src, 'package.json'))) {\n verboseLog('Running', 'npm i'.yellow, 'in the new plugin directory ...');\n try {\n await exec('npm i', { cwd: dest });\n } catch {\n log('Warning: npm i'.yellow, 'failed to execute. Proceeding anyway...');\n }\n }\n\n log('Initialized', type.yellow, 'plugin', `${name}`.cyan, 'successfully!');\n}\n\nfunction pluginLoaderFactory() {\n const workDir = getWorkDir();\n if (!workDir) {\n err('Not an omegga directory, run ', 'omegga init'.yellow, 'to setup one.');\n process.exit(1);\n }\n return new PluginLoader(workDir);\n}\n\n/** Loads in a plugin and it's documentation. */\nasync function loadPlugin(pluginName: string) {\n const pluginLoader = pluginLoaderFactory();\n const foundPluginDirectory = fs\n .readdirSync(pluginLoader.path)\n .find(dir => dir.toLowerCase() === pluginName.toLowerCase());\n if (!foundPluginDirectory) {\n err(\n `Plugin ${pluginName} not found! Make sure to use the plugin's directory name.`,\n );\n process.exit(1);\n }\n const plugin = await pluginLoader.scanPlugin(\n path.join(pluginLoader.path, foundPluginDirectory),\n );\n if (!plugin) {\n err(`Plugin ${pluginName} failed to load!`);\n process.exit(1);\n }\n return plugin;\n}\n\n/** Get a loaded plugin's config documentation or exit. */\nfunction getConfigDoc(plugin: Awaited<ReturnType<typeof loadPlugin>>) {\n const configDoc = plugin.getDocumentation()?.config;\n if (!configDoc) {\n err('Plugin', plugin.getName().cyan, 'has no config documentation');\n process.exit(1);\n }\n return configDoc;\n}\n\nasync function listConfig(pluginName: string, json = false) {\n const plugin = await loadPlugin(pluginName);\n // plugins without a config section are valid; list only skips unknown keys\n const configDoc = plugin.getDocumentation()?.config ?? {};\n const config = (await plugin.storage.getConfig()) ?? {};\n if (json) {\n console.log(JSON.stringify(config, null, 2));\n } else {\n for (const key in config) {\n if (!configDoc[key]) continue; // Skip unknown config keys.\n const value = config[key];\n log(\n key.cyan,\n '=',\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean'\n ? value.toString().yellow\n : JSON.stringify(value).yellow,\n );\n }\n }\n process.exit();\n}\n\nasync function getConfig(pluginName: string, configName: string, json = false) {\n const plugin = await loadPlugin(pluginName);\n const configDoc = getConfigDoc(plugin)[configName];\n if (configDoc === undefined) {\n err('Config', configName.cyan, 'not found');\n process.exit(1);\n }\n const config = (await plugin.storage.getConfig()) ?? {};\n if (json) {\n console.log(JSON.stringify(config[configName], null, 2));\n } else {\n log(config[configName]);\n }\n process.exit();\n}\n\nasync function setConfig(\n pluginName: string,\n configName: string,\n valueString: string,\n) {\n const plugin = await loadPlugin(pluginName);\n const configDoc = getConfigDoc(plugin)[configName];\n if (configDoc === undefined) {\n err('Config', configName.cyan, 'not found');\n process.exit(1);\n }\n\n // Parse the value string into a value of the correct type for the config.\n let parsed;\n switch (configDoc.type) {\n case 'boolean':\n parsed = valueString === 'true';\n break;\n case 'number':\n parsed = Number(valueString);\n if (isNaN(parsed)) {\n err('Invalid number value', valueString.yellow);\n process.exit(1);\n }\n break;\n case 'string':\n parsed = valueString;\n break;\n case 'enum':\n if (!configDoc.options.includes(valueString)) {\n err(\n 'Config',\n configName.cyan,\n 'must be one of',\n configDoc.options.join(', ').yellow,\n );\n process.exit(1);\n }\n parsed = valueString;\n break;\n default:\n err('set-context does not support config type', configDoc.type.cyan);\n process.exit(1);\n }\n\n const pluginConfig = (await plugin.storage.getConfig()) ?? {};\n pluginConfig[configName] = parsed;\n await plugin.storage.setConfig(pluginConfig);\n log(\n 'Set config',\n configName.cyan,\n 'of plugin',\n plugin.getName().cyan,\n 'to',\n parsed.toString().yellow,\n );\n process.exit();\n}\n\nasync function resetAllConfigs(pluginName: string, force: boolean) {\n const plugin = await loadPlugin(pluginName);\n if (!force) {\n const { answer } = await prompts([\n {\n type: 'confirm',\n name: 'answer',\n message: 'Are you sure you want to reset all configs?',\n initial: false,\n },\n ]);\n if (!answer) {\n log('Reset aborted.');\n process.exit(1);\n }\n }\n await plugin.storage.wipeConfig();\n await plugin.storage.init();\n log('Reset all configs of plugin', plugin.getName().cyan);\n process.exit();\n}\n\nasync function resetConfig(pluginName: string, configName: string) {\n const plugin = await loadPlugin(pluginName);\n const configDoc = getConfigDoc(plugin)[configName];\n if (configDoc === undefined) {\n err('Config', configName.cyan, 'not found');\n process.exit(1);\n }\n const pluginConfig = (await plugin.storage.getConfig()) ?? {};\n pluginConfig[configName] = plugin.storage.getDefaultConfig()[configName];\n await plugin.storage.setConfig(pluginConfig);\n log(\n 'Reset config',\n configName.cyan,\n 'of plugin',\n plugin.getName().cyan,\n 'to',\n pluginConfig[configName],\n );\n process.exit();\n}\n\nexport default {\n install,\n update,\n check,\n init,\n listConfig,\n getConfig,\n setConfig,\n resetAllConfigs,\n resetConfig,\n};\n"],"names":["promisify","execNonPromise","config.store","config.find","plugin","Logger","soft","VERSION","git","getPluginGit","src","dest","PluginLoader","config"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"plugin.js","sources":["../../src/cli/plugin.ts"],"sourcesContent":["import Logger from '@/logger';\nimport soft from '@/softconfig';\nimport * as config from '@config';\nimport { PluginLoader } from '@omegga/plugin';\nimport { getPluginGit } from '@cli/plugin/git';\nimport { exec as execNonPromise } from 'node:child_process';\nimport 'colors';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport prompts from 'prompts';\nimport semver from 'semver';\nimport { promisify } from 'node:util';\nimport { VERSION } from '@/version';\n\nconst exec = promisify(execNonPromise);\n\nconst MAIN_BRANCHES = ['master', 'main'];\n\n// get the working directory for omegga\nfunction getWorkDir() {\n // default working directory is the one specified in config\n let workDir = config.store.get('defaultOmegga');\n verboseLog('Using working directory', workDir.yellow);\n\n // if there's a config in the current directory, use that one instead\n if (config.find('.')) workDir = '.';\n\n const confFile = config.find(workDir);\n\n return confFile\n ? path.resolve(process.cwd(), path.dirname(confFile))\n : undefined;\n}\n\ninterface IPlugin {\n name?: string;\n type: string | 'raw';\n url: string;\n}\n\ninterface IInstalledPlugin {\n name: string;\n path?: string;\n}\n\ninterface ITransformer {\n pattern: RegExp;\n fn(match: Record<string, string>): IPlugin;\n}\n\nconst PLUGIN_TYPES = ['safe', 'safe-ts', 'unsafe', 'rust', 'rpc'];\ntype PluginType = (typeof PLUGIN_TYPES)[number];\n\n// plugin url transformers\nconst transformers: ITransformer[] = [\n {\n // github transformer\n pattern: /^gh:(?<owner>[^/]+)\\/(?<repo>[^/]+)$/,\n fn: ({ owner, repo }) => ({\n type: 'short',\n name: repo,\n url: `https://github.com/${owner}/omegga-${repo}`,\n }),\n },\n {\n // gitlab transformer\n pattern: /^gl:(?<owner>[^/]+)\\/(?<repo>[^/]+)$/,\n fn: ({ owner, repo }) => ({\n type: 'short',\n name: repo,\n url: `https://gitlab.com/${owner}/omegga-${repo}`,\n }),\n },\n];\n\n// convert a shortened url into a full length one\nconst transformUrl = (url: string): IPlugin => {\n for (const t of transformers) {\n const match = url.match(t.pattern);\n if (match?.groups) return t.fn(match.groups);\n }\n return { type: 'raw', url };\n};\n\nlet needsNL = false;\n\n// rewrite a console line. stays on raw stdout rather than going through\n// Logger: it rewinds the cursor for progress, and a partial line is noise in\n// the log file. the `needsNL` newline below is that same bookkeeping\nconst rewriteLine = (...args: unknown[]) => {\n // stdout has no cursor controls when omegga is piped or run in a container\n if (process.stdout.isTTY) {\n process.stdout.clearLine(0);\n process.stdout.cursorTo(0);\n }\n process.stdout.write(args.join(' '));\n needsNL = true;\n};\n\n// logging helper functions\nconst plg = (plugin: IPlugin | IInstalledPlugin, ...args: unknown[]) => {\n if (needsNL) {\n needsNL = false;\n console.log();\n }\n Logger.log(plugin.name, '>>'.green, ...args);\n};\nconst plgLog = (plugin: IPlugin | IInstalledPlugin, ...args: unknown[]) => {\n if (Logger.VERBOSE) plg(plugin, ...args);\n else\n rewriteLine(\n plugin.name ?? ('url' in plugin ? plugin.url : ''),\n '>>'.green,\n ...args,\n );\n};\nconst plgWarn = (plugin: IPlugin | IInstalledPlugin, ...args: unknown[]) => {\n if (needsNL) {\n needsNL = false;\n console.warn();\n }\n Logger.warn(plugin.name, 'W>'.yellow, ...args);\n};\nconst plgErr = (plugin: IPlugin | IInstalledPlugin, ...args: unknown[]) => {\n if (needsNL) {\n needsNL = false;\n console.error();\n }\n Logger.error(plugin.name, '!>'.red, ...args);\n};\n\nconst err = (...args: unknown[]) => {\n if (needsNL) {\n needsNL = false;\n console.error();\n }\n Logger.errorp(...args);\n};\nconst log = (...args: unknown[]) => {\n if (needsNL) {\n needsNL = false;\n console.log();\n }\n Logger.logp(...args);\n};\nconst verboseLog = (...args: unknown[]) => {\n if (!Logger.VERBOSE) return;\n if (needsNL) {\n needsNL = false;\n console.log();\n }\n Logger.verbose(...args);\n};\n\nfunction checkPlugin(\n omeggaPath: string,\n plugin: (IPlugin & { name: string }) | IInstalledPlugin,\n) {\n const pluginPath = path.join(omeggaPath, soft.PLUGIN_PATH, plugin.name);\n\n // check for the plugin file, whatever it's called\n if (fs.existsSync(path.join(pluginPath, soft.PLUGIN_FILE))) {\n if (needsNL) {\n console.log();\n needsNL = false;\n }\n plgLog(plugin, 'Checking plugin file...');\n let data;\n try {\n data = JSON.parse(\n fs.readFileSync(path.join(pluginPath, soft.PLUGIN_FILE), 'utf8'),\n );\n } catch (e) {\n plgErr(plugin, 'Error reading plugin file', e);\n return false;\n }\n\n // make sure this plugin version is okay.\n // in the future, this may include deprecation warnings and format changes\n if (data.formatVersion !== 1) {\n plgWarn(\n plugin,\n 'WARNING - Plugin file has invalid',\n 'formatVersion'.yellow + '. Expected',\n '1'.yellow,\n );\n return;\n }\n\n // check the omeggaVersion field of the plugin file\n if (!data.omeggaVersion || !semver.validRange(data.omeggaVersion)) {\n plgWarn(\n plugin,\n 'WARNING - Plugin file has invalid',\n 'omeggaVersion'.yellow + '. Expected semver expression',\n );\n return false;\n } else if (!semver.satisfies(VERSION, data.omeggaVersion)) {\n plgWarn(\n plugin,\n `WARNING - Plugin is not made for this version of omegga (${VERSION.yellow} vs ${data.omeggaVersion.yellow})`,\n );\n return false;\n }\n\n plgLog(plugin, 'Plugin file', 'OK'.green);\n return true;\n }\n\n // no plugin file, no problem!\n plgWarn(\n plugin,\n `WARNING - Plugin is missing plugin file (${soft.PLUGIN_FILE}), this may be a problem in future versions`,\n );\n return true;\n}\n\n// install plugins from a list of plugins\nexport async function install(plugins: string[], _options: unknown) {\n const omeggaPath = getWorkDir();\n if (!omeggaPath)\n return err(\n 'Not an omegga directory, run ',\n 'omegga init'.yellow,\n 'to setup one.',\n );\n\n log('Attempting to install', (plugins.length + '').yellow, 'plugins...');\n\n for (const pluginUrl of plugins) {\n const transformed = transformUrl(pluginUrl);\n\n // if the plugin wasn't transformed, try to extract its name from the git url\n let name = transformed.name;\n if (!name) {\n try {\n name = path.parse(transformed.url).name.replace(/^omegga-/, '');\n } catch {\n err('Error parsing name from url', transformed.url);\n break;\n }\n }\n const plugin = { ...transformed, name };\n\n log(\n 'Installing plugin',\n plugin.name.yellow,\n 'from',\n plugin.url.yellow + '...',\n );\n\n // plugin absolute path\n const pluginPath = path.join(omeggaPath, soft.PLUGIN_PATH, plugin.name);\n\n // check if plugin already exists\n // TODO: if force is passed in, remove the old directory\n if (\n fs.existsSync(pluginPath) &&\n fs.existsSync(path.join(pluginPath, 'doc.json'))\n ) {\n plgErr(\n plugin,\n 'Directory already exists! Try',\n ('omegga update ' + plugin.name).yellow,\n 'or check for plugin name collisions',\n );\n continue;\n }\n\n if (!fs.existsSync(pluginPath)) {\n // create plugin local directory\n try {\n fs.mkdirSync(pluginPath, { recursive: true });\n } catch (e) {\n plgErr(plugin, 'Error creating plugin directory', e);\n }\n }\n\n // clone the plugin from git\n try {\n const git = getPluginGit();\n plgLog(plugin, 'Cloning...');\n await git.clone(plugin.url, pluginPath);\n } catch (e) {\n plgErr(plugin, 'Error cloning plugin', e);\n }\n\n // check for the plugin file for issues\n // TODO: if force is passed in, ignore the plugin check\n if (!checkPlugin(omeggaPath, plugin)) continue;\n\n const postInstallPath = path.join(pluginPath, soft.PLUGIN_POSTINSTALL);\n if (fs.existsSync(postInstallPath)) {\n plgLog(plugin, 'Running post install script...');\n try {\n verboseLog('Changing permission of', postInstallPath);\n fs.chmodSync(postInstallPath, '0755');\n verboseLog('Executing bash file');\n const { stdout, stderr } = await exec(postInstallPath, {\n cwd: pluginPath,\n shell: 'bash',\n });\n\n if (stderr.length) plgErr(plugin, stderr);\n\n verboseLog(stdout);\n } catch (e) {\n plgErr(plugin, 'Error running post install script:', e);\n }\n }\n }\n}\nexport async function update(pluginsNames: string[], _options: unknown) {\n const omeggaPath = getWorkDir();\n if (!omeggaPath)\n return err(\n 'Not an omegga directory, run ',\n 'omegga init'.yellow,\n 'to setup one.',\n );\n\n const git = getPluginGit();\n const pluginFolder = path.join(omeggaPath, soft.PLUGIN_PATH);\n\n // if no plugins are passed in, use every plugin in the plugins folder\n if (pluginsNames.length === 0) {\n pluginsNames = fs.readdirSync(pluginFolder);\n }\n\n const plugins: (IInstalledPlugin & { path: string })[] = pluginsNames\n .map(dir => path.join(pluginFolder, dir))\n // every plugin must be a directory git can update\n .filter(\n dir =>\n fs.existsSync(dir) &&\n fs.lstatSync(dir).isDirectory() &&\n fs.existsSync(path.join(dir, '.git')),\n )\n .map(dir => ({ name: path.basename(dir), path: dir }));\n\n if (plugins.length === 0) {\n log('Found no plugins that can be updated');\n return;\n }\n\n log('Checking', (plugins.length + '').yellow, 'plugins for updates...');\n\n // list of plugins that will be updated\n const pluginsToUpdate: (IInstalledPlugin & { path: string })[] = [];\n\n for (const plugin of plugins) {\n if (needsNL) {\n console.log();\n needsNL = false;\n }\n plgLog(plugin, 'Checking...');\n\n try {\n // local edits are someone's work in progress, and an update would eat them\n if (await git.isDirty(plugin.path)) {\n plgErr(plugin, 'Detected uncommitted changes - ignoring');\n continue;\n }\n\n const branch = await git.currentBranch(plugin.path);\n if (!branch || !MAIN_BRANCHES.includes(branch)) {\n plgErr(plugin, 'Not on a main branch - ignoring');\n continue;\n }\n\n plgLog(plugin, 'Fetching...');\n await git.fetch(plugin.path);\n\n const upstream = await git.compareUpstream(plugin.path);\n if (!upstream) {\n plgErr(plugin, 'No upstream branch - ignoring');\n continue;\n }\n\n // local developers, publish your code please!!! :)\n if (upstream.ahead) {\n plgErr(plugin, 'Detected plugin is ahead - ignoring');\n continue;\n }\n\n if (!upstream.behind) {\n plgLog(plugin, 'Already up-to-date!'.green);\n continue;\n }\n\n plgLog(plugin, 'Update available');\n pluginsToUpdate.push(plugin);\n } catch (e) {\n plgErr(plugin, 'Error', e);\n }\n }\n\n if (pluginsToUpdate.length === 0) {\n log('All plugins are currently up-to-date');\n return;\n }\n\n log('Updating', (pluginsToUpdate.length + '').yellow, 'plugins...');\n let updates = 0;\n\n for (const plugin of pluginsToUpdate) {\n if (needsNL) {\n console.log();\n needsNL = false;\n }\n\n // the commit to fall back to when the new code turns out to be unusable\n let previous: string;\n try {\n previous = await git.headSha(plugin.path);\n } catch (e) {\n plgErr(plugin, 'Error reading current commit', e);\n continue;\n }\n\n try {\n plgLog(plugin, 'Pulling update...');\n await git.fastForward(plugin.path);\n\n plgLog(plugin, 'Checking plugin versions...');\n if (!checkPlugin(omeggaPath, plugin)) {\n throw 'Incompatible';\n }\n\n const postInstallPath = path.join(plugin.path, soft.PLUGIN_POSTINSTALL);\n if (fs.existsSync(postInstallPath)) {\n plgLog(plugin, 'Running post install script...');\n try {\n fs.chmodSync(postInstallPath, '0755');\n const { stdout, stderr } = await exec(postInstallPath, {\n cwd: plugin.path,\n shell: 'bash',\n });\n\n if (stderr.length) plgErr(plugin, stderr);\n\n verboseLog(stdout);\n } catch (e) {\n plgErr(plugin, 'Error running post install script:', e);\n }\n }\n\n plgLog(plugin, 'Updated!'.green);\n updates++;\n } catch (e) {\n plgErr(plugin, 'Error updating plugin', e);\n try {\n plgWarn(plugin, 'Rolling back to', previous.slice(0, 8).yellow);\n await git.resetTo(plugin.path, previous);\n } catch (rollback) {\n plgErr(plugin, 'Error rolling back', rollback);\n }\n }\n }\n\n log('Updated', (updates + '').yellow, 'plugins!');\n}\n\nexport async function check(pluginNames: string[], _options: unknown) {\n const omeggaPath = getWorkDir();\n if (!omeggaPath)\n return err(\n 'Not an omegga directory, run ',\n 'omegga init'.yellow,\n 'to setup one.',\n );\n\n const pluginFolder = path.join(omeggaPath, soft.PLUGIN_PATH);\n\n // if no plugins are passed in, use every plugin in the plugins folder\n if (pluginNames.length === 0) {\n pluginNames = fs.readdirSync(pluginFolder);\n }\n\n const plugins: IInstalledPlugin[] = pluginNames\n .map(dir => path.join(pluginFolder, dir))\n // every plugin must be in a directory\n .filter(\n dir =>\n fs.existsSync(dir) &&\n fs.lstatSync(dir).isDirectory() &&\n fs.existsSync(path.join(dir, '.git')),\n )\n .map(dir => ({ name: path.basename(dir) }));\n\n if (plugins.length === 0) {\n log('Found no plugins that can be checked');\n return;\n }\n\n log(\n 'Checking',\n (plugins.length + '').yellow,\n 'plugins for valid plugin files',\n );\n\n for (const plugin of plugins) {\n // a plugin copied in by hand is still a plugin worth checking, so this\n // does not care whether the directory came from git\n plugin.path = path.join(pluginFolder, plugin.name);\n checkPlugin(omeggaPath, plugin);\n }\n console.log();\n}\n\nconst EXECUTABLES = ['setup.sh', 'omegga_plugin'];\n\nasync function init() {\n const { author, ...response } = await prompts([\n {\n type: 'text',\n name: 'name',\n message: 'What would you like to ' + 'name'.yellow + ' your plugin?',\n validate: value =>\n value.match(/^[\\w-_]+$/) ? true : 'Invalid plugin name!',\n },\n {\n type: 'select',\n name: 'type',\n message:\n 'What ' + 'type'.yellow + ' of plugin would you like to initialize?',\n choices: [\n { title: 'safe ' + '(default)'.italic, value: 'safe' },\n { title: 'unsafe', value: 'unsafe' },\n { title: 'rust', value: 'rust' },\n { title: 'rpc', value: 'rpc' },\n ],\n },\n {\n type: prev => (prev === 'safe' ? 'confirm' : null),\n name: 'ts',\n message:\n 'Would you like to use ' + 'TypeScript'.yellow + ' in your plugin?',\n initial: false,\n },\n {\n type: 'text',\n name: 'author',\n message: 'Who is the ' + 'author'.yellow + ' of this plugin?',\n },\n ]);\n\n const name = response.name;\n const type: PluginType =\n response.type === 'safe' && response.ts ? 'safe-ts' : response.type;\n\n if (!PLUGIN_TYPES.includes(type)) {\n err('Invalid plugin type', type.red, '!');\n process.exit(1);\n }\n\n let dest: string;\n if (!config.find('.')) {\n log(\n 'Warning:'.yellow,\n 'This is not an omegga installation, initializing here instead...',\n );\n dest = `./${name}`;\n } else {\n dest = `./plugins/${name}`;\n if (!fs.existsSync('./plugins')) fs.mkdirSync('./plugins');\n }\n\n if (fs.existsSync(dest)) {\n err('A directory already exists at the desired plugin location.');\n process.exit(1);\n }\n\n log('Initializing new', type.yellow, 'plugin', name.cyan, '...');\n\n const templateData: Record<string, string> = {\n name,\n author: author ?? 'AUTHOR',\n omeggaVersion: VERSION,\n };\n\n const copyAndRender = async (src: string, dest: string) => {\n const stats = fs.statSync(src);\n // remove .rename suffix from files\n dest = dest.replace(/\\.rename$/, '');\n if (stats.isDirectory()) {\n await fs.promises.mkdir(dest);\n const contents = await fs.promises.readdir(src);\n for (const child of contents)\n await copyAndRender(path.join(src, child), path.join(dest, child));\n } else {\n // copy and render the file\n const data = (await fs.promises.readFile(src)).toString();\n const mode = EXECUTABLES.includes(path.basename(dest)) ? 0o755 : 0o644;\n\n await fs.promises.writeFile(\n dest,\n data.replace(/{{(\\w+)}}/g, (_, p) => templateData[p] ?? `{{${p}}}`),\n { mode },\n );\n }\n };\n\n const src = path.join(__dirname, `../../templates/${type}`);\n\n verboseLog('Copying and rendering template...');\n await copyAndRender(src, dest);\n\n verboseLog('Starting a repo in the new plugin directory ...');\n try {\n await getPluginGit().init(dest);\n } catch (e) {\n log('Warning: could not start a git repo here.'.yellow, e);\n }\n\n if (fs.existsSync(path.join(src, 'package.json'))) {\n verboseLog('Running', 'npm i'.yellow, 'in the new plugin directory ...');\n try {\n await exec('npm i', { cwd: dest });\n } catch {\n log('Warning: npm i'.yellow, 'failed to execute. Proceeding anyway...');\n }\n }\n\n log('Initialized', type.yellow, 'plugin', `${name}`.cyan, 'successfully!');\n}\n\nfunction pluginLoaderFactory() {\n const workDir = getWorkDir();\n if (!workDir) {\n err('Not an omegga directory, run ', 'omegga init'.yellow, 'to setup one.');\n process.exit(1);\n }\n return new PluginLoader(workDir);\n}\n\n/** Loads in a plugin and it's documentation. */\nasync function loadPlugin(pluginName: string) {\n const pluginLoader = pluginLoaderFactory();\n const foundPluginDirectory = fs\n .readdirSync(pluginLoader.path)\n .find(dir => dir.toLowerCase() === pluginName.toLowerCase());\n if (!foundPluginDirectory) {\n err(\n `Plugin ${pluginName} not found! Make sure to use the plugin's directory name.`,\n );\n process.exit(1);\n }\n const plugin = await pluginLoader.scanPlugin(\n path.join(pluginLoader.path, foundPluginDirectory),\n );\n if (!plugin) {\n err(`Plugin ${pluginName} failed to load!`);\n process.exit(1);\n }\n return plugin;\n}\n\n/** Get a loaded plugin's config documentation or exit. */\nfunction getConfigDoc(plugin: Awaited<ReturnType<typeof loadPlugin>>) {\n const configDoc = plugin.getDocumentation()?.config;\n if (!configDoc) {\n err('Plugin', plugin.getName().cyan, 'has no config documentation');\n process.exit(1);\n }\n return configDoc;\n}\n\nasync function listConfig(pluginName: string, json = false) {\n const plugin = await loadPlugin(pluginName);\n // plugins without a config section are valid; list only skips unknown keys\n const configDoc = plugin.getDocumentation()?.config ?? {};\n const config = (await plugin.storage.getConfig()) ?? {};\n if (json) {\n console.log(JSON.stringify(config, null, 2));\n } else {\n for (const key in config) {\n if (!configDoc[key]) continue; // Skip unknown config keys.\n const value = config[key];\n log(\n key.cyan,\n '=',\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean'\n ? value.toString().yellow\n : JSON.stringify(value).yellow,\n );\n }\n }\n process.exit();\n}\n\nasync function getConfig(pluginName: string, configName: string, json = false) {\n const plugin = await loadPlugin(pluginName);\n const configDoc = getConfigDoc(plugin)[configName];\n if (configDoc === undefined) {\n err('Config', configName.cyan, 'not found');\n process.exit(1);\n }\n const config = (await plugin.storage.getConfig()) ?? {};\n if (json) {\n console.log(JSON.stringify(config[configName], null, 2));\n } else {\n log(config[configName]);\n }\n process.exit();\n}\n\nasync function setConfig(\n pluginName: string,\n configName: string,\n valueString: string,\n) {\n const plugin = await loadPlugin(pluginName);\n const configDoc = getConfigDoc(plugin)[configName];\n if (configDoc === undefined) {\n err('Config', configName.cyan, 'not found');\n process.exit(1);\n }\n\n // Parse the value string into a value of the correct type for the config.\n let parsed;\n switch (configDoc.type) {\n case 'boolean':\n parsed = valueString === 'true';\n break;\n case 'number':\n parsed = Number(valueString);\n if (isNaN(parsed)) {\n err('Invalid number value', valueString.yellow);\n process.exit(1);\n }\n break;\n case 'string':\n parsed = valueString;\n break;\n case 'enum':\n if (!configDoc.options.includes(valueString)) {\n err(\n 'Config',\n configName.cyan,\n 'must be one of',\n configDoc.options.join(', ').yellow,\n );\n process.exit(1);\n }\n parsed = valueString;\n break;\n default:\n err('set-context does not support config type', configDoc.type.cyan);\n process.exit(1);\n }\n\n const pluginConfig = (await plugin.storage.getConfig()) ?? {};\n pluginConfig[configName] = parsed;\n await plugin.storage.setConfig(pluginConfig);\n log(\n 'Set config',\n configName.cyan,\n 'of plugin',\n plugin.getName().cyan,\n 'to',\n parsed.toString().yellow,\n );\n process.exit();\n}\n\nasync function resetAllConfigs(pluginName: string, force: boolean) {\n const plugin = await loadPlugin(pluginName);\n if (!force) {\n const { answer } = await prompts([\n {\n type: 'confirm',\n name: 'answer',\n message: 'Are you sure you want to reset all configs?',\n initial: false,\n },\n ]);\n if (!answer) {\n log('Reset aborted.');\n process.exit(1);\n }\n }\n await plugin.storage.wipeConfig();\n await plugin.storage.init();\n log('Reset all configs of plugin', plugin.getName().cyan);\n process.exit();\n}\n\nasync function resetConfig(pluginName: string, configName: string) {\n const plugin = await loadPlugin(pluginName);\n const configDoc = getConfigDoc(plugin)[configName];\n if (configDoc === undefined) {\n err('Config', configName.cyan, 'not found');\n process.exit(1);\n }\n const pluginConfig = (await plugin.storage.getConfig()) ?? {};\n pluginConfig[configName] = plugin.storage.getDefaultConfig()[configName];\n await plugin.storage.setConfig(pluginConfig);\n log(\n 'Reset config',\n configName.cyan,\n 'of plugin',\n plugin.getName().cyan,\n 'to',\n pluginConfig[configName],\n );\n process.exit();\n}\n\nexport default {\n install,\n update,\n check,\n init,\n listConfig,\n getConfig,\n setConfig,\n resetAllConfigs,\n resetConfig,\n};\n"],"names":["promisify","execNonPromise","config.store","config.find","plugin","Logger","soft","VERSION","git","getPluginGit","src","dest","PluginLoader","config"],"mappings":"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"}
|
package/dist/cli/terminal.js
CHANGED
|
@@ -948,6 +948,18 @@ class Terminal {
|
|
|
948
948
|
`${p.displayName.underline} (${p.name.underline}) left.`.brightBlue
|
|
949
949
|
)
|
|
950
950
|
);
|
|
951
|
+
omegga.on(
|
|
952
|
+
"kick",
|
|
953
|
+
(name, kicker, reason) => this.log(
|
|
954
|
+
`${name.underline} was kicked by ${kicker.underline} (${reason})`.brightRed
|
|
955
|
+
)
|
|
956
|
+
);
|
|
957
|
+
omegga.on(
|
|
958
|
+
"ban",
|
|
959
|
+
(name, kicker, reason, duration) => this.log(
|
|
960
|
+
`${name.underline} was banned by ${kicker.underline} (${reason})${duration ? `, expires in ${duration}` : ""}`.brightRed
|
|
961
|
+
)
|
|
962
|
+
);
|
|
951
963
|
omegga.on("chat", (name, message) => {
|
|
952
964
|
const player = omegga.getPlayer(name);
|
|
953
965
|
this.log(
|
|
@@ -1024,9 +1036,11 @@ class Terminal {
|
|
|
1024
1036
|
err("Error stopping server:", e);
|
|
1025
1037
|
}
|
|
1026
1038
|
this.rl.close();
|
|
1039
|
+
logger.default.record("log", [">>".green, "Goodbye"]);
|
|
1027
1040
|
process.exit();
|
|
1028
1041
|
}
|
|
1029
1042
|
async handleLine(line) {
|
|
1043
|
+
if (line.trim()) logger.default.record("log", ["$".grey, line]);
|
|
1030
1044
|
if (line.startsWith("/")) {
|
|
1031
1045
|
const [cmd, ...args] = line.slice(1).split(" ");
|
|
1032
1046
|
const c = COMMANDS.find((c2) => c2.aliases.includes(cmd));
|
|
@@ -1069,6 +1083,7 @@ class Terminal {
|
|
|
1069
1083
|
}
|
|
1070
1084
|
// let readline render a log without interrupting user input
|
|
1071
1085
|
#write(method, args) {
|
|
1086
|
+
logger.default.record(method, args);
|
|
1072
1087
|
if (process.stdout.isTTY) {
|
|
1073
1088
|
process.stdout.clearLine(0);
|
|
1074
1089
|
process.stdout.cursorTo(0);
|