@automattic/vip 3.25.2-dev.0 → 3.25.3-dev.0
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/AGENTS.md +0 -6
- package/CLAUDE.md +0 -1
- package/dist/bin/vip-db-phpmyadmin.js +11 -4
- package/dist/bin/vip-dev-env-exec.js +1 -18
- package/dist/bin/vip-dev-env-start.js +8 -3
- package/dist/bin/vip.js +69 -111
- package/dist/commands/phpmyadmin.js +64 -16
- package/dist/lib/cli/command.js +53 -224
- package/dist/lib/cli/config.js +5 -13
- package/dist/lib/cli/exit.js +1 -2
- package/dist/lib/dev-environment/dev-environment-cli.js +2 -9
- package/dist/lib/dev-environment/dev-environment-core.js +6 -64
- package/dist/lib/dev-environment/dev-environment-lando.js +95 -53
- package/dist/lib/dev-environment/hosts-updater.js +184 -0
- package/npm-shrinkwrap.json +669 -933
- package/package.json +11 -14
- package/tsconfig.json +1 -7
- package/dist/bin/vip-sea.js +0 -19
- package/dist/lib/cli/internal-bin-loader.js +0 -81
- package/dist/lib/cli/runtime-mode.js +0 -21
- package/dist/lib/cli/sea-dispatch.js +0 -88
- package/dist/lib/cli/sea-runtime.js +0 -75
- package/dist/lib/dev-environment/lando-loader.js +0 -48
- package/docs/COMMANDER-MIGRATION.md +0 -55
- package/docs/SEA-BUILD-SIGNING.md +0 -171
- package/helpers/build-sea.js +0 -167
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@automattic/vip",
|
|
3
|
-
"version": "3.25.
|
|
3
|
+
"version": "3.25.3-dev.0",
|
|
4
4
|
"description": "The VIP Javascript library & CLI",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -72,13 +72,12 @@
|
|
|
72
72
|
"test": "npm run lint && npm run check-types && jest --coverage --testPathIgnorePatterns __tests__/devenv-e2e/",
|
|
73
73
|
"test:e2e:dev-env": "jest -c __tests__/devenv-e2e/jest/jest.config.js",
|
|
74
74
|
"clean": "node -e \"require('fs').rmSync('dist', { recursive: true, force: true })\"",
|
|
75
|
-
"cmd:format": "prettier
|
|
75
|
+
"cmd:format": "prettier '**/*.(js|json|jsx|md|ts|tsx|yml|yaml)'",
|
|
76
76
|
"cmd:lint": "eslint --ext 'js,jsx,ts,tsx'",
|
|
77
77
|
"prepare": "npm run clean && npm run build",
|
|
78
78
|
"check-types": "tsc",
|
|
79
79
|
"postinstall": "node ./helpers/check-version.js",
|
|
80
80
|
"build": "babel src -d dist --extensions=\".js,.ts\"",
|
|
81
|
-
"build:sea": "node ./helpers/build-sea.js",
|
|
82
81
|
"build:watch": "babel src -d dist --watch --source-maps --extensions=\".js,.ts\"",
|
|
83
82
|
"format": "npm run cmd:format -- --write",
|
|
84
83
|
"format:check": "npm run cmd:format -- --check",
|
|
@@ -115,7 +114,7 @@
|
|
|
115
114
|
"@automattic/eslint-plugin-wpvip": "^1.0.0",
|
|
116
115
|
"@babel/cli": "7.28.6",
|
|
117
116
|
"@babel/core": "7.29.0",
|
|
118
|
-
"@babel/preset-env": "7.29.
|
|
117
|
+
"@babel/preset-env": "7.29.3",
|
|
119
118
|
"@babel/preset-typescript": "7.28.5",
|
|
120
119
|
"@jest/globals": "^30.0.0",
|
|
121
120
|
"@jest/test-sequencer": "^30.0.0",
|
|
@@ -132,35 +131,33 @@
|
|
|
132
131
|
"@types/ssh2": "^1.15.4",
|
|
133
132
|
"@types/tar": "^7.0.87",
|
|
134
133
|
"@types/xml2js": "^0.4.14",
|
|
135
|
-
"dockerode": "^
|
|
136
|
-
"esbuild": "^0.27.3",
|
|
134
|
+
"dockerode": "^5.0.0",
|
|
137
135
|
"jest": "^30.0.0",
|
|
138
136
|
"nock": "13.5.6",
|
|
139
|
-
"postject": "^1.0.0-alpha.6",
|
|
140
137
|
"prettier": "npm:wp-prettier@3.0.3",
|
|
141
|
-
"typescript": "^
|
|
138
|
+
"typescript": "^6.0.2"
|
|
142
139
|
},
|
|
143
140
|
"dependencies": {
|
|
144
|
-
"@apollo/client": "4.1.
|
|
141
|
+
"@apollo/client": "4.1.9",
|
|
145
142
|
"@automattic/vip-search-replace": "^2.0.0",
|
|
146
143
|
"@json2csv/plainjs": "^7.0.3",
|
|
147
144
|
"@wwa/single-line-log": "^1.1.4",
|
|
145
|
+
"args": "5.0.3",
|
|
148
146
|
"chalk": "^5.6.2",
|
|
149
147
|
"check-disk-space": "3.4.0",
|
|
150
148
|
"cli-columns": "^4.0.0",
|
|
151
149
|
"cli-table3": "^0.6.3",
|
|
152
|
-
"commander": "^14.0.3",
|
|
153
150
|
"configstore": "^8.0.0",
|
|
154
151
|
"debug": "4.4.3",
|
|
155
152
|
"ejs": "^5.0.1",
|
|
156
153
|
"enquirer": "2.4.1",
|
|
157
154
|
"fetch-retry": "^6.0.0",
|
|
158
|
-
"graphql": "16.13.
|
|
155
|
+
"graphql": "16.13.2",
|
|
159
156
|
"graphql-tag": "2.12.6",
|
|
160
|
-
"https-proxy-agent": "^
|
|
157
|
+
"https-proxy-agent": "^9.0.0",
|
|
161
158
|
"js-yaml": "^4.1.0",
|
|
162
159
|
"jwt-decode": "4.0.0",
|
|
163
|
-
"lando": "github:automattic/lando-cli#
|
|
160
|
+
"lando": "github:automattic/lando-cli#78d382fcf40357c4a4cebe4a3cfaef032eab743a",
|
|
164
161
|
"node-fetch": "^3.3.2",
|
|
165
162
|
"node-stream-zip": "1.15.0",
|
|
166
163
|
"open": "^11.0.0",
|
|
@@ -169,7 +166,7 @@
|
|
|
169
166
|
"shelljs": "^0.10.0",
|
|
170
167
|
"socket.io-client": "^4.5.3",
|
|
171
168
|
"socket.io-stream": "npm:@wwa/socket.io-stream@^0.10.0",
|
|
172
|
-
"socks-proxy-agent": "^
|
|
169
|
+
"socks-proxy-agent": "^10.0.0",
|
|
173
170
|
"ssh2": "1.17.0",
|
|
174
171
|
"tar": "^7.4.0",
|
|
175
172
|
"update-notifier": "7.3.1",
|
package/tsconfig.json
CHANGED
|
@@ -3,23 +3,17 @@
|
|
|
3
3
|
"lib": [ "ES2022" ],
|
|
4
4
|
"module": "nodenext",
|
|
5
5
|
"strict": true,
|
|
6
|
-
"esModuleInterop": true,
|
|
7
6
|
"skipLibCheck": true,
|
|
8
7
|
"forceConsistentCasingInFileNames": true,
|
|
9
8
|
"moduleResolution": "nodenext",
|
|
9
|
+
"types": [ "node", "jest" ],
|
|
10
10
|
|
|
11
|
-
// Target latest version of ECMAScript.
|
|
12
11
|
"target": "ES2022",
|
|
13
|
-
// Don't parse types from JS as TS doesn't play well with Flow-ish JS.
|
|
14
|
-
"allowJs": false,
|
|
15
12
|
// Don't emit; allow Babel to transform files.
|
|
16
13
|
"noEmit": true,
|
|
17
|
-
// Can't checkJs if we don't allowJs, so this remains false
|
|
18
|
-
"checkJs": false,
|
|
19
14
|
// Disallow features that require cross-file information for emit as we're using Babel
|
|
20
15
|
"isolatedModules": true,
|
|
21
16
|
"resolveJsonModule": true,
|
|
22
|
-
"baseUrl": ".",
|
|
23
17
|
"paths": {
|
|
24
18
|
"*": [ "./types/*", "./node_modules/@types/node/*" ]
|
|
25
19
|
},
|
package/dist/bin/vip-sea.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
"use strict";
|
|
3
|
-
|
|
4
|
-
var _seaDispatch = require("../lib/cli/sea-dispatch");
|
|
5
|
-
var _seaRuntime = require("../lib/cli/sea-runtime");
|
|
6
|
-
const run = async () => {
|
|
7
|
-
if ((0, _seaDispatch.isSeaRuntime)()) {
|
|
8
|
-
process.env.VIP_CLI_SEA_MODE = '1';
|
|
9
|
-
await (0, _seaRuntime.prepareSeaRuntimeFilesystem)();
|
|
10
|
-
const resolution = (0, _seaDispatch.resolveInternalBinFromArgv)(process.argv);
|
|
11
|
-
if (resolution.bin !== 'vip') {
|
|
12
|
-
process.env.VIP_CLI_TARGET_BIN = resolution.bin;
|
|
13
|
-
process.env.VIP_CLI_TARGET_START = String(resolution.start);
|
|
14
|
-
process.env.VIP_CLI_TARGET_LENGTH = String(resolution.length);
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
await import('./vip.js');
|
|
18
|
-
};
|
|
19
|
-
void run();
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
exports.__esModule = true;
|
|
4
|
-
exports.hasInternalBin = hasInternalBin;
|
|
5
|
-
exports.internalBinNames = void 0;
|
|
6
|
-
exports.loadInternalBin = loadInternalBin;
|
|
7
|
-
const internalBinLoaders = {
|
|
8
|
-
vip: () => import('../../bin/vip'),
|
|
9
|
-
'vip-app': () => import('../../bin/vip-app'),
|
|
10
|
-
'vip-app-deploy': () => import('../../bin/vip-app-deploy'),
|
|
11
|
-
'vip-app-deploy-validate': () => import('../../bin/vip-app-deploy-validate'),
|
|
12
|
-
'vip-app-list': () => import('../../bin/vip-app-list'),
|
|
13
|
-
'vip-backup': () => import('../../bin/vip-backup'),
|
|
14
|
-
'vip-backup-db': () => import('../../bin/vip-backup-db'),
|
|
15
|
-
'vip-cache': () => import('../../bin/vip-cache'),
|
|
16
|
-
'vip-cache-purge-url': () => import('../../bin/vip-cache-purge-url'),
|
|
17
|
-
'vip-config': () => import('../../bin/vip-config'),
|
|
18
|
-
'vip-config-envvar': () => import('../../bin/vip-config-envvar'),
|
|
19
|
-
'vip-config-envvar-delete': () => import('../../bin/vip-config-envvar-delete'),
|
|
20
|
-
'vip-config-envvar-get': () => import('../../bin/vip-config-envvar-get'),
|
|
21
|
-
'vip-config-envvar-get-all': () => import('../../bin/vip-config-envvar-get-all'),
|
|
22
|
-
'vip-config-envvar-list': () => import('../../bin/vip-config-envvar-list'),
|
|
23
|
-
'vip-config-envvar-set': () => import('../../bin/vip-config-envvar-set'),
|
|
24
|
-
'vip-config-software': () => import('../../bin/vip-config-software'),
|
|
25
|
-
'vip-config-software-get': () => import('../../bin/vip-config-software-get'),
|
|
26
|
-
'vip-config-software-update': () => import('../../bin/vip-config-software-update'),
|
|
27
|
-
'vip-db': () => import('../../bin/vip-db'),
|
|
28
|
-
'vip-db-phpmyadmin': () => import('../../bin/vip-db-phpmyadmin'),
|
|
29
|
-
'vip-dev-env': () => import('../../bin/vip-dev-env'),
|
|
30
|
-
'vip-dev-env-create': () => import('../../bin/vip-dev-env-create'),
|
|
31
|
-
'vip-dev-env-destroy': () => import('../../bin/vip-dev-env-destroy'),
|
|
32
|
-
'vip-dev-env-envvar': () => import('../../bin/vip-dev-env-envvar'),
|
|
33
|
-
'vip-dev-env-envvar-delete': () => import('../../bin/vip-dev-env-envvar-delete'),
|
|
34
|
-
'vip-dev-env-envvar-get': () => import('../../bin/vip-dev-env-envvar-get'),
|
|
35
|
-
'vip-dev-env-envvar-get-all': () => import('../../bin/vip-dev-env-envvar-get-all'),
|
|
36
|
-
'vip-dev-env-envvar-list': () => import('../../bin/vip-dev-env-envvar-list'),
|
|
37
|
-
'vip-dev-env-envvar-set': () => import('../../bin/vip-dev-env-envvar-set'),
|
|
38
|
-
'vip-dev-env-exec': () => import('../../bin/vip-dev-env-exec'),
|
|
39
|
-
'vip-dev-env-import': () => import('../../bin/vip-dev-env-import'),
|
|
40
|
-
'vip-dev-env-import-media': () => import('../../bin/vip-dev-env-import-media'),
|
|
41
|
-
'vip-dev-env-import-sql': () => import('../../bin/vip-dev-env-import-sql'),
|
|
42
|
-
'vip-dev-env-info': () => import('../../bin/vip-dev-env-info'),
|
|
43
|
-
'vip-dev-env-list': () => import('../../bin/vip-dev-env-list'),
|
|
44
|
-
'vip-dev-env-logs': () => import('../../bin/vip-dev-env-logs'),
|
|
45
|
-
'vip-dev-env-purge': () => import('../../bin/vip-dev-env-purge'),
|
|
46
|
-
'vip-dev-env-shell': () => import('../../bin/vip-dev-env-shell'),
|
|
47
|
-
'vip-dev-env-start': () => import('../../bin/vip-dev-env-start'),
|
|
48
|
-
'vip-dev-env-stop': () => import('../../bin/vip-dev-env-stop'),
|
|
49
|
-
'vip-dev-env-sync': () => import('../../bin/vip-dev-env-sync'),
|
|
50
|
-
'vip-dev-env-sync-sql': () => import('../../bin/vip-dev-env-sync-sql'),
|
|
51
|
-
'vip-dev-env-update': () => import('../../bin/vip-dev-env-update'),
|
|
52
|
-
'vip-export': () => import('../../bin/vip-export'),
|
|
53
|
-
'vip-export-sql': () => import('../../bin/vip-export-sql'),
|
|
54
|
-
'vip-import': () => import('../../bin/vip-import'),
|
|
55
|
-
'vip-import-media': () => import('../../bin/vip-import-media'),
|
|
56
|
-
'vip-import-media-abort': () => import('../../bin/vip-import-media-abort'),
|
|
57
|
-
'vip-import-media-status': () => import('../../bin/vip-import-media-status'),
|
|
58
|
-
'vip-import-sql': () => import('../../bin/vip-import-sql'),
|
|
59
|
-
'vip-import-sql-status': () => import('../../bin/vip-import-sql-status'),
|
|
60
|
-
'vip-import-validate-files': () => import('../../bin/vip-import-validate-files'),
|
|
61
|
-
'vip-import-validate-sql': () => import('../../bin/vip-import-validate-sql'),
|
|
62
|
-
'vip-logout': () => import('../../bin/vip-logout'),
|
|
63
|
-
'vip-logs': () => import('../../bin/vip-logs'),
|
|
64
|
-
'vip-search-replace': () => import('../../bin/vip-search-replace'),
|
|
65
|
-
'vip-slowlogs': () => import('../../bin/vip-slowlogs'),
|
|
66
|
-
'vip-sync': () => import('../../bin/vip-sync'),
|
|
67
|
-
'vip-whoami': () => import('../../bin/vip-whoami'),
|
|
68
|
-
'vip-wp': () => import('../../bin/vip-wp')
|
|
69
|
-
};
|
|
70
|
-
const internalBinNames = exports.internalBinNames = Object.freeze(Object.keys(internalBinLoaders));
|
|
71
|
-
async function loadInternalBin(binName) {
|
|
72
|
-
const loader = internalBinLoaders[binName];
|
|
73
|
-
if (!loader) {
|
|
74
|
-
return false;
|
|
75
|
-
}
|
|
76
|
-
await loader();
|
|
77
|
-
return true;
|
|
78
|
-
}
|
|
79
|
-
function hasInternalBin(binName) {
|
|
80
|
-
return Object.hasOwn(internalBinLoaders, binName);
|
|
81
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
exports.__esModule = true;
|
|
4
|
-
exports.getRuntimeModeLabel = getRuntimeModeLabel;
|
|
5
|
-
exports.isStandaloneExecutableRuntime = isStandaloneExecutableRuntime;
|
|
6
|
-
var _nodeModule = require("node:module");
|
|
7
|
-
const runtimeRequire = (0, _nodeModule.createRequire)(__filename);
|
|
8
|
-
function isStandaloneExecutableRuntime() {
|
|
9
|
-
if (process.env.VIP_CLI_SEA_MODE === '1') {
|
|
10
|
-
return true;
|
|
11
|
-
}
|
|
12
|
-
try {
|
|
13
|
-
const sea = runtimeRequire('node:sea');
|
|
14
|
-
return Boolean(sea?.isSea?.());
|
|
15
|
-
} catch {
|
|
16
|
-
return false;
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
function getRuntimeModeLabel() {
|
|
20
|
-
return isStandaloneExecutableRuntime() ? 'standalone-sea' : 'node-script';
|
|
21
|
-
}
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
exports.__esModule = true;
|
|
4
|
-
exports.isSeaRuntime = isSeaRuntime;
|
|
5
|
-
exports.resolveInternalBinFromArgv = resolveInternalBinFromArgv;
|
|
6
|
-
exports.rewriteArgvForInternalBin = rewriteArgvForInternalBin;
|
|
7
|
-
var _envAlias = require("./envAlias");
|
|
8
|
-
var _internalBinLoader = require("./internal-bin-loader");
|
|
9
|
-
const internalBinSet = new Set(_internalBinLoader.internalBinNames);
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Resolve the best matching internal bin for a command argv.
|
|
13
|
-
*
|
|
14
|
-
* @param {string[]} argv process.argv style array
|
|
15
|
-
* @returns {{ bin: string, start: number, length: number }}
|
|
16
|
-
*/
|
|
17
|
-
function resolveInternalBinFromArgv(argv) {
|
|
18
|
-
const args = argv.slice(2);
|
|
19
|
-
const dashDashIndex = args.indexOf('--');
|
|
20
|
-
const commandBoundary = dashDashIndex > -1 ? dashDashIndex : args.length;
|
|
21
|
-
let best = {
|
|
22
|
-
bin: 'vip',
|
|
23
|
-
start: 0,
|
|
24
|
-
length: 0
|
|
25
|
-
};
|
|
26
|
-
for (let start = 0; start < commandBoundary; start++) {
|
|
27
|
-
const firstToken = args[start];
|
|
28
|
-
if (!firstToken || firstToken.startsWith('-') || (0, _envAlias.isAlias)(firstToken)) {
|
|
29
|
-
continue;
|
|
30
|
-
}
|
|
31
|
-
const commandParts = [];
|
|
32
|
-
for (let index = start; index < commandBoundary; index++) {
|
|
33
|
-
const token = args[index];
|
|
34
|
-
if (!token || token.startsWith('-') || (0, _envAlias.isAlias)(token)) {
|
|
35
|
-
break;
|
|
36
|
-
}
|
|
37
|
-
commandParts.push(token);
|
|
38
|
-
const candidateBin = `vip-${commandParts.join('-')}`;
|
|
39
|
-
if (internalBinSet.has(candidateBin)) {
|
|
40
|
-
const isLongerMatch = commandParts.length > best.length;
|
|
41
|
-
const isEarlierEqualMatch = commandParts.length === best.length && commandParts.length > 0 && start < best.start;
|
|
42
|
-
if (isLongerMatch || isEarlierEqualMatch) {
|
|
43
|
-
best = {
|
|
44
|
-
bin: candidateBin,
|
|
45
|
-
start,
|
|
46
|
-
length: commandParts.length
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
return best;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Rewrites argv so the resolved command segment is removed and the target bin
|
|
57
|
-
* can parse its native flags/args shape.
|
|
58
|
-
*
|
|
59
|
-
* @param {string[]} argv process.argv style array
|
|
60
|
-
* @param {{ start: number, length: number }} resolution command resolution
|
|
61
|
-
* @returns {string[]} rewritten argv
|
|
62
|
-
*/
|
|
63
|
-
function rewriteArgvForInternalBin(argv, resolution) {
|
|
64
|
-
const args = argv.slice(2);
|
|
65
|
-
const start = resolution.start ?? 0;
|
|
66
|
-
const length = resolution.length ?? 0;
|
|
67
|
-
if (length <= 0) {
|
|
68
|
-
return argv.slice(0);
|
|
69
|
-
}
|
|
70
|
-
const rewrittenArgs = args.slice(0, start).concat(args.slice(start + length));
|
|
71
|
-
return [argv[0], argv[1], ...rewrittenArgs];
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* @returns {boolean}
|
|
76
|
-
*/
|
|
77
|
-
function isSeaRuntime() {
|
|
78
|
-
try {
|
|
79
|
-
const runtimeRequire = typeof module !== 'undefined' && module?.require ? module.require.bind(module) : null;
|
|
80
|
-
if (!runtimeRequire) {
|
|
81
|
-
return false;
|
|
82
|
-
}
|
|
83
|
-
const sea = runtimeRequire('node:sea');
|
|
84
|
-
return Boolean(sea?.isSea?.());
|
|
85
|
-
} catch {
|
|
86
|
-
return false;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
exports.__esModule = true;
|
|
4
|
-
exports.prepareSeaRuntimeFilesystem = prepareSeaRuntimeFilesystem;
|
|
5
|
-
var _nodeFs = require("node:fs");
|
|
6
|
-
var _promises = require("node:fs/promises");
|
|
7
|
-
var _nodePath = _interopRequireDefault(require("node:path"));
|
|
8
|
-
var _package = _interopRequireDefault(require("../../../package.json"));
|
|
9
|
-
var _xdgData = require("../xdg-data");
|
|
10
|
-
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
11
|
-
const RUNTIME_ARCHIVE_KEY = 'sea.node_modules.tgz';
|
|
12
|
-
const RUNTIME_DIR_NAME = 'sea-runtime';
|
|
13
|
-
const READY_FILE_NAME = '.ready';
|
|
14
|
-
const ARCHIVE_FILE_NAME = 'node_modules.tgz';
|
|
15
|
-
async function getSeaModule() {
|
|
16
|
-
try {
|
|
17
|
-
return await import('node:sea');
|
|
18
|
-
} catch {
|
|
19
|
-
return null;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
function getRuntimeRootPath() {
|
|
23
|
-
return _nodePath.default.join((0, _xdgData.xdgData)(), 'vip', RUNTIME_DIR_NAME, _package.default.version);
|
|
24
|
-
}
|
|
25
|
-
function getRuntimeNodeModulesPath(runtimeRootPath) {
|
|
26
|
-
return _nodePath.default.join(runtimeRootPath, 'node_modules');
|
|
27
|
-
}
|
|
28
|
-
function getRuntimeReadyPath(runtimeRootPath) {
|
|
29
|
-
return _nodePath.default.join(runtimeRootPath, READY_FILE_NAME);
|
|
30
|
-
}
|
|
31
|
-
function appendNodePath(nodeModulesPath) {
|
|
32
|
-
const existing = process.env.NODE_PATH ? process.env.NODE_PATH.split(_nodePath.default.delimiter) : [];
|
|
33
|
-
if (!existing.includes(nodeModulesPath)) {
|
|
34
|
-
process.env.NODE_PATH = [nodeModulesPath, ...existing].join(_nodePath.default.delimiter);
|
|
35
|
-
}
|
|
36
|
-
const Module = require('node:module');
|
|
37
|
-
Module.Module._initPaths();
|
|
38
|
-
const runtimeEntryPath = _nodePath.default.join(nodeModulesPath, '..', '__sea-entry__.js');
|
|
39
|
-
const runtimeRequire = Module.createRequire(runtimeEntryPath);
|
|
40
|
-
module.filename = runtimeEntryPath;
|
|
41
|
-
module.paths = Module._nodeModulePaths(_nodePath.default.dirname(runtimeEntryPath));
|
|
42
|
-
module.require = runtimeRequire;
|
|
43
|
-
}
|
|
44
|
-
async function extractRuntimeDependencies(runtimeRootPath, archiveBuffer) {
|
|
45
|
-
await (0, _promises.rm)(runtimeRootPath, {
|
|
46
|
-
recursive: true,
|
|
47
|
-
force: true
|
|
48
|
-
});
|
|
49
|
-
await (0, _promises.mkdir)(runtimeRootPath, {
|
|
50
|
-
recursive: true
|
|
51
|
-
});
|
|
52
|
-
const archivePath = _nodePath.default.join(runtimeRootPath, ARCHIVE_FILE_NAME);
|
|
53
|
-
await (0, _promises.writeFile)(archivePath, archiveBuffer);
|
|
54
|
-
const tar = require('tar');
|
|
55
|
-
await tar.x({
|
|
56
|
-
file: archivePath,
|
|
57
|
-
cwd: runtimeRootPath
|
|
58
|
-
});
|
|
59
|
-
await (0, _promises.writeFile)(getRuntimeReadyPath(runtimeRootPath), _package.default.version, 'utf8');
|
|
60
|
-
}
|
|
61
|
-
async function prepareSeaRuntimeFilesystem() {
|
|
62
|
-
const sea = await getSeaModule();
|
|
63
|
-
if (!sea?.isSea?.() || !sea.getAsset) {
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
const runtimeRootPath = getRuntimeRootPath();
|
|
67
|
-
const runtimeNodeModulesPath = getRuntimeNodeModulesPath(runtimeRootPath);
|
|
68
|
-
const runtimeReadyPath = getRuntimeReadyPath(runtimeRootPath);
|
|
69
|
-
if (!(0, _nodeFs.existsSync)(runtimeReadyPath) || !(0, _nodeFs.existsSync)(runtimeNodeModulesPath)) {
|
|
70
|
-
const archiveAsset = sea.getAsset(RUNTIME_ARCHIVE_KEY);
|
|
71
|
-
const archiveBuffer = Buffer.isBuffer(archiveAsset) ? archiveAsset : Buffer.from(archiveAsset);
|
|
72
|
-
await extractRuntimeDependencies(runtimeRootPath, archiveBuffer);
|
|
73
|
-
}
|
|
74
|
-
appendNodePath(runtimeNodeModulesPath);
|
|
75
|
-
}
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
exports.__esModule = true;
|
|
4
|
-
exports.loadLandoModule = loadLandoModule;
|
|
5
|
-
exports.resolveLandoModule = resolveLandoModule;
|
|
6
|
-
var _nodeFs = require("node:fs");
|
|
7
|
-
var _nodeModule = require("node:module");
|
|
8
|
-
var _nodePath = _interopRequireDefault(require("node:path"));
|
|
9
|
-
var _package = _interopRequireDefault(require("../../../package.json"));
|
|
10
|
-
var _xdgData = require("../xdg-data");
|
|
11
|
-
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
12
|
-
const SEA_RUNTIME_DIR_NAME = 'sea-runtime';
|
|
13
|
-
let cachedRequire = null;
|
|
14
|
-
let didResolveRequire = false;
|
|
15
|
-
const baseRequire = (0, _nodeModule.createRequire)(__filename);
|
|
16
|
-
function isSeaRuntime() {
|
|
17
|
-
try {
|
|
18
|
-
const sea = baseRequire('node:sea');
|
|
19
|
-
return Boolean(sea?.isSea?.());
|
|
20
|
-
} catch {
|
|
21
|
-
return false;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
function getSeaRuntimeNodeModulesPath() {
|
|
25
|
-
return _nodePath.default.join((0, _xdgData.xdgData)(), 'vip', SEA_RUNTIME_DIR_NAME, _package.default.version, 'node_modules');
|
|
26
|
-
}
|
|
27
|
-
function getRuntimeRequire() {
|
|
28
|
-
if (didResolveRequire && cachedRequire) {
|
|
29
|
-
return cachedRequire;
|
|
30
|
-
}
|
|
31
|
-
didResolveRequire = true;
|
|
32
|
-
if (isSeaRuntime()) {
|
|
33
|
-
const runtimeNodeModulesPath = getSeaRuntimeNodeModulesPath();
|
|
34
|
-
if ((0, _nodeFs.existsSync)(runtimeNodeModulesPath)) {
|
|
35
|
-
const runtimeEntryPath = _nodePath.default.join(runtimeNodeModulesPath, '..', '__sea-entry__.js');
|
|
36
|
-
cachedRequire = (0, _nodeModule.createRequire)(runtimeEntryPath);
|
|
37
|
-
return cachedRequire;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
cachedRequire = baseRequire;
|
|
41
|
-
return cachedRequire;
|
|
42
|
-
}
|
|
43
|
-
function loadLandoModule(request) {
|
|
44
|
-
return getRuntimeRequire()(request);
|
|
45
|
-
}
|
|
46
|
-
function resolveLandoModule(request) {
|
|
47
|
-
return getRuntimeRequire().resolve(request);
|
|
48
|
-
}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
# Commander Migration Status
|
|
2
|
-
|
|
3
|
-
Goal: remove the abandoned `args` package, keep CLI behavior stable, and support packaging to a single bundled executable (Node SEA or similar). See `AGENTS.md` for broader architecture traps.
|
|
4
|
-
|
|
5
|
-
## Migration Outcome
|
|
6
|
-
|
|
7
|
-
- `src/lib/cli/command.js` is the active Commander-backed compatibility wrapper for all bins that call `command()`.
|
|
8
|
-
- `args` has been removed from `package.json` and `npm-shrinkwrap.json`.
|
|
9
|
-
- Root command flow (`src/bin/vip.js`) now dispatches via the shared Commander wrapper again, preserving login gating and subcommand chaining.
|
|
10
|
-
- Temporary side-path wrapper work has been removed (`src/lib/cli/command-commander.ts` deleted).
|
|
11
|
-
|
|
12
|
-
## Compatibility Behaviors Preserved
|
|
13
|
-
|
|
14
|
-
- Legacy command contract stays the same: `command(opts).option(...).argv(process.argv, handler)`.
|
|
15
|
-
- Alias behavior remains pre-parse: `@app` and `@app.env` are stripped before `--`; alias + `--app/--env` still errors.
|
|
16
|
-
- `_opts` controls are still honored: app/env context fetch, confirmation gating, output formatting, wildcard command handling, required positional args.
|
|
17
|
-
- Shared formatting/output and telemetry hooks are still in the wrapper path.
|
|
18
|
-
- Local nested subcommand dispatch still works via sibling executable resolution.
|
|
19
|
-
|
|
20
|
-
## Post-Migration Hardening
|
|
21
|
-
|
|
22
|
-
- Short-flag compatibility was restored for long options without explicit aliases:
|
|
23
|
-
- Example: `--elasticsearch` accepts `-e`, `--phpmyadmin` accepts `-p`, etc.
|
|
24
|
-
- Auto-short generation skips reserved global flags (`-h`, `-v`, `-d`) and avoids duplicate collisions.
|
|
25
|
-
- `vip dev-env exec` now performs bounded readiness checks before deciding an environment is not running.
|
|
26
|
-
- `startEnvironment()` now includes bounded post-start readiness checks and one recovery `landoStart` retry if the environment stays `DOWN` after rebuild/start.
|
|
27
|
-
|
|
28
|
-
## Remaining Technical Debt
|
|
29
|
-
|
|
30
|
-
- `_opts` is still module-level state in `src/lib/cli/command.js` and can leak between command instances in one process.
|
|
31
|
-
- Help text parity against historical `args` output is close but still a verification target for high-traffic commands.
|
|
32
|
-
- Full dev-env E2E can still show Docker/Lando infrastructure flakiness (network cleanup and startup latency), which is environment-level, not parser-level.
|
|
33
|
-
|
|
34
|
-
## Verification Commands
|
|
35
|
-
|
|
36
|
-
- `npm run build`
|
|
37
|
-
- `npm run check-types`
|
|
38
|
-
- `npm run test:e2e:dev-env -- --runInBand __tests__/devenv-e2e/001-create.spec.js __tests__/devenv-e2e/005-update.spec.js`
|
|
39
|
-
- `npm run test:e2e:dev-env -- --runInBand __tests__/devenv-e2e/008-exec.spec.js __tests__/devenv-e2e/010-import-sql.spec.js`
|
|
40
|
-
|
|
41
|
-
## Single-Bundle Direction
|
|
42
|
-
|
|
43
|
-
- Preferred: `esbuild` bundle rooted at `src/bin/vip.js`.
|
|
44
|
-
- Keep native deps external (`@postman/node-keytar`) for SEA/packaging workflows.
|
|
45
|
-
- Candidate build target:
|
|
46
|
-
- `dist/vip.bundle.cjs` for SEA ingestion or launcher wrapping.
|
|
47
|
-
- Example command:
|
|
48
|
-
- `esbuild src/bin/vip.js --bundle --platform=node --target=node20 --format=cjs --outfile=dist/vip.bundle.cjs --banner:js="#!/usr/bin/env node" --external:@postman/node-keytar`
|
|
49
|
-
|
|
50
|
-
## Next Refactor Steps
|
|
51
|
-
|
|
52
|
-
1. Remove global `_opts` state from `src/lib/cli/command.js` by moving to per-instance configuration.
|
|
53
|
-
2. Add parser contract tests for aliasing, wildcard behavior, and short/long boolean coercion.
|
|
54
|
-
3. Add stable startup/readiness integration checks around dev-env commands in CI environments with Docker.
|
|
55
|
-
4. Add bundling script(s) and SEA config proof-of-concept for a single-file executable artifact.
|
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
# SEA Build and Signing Runbook
|
|
2
|
-
|
|
3
|
-
Purpose: build and sign the standalone VIP CLI executable (`dist/sea/vip` or `dist/sea/vip.exe`) for each supported platform.
|
|
4
|
-
|
|
5
|
-
This repo uses `helpers/build-sea.js` and the `npm run build:sea` script. SEA build is pinned to Node 22.
|
|
6
|
-
|
|
7
|
-
## Shared Prerequisites
|
|
8
|
-
|
|
9
|
-
- Use Node 22.x exactly for SEA builds.
|
|
10
|
-
- Install dependencies before building: `npm ci`.
|
|
11
|
-
- Build from repo root.
|
|
12
|
-
- The build script embeds:
|
|
13
|
-
- Node runtime
|
|
14
|
-
- bundled CLI code (`src/bin/vip-sea.js`)
|
|
15
|
-
- SEA assets and runtime dependency archive (`sea.node_modules.tgz`)
|
|
16
|
-
- Output paths:
|
|
17
|
-
- Unix: `dist/sea/vip`
|
|
18
|
-
- Windows: `dist/sea/vip.exe`
|
|
19
|
-
|
|
20
|
-
## Shared Build Steps
|
|
21
|
-
|
|
22
|
-
```bash
|
|
23
|
-
npm ci
|
|
24
|
-
npm run build
|
|
25
|
-
npm run build:sea
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
Quick smoke checks after every build:
|
|
29
|
-
|
|
30
|
-
```bash
|
|
31
|
-
dist/sea/vip --version
|
|
32
|
-
dist/sea/vip whoami --help
|
|
33
|
-
dist/sea/vip dev-env info --help
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
## macOS (native)
|
|
37
|
-
|
|
38
|
-
Node/tool setup:
|
|
39
|
-
|
|
40
|
-
```bash
|
|
41
|
-
export NVM_DIR="$HOME/.nvm"
|
|
42
|
-
. "$NVM_DIR/nvm.sh"
|
|
43
|
-
nvm use 22
|
|
44
|
-
node -v
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
Build:
|
|
48
|
-
|
|
49
|
-
```bash
|
|
50
|
-
npm ci
|
|
51
|
-
npm run build
|
|
52
|
-
npm run build:sea
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
Notes:
|
|
56
|
-
|
|
57
|
-
- `helpers/build-sea.js` already does ad-hoc signing (`codesign --sign -`) after blob injection so local execution works.
|
|
58
|
-
- For distribution, replace ad-hoc signature with a real Developer ID certificate.
|
|
59
|
-
|
|
60
|
-
Distribution signing:
|
|
61
|
-
|
|
62
|
-
```bash
|
|
63
|
-
codesign --remove-signature dist/sea/vip
|
|
64
|
-
codesign --sign "Developer ID Application: <TEAM/ORG>" --force --options runtime dist/sea/vip
|
|
65
|
-
codesign --verify --strict --verbose=2 dist/sea/vip
|
|
66
|
-
spctl -a -t exec -vv dist/sea/vip
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
## Linux (native)
|
|
70
|
-
|
|
71
|
-
Node/tool setup:
|
|
72
|
-
|
|
73
|
-
```bash
|
|
74
|
-
node -v
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
(Use Node 22 before build.)
|
|
78
|
-
|
|
79
|
-
Build:
|
|
80
|
-
|
|
81
|
-
```bash
|
|
82
|
-
npm ci
|
|
83
|
-
npm run build
|
|
84
|
-
npm run build:sea
|
|
85
|
-
chmod +x dist/sea/vip
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
Signing guidance:
|
|
89
|
-
|
|
90
|
-
- Linux does not have a universal OS-enforced Authenticode-style executable signature.
|
|
91
|
-
- Recommended: publish checksums and detached signatures.
|
|
92
|
-
|
|
93
|
-
Checksum + GPG example:
|
|
94
|
-
|
|
95
|
-
```bash
|
|
96
|
-
sha256sum dist/sea/vip > dist/sea/vip.sha256
|
|
97
|
-
gpg --armor --detach-sign dist/sea/vip
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
Cosign blob example:
|
|
101
|
-
|
|
102
|
-
```bash
|
|
103
|
-
cosign sign-blob --yes --output-signature dist/sea/vip.sig dist/sea/vip
|
|
104
|
-
cosign verify-blob --signature dist/sea/vip.sig dist/sea/vip
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
## Windows (native)
|
|
108
|
-
|
|
109
|
-
Use PowerShell or `cmd.exe` on Windows (not WSL) when producing Windows artifacts.
|
|
110
|
-
|
|
111
|
-
Build:
|
|
112
|
-
|
|
113
|
-
```powershell
|
|
114
|
-
npm ci
|
|
115
|
-
npm run build
|
|
116
|
-
npm run build:sea
|
|
117
|
-
.\dist\sea\vip.exe --version
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
Authenticode signing (SignTool):
|
|
121
|
-
|
|
122
|
-
```powershell
|
|
123
|
-
signtool sign /fd SHA256 /td SHA256 /tr http://timestamp.digicert.com /a .\dist\sea\vip.exe
|
|
124
|
-
signtool verify /pa /v .\dist\sea\vip.exe
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
If your cert is in a PFX file:
|
|
128
|
-
|
|
129
|
-
```powershell
|
|
130
|
-
signtool sign /f C:\path\cert.pfx /p <PFX_PASSWORD> /fd SHA256 /td SHA256 /tr http://timestamp.digicert.com .\dist\sea\vip.exe
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
## Windows from WSL
|
|
134
|
-
|
|
135
|
-
Important: WSL builds Linux binaries by default.
|
|
136
|
-
|
|
137
|
-
- If target is Linux binary: build/sign inside WSL using the Linux flow.
|
|
138
|
-
- If target is Windows `.exe`: run the build and signing commands in Windows context.
|
|
139
|
-
|
|
140
|
-
From WSL, invoke Windows PowerShell for a Windows-target build:
|
|
141
|
-
|
|
142
|
-
```bash
|
|
143
|
-
WIN_REPO_PATH="$(wslpath -w "$PWD")"
|
|
144
|
-
powershell.exe -NoProfile -Command "Set-Location '$WIN_REPO_PATH'; npm ci; npm run build; npm run build:sea"
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
Then sign in Windows context:
|
|
148
|
-
|
|
149
|
-
```bash
|
|
150
|
-
powershell.exe -NoProfile -Command "Set-Location '$WIN_REPO_PATH'; signtool sign /fd SHA256 /td SHA256 /tr http://timestamp.digicert.com /a .\\dist\\sea\\vip.exe; signtool verify /pa /v .\\dist\\sea\\vip.exe"
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
## Release Checklist for Agents
|
|
154
|
-
|
|
155
|
-
- Confirm Node 22 before SEA build.
|
|
156
|
-
- Confirm artifact type matches target OS (`vip` vs `vip.exe`).
|
|
157
|
-
- Run smoke checks on the produced executable.
|
|
158
|
-
- Apply platform-appropriate signature method.
|
|
159
|
-
- Verify signature/checksum before publishing.
|
|
160
|
-
- Record signing method and timestamp authority in release notes.
|
|
161
|
-
|
|
162
|
-
## GitHub Actions Automation
|
|
163
|
-
|
|
164
|
-
- Workflow: `.github/workflows/sea-build-sign.yml`
|
|
165
|
-
- Trigger: manual `workflow_dispatch`
|
|
166
|
-
- Jobs: native macOS/Linux/Windows SEA builds plus a Windows WSL SEA build
|
|
167
|
-
- Optional signing: set `sign_artifacts=true` and provide signing secrets/vars:
|
|
168
|
-
- macOS: `MACOS_CERTIFICATE_P12_BASE64`, `MACOS_CERTIFICATE_PASSWORD`, `MACOS_SIGNING_IDENTITY`
|
|
169
|
-
- Windows: `WINDOWS_CERTIFICATE_PFX_BASE64`, `WINDOWS_CERTIFICATE_PASSWORD`
|
|
170
|
-
- optional variable: `WINDOWS_TIMESTAMP_URL`
|
|
171
|
-
- Output: uploaded SEA binary + SHA256 artifact per job
|