@runium/cli 0.0.1 → 0.0.2
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/{lib/commands → commands}/index.js +0 -0
- package/{lib/commands → commands}/project/project-start.js +1 -1
- package/{lib/constants → constants}/index.js +0 -0
- package/{lib/macros → macros}/index.js +0 -0
- package/package.json +7 -30
- package/{lib/services → services}/index.js +0 -0
- package/services/plugin-context.js +1 -0
- package/services/shutdown.js +1 -0
- package/{lib/utils → utils}/index.js +0 -0
- package/.eslintrc.json +0 -31
- package/.prettierrc.json +0 -10
- package/README.md +0 -3
- package/build.js +0 -104
- package/lib/package.json +0 -21
- package/lib/services/plugin-context.js +0 -1
- package/lib/services/shutdown.js +0 -1
- package/src/app.ts +0 -175
- package/src/commands/index.ts +0 -2
- package/src/commands/plugin/plugin-add.ts +0 -48
- package/src/commands/plugin/plugin-command.ts +0 -36
- package/src/commands/plugin/plugin-disable.ts +0 -46
- package/src/commands/plugin/plugin-enable.ts +0 -50
- package/src/commands/plugin/plugin-list.ts +0 -61
- package/src/commands/plugin/plugin-remove.ts +0 -42
- package/src/commands/plugin/plugin.ts +0 -41
- package/src/commands/project/project-add.ts +0 -46
- package/src/commands/project/project-command.ts +0 -36
- package/src/commands/project/project-list.ts +0 -32
- package/src/commands/project/project-remove.ts +0 -41
- package/src/commands/project/project-start.ts +0 -152
- package/src/commands/project/project-state-command.ts +0 -68
- package/src/commands/project/project-status.ts +0 -103
- package/src/commands/project/project-stop.ts +0 -55
- package/src/commands/project/project-validate.ts +0 -43
- package/src/commands/project/project.ts +0 -45
- package/src/commands/runium-command.ts +0 -50
- package/src/constants/error-code.ts +0 -15
- package/src/constants/index.ts +0 -1
- package/src/index.ts +0 -21
- package/src/macros/conditional.ts +0 -31
- package/src/macros/empty.ts +0 -6
- package/src/macros/env.ts +0 -8
- package/src/macros/index.ts +0 -12
- package/src/macros/path.ts +0 -9
- package/src/services/config.ts +0 -76
- package/src/services/index.ts +0 -7
- package/src/services/output.ts +0 -201
- package/src/services/plugin-context.ts +0 -81
- package/src/services/plugin.ts +0 -144
- package/src/services/profile.ts +0 -211
- package/src/services/project.ts +0 -114
- package/src/services/shutdown.ts +0 -130
- package/src/utils/convert-path-to-valid-file-name.ts +0 -39
- package/src/utils/debounce.ts +0 -23
- package/src/utils/format-timestamp.ts +0 -17
- package/src/utils/index.ts +0 -3
- package/tsconfig.json +0 -40
- /package/{lib/app.js → app.js} +0 -0
- /package/{lib/commands → commands}/plugin/plugin-add.js +0 -0
- /package/{lib/commands → commands}/plugin/plugin-command.js +0 -0
- /package/{lib/commands → commands}/plugin/plugin-disable.js +0 -0
- /package/{lib/commands → commands}/plugin/plugin-enable.js +0 -0
- /package/{lib/commands → commands}/plugin/plugin-list.js +0 -0
- /package/{lib/commands → commands}/plugin/plugin-remove.js +0 -0
- /package/{lib/commands → commands}/plugin/plugin.js +0 -0
- /package/{lib/commands → commands}/project/project-add.js +0 -0
- /package/{lib/commands → commands}/project/project-command.js +0 -0
- /package/{lib/commands → commands}/project/project-list.js +0 -0
- /package/{lib/commands → commands}/project/project-remove.js +0 -0
- /package/{lib/commands → commands}/project/project-state-command.js +0 -0
- /package/{lib/commands → commands}/project/project-status.js +0 -0
- /package/{lib/commands → commands}/project/project-stop.js +0 -0
- /package/{lib/commands → commands}/project/project-validate.js +0 -0
- /package/{lib/commands → commands}/project/project.js +0 -0
- /package/{lib/commands → commands}/runium-command.js +0 -0
- /package/{lib/constants → constants}/error-code.js +0 -0
- /package/{lib/index.js → index.js} +0 -0
- /package/{lib/macros → macros}/conditional.js +0 -0
- /package/{lib/macros → macros}/empty.js +0 -0
- /package/{lib/macros → macros}/env.js +0 -0
- /package/{lib/macros → macros}/path.js +0 -0
- /package/{lib/services → services}/config.js +0 -0
- /package/{lib/services → services}/output.js +0 -0
- /package/{lib/services → services}/plugin.js +0 -0
- /package/{lib/services → services}/profile.js +0 -0
- /package/{lib/services → services}/project.js +0 -0
- /package/{lib/utils → utils}/convert-path-to-valid-file-name.js +0 -0
- /package/{lib/utils → utils}/debounce.js +0 -0
- /package/{lib/utils → utils}/format-timestamp.js +0 -0
|
File without changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{dirname as d}from"node:path";import{Option as j}from"commander";import{Container as m}from"typedi";import{ProjectEvent as p,RuniumError as h}from"@runium/core";import{ErrorCode as u}from"../../constants/index.js";import{ShutdownService as P}from"../../services/index.js";import{debounce as f}from"../../utils/index.js";import{ProjectStateCommand as w}from"./project-state-command.js";const S=100;class b extends w{shutdownService;constructor(t){super(t),this.shutdownService=m.get(P)}config(){this.command.name("start").description("start project").option("-f, --file","use file path instead of project name").option("-o, --output","output project state changes").addOption(new j("-w, --working-dir <choice>","set working directory").choices(["cwd","project"]).default("cwd")).argument("<name>","project name")}async handle(t,{file:
|
|
1
|
+
import{dirname as d}from"node:path";import{Option as j}from"commander";import{Container as m}from"typedi";import{ProjectEvent as p,RuniumError as h}from"@runium/core";import{ErrorCode as u}from"../../constants/index.js";import{ShutdownService as P}from"../../services/index.js";import{debounce as f}from"../../utils/index.js";import{ProjectStateCommand as w}from"./project-state-command.js";const S=100;class b extends w{shutdownService;constructor(t){super(t),this.shutdownService=m.get(P)}config(){this.command.name("start").description("start project").option("-f, --file","use file path instead of project name").option("-o, --output","output project state changes").addOption(new j("-w, --working-dir <choice>","set working directory").choices(["cwd","project"]).default("cwd")).argument("<name>","project name")}async handle(t,{file:a,workingDir:c,output:n}){const i=a?this.projectService.resolvePath(t):this.ensureProfileProject(t).path,r=this.getProjectDataFileName(a?i:t),s=await this.readProjectData(r);if(s&&this.isProjectProcessStarted(s.pid))throw new h(`Project "${t}" is already started`,u.PROJECT_ALREADY_STARTED,{name:t});if(c==="project"){const o=d(i);o!==process.cwd()&&process.chdir(o)}const e=await this.projectService.initProject(i);this.shutdownService.addBlocker(o=>e.stop(o)),this.addProjectListeners(e,{dataFileName:r,projectPath:i,output:n}),await e.start()}addProjectListeners(t,a){const{dataFileName:c,projectPath:n,output:i}=a,r={id:t.getConfig().id,pid:process.pid,cwd:process.cwd(),path:n,state:{project:[],tasks:{}}},s=f(()=>{this.writeProjectData(r,c)},S);s(),t.on(p.STATE_CHANGE,async e=>{r.state.project.push(e),s(),i&&this.outputService.info("Project %s",e.status)}),t.on(p.TASK_STATE_CHANGE,(e,o)=>{r.state.tasks[e]||(r.state.tasks[e]=[]),r.state.tasks[e].push(o),s(),i&&this.outputService.info("Task %s %s %s",e,o.status,o.exitCode||o.error||"")})}}export{b as ProjectStartCommand};
|
|
File without changes
|
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,44 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@runium/cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"description": "Runium CLI",
|
|
5
5
|
"author": "TheBeastApp",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"type": "module",
|
|
8
|
-
"module": "./lib/index.js",
|
|
9
8
|
"bin": {
|
|
10
|
-
"runium": "./
|
|
9
|
+
"runium": "./index.js"
|
|
11
10
|
},
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
"build:tsc": "rimraf ./lib && tsc",
|
|
15
|
-
"start": "node lib/index.js",
|
|
16
|
-
"lint": "eslint ./src --ext .ts",
|
|
17
|
-
"lint:fix": "eslint ./src --ext .ts --fix",
|
|
18
|
-
"format": "prettier --write \"src/**/*.ts\""
|
|
11
|
+
"engines": {
|
|
12
|
+
"node": ">=20.10.0"
|
|
19
13
|
},
|
|
14
|
+
"module": "./index.js",
|
|
20
15
|
"dependencies": {
|
|
21
|
-
"@runium/core": "^0.0.
|
|
16
|
+
"@runium/core": "^0.0.4",
|
|
22
17
|
"commander": "^14.0.2",
|
|
23
18
|
"reflect-metadata": "^0.2.2",
|
|
24
19
|
"typedi": "^0.10.0"
|
|
25
|
-
},
|
|
26
|
-
"devDependencies": {
|
|
27
|
-
"@types/node": "^22.18.0",
|
|
28
|
-
"@typescript-eslint/eslint-plugin": "^7.0.0",
|
|
29
|
-
"@typescript-eslint/parser": "^7.0.0",
|
|
30
|
-
"esbuild": "^0.25.11",
|
|
31
|
-
"esbuild-decorators": "^1.0.0",
|
|
32
|
-
"eslint": "^8.56.0",
|
|
33
|
-
"eslint-config-prettier": "^9.1.0",
|
|
34
|
-
"eslint-plugin-prettier": "^5.1.3",
|
|
35
|
-
"prettier": "^3.2.5",
|
|
36
|
-
"rimraf": "^6.1.0",
|
|
37
|
-
"ts-node": "^10.9.2",
|
|
38
|
-
"tsc-alias": "^1.8.16",
|
|
39
|
-
"typescript": "^5.3.3"
|
|
40
|
-
},
|
|
41
|
-
"engines": {
|
|
42
|
-
"node": ">=20.12.0"
|
|
43
20
|
}
|
|
44
|
-
}
|
|
21
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var v=function(i,e,t,o){var n=arguments.length,r=n<3?e:o===null?o=Object.getOwnPropertyDescriptor(e,t):o,u;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")r=Reflect.decorate(i,e,t,o);else for(var c=i.length-1;c>=0;c--)(u=i[c])&&(r=(n<3?u(r):n>3?u(e,t,r):u(e,t))||r);return n>3&&r&&Object.defineProperty(e,t,r),r},h=function(i,e){if(typeof Reflect=="object"&&typeof Reflect.metadata=="function")return Reflect.metadata(i,e)},l=function(i,e){return function(t,o){e(t,o,i)}},s,f;import{Inject as d,Service as S}from"typedi";import{RuniumError as _,isRuniumError as g,RuniumTask as j,RuniumTrigger as R,readJsonFile as w,writeJsonFile as O,applyMacros as y,Task as L,TaskEvent as P,TaskStatus as T,ProjectEvent as k,ProjectStatus as B}from"@runium/core";import{RuniumCommand as E}from"../commands/runium-command.js";import{OutputLevel as m,OutputService as p,ShutdownService as b}from"./index.js";global.runium=null;let a=class{outputService;shutdownService;constructor(e,t){this.outputService=e,this.shutdownService=t}async init(){const e=this.outputService,t=this.shutdownService,o={class:{RuniumCommand:E,RuniumError:_,RuniumTask:j,RuniumTrigger:R,Task:L},enum:{OutputLevel:Object.keys(m).filter(n=>isNaN(Number(n))).reduce((n,r)=>(n[r]=m[r],n),{}),ProjectEvent:k,ProjectStatus:B,TaskEvent:P,TaskStatus:T},utils:{applyMacros:y,isRuniumError:g,readJsonFile:w,writeJsonFile:O},output:{getLevel:e.getLevel.bind(e),setLevel:e.setLevel.bind(e),trace:e.trace.bind(e),debug:e.debug.bind(e),info:e.info.bind(e),warn:e.warn.bind(e),error:e.error.bind(e),table:e.table.bind(e),log:e.log.bind(e)},shutdown:{addBlocker:t.addBlocker.bind(t),removeBlocker:t.removeBlocker.bind(t)}};global.runium=Object.freeze(o)}};a=v([S(),l(0,d()),l(1,d()),h("design:paramtypes",[typeof(s=typeof p<"u"&&p)=="function"?s:Object,typeof(f=typeof b<"u"&&b)=="function"?f:Object])],a);export{a as PluginContextService};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var d=function(i,t,e,o){var s=arguments.length,r=s<3?t:o===null?o=Object.getOwnPropertyDescriptor(t,e):o,c;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")r=Reflect.decorate(i,t,e,o);else for(var n=i.length-1;n>=0;n--)(c=i[n])&&(r=(s<3?c(r):s>3?c(t,e,r):c(t,e))||r);return s>3&&r&&Object.defineProperty(t,e,r),r},f=function(i,t){if(typeof Reflect=="object"&&typeof Reflect.metadata=="function")return Reflect.metadata(i,t)},l=function(i,t){return function(e,o){t(e,o,i)}},a;import{Inject as m,Service as S}from"typedi";import{OutputService as h}from"./index.js";const p=3e4,w=250,v=["SIGHUP","SIGINT","SIGTERM","SIGQUIT"];let u=class{outputService;blockers=new Set;isShuttingDown=!1;constructor(t){this.outputService=t}async init(){v.forEach(t=>{process.on(t,()=>{this.shutdown(t).catch(e=>{this.outputService.error("Error during shutdown: %s",e.message),this.outputService.debug("Error details:",e),process.exit(1)})})}),process.on("uncaughtException",t=>{this.outputService.error("Uncaught exception: %s",t.message),this.outputService.debug("Error details:",t),this.shutdown("uncaughtException").catch(()=>{process.exit(1)})}),process.on("unhandledRejection",(t,e)=>{this.outputService.error("Unhandled rejection at:",e,"reason:",t),this.outputService.debug("Error details:",{reason:t,promise:e}),this.shutdown("unhandledRejection").catch(()=>{process.exit(1)})}),process.on("beforeExit",()=>{this.isShuttingDown||this.shutdown("exit").catch(()=>{process.exit(1)})})}addBlocker(t){this.blockers.add(t)}removeBlocker(t){return this.blockers.delete(t)}async shutdown(t){if(this.isShuttingDown||!t)return;this.isShuttingDown=!0;const e=o=>{setTimeout(()=>{process.exit(o)},w)};if(this.blockers.size===0){e(0);return}try{await this.executeBlockersWithTimeout(t),e(0)}catch{e(1)}}async executeBlockersWithTimeout(t){const e=Array.from(this.blockers).map(s=>this.executeBlocker(s,t)),o=new Promise((s,r)=>{setTimeout(()=>{r(new Error(`Shutdown timeout after ${p}ms`))},p)});await Promise.race([Promise.allSettled(e),o])}async executeBlocker(t,e){await t(e)}};u=d([S(),l(0,m()),f("design:paramtypes",[typeof(a=typeof h<"u"&&h)=="function"?a:Object])],u);export{u as ShutdownService};
|
|
File without changes
|
package/.eslintrc.json
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"env": {
|
|
3
|
-
"node": true,
|
|
4
|
-
"es2022": true
|
|
5
|
-
},
|
|
6
|
-
"extends": [
|
|
7
|
-
"eslint:recommended",
|
|
8
|
-
"plugin:@typescript-eslint/recommended",
|
|
9
|
-
"plugin:prettier/recommended"
|
|
10
|
-
],
|
|
11
|
-
"parser": "@typescript-eslint/parser",
|
|
12
|
-
"parserOptions": {
|
|
13
|
-
"ecmaVersion": 2022,
|
|
14
|
-
"sourceType": "module"
|
|
15
|
-
},
|
|
16
|
-
"plugins": ["@typescript-eslint", "prettier"],
|
|
17
|
-
"rules": {
|
|
18
|
-
"prettier/prettier": "error",
|
|
19
|
-
"@typescript-eslint/no-unused-vars": [
|
|
20
|
-
"error",
|
|
21
|
-
{
|
|
22
|
-
"argsIgnorePattern": "^_",
|
|
23
|
-
"varsIgnorePattern": "^_"
|
|
24
|
-
}
|
|
25
|
-
],
|
|
26
|
-
"@typescript-eslint/no-explicit-any": "warn",
|
|
27
|
-
"no-console": "warn",
|
|
28
|
-
"@typescript-eslint/ban-ts-ignore": "off"
|
|
29
|
-
},
|
|
30
|
-
"ignorePatterns": ["dist/", "node_modules/"]
|
|
31
|
-
}
|
package/.prettierrc.json
DELETED
package/README.md
DELETED
package/build.js
DELETED
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
chmodSync,
|
|
5
|
-
existsSync,
|
|
6
|
-
mkdirSync,
|
|
7
|
-
readFileSync,
|
|
8
|
-
writeFileSync,
|
|
9
|
-
} from 'node:fs';
|
|
10
|
-
import { resolve } from 'node:path';
|
|
11
|
-
import { build } from 'esbuild';
|
|
12
|
-
import { esbuildDecorators } from 'esbuild-decorators';
|
|
13
|
-
|
|
14
|
-
const buildConfig = {
|
|
15
|
-
entryPoints: ['src/**/*.ts'],
|
|
16
|
-
bundle: false,
|
|
17
|
-
platform: 'node',
|
|
18
|
-
target: 'esnext',
|
|
19
|
-
format: 'esm',
|
|
20
|
-
outdir: 'lib',
|
|
21
|
-
sourcemap: false,
|
|
22
|
-
minify: true,
|
|
23
|
-
treeShaking: false,
|
|
24
|
-
plugins: [
|
|
25
|
-
esbuildDecorators({
|
|
26
|
-
experimentalDecorators: true,
|
|
27
|
-
emitDecoratorMetadata: true,
|
|
28
|
-
customDecoratorHandler: undefined,
|
|
29
|
-
}),
|
|
30
|
-
],
|
|
31
|
-
metafile: true,
|
|
32
|
-
logLevel: 'info',
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
async function buildProject() {
|
|
36
|
-
try {
|
|
37
|
-
console.log('🔨 Building project with esbuild...');
|
|
38
|
-
|
|
39
|
-
const libDir = 'lib';
|
|
40
|
-
if (!existsSync(libDir)) {
|
|
41
|
-
mkdirSync(libDir, { recursive: true });
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const result = await build(buildConfig);
|
|
45
|
-
|
|
46
|
-
if (process.platform !== 'win32') {
|
|
47
|
-
try {
|
|
48
|
-
chmodSync('lib/index.js', '755');
|
|
49
|
-
console.log('🔐 Made lib/index.js executable');
|
|
50
|
-
} catch (error) {
|
|
51
|
-
console.warn('⚠️ Could not make file executable:', error.message);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
console.log('🔨 Processing package.json...');
|
|
56
|
-
await processPackageJson();
|
|
57
|
-
|
|
58
|
-
console.log('✅ Build completed successfully!');
|
|
59
|
-
|
|
60
|
-
// Print build stats if in development mode
|
|
61
|
-
if (result.metafile) {
|
|
62
|
-
console.log('\n📊 Build statistics:');
|
|
63
|
-
const outputs = result.metafile.outputs;
|
|
64
|
-
for (const [file, info] of Object.entries(outputs)) {
|
|
65
|
-
console.log(` ${file}: ${(info.bytes / 1024).toFixed(2)} KB`);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
} catch (error) {
|
|
69
|
-
console.error('❌ Build failed:', error);
|
|
70
|
-
process.exit(1);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
async function processPackageJson() {
|
|
75
|
-
let originalPackageJson = readFileSync('./package.json', {
|
|
76
|
-
encoding: 'utf-8',
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
let packageJson = JSON.parse(originalPackageJson);
|
|
80
|
-
const { dependencies } = packageJson;
|
|
81
|
-
|
|
82
|
-
delete packageJson.dependencies;
|
|
83
|
-
delete packageJson.devDependencies;
|
|
84
|
-
delete packageJson.scripts;
|
|
85
|
-
delete packageJson.module;
|
|
86
|
-
delete packageJson.main;
|
|
87
|
-
|
|
88
|
-
console.log('✅ Processed package.json', packageJson);
|
|
89
|
-
|
|
90
|
-
packageJson = Object.assign(packageJson, {
|
|
91
|
-
module: './index.js',
|
|
92
|
-
bin: {
|
|
93
|
-
runium: './index.js',
|
|
94
|
-
},
|
|
95
|
-
dependencies,
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
writeFileSync(
|
|
99
|
-
resolve(import.meta.dirname, 'lib', 'package.json'),
|
|
100
|
-
JSON.stringify(packageJson, null, 2)
|
|
101
|
-
);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
buildProject();
|
package/lib/package.json
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@runium/cli",
|
|
3
|
-
"version": "0.0.1",
|
|
4
|
-
"description": "Runium CLI",
|
|
5
|
-
"author": "TheBeastApp",
|
|
6
|
-
"license": "MIT",
|
|
7
|
-
"type": "module",
|
|
8
|
-
"bin": {
|
|
9
|
-
"runium": "./index.js"
|
|
10
|
-
},
|
|
11
|
-
"engines": {
|
|
12
|
-
"node": ">=20.12.0"
|
|
13
|
-
},
|
|
14
|
-
"module": "./index.js",
|
|
15
|
-
"dependencies": {
|
|
16
|
-
"@runium/core": "^0.0.3",
|
|
17
|
-
"commander": "^14.0.2",
|
|
18
|
-
"reflect-metadata": "^0.2.2",
|
|
19
|
-
"typedi": "^0.10.0"
|
|
20
|
-
}
|
|
21
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var v=function(i,e,t,o){var n=arguments.length,r=n<3?e:o===null?o=Object.getOwnPropertyDescriptor(e,t):o,u;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")r=Reflect.decorate(i,e,t,o);else for(var c=i.length-1;c>=0;c--)(u=i[c])&&(r=(n<3?u(r):n>3?u(e,t,r):u(e,t))||r);return n>3&&r&&Object.defineProperty(e,t,r),r},h=function(i,e){if(typeof Reflect=="object"&&typeof Reflect.metadata=="function")return Reflect.metadata(i,e)},l=function(i,e){return function(t,o){e(t,o,i)}},f,s;import{Inject as d,Service as S}from"typedi";import{RuniumError as _,isRuniumError as g,RuniumTask as j,RuniumTrigger as R,readJsonFile as w,writeJsonFile as O,applyMacros as y,TaskStatus as L,ProjectEvent as P,ProjectStatus as B}from"@runium/core";import{RuniumCommand as x}from"../commands/runium-command.js";import{OutputLevel as m,OutputService as p,ShutdownService as b}from"./index.js";global.runium=null;let a=class{outputService;shutdownService;constructor(e,t){this.outputService=e,this.shutdownService=t}async init(){const e=this.outputService,t=this.shutdownService,o={class:{RuniumCommand:x,RuniumError:_,RuniumTask:j,RuniumTrigger:R},enum:{OutputLevel:Object.keys(m).filter(n=>isNaN(Number(n))).reduce((n,r)=>(n[r]=m[r],n),{}),ProjectEvent:P,ProjectStatus:B,TaskStatus:L},utils:{applyMacros:y,isRuniumError:g,readJsonFile:w,writeJsonFile:O},output:{getLevel:e.getLevel.bind(e),setLevel:e.setLevel.bind(e),trace:e.trace.bind(e),debug:e.debug.bind(e),info:e.info.bind(e),warn:e.warn.bind(e),error:e.error.bind(e),table:e.table.bind(e),log:e.log.bind(e)},shutdown:{addBlocker:t.addBlocker.bind(t),removeBlocker:t.removeBlocker.bind(t)}};global.runium=Object.freeze(o)}};a=v([S(),l(0,d()),l(1,d()),h("design:paramtypes",[typeof(f=typeof p<"u"&&p)=="function"?f:Object,typeof(s=typeof b<"u"&&b)=="function"?s:Object])],a);export{a as PluginContextService};
|
package/lib/services/shutdown.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var d=function(r,e,t,o){var s=arguments.length,i=s<3?e:o===null?o=Object.getOwnPropertyDescriptor(e,t):o,c;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")i=Reflect.decorate(r,e,t,o);else for(var n=r.length-1;n>=0;n--)(c=r[n])&&(i=(s<3?c(i):s>3?c(e,t,i):c(e,t))||i);return s>3&&i&&Object.defineProperty(e,t,i),i},f=function(r,e){if(typeof Reflect=="object"&&typeof Reflect.metadata=="function")return Reflect.metadata(r,e)},l=function(r,e){return function(t,o){e(t,o,r)}},a;import{Inject as m,Service as S}from"typedi";import{OutputService as h}from"./index.js";const p=3e4,w=250,v=["SIGHUP","SIGINT","SIGTERM","SIGQUIT"];let u=class{outputService;blockers=new Set;isShuttingDown=!1;constructor(e){this.outputService=e}async init(){v.forEach(e=>{process.on(e,()=>{this.shutdown(e).catch(t=>{this.outputService.error("Error during shutdown: %s",t.message),this.outputService.debug("Error details:",t),process.exit(1)})})}),process.on("uncaughtException",e=>{this.outputService.error("Uncaught exception: %s",e.message),this.outputService.debug("Error details:",e),this.shutdown("uncaughtException").catch(()=>{process.exit(1)})}),process.on("unhandledRejection",(e,t)=>{this.outputService.error("Unhandled rejection at:",t,"reason:",e),this.outputService.debug("Error details:",{reason:e,promise:t}),this.shutdown("unhandledRejection").catch(()=>{process.exit(1)})}),process.on("beforeExit",()=>{this.isShuttingDown||this.shutdown("exit").catch(()=>{process.exit(1)})})}addBlocker(e){this.blockers.add(e)}removeBlocker(e){return this.blockers.delete(e)}async shutdown(e){if(this.isShuttingDown||!e)return;this.isShuttingDown=!0;const t=o=>{setTimeout(()=>{process.exit(o)},w)};if(this.blockers.size===0){t(0);return}try{await this.executeBlockersWithTimeout(),t(0)}catch{t(1)}}async executeBlockersWithTimeout(){const e=Array.from(this.blockers).map(o=>this.executeBlocker(o)),t=new Promise((o,s)=>{setTimeout(()=>{s(new Error(`Shutdown timeout after ${p}ms`))},p)});await Promise.race([Promise.allSettled(e),t])}async executeBlocker(e){await e()}};u=d([S(),l(0,m()),f("design:paramtypes",[typeof(a=typeof h<"u"&&h)=="function"?a:Object])],u);export{u as ShutdownService};
|
package/src/app.ts
DELETED
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
import { existsSync } from 'node:fs';
|
|
2
|
-
import { resolve } from 'node:path';
|
|
3
|
-
import { Command } from 'commander';
|
|
4
|
-
import { Container } from 'typedi';
|
|
5
|
-
import { RuniumError } from '@runium/core';
|
|
6
|
-
import { RuniumCommand } from '@commands/runium-command';
|
|
7
|
-
import * as commands from '@commands';
|
|
8
|
-
import {
|
|
9
|
-
ConfigService,
|
|
10
|
-
ProfileService,
|
|
11
|
-
PluginService,
|
|
12
|
-
ShutdownService,
|
|
13
|
-
OutputService,
|
|
14
|
-
OutputLevel,
|
|
15
|
-
PluginContextService,
|
|
16
|
-
} from '@services';
|
|
17
|
-
|
|
18
|
-
const RUNIUM_DESCRIPTION = `╔═══════════════════════╗
|
|
19
|
-
║ ╔═╗ ╦ ╦ ╔╗╔ ╦ ╦ ╦ ╔╦╗ ║
|
|
20
|
-
║ ╠╦╝ ║ ║ ║║║ ║ ║ ║ ║║║ ║
|
|
21
|
-
║ ╩╚═ ╚═╝ ╝╚╝ ╩ ╚═╝ ╩ ╩ ║
|
|
22
|
-
╚═══════════════════════╝
|
|
23
|
-
One Tool to Run Them All!`;
|
|
24
|
-
|
|
25
|
-
export class RuniumCliApp {
|
|
26
|
-
private readonly program: Command;
|
|
27
|
-
|
|
28
|
-
private configService: ConfigService;
|
|
29
|
-
private profileService: ProfileService;
|
|
30
|
-
private pluginService: PluginService;
|
|
31
|
-
private shutdownService: ShutdownService;
|
|
32
|
-
private outputService: OutputService;
|
|
33
|
-
private pluginContextService: PluginContextService;
|
|
34
|
-
|
|
35
|
-
constructor() {
|
|
36
|
-
this.program = new Command('runium');
|
|
37
|
-
this.configService = Container.get(ConfigService);
|
|
38
|
-
this.profileService = Container.get(ProfileService);
|
|
39
|
-
this.pluginService = Container.get(PluginService);
|
|
40
|
-
this.shutdownService = Container.get(ShutdownService);
|
|
41
|
-
this.outputService = Container.get(OutputService);
|
|
42
|
-
this.pluginContextService = Container.get(PluginContextService);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Start the application
|
|
47
|
-
*/
|
|
48
|
-
async start(): Promise<Command> {
|
|
49
|
-
await this.shutdownService.init();
|
|
50
|
-
await this.configService.init();
|
|
51
|
-
await this.profileService.init();
|
|
52
|
-
await this.pluginContextService.init();
|
|
53
|
-
|
|
54
|
-
this.initOutput();
|
|
55
|
-
this.initEnv();
|
|
56
|
-
|
|
57
|
-
await this.loadPlugins();
|
|
58
|
-
await this.initProgram();
|
|
59
|
-
|
|
60
|
-
return this.program.parseAsync();
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Load plugins
|
|
65
|
-
*/
|
|
66
|
-
private async loadPlugins(): Promise<void> {
|
|
67
|
-
const plugins = this.profileService.getPlugins();
|
|
68
|
-
for (const plugin of plugins) {
|
|
69
|
-
if (plugin.disabled !== true) {
|
|
70
|
-
try {
|
|
71
|
-
const pluginPath = this.pluginService.resolvePath(
|
|
72
|
-
plugin.path,
|
|
73
|
-
plugin.file
|
|
74
|
-
);
|
|
75
|
-
await this.pluginService.loadPlugin(pluginPath);
|
|
76
|
-
} catch (error) {
|
|
77
|
-
this.outputService.error(`Failed to load plugin "${plugin.name}"`);
|
|
78
|
-
const { code, message, payload } = error as RuniumError;
|
|
79
|
-
this.outputService.debug('Error details:', {
|
|
80
|
-
message,
|
|
81
|
-
code,
|
|
82
|
-
payload,
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Initialize the program
|
|
91
|
-
*/
|
|
92
|
-
private async initProgram(): Promise<void> {
|
|
93
|
-
const program = this.program;
|
|
94
|
-
|
|
95
|
-
program.option('-D, --debug', 'enable debug mode');
|
|
96
|
-
program.option('-e, --env [paths...]', 'load env files');
|
|
97
|
-
program.version(await this.getVersion());
|
|
98
|
-
program.description(RUNIUM_DESCRIPTION);
|
|
99
|
-
|
|
100
|
-
program.on('option:debug', () => {
|
|
101
|
-
this.setDebugMode();
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
program.on('option:env', path => {
|
|
105
|
-
this.loadEnvFiles([path]);
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
const programCommands: RuniumCommand[] = [];
|
|
109
|
-
Object.values(commands).forEach(CommandConstructor => {
|
|
110
|
-
programCommands.push(new CommandConstructor(program));
|
|
111
|
-
});
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* Initialize the output
|
|
116
|
-
*/
|
|
117
|
-
private initOutput(): void {
|
|
118
|
-
const output = this.configService.get('output');
|
|
119
|
-
if (
|
|
120
|
-
output.debug ||
|
|
121
|
-
process.argv.includes('-D') ||
|
|
122
|
-
process.argv.includes('--debug')
|
|
123
|
-
) {
|
|
124
|
-
this.setDebugMode();
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* Set debug mode
|
|
130
|
-
*/
|
|
131
|
-
private setDebugMode(): void {
|
|
132
|
-
if (this.outputService.getLevel() !== OutputLevel.DEBUG) {
|
|
133
|
-
this.outputService.setLevel(OutputLevel.DEBUG);
|
|
134
|
-
this.outputService.debug('Debug mode enabled');
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* Initialize the environment
|
|
140
|
-
*/
|
|
141
|
-
private initEnv(): void {
|
|
142
|
-
const env = this.configService.get('env');
|
|
143
|
-
if (env.path.length > 0) {
|
|
144
|
-
this.loadEnvFiles(env.path);
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Set environment variables
|
|
150
|
-
* @param path
|
|
151
|
-
*/
|
|
152
|
-
private loadEnvFiles(path: string[]): void {
|
|
153
|
-
for (const p of path) {
|
|
154
|
-
if (p) {
|
|
155
|
-
if (existsSync(p)) {
|
|
156
|
-
process.loadEnvFile(resolve(p));
|
|
157
|
-
} else {
|
|
158
|
-
this.outputService.debug(`Env file "${p}" not found`);
|
|
159
|
-
}
|
|
160
|
-
} else {
|
|
161
|
-
process.loadEnvFile();
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
/**
|
|
166
|
-
* Get version from package.json
|
|
167
|
-
*/
|
|
168
|
-
private async getVersion(): Promise<string> {
|
|
169
|
-
// @ts-expect-error incorrect path for src but not build
|
|
170
|
-
const packageJson = await import(`./package.json`, {
|
|
171
|
-
with: { type: 'json' },
|
|
172
|
-
});
|
|
173
|
-
return packageJson.default.version;
|
|
174
|
-
}
|
|
175
|
-
}
|
package/src/commands/index.ts
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { RuniumError } from '@runium/core';
|
|
2
|
-
import { ErrorCode } from '@constants';
|
|
3
|
-
import { PluginCommand } from './plugin-command.js';
|
|
4
|
-
/**
|
|
5
|
-
* Plugin add command
|
|
6
|
-
*/
|
|
7
|
-
export class PluginAddCommand extends PluginCommand {
|
|
8
|
-
/**
|
|
9
|
-
* Config command
|
|
10
|
-
*/
|
|
11
|
-
protected config(): void {
|
|
12
|
-
this.command
|
|
13
|
-
.name('add')
|
|
14
|
-
.description('add plugin')
|
|
15
|
-
.option('-f, --file', 'use file path instead of plugin package name')
|
|
16
|
-
.argument('<plugin>', 'plugin package name or absolute file path');
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Handle command
|
|
21
|
-
* @param path
|
|
22
|
-
* @param file
|
|
23
|
-
*/
|
|
24
|
-
protected async handle(
|
|
25
|
-
path: string,
|
|
26
|
-
{ file: isFile }: { file: boolean }
|
|
27
|
-
): Promise<void> {
|
|
28
|
-
const pluginPath = this.pluginService.resolvePath(path, isFile);
|
|
29
|
-
const name = await this.pluginService.loadPlugin(pluginPath);
|
|
30
|
-
const plugin = this.pluginService.getPluginByName(name);
|
|
31
|
-
if (plugin) {
|
|
32
|
-
await this.profileService.addPlugin({
|
|
33
|
-
name,
|
|
34
|
-
path: isFile ? pluginPath : path,
|
|
35
|
-
file: isFile,
|
|
36
|
-
disabled: false,
|
|
37
|
-
options: {},
|
|
38
|
-
});
|
|
39
|
-
this.outputService.success(`Plugin "%s" successfully added`, name);
|
|
40
|
-
} else {
|
|
41
|
-
throw new RuniumError(
|
|
42
|
-
`Failed to add plugin "${path}"`,
|
|
43
|
-
ErrorCode.PLUGIN_NOT_FOUND,
|
|
44
|
-
{ name, path }
|
|
45
|
-
);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { Command } from 'commander';
|
|
2
|
-
import { Container } from 'typedi';
|
|
3
|
-
import { RuniumError } from '@runium/core';
|
|
4
|
-
import { RuniumCommand } from '@commands/runium-command.js';
|
|
5
|
-
import { ErrorCode } from '@constants';
|
|
6
|
-
import { PluginService, ProfileService, ProfilePlugin } from '@services';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Base plugin command
|
|
10
|
-
*/
|
|
11
|
-
export abstract class PluginCommand extends RuniumCommand {
|
|
12
|
-
protected pluginService: PluginService;
|
|
13
|
-
protected profileService: ProfileService;
|
|
14
|
-
|
|
15
|
-
constructor(parent: Command) {
|
|
16
|
-
super(parent);
|
|
17
|
-
this.pluginService = Container.get(PluginService);
|
|
18
|
-
this.profileService = Container.get(ProfileService);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Ensure plugin exists
|
|
23
|
-
* @param name
|
|
24
|
-
*/
|
|
25
|
-
protected ensureProfilePlugin(name: string): ProfilePlugin {
|
|
26
|
-
const plugin = this.profileService.getPluginByName(name);
|
|
27
|
-
if (!plugin) {
|
|
28
|
-
throw new RuniumError(
|
|
29
|
-
`Plugin "${name}" not found`,
|
|
30
|
-
ErrorCode.PLUGIN_NOT_FOUND,
|
|
31
|
-
{ name }
|
|
32
|
-
);
|
|
33
|
-
}
|
|
34
|
-
return plugin;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { PluginCommand } from './plugin-command.js';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Plugin disable command
|
|
5
|
-
*/
|
|
6
|
-
export class PluginDisableCommand extends PluginCommand {
|
|
7
|
-
/**
|
|
8
|
-
* Config command
|
|
9
|
-
*/
|
|
10
|
-
protected config(): void {
|
|
11
|
-
this.command
|
|
12
|
-
.name('disable')
|
|
13
|
-
.description('disable plugin')
|
|
14
|
-
.option('-a, --all', 'disable all plugins')
|
|
15
|
-
.argument('[plugin...]', 'plugin names');
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Handle command
|
|
20
|
-
* @param names
|
|
21
|
-
* @param all
|
|
22
|
-
*/
|
|
23
|
-
protected async handle(
|
|
24
|
-
names: string[],
|
|
25
|
-
{ all }: { all: boolean }
|
|
26
|
-
): Promise<void> {
|
|
27
|
-
if (names.length === 0 && !all) {
|
|
28
|
-
this.outputService.warn('No plugins specified to disable');
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
|
-
if (all) {
|
|
32
|
-
names = this.profileService.getPlugins().map(p => p.name);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
for (const name of names) {
|
|
36
|
-
const plugin = this.ensureProfilePlugin(name);
|
|
37
|
-
if (plugin.disabled) {
|
|
38
|
-
this.outputService.info(`Plugin "%s" is already disabled`, name);
|
|
39
|
-
continue;
|
|
40
|
-
}
|
|
41
|
-
await this.profileService.updatePlugin(name, { disabled: true });
|
|
42
|
-
await this.pluginService.unloadPlugin(name);
|
|
43
|
-
this.outputService.success(`Plugin "%s" successfully disabled`, name);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { PluginCommand } from './plugin-command.js';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Plugin enable command
|
|
5
|
-
*/
|
|
6
|
-
export class PluginEnableCommand extends PluginCommand {
|
|
7
|
-
/**
|
|
8
|
-
* Config command
|
|
9
|
-
*/
|
|
10
|
-
protected config(): void {
|
|
11
|
-
this.command
|
|
12
|
-
.name('enable')
|
|
13
|
-
.description('enable plugin')
|
|
14
|
-
.option('-a, --all', 'enable all plugins')
|
|
15
|
-
.argument('[plugin...]', 'plugin names');
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Handle command
|
|
20
|
-
* @param names
|
|
21
|
-
* @param all
|
|
22
|
-
*/
|
|
23
|
-
protected async handle(
|
|
24
|
-
names: string[],
|
|
25
|
-
{ all }: { all: boolean }
|
|
26
|
-
): Promise<void> {
|
|
27
|
-
if (names.length === 0 && !all) {
|
|
28
|
-
this.outputService.warn('No plugins specified to enable');
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
|
-
if (all) {
|
|
32
|
-
names = this.profileService.getPlugins().map(p => p.name);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
for (const name of names) {
|
|
36
|
-
const plugin = this.ensureProfilePlugin(name);
|
|
37
|
-
if (!plugin.disabled) {
|
|
38
|
-
this.outputService.info(`Plugin "%s" is already enabled`, name);
|
|
39
|
-
continue;
|
|
40
|
-
}
|
|
41
|
-
await this.profileService.updatePlugin(name, { disabled: false });
|
|
42
|
-
const pluginPath = this.pluginService.resolvePath(
|
|
43
|
-
plugin.path,
|
|
44
|
-
plugin.file
|
|
45
|
-
);
|
|
46
|
-
await this.pluginService.loadPlugin(pluginPath);
|
|
47
|
-
this.outputService.success(`Plugin "%s" successfully enabled`, name);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
}
|