@lappis/cg-manager 0.0.36 → 0.0.38

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/bin/cli.js ADDED
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ const { build } = require('../builder');
5
+
6
+ const args = process.argv.slice(2);
7
+
8
+ function flag(name) {
9
+ const eq = args.find(a => a.startsWith(`${name}=`));
10
+ if (eq !== undefined) return eq.slice(name.length + 1);
11
+
12
+ const i = args.indexOf(name);
13
+ if (i === -1) return undefined;
14
+
15
+ const value = args[i + 1];
16
+ if (value === undefined || value.startsWith('--')) {
17
+ console.error(`Missing value for ${name}`);
18
+ process.exit(1);
19
+ }
20
+ return value;
21
+ }
22
+
23
+ const [subcommand] = args;
24
+
25
+ if (subcommand !== 'package') {
26
+ console.error('Usage: cg-manager package [--dest <path>] [--out <name>]');
27
+ process.exit(1);
28
+ }
29
+
30
+ const options = {};
31
+
32
+ const dest = flag('--dest');
33
+ if (dest) options.dest = dest;
34
+
35
+ const out = flag('--out');
36
+ if (out) options.out = out;
37
+
38
+ build(options).then(ok => process.exit(ok ? 0 : 1)).catch(e => {
39
+ console.error(e);
40
+ process.exit(1);
41
+ });
@@ -0,0 +1,153 @@
1
+ 'use strict';
2
+
3
+ const { exec, execFile } = require('child_process');
4
+ const fss = require('fs');
5
+ const fs = fss.promises;
6
+ const path = require('path');
7
+ const archiver = require('archiver');
8
+
9
+ const MAX_BUFFER = 1024 * 1024 * 64;
10
+
11
+ function handle(resolve, reject) {
12
+ return (error, stdout, stderr) => {
13
+ if (error) {
14
+ console.error(stdout);
15
+ console.error(stderr);
16
+ reject(error);
17
+ return;
18
+ }
19
+
20
+ resolve(stdout ? stdout : stderr);
21
+ };
22
+ }
23
+
24
+ // Shell-interpreted; for user-provided step strings only.
25
+ function sh(root, command) {
26
+ return new Promise((resolve, reject) => {
27
+ exec(command, { cwd: root, maxBuffer: MAX_BUFFER }, handle(resolve, reject));
28
+ });
29
+ }
30
+
31
+ // argv-based, no shell — paths with spaces/special chars are passed verbatim.
32
+ function node(root, command, ...args) {
33
+ const bin = path.join(root, 'node_modules', command);
34
+ return new Promise((resolve, reject) => {
35
+ execFile('node', [bin, ...args], { cwd: root, maxBuffer: MAX_BUFFER }, handle(resolve, reject));
36
+ });
37
+ }
38
+
39
+ async function packageSource(ctx) {
40
+ const { root } = ctx;
41
+ console.log('Compiling plugin source...');
42
+ await node(root, path.join('webpack-cli', 'bin', 'cli'));
43
+ await fs.rm(path.join(root, 'dist', 'index.js.LICENSE.txt')).catch(() => null);
44
+ await fs.cp(path.join(root, 'package.json'), path.join(root, 'dist', 'package.json'));
45
+ // Full node_modules copy — externals need their deps at runtime.
46
+ // TODO: prune to transitive closure of pkg.dependencies once a safe walk is validated.
47
+ await fs.cp(path.join(root, 'node_modules'), path.join(root, 'dist', 'node_modules'), { recursive: true });
48
+ }
49
+
50
+ async function packageUI(ctx) {
51
+ const { root, ui } = ctx;
52
+ const uiDir = path.join(root, ui);
53
+ const exists = await fs.access(uiDir).then(() => true).catch(() => false);
54
+ if (!exists) return;
55
+
56
+ console.log('Packaging UI...');
57
+ await fs.cp(uiDir, path.join(root, 'dist', 'ui'), { recursive: true });
58
+ }
59
+
60
+ async function runSteps(ctx) {
61
+ const { root, steps } = ctx;
62
+ if (!steps || !steps.length) return;
63
+
64
+ for (const step of steps) {
65
+ if (typeof step === 'function') {
66
+ await step(ctx);
67
+ continue;
68
+ }
69
+
70
+ const { name, run } = typeof step === 'string' ? { name: step, run: step } : step;
71
+ console.log(`Running step: ${name}...`);
72
+ await sh(root, run);
73
+ }
74
+ }
75
+
76
+ async function assemble(ctx) {
77
+ const { root, out } = ctx;
78
+ const dest = path.join(root, out);
79
+
80
+ console.log('Packaging plugin...');
81
+ // Consumes dist — must run before archive/movePlugin.
82
+ await fs.rm(dest, { recursive: true }).catch(() => null);
83
+ await fs.rename(path.join(root, 'dist'), dest);
84
+ }
85
+
86
+ function archive(ctx) {
87
+ const { root, out, name } = ctx;
88
+ const src = path.join(root, out);
89
+ const dest = path.join(root, `${name}.cgplugin`);
90
+
91
+ console.log('Archiving plugin...');
92
+ return new Promise((resolve, reject) => {
93
+ const output = fss.createWriteStream(dest);
94
+ const zip = archiver('zip');
95
+
96
+ output.on('close', resolve);
97
+ output.on('error', reject);
98
+ zip.on('error', reject);
99
+
100
+ zip.pipe(output);
101
+ zip.directory(src, false);
102
+ zip.finalize().catch(reject);
103
+ });
104
+ }
105
+
106
+ async function movePlugin(ctx) {
107
+ const { root, out, dest } = ctx;
108
+ if (!dest) return;
109
+
110
+ console.log('Moving plugin...');
111
+
112
+ // dest is always the parent plugins directory; we only ever touch dest/out.
113
+ const target = path.join(path.resolve(root, dest), out);
114
+ const src = path.join(root, out);
115
+ await fs.rm(target, { recursive: true }).catch(() => null);
116
+ await fs.cp(src, target, { recursive: true });
117
+
118
+ console.log(`Plugin installed to ${target}`);
119
+ }
120
+
121
+ // Leave only the archive at root; the assembled dir lives at dest (if any).
122
+ async function cleanup(ctx) {
123
+ const { root, out } = ctx;
124
+ await fs.rm(path.join(root, out), { recursive: true }).catch(() => null);
125
+ }
126
+
127
+ async function build(options = {}) {
128
+ const root = options.root || process.cwd();
129
+ const pkg = JSON.parse(await fs.readFile(path.join(root, 'package.json'), 'utf8'));
130
+ const cfg = pkg.cgplugin || {};
131
+
132
+ const name = options.name || (pkg.name || '').replace(/^@[^/]+\//, '').replace(/[^a-z0-9_-]/gi, '-') || 'plugin';
133
+ const out = options.out || cfg.out || name;
134
+ const ui = options.ui || cfg.ui || 'ui';
135
+ const steps = options.steps !== undefined ? options.steps : (cfg.steps || []);
136
+ const dest = options.dest || cfg.dest || process.env.DEST || null;
137
+
138
+ const ctx = { root, name, out, ui, steps, dest };
139
+
140
+ const pipeline = [packageSource, packageUI, runSteps, assemble, archive, movePlugin, cleanup];
141
+ for (const step of pipeline) {
142
+ const failed = await step(ctx).then(() => false).catch(e => (console.error(e), true));
143
+ if (failed) {
144
+ console.error('Build failed!');
145
+ return false;
146
+ }
147
+ }
148
+
149
+ console.log('Build complete!');
150
+ return true;
151
+ }
152
+
153
+ module.exports = { build, packageSource, packageUI, runSteps, assemble, archive, movePlugin, cleanup };
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "repository": "https://github.com/Lapplandsveckan/cg-manager-plugin",
4
4
  "author": "firecraftgaming <eliyah@sundstroem.com>",
5
5
  "license": "MIT",
6
- "version": "0.0.36",
6
+ "version": "0.0.38",
7
7
  "main": "dist/index.js",
8
8
  "types": "dist/index.d.ts",
9
9
  "devDependencies": {
@@ -25,8 +25,13 @@
25
25
  "webpack": "^5.69.0",
26
26
  "webpack-cli": "^4.9.2"
27
27
  },
28
+ "bin": {
29
+ "cg-manager": "bin/cli.js"
30
+ },
28
31
  "files": [
29
32
  "dist",
33
+ "builder",
34
+ "bin",
30
35
  "LICENSE",
31
36
  "package.json"
32
37
  ],
@@ -40,6 +45,7 @@
40
45
  "lint:fix": "eslint src test --ext .ts --fix"
41
46
  },
42
47
  "dependencies": {
48
+ "archiver": "^7.0.1",
43
49
  "babel-loader": "^8.2.5",
44
50
  "no-try": "^3.1.0",
45
51
  "rest-exchange-protocol": "^0.0.16",