@zerodeploy/cli 0.1.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/README.md +523 -0
- package/dist/cli.js +4954 -0
- package/package.json +41 -0
package/dist/cli.js
ADDED
|
@@ -0,0 +1,4954 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// @bun
|
|
3
|
+
import { createRequire } from "node:module";
|
|
4
|
+
var __create = Object.create;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __defProp = Object.defineProperty;
|
|
7
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __toESM = (mod, isNodeMode, target) => {
|
|
10
|
+
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
11
|
+
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
12
|
+
for (let key of __getOwnPropNames(mod))
|
|
13
|
+
if (!__hasOwnProp.call(to, key))
|
|
14
|
+
__defProp(to, key, {
|
|
15
|
+
get: () => mod[key],
|
|
16
|
+
enumerable: true
|
|
17
|
+
});
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
21
|
+
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
22
|
+
|
|
23
|
+
// ../../node_modules/.bun/commander@14.0.2/node_modules/commander/lib/error.js
|
|
24
|
+
var require_error = __commonJS((exports) => {
|
|
25
|
+
class CommanderError extends Error {
|
|
26
|
+
constructor(exitCode, code, message) {
|
|
27
|
+
super(message);
|
|
28
|
+
Error.captureStackTrace(this, this.constructor);
|
|
29
|
+
this.name = this.constructor.name;
|
|
30
|
+
this.code = code;
|
|
31
|
+
this.exitCode = exitCode;
|
|
32
|
+
this.nestedError = undefined;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
class InvalidArgumentError extends CommanderError {
|
|
37
|
+
constructor(message) {
|
|
38
|
+
super(1, "commander.invalidArgument", message);
|
|
39
|
+
Error.captureStackTrace(this, this.constructor);
|
|
40
|
+
this.name = this.constructor.name;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
exports.CommanderError = CommanderError;
|
|
44
|
+
exports.InvalidArgumentError = InvalidArgumentError;
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// ../../node_modules/.bun/commander@14.0.2/node_modules/commander/lib/argument.js
|
|
48
|
+
var require_argument = __commonJS((exports) => {
|
|
49
|
+
var { InvalidArgumentError } = require_error();
|
|
50
|
+
|
|
51
|
+
class Argument {
|
|
52
|
+
constructor(name, description) {
|
|
53
|
+
this.description = description || "";
|
|
54
|
+
this.variadic = false;
|
|
55
|
+
this.parseArg = undefined;
|
|
56
|
+
this.defaultValue = undefined;
|
|
57
|
+
this.defaultValueDescription = undefined;
|
|
58
|
+
this.argChoices = undefined;
|
|
59
|
+
switch (name[0]) {
|
|
60
|
+
case "<":
|
|
61
|
+
this.required = true;
|
|
62
|
+
this._name = name.slice(1, -1);
|
|
63
|
+
break;
|
|
64
|
+
case "[":
|
|
65
|
+
this.required = false;
|
|
66
|
+
this._name = name.slice(1, -1);
|
|
67
|
+
break;
|
|
68
|
+
default:
|
|
69
|
+
this.required = true;
|
|
70
|
+
this._name = name;
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
73
|
+
if (this._name.endsWith("...")) {
|
|
74
|
+
this.variadic = true;
|
|
75
|
+
this._name = this._name.slice(0, -3);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
name() {
|
|
79
|
+
return this._name;
|
|
80
|
+
}
|
|
81
|
+
_collectValue(value, previous) {
|
|
82
|
+
if (previous === this.defaultValue || !Array.isArray(previous)) {
|
|
83
|
+
return [value];
|
|
84
|
+
}
|
|
85
|
+
previous.push(value);
|
|
86
|
+
return previous;
|
|
87
|
+
}
|
|
88
|
+
default(value, description) {
|
|
89
|
+
this.defaultValue = value;
|
|
90
|
+
this.defaultValueDescription = description;
|
|
91
|
+
return this;
|
|
92
|
+
}
|
|
93
|
+
argParser(fn) {
|
|
94
|
+
this.parseArg = fn;
|
|
95
|
+
return this;
|
|
96
|
+
}
|
|
97
|
+
choices(values) {
|
|
98
|
+
this.argChoices = values.slice();
|
|
99
|
+
this.parseArg = (arg, previous) => {
|
|
100
|
+
if (!this.argChoices.includes(arg)) {
|
|
101
|
+
throw new InvalidArgumentError(`Allowed choices are ${this.argChoices.join(", ")}.`);
|
|
102
|
+
}
|
|
103
|
+
if (this.variadic) {
|
|
104
|
+
return this._collectValue(arg, previous);
|
|
105
|
+
}
|
|
106
|
+
return arg;
|
|
107
|
+
};
|
|
108
|
+
return this;
|
|
109
|
+
}
|
|
110
|
+
argRequired() {
|
|
111
|
+
this.required = true;
|
|
112
|
+
return this;
|
|
113
|
+
}
|
|
114
|
+
argOptional() {
|
|
115
|
+
this.required = false;
|
|
116
|
+
return this;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
function humanReadableArgName(arg) {
|
|
120
|
+
const nameOutput = arg.name() + (arg.variadic === true ? "..." : "");
|
|
121
|
+
return arg.required ? "<" + nameOutput + ">" : "[" + nameOutput + "]";
|
|
122
|
+
}
|
|
123
|
+
exports.Argument = Argument;
|
|
124
|
+
exports.humanReadableArgName = humanReadableArgName;
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
// ../../node_modules/.bun/commander@14.0.2/node_modules/commander/lib/help.js
|
|
128
|
+
var require_help = __commonJS((exports) => {
|
|
129
|
+
var { humanReadableArgName } = require_argument();
|
|
130
|
+
|
|
131
|
+
class Help {
|
|
132
|
+
constructor() {
|
|
133
|
+
this.helpWidth = undefined;
|
|
134
|
+
this.minWidthToWrap = 40;
|
|
135
|
+
this.sortSubcommands = false;
|
|
136
|
+
this.sortOptions = false;
|
|
137
|
+
this.showGlobalOptions = false;
|
|
138
|
+
}
|
|
139
|
+
prepareContext(contextOptions) {
|
|
140
|
+
this.helpWidth = this.helpWidth ?? contextOptions.helpWidth ?? 80;
|
|
141
|
+
}
|
|
142
|
+
visibleCommands(cmd) {
|
|
143
|
+
const visibleCommands = cmd.commands.filter((cmd2) => !cmd2._hidden);
|
|
144
|
+
const helpCommand = cmd._getHelpCommand();
|
|
145
|
+
if (helpCommand && !helpCommand._hidden) {
|
|
146
|
+
visibleCommands.push(helpCommand);
|
|
147
|
+
}
|
|
148
|
+
if (this.sortSubcommands) {
|
|
149
|
+
visibleCommands.sort((a, b) => {
|
|
150
|
+
return a.name().localeCompare(b.name());
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
return visibleCommands;
|
|
154
|
+
}
|
|
155
|
+
compareOptions(a, b) {
|
|
156
|
+
const getSortKey = (option) => {
|
|
157
|
+
return option.short ? option.short.replace(/^-/, "") : option.long.replace(/^--/, "");
|
|
158
|
+
};
|
|
159
|
+
return getSortKey(a).localeCompare(getSortKey(b));
|
|
160
|
+
}
|
|
161
|
+
visibleOptions(cmd) {
|
|
162
|
+
const visibleOptions = cmd.options.filter((option) => !option.hidden);
|
|
163
|
+
const helpOption = cmd._getHelpOption();
|
|
164
|
+
if (helpOption && !helpOption.hidden) {
|
|
165
|
+
const removeShort = helpOption.short && cmd._findOption(helpOption.short);
|
|
166
|
+
const removeLong = helpOption.long && cmd._findOption(helpOption.long);
|
|
167
|
+
if (!removeShort && !removeLong) {
|
|
168
|
+
visibleOptions.push(helpOption);
|
|
169
|
+
} else if (helpOption.long && !removeLong) {
|
|
170
|
+
visibleOptions.push(cmd.createOption(helpOption.long, helpOption.description));
|
|
171
|
+
} else if (helpOption.short && !removeShort) {
|
|
172
|
+
visibleOptions.push(cmd.createOption(helpOption.short, helpOption.description));
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
if (this.sortOptions) {
|
|
176
|
+
visibleOptions.sort(this.compareOptions);
|
|
177
|
+
}
|
|
178
|
+
return visibleOptions;
|
|
179
|
+
}
|
|
180
|
+
visibleGlobalOptions(cmd) {
|
|
181
|
+
if (!this.showGlobalOptions)
|
|
182
|
+
return [];
|
|
183
|
+
const globalOptions = [];
|
|
184
|
+
for (let ancestorCmd = cmd.parent;ancestorCmd; ancestorCmd = ancestorCmd.parent) {
|
|
185
|
+
const visibleOptions = ancestorCmd.options.filter((option) => !option.hidden);
|
|
186
|
+
globalOptions.push(...visibleOptions);
|
|
187
|
+
}
|
|
188
|
+
if (this.sortOptions) {
|
|
189
|
+
globalOptions.sort(this.compareOptions);
|
|
190
|
+
}
|
|
191
|
+
return globalOptions;
|
|
192
|
+
}
|
|
193
|
+
visibleArguments(cmd) {
|
|
194
|
+
if (cmd._argsDescription) {
|
|
195
|
+
cmd.registeredArguments.forEach((argument) => {
|
|
196
|
+
argument.description = argument.description || cmd._argsDescription[argument.name()] || "";
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
if (cmd.registeredArguments.find((argument) => argument.description)) {
|
|
200
|
+
return cmd.registeredArguments;
|
|
201
|
+
}
|
|
202
|
+
return [];
|
|
203
|
+
}
|
|
204
|
+
subcommandTerm(cmd) {
|
|
205
|
+
const args = cmd.registeredArguments.map((arg) => humanReadableArgName(arg)).join(" ");
|
|
206
|
+
return cmd._name + (cmd._aliases[0] ? "|" + cmd._aliases[0] : "") + (cmd.options.length ? " [options]" : "") + (args ? " " + args : "");
|
|
207
|
+
}
|
|
208
|
+
optionTerm(option) {
|
|
209
|
+
return option.flags;
|
|
210
|
+
}
|
|
211
|
+
argumentTerm(argument) {
|
|
212
|
+
return argument.name();
|
|
213
|
+
}
|
|
214
|
+
longestSubcommandTermLength(cmd, helper) {
|
|
215
|
+
return helper.visibleCommands(cmd).reduce((max, command) => {
|
|
216
|
+
return Math.max(max, this.displayWidth(helper.styleSubcommandTerm(helper.subcommandTerm(command))));
|
|
217
|
+
}, 0);
|
|
218
|
+
}
|
|
219
|
+
longestOptionTermLength(cmd, helper) {
|
|
220
|
+
return helper.visibleOptions(cmd).reduce((max, option) => {
|
|
221
|
+
return Math.max(max, this.displayWidth(helper.styleOptionTerm(helper.optionTerm(option))));
|
|
222
|
+
}, 0);
|
|
223
|
+
}
|
|
224
|
+
longestGlobalOptionTermLength(cmd, helper) {
|
|
225
|
+
return helper.visibleGlobalOptions(cmd).reduce((max, option) => {
|
|
226
|
+
return Math.max(max, this.displayWidth(helper.styleOptionTerm(helper.optionTerm(option))));
|
|
227
|
+
}, 0);
|
|
228
|
+
}
|
|
229
|
+
longestArgumentTermLength(cmd, helper) {
|
|
230
|
+
return helper.visibleArguments(cmd).reduce((max, argument) => {
|
|
231
|
+
return Math.max(max, this.displayWidth(helper.styleArgumentTerm(helper.argumentTerm(argument))));
|
|
232
|
+
}, 0);
|
|
233
|
+
}
|
|
234
|
+
commandUsage(cmd) {
|
|
235
|
+
let cmdName = cmd._name;
|
|
236
|
+
if (cmd._aliases[0]) {
|
|
237
|
+
cmdName = cmdName + "|" + cmd._aliases[0];
|
|
238
|
+
}
|
|
239
|
+
let ancestorCmdNames = "";
|
|
240
|
+
for (let ancestorCmd = cmd.parent;ancestorCmd; ancestorCmd = ancestorCmd.parent) {
|
|
241
|
+
ancestorCmdNames = ancestorCmd.name() + " " + ancestorCmdNames;
|
|
242
|
+
}
|
|
243
|
+
return ancestorCmdNames + cmdName + " " + cmd.usage();
|
|
244
|
+
}
|
|
245
|
+
commandDescription(cmd) {
|
|
246
|
+
return cmd.description();
|
|
247
|
+
}
|
|
248
|
+
subcommandDescription(cmd) {
|
|
249
|
+
return cmd.summary() || cmd.description();
|
|
250
|
+
}
|
|
251
|
+
optionDescription(option) {
|
|
252
|
+
const extraInfo = [];
|
|
253
|
+
if (option.argChoices) {
|
|
254
|
+
extraInfo.push(`choices: ${option.argChoices.map((choice) => JSON.stringify(choice)).join(", ")}`);
|
|
255
|
+
}
|
|
256
|
+
if (option.defaultValue !== undefined) {
|
|
257
|
+
const showDefault = option.required || option.optional || option.isBoolean() && typeof option.defaultValue === "boolean";
|
|
258
|
+
if (showDefault) {
|
|
259
|
+
extraInfo.push(`default: ${option.defaultValueDescription || JSON.stringify(option.defaultValue)}`);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
if (option.presetArg !== undefined && option.optional) {
|
|
263
|
+
extraInfo.push(`preset: ${JSON.stringify(option.presetArg)}`);
|
|
264
|
+
}
|
|
265
|
+
if (option.envVar !== undefined) {
|
|
266
|
+
extraInfo.push(`env: ${option.envVar}`);
|
|
267
|
+
}
|
|
268
|
+
if (extraInfo.length > 0) {
|
|
269
|
+
const extraDescription = `(${extraInfo.join(", ")})`;
|
|
270
|
+
if (option.description) {
|
|
271
|
+
return `${option.description} ${extraDescription}`;
|
|
272
|
+
}
|
|
273
|
+
return extraDescription;
|
|
274
|
+
}
|
|
275
|
+
return option.description;
|
|
276
|
+
}
|
|
277
|
+
argumentDescription(argument) {
|
|
278
|
+
const extraInfo = [];
|
|
279
|
+
if (argument.argChoices) {
|
|
280
|
+
extraInfo.push(`choices: ${argument.argChoices.map((choice) => JSON.stringify(choice)).join(", ")}`);
|
|
281
|
+
}
|
|
282
|
+
if (argument.defaultValue !== undefined) {
|
|
283
|
+
extraInfo.push(`default: ${argument.defaultValueDescription || JSON.stringify(argument.defaultValue)}`);
|
|
284
|
+
}
|
|
285
|
+
if (extraInfo.length > 0) {
|
|
286
|
+
const extraDescription = `(${extraInfo.join(", ")})`;
|
|
287
|
+
if (argument.description) {
|
|
288
|
+
return `${argument.description} ${extraDescription}`;
|
|
289
|
+
}
|
|
290
|
+
return extraDescription;
|
|
291
|
+
}
|
|
292
|
+
return argument.description;
|
|
293
|
+
}
|
|
294
|
+
formatItemList(heading, items, helper) {
|
|
295
|
+
if (items.length === 0)
|
|
296
|
+
return [];
|
|
297
|
+
return [helper.styleTitle(heading), ...items, ""];
|
|
298
|
+
}
|
|
299
|
+
groupItems(unsortedItems, visibleItems, getGroup) {
|
|
300
|
+
const result = new Map;
|
|
301
|
+
unsortedItems.forEach((item) => {
|
|
302
|
+
const group = getGroup(item);
|
|
303
|
+
if (!result.has(group))
|
|
304
|
+
result.set(group, []);
|
|
305
|
+
});
|
|
306
|
+
visibleItems.forEach((item) => {
|
|
307
|
+
const group = getGroup(item);
|
|
308
|
+
if (!result.has(group)) {
|
|
309
|
+
result.set(group, []);
|
|
310
|
+
}
|
|
311
|
+
result.get(group).push(item);
|
|
312
|
+
});
|
|
313
|
+
return result;
|
|
314
|
+
}
|
|
315
|
+
formatHelp(cmd, helper) {
|
|
316
|
+
const termWidth = helper.padWidth(cmd, helper);
|
|
317
|
+
const helpWidth = helper.helpWidth ?? 80;
|
|
318
|
+
function callFormatItem(term, description) {
|
|
319
|
+
return helper.formatItem(term, termWidth, description, helper);
|
|
320
|
+
}
|
|
321
|
+
let output = [
|
|
322
|
+
`${helper.styleTitle("Usage:")} ${helper.styleUsage(helper.commandUsage(cmd))}`,
|
|
323
|
+
""
|
|
324
|
+
];
|
|
325
|
+
const commandDescription = helper.commandDescription(cmd);
|
|
326
|
+
if (commandDescription.length > 0) {
|
|
327
|
+
output = output.concat([
|
|
328
|
+
helper.boxWrap(helper.styleCommandDescription(commandDescription), helpWidth),
|
|
329
|
+
""
|
|
330
|
+
]);
|
|
331
|
+
}
|
|
332
|
+
const argumentList = helper.visibleArguments(cmd).map((argument) => {
|
|
333
|
+
return callFormatItem(helper.styleArgumentTerm(helper.argumentTerm(argument)), helper.styleArgumentDescription(helper.argumentDescription(argument)));
|
|
334
|
+
});
|
|
335
|
+
output = output.concat(this.formatItemList("Arguments:", argumentList, helper));
|
|
336
|
+
const optionGroups = this.groupItems(cmd.options, helper.visibleOptions(cmd), (option) => option.helpGroupHeading ?? "Options:");
|
|
337
|
+
optionGroups.forEach((options, group) => {
|
|
338
|
+
const optionList = options.map((option) => {
|
|
339
|
+
return callFormatItem(helper.styleOptionTerm(helper.optionTerm(option)), helper.styleOptionDescription(helper.optionDescription(option)));
|
|
340
|
+
});
|
|
341
|
+
output = output.concat(this.formatItemList(group, optionList, helper));
|
|
342
|
+
});
|
|
343
|
+
if (helper.showGlobalOptions) {
|
|
344
|
+
const globalOptionList = helper.visibleGlobalOptions(cmd).map((option) => {
|
|
345
|
+
return callFormatItem(helper.styleOptionTerm(helper.optionTerm(option)), helper.styleOptionDescription(helper.optionDescription(option)));
|
|
346
|
+
});
|
|
347
|
+
output = output.concat(this.formatItemList("Global Options:", globalOptionList, helper));
|
|
348
|
+
}
|
|
349
|
+
const commandGroups = this.groupItems(cmd.commands, helper.visibleCommands(cmd), (sub) => sub.helpGroup() || "Commands:");
|
|
350
|
+
commandGroups.forEach((commands, group) => {
|
|
351
|
+
const commandList = commands.map((sub) => {
|
|
352
|
+
return callFormatItem(helper.styleSubcommandTerm(helper.subcommandTerm(sub)), helper.styleSubcommandDescription(helper.subcommandDescription(sub)));
|
|
353
|
+
});
|
|
354
|
+
output = output.concat(this.formatItemList(group, commandList, helper));
|
|
355
|
+
});
|
|
356
|
+
return output.join(`
|
|
357
|
+
`);
|
|
358
|
+
}
|
|
359
|
+
displayWidth(str) {
|
|
360
|
+
return stripColor(str).length;
|
|
361
|
+
}
|
|
362
|
+
styleTitle(str) {
|
|
363
|
+
return str;
|
|
364
|
+
}
|
|
365
|
+
styleUsage(str) {
|
|
366
|
+
return str.split(" ").map((word) => {
|
|
367
|
+
if (word === "[options]")
|
|
368
|
+
return this.styleOptionText(word);
|
|
369
|
+
if (word === "[command]")
|
|
370
|
+
return this.styleSubcommandText(word);
|
|
371
|
+
if (word[0] === "[" || word[0] === "<")
|
|
372
|
+
return this.styleArgumentText(word);
|
|
373
|
+
return this.styleCommandText(word);
|
|
374
|
+
}).join(" ");
|
|
375
|
+
}
|
|
376
|
+
styleCommandDescription(str) {
|
|
377
|
+
return this.styleDescriptionText(str);
|
|
378
|
+
}
|
|
379
|
+
styleOptionDescription(str) {
|
|
380
|
+
return this.styleDescriptionText(str);
|
|
381
|
+
}
|
|
382
|
+
styleSubcommandDescription(str) {
|
|
383
|
+
return this.styleDescriptionText(str);
|
|
384
|
+
}
|
|
385
|
+
styleArgumentDescription(str) {
|
|
386
|
+
return this.styleDescriptionText(str);
|
|
387
|
+
}
|
|
388
|
+
styleDescriptionText(str) {
|
|
389
|
+
return str;
|
|
390
|
+
}
|
|
391
|
+
styleOptionTerm(str) {
|
|
392
|
+
return this.styleOptionText(str);
|
|
393
|
+
}
|
|
394
|
+
styleSubcommandTerm(str) {
|
|
395
|
+
return str.split(" ").map((word) => {
|
|
396
|
+
if (word === "[options]")
|
|
397
|
+
return this.styleOptionText(word);
|
|
398
|
+
if (word[0] === "[" || word[0] === "<")
|
|
399
|
+
return this.styleArgumentText(word);
|
|
400
|
+
return this.styleSubcommandText(word);
|
|
401
|
+
}).join(" ");
|
|
402
|
+
}
|
|
403
|
+
styleArgumentTerm(str) {
|
|
404
|
+
return this.styleArgumentText(str);
|
|
405
|
+
}
|
|
406
|
+
styleOptionText(str) {
|
|
407
|
+
return str;
|
|
408
|
+
}
|
|
409
|
+
styleArgumentText(str) {
|
|
410
|
+
return str;
|
|
411
|
+
}
|
|
412
|
+
styleSubcommandText(str) {
|
|
413
|
+
return str;
|
|
414
|
+
}
|
|
415
|
+
styleCommandText(str) {
|
|
416
|
+
return str;
|
|
417
|
+
}
|
|
418
|
+
padWidth(cmd, helper) {
|
|
419
|
+
return Math.max(helper.longestOptionTermLength(cmd, helper), helper.longestGlobalOptionTermLength(cmd, helper), helper.longestSubcommandTermLength(cmd, helper), helper.longestArgumentTermLength(cmd, helper));
|
|
420
|
+
}
|
|
421
|
+
preformatted(str) {
|
|
422
|
+
return /\n[^\S\r\n]/.test(str);
|
|
423
|
+
}
|
|
424
|
+
formatItem(term, termWidth, description, helper) {
|
|
425
|
+
const itemIndent = 2;
|
|
426
|
+
const itemIndentStr = " ".repeat(itemIndent);
|
|
427
|
+
if (!description)
|
|
428
|
+
return itemIndentStr + term;
|
|
429
|
+
const paddedTerm = term.padEnd(termWidth + term.length - helper.displayWidth(term));
|
|
430
|
+
const spacerWidth = 2;
|
|
431
|
+
const helpWidth = this.helpWidth ?? 80;
|
|
432
|
+
const remainingWidth = helpWidth - termWidth - spacerWidth - itemIndent;
|
|
433
|
+
let formattedDescription;
|
|
434
|
+
if (remainingWidth < this.minWidthToWrap || helper.preformatted(description)) {
|
|
435
|
+
formattedDescription = description;
|
|
436
|
+
} else {
|
|
437
|
+
const wrappedDescription = helper.boxWrap(description, remainingWidth);
|
|
438
|
+
formattedDescription = wrappedDescription.replace(/\n/g, `
|
|
439
|
+
` + " ".repeat(termWidth + spacerWidth));
|
|
440
|
+
}
|
|
441
|
+
return itemIndentStr + paddedTerm + " ".repeat(spacerWidth) + formattedDescription.replace(/\n/g, `
|
|
442
|
+
${itemIndentStr}`);
|
|
443
|
+
}
|
|
444
|
+
boxWrap(str, width) {
|
|
445
|
+
if (width < this.minWidthToWrap)
|
|
446
|
+
return str;
|
|
447
|
+
const rawLines = str.split(/\r\n|\n/);
|
|
448
|
+
const chunkPattern = /[\s]*[^\s]+/g;
|
|
449
|
+
const wrappedLines = [];
|
|
450
|
+
rawLines.forEach((line) => {
|
|
451
|
+
const chunks = line.match(chunkPattern);
|
|
452
|
+
if (chunks === null) {
|
|
453
|
+
wrappedLines.push("");
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
456
|
+
let sumChunks = [chunks.shift()];
|
|
457
|
+
let sumWidth = this.displayWidth(sumChunks[0]);
|
|
458
|
+
chunks.forEach((chunk) => {
|
|
459
|
+
const visibleWidth = this.displayWidth(chunk);
|
|
460
|
+
if (sumWidth + visibleWidth <= width) {
|
|
461
|
+
sumChunks.push(chunk);
|
|
462
|
+
sumWidth += visibleWidth;
|
|
463
|
+
return;
|
|
464
|
+
}
|
|
465
|
+
wrappedLines.push(sumChunks.join(""));
|
|
466
|
+
const nextChunk = chunk.trimStart();
|
|
467
|
+
sumChunks = [nextChunk];
|
|
468
|
+
sumWidth = this.displayWidth(nextChunk);
|
|
469
|
+
});
|
|
470
|
+
wrappedLines.push(sumChunks.join(""));
|
|
471
|
+
});
|
|
472
|
+
return wrappedLines.join(`
|
|
473
|
+
`);
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
function stripColor(str) {
|
|
477
|
+
const sgrPattern = /\x1b\[\d*(;\d*)*m/g;
|
|
478
|
+
return str.replace(sgrPattern, "");
|
|
479
|
+
}
|
|
480
|
+
exports.Help = Help;
|
|
481
|
+
exports.stripColor = stripColor;
|
|
482
|
+
});
|
|
483
|
+
|
|
484
|
+
// ../../node_modules/.bun/commander@14.0.2/node_modules/commander/lib/option.js
|
|
485
|
+
var require_option = __commonJS((exports) => {
|
|
486
|
+
var { InvalidArgumentError } = require_error();
|
|
487
|
+
|
|
488
|
+
class Option {
|
|
489
|
+
constructor(flags, description) {
|
|
490
|
+
this.flags = flags;
|
|
491
|
+
this.description = description || "";
|
|
492
|
+
this.required = flags.includes("<");
|
|
493
|
+
this.optional = flags.includes("[");
|
|
494
|
+
this.variadic = /\w\.\.\.[>\]]$/.test(flags);
|
|
495
|
+
this.mandatory = false;
|
|
496
|
+
const optionFlags = splitOptionFlags(flags);
|
|
497
|
+
this.short = optionFlags.shortFlag;
|
|
498
|
+
this.long = optionFlags.longFlag;
|
|
499
|
+
this.negate = false;
|
|
500
|
+
if (this.long) {
|
|
501
|
+
this.negate = this.long.startsWith("--no-");
|
|
502
|
+
}
|
|
503
|
+
this.defaultValue = undefined;
|
|
504
|
+
this.defaultValueDescription = undefined;
|
|
505
|
+
this.presetArg = undefined;
|
|
506
|
+
this.envVar = undefined;
|
|
507
|
+
this.parseArg = undefined;
|
|
508
|
+
this.hidden = false;
|
|
509
|
+
this.argChoices = undefined;
|
|
510
|
+
this.conflictsWith = [];
|
|
511
|
+
this.implied = undefined;
|
|
512
|
+
this.helpGroupHeading = undefined;
|
|
513
|
+
}
|
|
514
|
+
default(value, description) {
|
|
515
|
+
this.defaultValue = value;
|
|
516
|
+
this.defaultValueDescription = description;
|
|
517
|
+
return this;
|
|
518
|
+
}
|
|
519
|
+
preset(arg) {
|
|
520
|
+
this.presetArg = arg;
|
|
521
|
+
return this;
|
|
522
|
+
}
|
|
523
|
+
conflicts(names) {
|
|
524
|
+
this.conflictsWith = this.conflictsWith.concat(names);
|
|
525
|
+
return this;
|
|
526
|
+
}
|
|
527
|
+
implies(impliedOptionValues) {
|
|
528
|
+
let newImplied = impliedOptionValues;
|
|
529
|
+
if (typeof impliedOptionValues === "string") {
|
|
530
|
+
newImplied = { [impliedOptionValues]: true };
|
|
531
|
+
}
|
|
532
|
+
this.implied = Object.assign(this.implied || {}, newImplied);
|
|
533
|
+
return this;
|
|
534
|
+
}
|
|
535
|
+
env(name) {
|
|
536
|
+
this.envVar = name;
|
|
537
|
+
return this;
|
|
538
|
+
}
|
|
539
|
+
argParser(fn) {
|
|
540
|
+
this.parseArg = fn;
|
|
541
|
+
return this;
|
|
542
|
+
}
|
|
543
|
+
makeOptionMandatory(mandatory = true) {
|
|
544
|
+
this.mandatory = !!mandatory;
|
|
545
|
+
return this;
|
|
546
|
+
}
|
|
547
|
+
hideHelp(hide = true) {
|
|
548
|
+
this.hidden = !!hide;
|
|
549
|
+
return this;
|
|
550
|
+
}
|
|
551
|
+
_collectValue(value, previous) {
|
|
552
|
+
if (previous === this.defaultValue || !Array.isArray(previous)) {
|
|
553
|
+
return [value];
|
|
554
|
+
}
|
|
555
|
+
previous.push(value);
|
|
556
|
+
return previous;
|
|
557
|
+
}
|
|
558
|
+
choices(values) {
|
|
559
|
+
this.argChoices = values.slice();
|
|
560
|
+
this.parseArg = (arg, previous) => {
|
|
561
|
+
if (!this.argChoices.includes(arg)) {
|
|
562
|
+
throw new InvalidArgumentError(`Allowed choices are ${this.argChoices.join(", ")}.`);
|
|
563
|
+
}
|
|
564
|
+
if (this.variadic) {
|
|
565
|
+
return this._collectValue(arg, previous);
|
|
566
|
+
}
|
|
567
|
+
return arg;
|
|
568
|
+
};
|
|
569
|
+
return this;
|
|
570
|
+
}
|
|
571
|
+
name() {
|
|
572
|
+
if (this.long) {
|
|
573
|
+
return this.long.replace(/^--/, "");
|
|
574
|
+
}
|
|
575
|
+
return this.short.replace(/^-/, "");
|
|
576
|
+
}
|
|
577
|
+
attributeName() {
|
|
578
|
+
if (this.negate) {
|
|
579
|
+
return camelcase(this.name().replace(/^no-/, ""));
|
|
580
|
+
}
|
|
581
|
+
return camelcase(this.name());
|
|
582
|
+
}
|
|
583
|
+
helpGroup(heading) {
|
|
584
|
+
this.helpGroupHeading = heading;
|
|
585
|
+
return this;
|
|
586
|
+
}
|
|
587
|
+
is(arg) {
|
|
588
|
+
return this.short === arg || this.long === arg;
|
|
589
|
+
}
|
|
590
|
+
isBoolean() {
|
|
591
|
+
return !this.required && !this.optional && !this.negate;
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
class DualOptions {
|
|
596
|
+
constructor(options) {
|
|
597
|
+
this.positiveOptions = new Map;
|
|
598
|
+
this.negativeOptions = new Map;
|
|
599
|
+
this.dualOptions = new Set;
|
|
600
|
+
options.forEach((option) => {
|
|
601
|
+
if (option.negate) {
|
|
602
|
+
this.negativeOptions.set(option.attributeName(), option);
|
|
603
|
+
} else {
|
|
604
|
+
this.positiveOptions.set(option.attributeName(), option);
|
|
605
|
+
}
|
|
606
|
+
});
|
|
607
|
+
this.negativeOptions.forEach((value, key) => {
|
|
608
|
+
if (this.positiveOptions.has(key)) {
|
|
609
|
+
this.dualOptions.add(key);
|
|
610
|
+
}
|
|
611
|
+
});
|
|
612
|
+
}
|
|
613
|
+
valueFromOption(value, option) {
|
|
614
|
+
const optionKey = option.attributeName();
|
|
615
|
+
if (!this.dualOptions.has(optionKey))
|
|
616
|
+
return true;
|
|
617
|
+
const preset = this.negativeOptions.get(optionKey).presetArg;
|
|
618
|
+
const negativeValue = preset !== undefined ? preset : false;
|
|
619
|
+
return option.negate === (negativeValue === value);
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
function camelcase(str) {
|
|
623
|
+
return str.split("-").reduce((str2, word) => {
|
|
624
|
+
return str2 + word[0].toUpperCase() + word.slice(1);
|
|
625
|
+
});
|
|
626
|
+
}
|
|
627
|
+
function splitOptionFlags(flags) {
|
|
628
|
+
let shortFlag;
|
|
629
|
+
let longFlag;
|
|
630
|
+
const shortFlagExp = /^-[^-]$/;
|
|
631
|
+
const longFlagExp = /^--[^-]/;
|
|
632
|
+
const flagParts = flags.split(/[ |,]+/).concat("guard");
|
|
633
|
+
if (shortFlagExp.test(flagParts[0]))
|
|
634
|
+
shortFlag = flagParts.shift();
|
|
635
|
+
if (longFlagExp.test(flagParts[0]))
|
|
636
|
+
longFlag = flagParts.shift();
|
|
637
|
+
if (!shortFlag && shortFlagExp.test(flagParts[0]))
|
|
638
|
+
shortFlag = flagParts.shift();
|
|
639
|
+
if (!shortFlag && longFlagExp.test(flagParts[0])) {
|
|
640
|
+
shortFlag = longFlag;
|
|
641
|
+
longFlag = flagParts.shift();
|
|
642
|
+
}
|
|
643
|
+
if (flagParts[0].startsWith("-")) {
|
|
644
|
+
const unsupportedFlag = flagParts[0];
|
|
645
|
+
const baseError = `option creation failed due to '${unsupportedFlag}' in option flags '${flags}'`;
|
|
646
|
+
if (/^-[^-][^-]/.test(unsupportedFlag))
|
|
647
|
+
throw new Error(`${baseError}
|
|
648
|
+
- a short flag is a single dash and a single character
|
|
649
|
+
- either use a single dash and a single character (for a short flag)
|
|
650
|
+
- or use a double dash for a long option (and can have two, like '--ws, --workspace')`);
|
|
651
|
+
if (shortFlagExp.test(unsupportedFlag))
|
|
652
|
+
throw new Error(`${baseError}
|
|
653
|
+
- too many short flags`);
|
|
654
|
+
if (longFlagExp.test(unsupportedFlag))
|
|
655
|
+
throw new Error(`${baseError}
|
|
656
|
+
- too many long flags`);
|
|
657
|
+
throw new Error(`${baseError}
|
|
658
|
+
- unrecognised flag format`);
|
|
659
|
+
}
|
|
660
|
+
if (shortFlag === undefined && longFlag === undefined)
|
|
661
|
+
throw new Error(`option creation failed due to no flags found in '${flags}'.`);
|
|
662
|
+
return { shortFlag, longFlag };
|
|
663
|
+
}
|
|
664
|
+
exports.Option = Option;
|
|
665
|
+
exports.DualOptions = DualOptions;
|
|
666
|
+
});
|
|
667
|
+
|
|
668
|
+
// ../../node_modules/.bun/commander@14.0.2/node_modules/commander/lib/suggestSimilar.js
|
|
669
|
+
var require_suggestSimilar = __commonJS((exports) => {
|
|
670
|
+
var maxDistance = 3;
|
|
671
|
+
function editDistance(a, b) {
|
|
672
|
+
if (Math.abs(a.length - b.length) > maxDistance)
|
|
673
|
+
return Math.max(a.length, b.length);
|
|
674
|
+
const d = [];
|
|
675
|
+
for (let i = 0;i <= a.length; i++) {
|
|
676
|
+
d[i] = [i];
|
|
677
|
+
}
|
|
678
|
+
for (let j = 0;j <= b.length; j++) {
|
|
679
|
+
d[0][j] = j;
|
|
680
|
+
}
|
|
681
|
+
for (let j = 1;j <= b.length; j++) {
|
|
682
|
+
for (let i = 1;i <= a.length; i++) {
|
|
683
|
+
let cost = 1;
|
|
684
|
+
if (a[i - 1] === b[j - 1]) {
|
|
685
|
+
cost = 0;
|
|
686
|
+
} else {
|
|
687
|
+
cost = 1;
|
|
688
|
+
}
|
|
689
|
+
d[i][j] = Math.min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + cost);
|
|
690
|
+
if (i > 1 && j > 1 && a[i - 1] === b[j - 2] && a[i - 2] === b[j - 1]) {
|
|
691
|
+
d[i][j] = Math.min(d[i][j], d[i - 2][j - 2] + 1);
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
return d[a.length][b.length];
|
|
696
|
+
}
|
|
697
|
+
function suggestSimilar(word, candidates) {
|
|
698
|
+
if (!candidates || candidates.length === 0)
|
|
699
|
+
return "";
|
|
700
|
+
candidates = Array.from(new Set(candidates));
|
|
701
|
+
const searchingOptions = word.startsWith("--");
|
|
702
|
+
if (searchingOptions) {
|
|
703
|
+
word = word.slice(2);
|
|
704
|
+
candidates = candidates.map((candidate) => candidate.slice(2));
|
|
705
|
+
}
|
|
706
|
+
let similar = [];
|
|
707
|
+
let bestDistance = maxDistance;
|
|
708
|
+
const minSimilarity = 0.4;
|
|
709
|
+
candidates.forEach((candidate) => {
|
|
710
|
+
if (candidate.length <= 1)
|
|
711
|
+
return;
|
|
712
|
+
const distance = editDistance(word, candidate);
|
|
713
|
+
const length = Math.max(word.length, candidate.length);
|
|
714
|
+
const similarity = (length - distance) / length;
|
|
715
|
+
if (similarity > minSimilarity) {
|
|
716
|
+
if (distance < bestDistance) {
|
|
717
|
+
bestDistance = distance;
|
|
718
|
+
similar = [candidate];
|
|
719
|
+
} else if (distance === bestDistance) {
|
|
720
|
+
similar.push(candidate);
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
});
|
|
724
|
+
similar.sort((a, b) => a.localeCompare(b));
|
|
725
|
+
if (searchingOptions) {
|
|
726
|
+
similar = similar.map((candidate) => `--${candidate}`);
|
|
727
|
+
}
|
|
728
|
+
if (similar.length > 1) {
|
|
729
|
+
return `
|
|
730
|
+
(Did you mean one of ${similar.join(", ")}?)`;
|
|
731
|
+
}
|
|
732
|
+
if (similar.length === 1) {
|
|
733
|
+
return `
|
|
734
|
+
(Did you mean ${similar[0]}?)`;
|
|
735
|
+
}
|
|
736
|
+
return "";
|
|
737
|
+
}
|
|
738
|
+
exports.suggestSimilar = suggestSimilar;
|
|
739
|
+
});
|
|
740
|
+
|
|
741
|
+
// ../../node_modules/.bun/commander@14.0.2/node_modules/commander/lib/command.js
|
|
742
|
+
var require_command = __commonJS((exports) => {
|
|
743
|
+
var EventEmitter = __require("node:events").EventEmitter;
|
|
744
|
+
var childProcess = __require("node:child_process");
|
|
745
|
+
var path = __require("node:path");
|
|
746
|
+
var fs = __require("node:fs");
|
|
747
|
+
var process2 = __require("node:process");
|
|
748
|
+
var { Argument, humanReadableArgName } = require_argument();
|
|
749
|
+
var { CommanderError } = require_error();
|
|
750
|
+
var { Help, stripColor } = require_help();
|
|
751
|
+
var { Option, DualOptions } = require_option();
|
|
752
|
+
var { suggestSimilar } = require_suggestSimilar();
|
|
753
|
+
|
|
754
|
+
class Command extends EventEmitter {
|
|
755
|
+
constructor(name) {
|
|
756
|
+
super();
|
|
757
|
+
this.commands = [];
|
|
758
|
+
this.options = [];
|
|
759
|
+
this.parent = null;
|
|
760
|
+
this._allowUnknownOption = false;
|
|
761
|
+
this._allowExcessArguments = false;
|
|
762
|
+
this.registeredArguments = [];
|
|
763
|
+
this._args = this.registeredArguments;
|
|
764
|
+
this.args = [];
|
|
765
|
+
this.rawArgs = [];
|
|
766
|
+
this.processedArgs = [];
|
|
767
|
+
this._scriptPath = null;
|
|
768
|
+
this._name = name || "";
|
|
769
|
+
this._optionValues = {};
|
|
770
|
+
this._optionValueSources = {};
|
|
771
|
+
this._storeOptionsAsProperties = false;
|
|
772
|
+
this._actionHandler = null;
|
|
773
|
+
this._executableHandler = false;
|
|
774
|
+
this._executableFile = null;
|
|
775
|
+
this._executableDir = null;
|
|
776
|
+
this._defaultCommandName = null;
|
|
777
|
+
this._exitCallback = null;
|
|
778
|
+
this._aliases = [];
|
|
779
|
+
this._combineFlagAndOptionalValue = true;
|
|
780
|
+
this._description = "";
|
|
781
|
+
this._summary = "";
|
|
782
|
+
this._argsDescription = undefined;
|
|
783
|
+
this._enablePositionalOptions = false;
|
|
784
|
+
this._passThroughOptions = false;
|
|
785
|
+
this._lifeCycleHooks = {};
|
|
786
|
+
this._showHelpAfterError = false;
|
|
787
|
+
this._showSuggestionAfterError = true;
|
|
788
|
+
this._savedState = null;
|
|
789
|
+
this._outputConfiguration = {
|
|
790
|
+
writeOut: (str) => process2.stdout.write(str),
|
|
791
|
+
writeErr: (str) => process2.stderr.write(str),
|
|
792
|
+
outputError: (str, write) => write(str),
|
|
793
|
+
getOutHelpWidth: () => process2.stdout.isTTY ? process2.stdout.columns : undefined,
|
|
794
|
+
getErrHelpWidth: () => process2.stderr.isTTY ? process2.stderr.columns : undefined,
|
|
795
|
+
getOutHasColors: () => useColor() ?? (process2.stdout.isTTY && process2.stdout.hasColors?.()),
|
|
796
|
+
getErrHasColors: () => useColor() ?? (process2.stderr.isTTY && process2.stderr.hasColors?.()),
|
|
797
|
+
stripColor: (str) => stripColor(str)
|
|
798
|
+
};
|
|
799
|
+
this._hidden = false;
|
|
800
|
+
this._helpOption = undefined;
|
|
801
|
+
this._addImplicitHelpCommand = undefined;
|
|
802
|
+
this._helpCommand = undefined;
|
|
803
|
+
this._helpConfiguration = {};
|
|
804
|
+
this._helpGroupHeading = undefined;
|
|
805
|
+
this._defaultCommandGroup = undefined;
|
|
806
|
+
this._defaultOptionGroup = undefined;
|
|
807
|
+
}
|
|
808
|
+
copyInheritedSettings(sourceCommand) {
|
|
809
|
+
this._outputConfiguration = sourceCommand._outputConfiguration;
|
|
810
|
+
this._helpOption = sourceCommand._helpOption;
|
|
811
|
+
this._helpCommand = sourceCommand._helpCommand;
|
|
812
|
+
this._helpConfiguration = sourceCommand._helpConfiguration;
|
|
813
|
+
this._exitCallback = sourceCommand._exitCallback;
|
|
814
|
+
this._storeOptionsAsProperties = sourceCommand._storeOptionsAsProperties;
|
|
815
|
+
this._combineFlagAndOptionalValue = sourceCommand._combineFlagAndOptionalValue;
|
|
816
|
+
this._allowExcessArguments = sourceCommand._allowExcessArguments;
|
|
817
|
+
this._enablePositionalOptions = sourceCommand._enablePositionalOptions;
|
|
818
|
+
this._showHelpAfterError = sourceCommand._showHelpAfterError;
|
|
819
|
+
this._showSuggestionAfterError = sourceCommand._showSuggestionAfterError;
|
|
820
|
+
return this;
|
|
821
|
+
}
|
|
822
|
+
_getCommandAndAncestors() {
|
|
823
|
+
const result = [];
|
|
824
|
+
for (let command = this;command; command = command.parent) {
|
|
825
|
+
result.push(command);
|
|
826
|
+
}
|
|
827
|
+
return result;
|
|
828
|
+
}
|
|
829
|
+
command(nameAndArgs, actionOptsOrExecDesc, execOpts) {
|
|
830
|
+
let desc = actionOptsOrExecDesc;
|
|
831
|
+
let opts = execOpts;
|
|
832
|
+
if (typeof desc === "object" && desc !== null) {
|
|
833
|
+
opts = desc;
|
|
834
|
+
desc = null;
|
|
835
|
+
}
|
|
836
|
+
opts = opts || {};
|
|
837
|
+
const [, name, args] = nameAndArgs.match(/([^ ]+) *(.*)/);
|
|
838
|
+
const cmd = this.createCommand(name);
|
|
839
|
+
if (desc) {
|
|
840
|
+
cmd.description(desc);
|
|
841
|
+
cmd._executableHandler = true;
|
|
842
|
+
}
|
|
843
|
+
if (opts.isDefault)
|
|
844
|
+
this._defaultCommandName = cmd._name;
|
|
845
|
+
cmd._hidden = !!(opts.noHelp || opts.hidden);
|
|
846
|
+
cmd._executableFile = opts.executableFile || null;
|
|
847
|
+
if (args)
|
|
848
|
+
cmd.arguments(args);
|
|
849
|
+
this._registerCommand(cmd);
|
|
850
|
+
cmd.parent = this;
|
|
851
|
+
cmd.copyInheritedSettings(this);
|
|
852
|
+
if (desc)
|
|
853
|
+
return this;
|
|
854
|
+
return cmd;
|
|
855
|
+
}
|
|
856
|
+
createCommand(name) {
|
|
857
|
+
return new Command(name);
|
|
858
|
+
}
|
|
859
|
+
createHelp() {
|
|
860
|
+
return Object.assign(new Help, this.configureHelp());
|
|
861
|
+
}
|
|
862
|
+
configureHelp(configuration) {
|
|
863
|
+
if (configuration === undefined)
|
|
864
|
+
return this._helpConfiguration;
|
|
865
|
+
this._helpConfiguration = configuration;
|
|
866
|
+
return this;
|
|
867
|
+
}
|
|
868
|
+
configureOutput(configuration) {
|
|
869
|
+
if (configuration === undefined)
|
|
870
|
+
return this._outputConfiguration;
|
|
871
|
+
this._outputConfiguration = {
|
|
872
|
+
...this._outputConfiguration,
|
|
873
|
+
...configuration
|
|
874
|
+
};
|
|
875
|
+
return this;
|
|
876
|
+
}
|
|
877
|
+
showHelpAfterError(displayHelp = true) {
|
|
878
|
+
if (typeof displayHelp !== "string")
|
|
879
|
+
displayHelp = !!displayHelp;
|
|
880
|
+
this._showHelpAfterError = displayHelp;
|
|
881
|
+
return this;
|
|
882
|
+
}
|
|
883
|
+
showSuggestionAfterError(displaySuggestion = true) {
|
|
884
|
+
this._showSuggestionAfterError = !!displaySuggestion;
|
|
885
|
+
return this;
|
|
886
|
+
}
|
|
887
|
+
addCommand(cmd, opts) {
|
|
888
|
+
if (!cmd._name) {
|
|
889
|
+
throw new Error(`Command passed to .addCommand() must have a name
|
|
890
|
+
- specify the name in Command constructor or using .name()`);
|
|
891
|
+
}
|
|
892
|
+
opts = opts || {};
|
|
893
|
+
if (opts.isDefault)
|
|
894
|
+
this._defaultCommandName = cmd._name;
|
|
895
|
+
if (opts.noHelp || opts.hidden)
|
|
896
|
+
cmd._hidden = true;
|
|
897
|
+
this._registerCommand(cmd);
|
|
898
|
+
cmd.parent = this;
|
|
899
|
+
cmd._checkForBrokenPassThrough();
|
|
900
|
+
return this;
|
|
901
|
+
}
|
|
902
|
+
createArgument(name, description) {
|
|
903
|
+
return new Argument(name, description);
|
|
904
|
+
}
|
|
905
|
+
argument(name, description, parseArg, defaultValue) {
|
|
906
|
+
const argument = this.createArgument(name, description);
|
|
907
|
+
if (typeof parseArg === "function") {
|
|
908
|
+
argument.default(defaultValue).argParser(parseArg);
|
|
909
|
+
} else {
|
|
910
|
+
argument.default(parseArg);
|
|
911
|
+
}
|
|
912
|
+
this.addArgument(argument);
|
|
913
|
+
return this;
|
|
914
|
+
}
|
|
915
|
+
arguments(names) {
|
|
916
|
+
names.trim().split(/ +/).forEach((detail) => {
|
|
917
|
+
this.argument(detail);
|
|
918
|
+
});
|
|
919
|
+
return this;
|
|
920
|
+
}
|
|
921
|
+
addArgument(argument) {
|
|
922
|
+
const previousArgument = this.registeredArguments.slice(-1)[0];
|
|
923
|
+
if (previousArgument?.variadic) {
|
|
924
|
+
throw new Error(`only the last argument can be variadic '${previousArgument.name()}'`);
|
|
925
|
+
}
|
|
926
|
+
if (argument.required && argument.defaultValue !== undefined && argument.parseArg === undefined) {
|
|
927
|
+
throw new Error(`a default value for a required argument is never used: '${argument.name()}'`);
|
|
928
|
+
}
|
|
929
|
+
this.registeredArguments.push(argument);
|
|
930
|
+
return this;
|
|
931
|
+
}
|
|
932
|
+
helpCommand(enableOrNameAndArgs, description) {
|
|
933
|
+
if (typeof enableOrNameAndArgs === "boolean") {
|
|
934
|
+
this._addImplicitHelpCommand = enableOrNameAndArgs;
|
|
935
|
+
if (enableOrNameAndArgs && this._defaultCommandGroup) {
|
|
936
|
+
this._initCommandGroup(this._getHelpCommand());
|
|
937
|
+
}
|
|
938
|
+
return this;
|
|
939
|
+
}
|
|
940
|
+
const nameAndArgs = enableOrNameAndArgs ?? "help [command]";
|
|
941
|
+
const [, helpName, helpArgs] = nameAndArgs.match(/([^ ]+) *(.*)/);
|
|
942
|
+
const helpDescription = description ?? "display help for command";
|
|
943
|
+
const helpCommand = this.createCommand(helpName);
|
|
944
|
+
helpCommand.helpOption(false);
|
|
945
|
+
if (helpArgs)
|
|
946
|
+
helpCommand.arguments(helpArgs);
|
|
947
|
+
if (helpDescription)
|
|
948
|
+
helpCommand.description(helpDescription);
|
|
949
|
+
this._addImplicitHelpCommand = true;
|
|
950
|
+
this._helpCommand = helpCommand;
|
|
951
|
+
if (enableOrNameAndArgs || description)
|
|
952
|
+
this._initCommandGroup(helpCommand);
|
|
953
|
+
return this;
|
|
954
|
+
}
|
|
955
|
+
addHelpCommand(helpCommand, deprecatedDescription) {
|
|
956
|
+
if (typeof helpCommand !== "object") {
|
|
957
|
+
this.helpCommand(helpCommand, deprecatedDescription);
|
|
958
|
+
return this;
|
|
959
|
+
}
|
|
960
|
+
this._addImplicitHelpCommand = true;
|
|
961
|
+
this._helpCommand = helpCommand;
|
|
962
|
+
this._initCommandGroup(helpCommand);
|
|
963
|
+
return this;
|
|
964
|
+
}
|
|
965
|
+
_getHelpCommand() {
|
|
966
|
+
const hasImplicitHelpCommand = this._addImplicitHelpCommand ?? (this.commands.length && !this._actionHandler && !this._findCommand("help"));
|
|
967
|
+
if (hasImplicitHelpCommand) {
|
|
968
|
+
if (this._helpCommand === undefined) {
|
|
969
|
+
this.helpCommand(undefined, undefined);
|
|
970
|
+
}
|
|
971
|
+
return this._helpCommand;
|
|
972
|
+
}
|
|
973
|
+
return null;
|
|
974
|
+
}
|
|
975
|
+
hook(event, listener) {
|
|
976
|
+
const allowedValues = ["preSubcommand", "preAction", "postAction"];
|
|
977
|
+
if (!allowedValues.includes(event)) {
|
|
978
|
+
throw new Error(`Unexpected value for event passed to hook : '${event}'.
|
|
979
|
+
Expecting one of '${allowedValues.join("', '")}'`);
|
|
980
|
+
}
|
|
981
|
+
if (this._lifeCycleHooks[event]) {
|
|
982
|
+
this._lifeCycleHooks[event].push(listener);
|
|
983
|
+
} else {
|
|
984
|
+
this._lifeCycleHooks[event] = [listener];
|
|
985
|
+
}
|
|
986
|
+
return this;
|
|
987
|
+
}
|
|
988
|
+
exitOverride(fn) {
|
|
989
|
+
if (fn) {
|
|
990
|
+
this._exitCallback = fn;
|
|
991
|
+
} else {
|
|
992
|
+
this._exitCallback = (err) => {
|
|
993
|
+
if (err.code !== "commander.executeSubCommandAsync") {
|
|
994
|
+
throw err;
|
|
995
|
+
} else {}
|
|
996
|
+
};
|
|
997
|
+
}
|
|
998
|
+
return this;
|
|
999
|
+
}
|
|
1000
|
+
_exit(exitCode, code, message) {
|
|
1001
|
+
if (this._exitCallback) {
|
|
1002
|
+
this._exitCallback(new CommanderError(exitCode, code, message));
|
|
1003
|
+
}
|
|
1004
|
+
process2.exit(exitCode);
|
|
1005
|
+
}
|
|
1006
|
+
action(fn) {
|
|
1007
|
+
const listener = (args) => {
|
|
1008
|
+
const expectedArgsCount = this.registeredArguments.length;
|
|
1009
|
+
const actionArgs = args.slice(0, expectedArgsCount);
|
|
1010
|
+
if (this._storeOptionsAsProperties) {
|
|
1011
|
+
actionArgs[expectedArgsCount] = this;
|
|
1012
|
+
} else {
|
|
1013
|
+
actionArgs[expectedArgsCount] = this.opts();
|
|
1014
|
+
}
|
|
1015
|
+
actionArgs.push(this);
|
|
1016
|
+
return fn.apply(this, actionArgs);
|
|
1017
|
+
};
|
|
1018
|
+
this._actionHandler = listener;
|
|
1019
|
+
return this;
|
|
1020
|
+
}
|
|
1021
|
+
createOption(flags, description) {
|
|
1022
|
+
return new Option(flags, description);
|
|
1023
|
+
}
|
|
1024
|
+
_callParseArg(target, value, previous, invalidArgumentMessage) {
|
|
1025
|
+
try {
|
|
1026
|
+
return target.parseArg(value, previous);
|
|
1027
|
+
} catch (err) {
|
|
1028
|
+
if (err.code === "commander.invalidArgument") {
|
|
1029
|
+
const message = `${invalidArgumentMessage} ${err.message}`;
|
|
1030
|
+
this.error(message, { exitCode: err.exitCode, code: err.code });
|
|
1031
|
+
}
|
|
1032
|
+
throw err;
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
_registerOption(option) {
|
|
1036
|
+
const matchingOption = option.short && this._findOption(option.short) || option.long && this._findOption(option.long);
|
|
1037
|
+
if (matchingOption) {
|
|
1038
|
+
const matchingFlag = option.long && this._findOption(option.long) ? option.long : option.short;
|
|
1039
|
+
throw new Error(`Cannot add option '${option.flags}'${this._name && ` to command '${this._name}'`} due to conflicting flag '${matchingFlag}'
|
|
1040
|
+
- already used by option '${matchingOption.flags}'`);
|
|
1041
|
+
}
|
|
1042
|
+
this._initOptionGroup(option);
|
|
1043
|
+
this.options.push(option);
|
|
1044
|
+
}
|
|
1045
|
+
_registerCommand(command) {
|
|
1046
|
+
const knownBy = (cmd) => {
|
|
1047
|
+
return [cmd.name()].concat(cmd.aliases());
|
|
1048
|
+
};
|
|
1049
|
+
const alreadyUsed = knownBy(command).find((name) => this._findCommand(name));
|
|
1050
|
+
if (alreadyUsed) {
|
|
1051
|
+
const existingCmd = knownBy(this._findCommand(alreadyUsed)).join("|");
|
|
1052
|
+
const newCmd = knownBy(command).join("|");
|
|
1053
|
+
throw new Error(`cannot add command '${newCmd}' as already have command '${existingCmd}'`);
|
|
1054
|
+
}
|
|
1055
|
+
this._initCommandGroup(command);
|
|
1056
|
+
this.commands.push(command);
|
|
1057
|
+
}
|
|
1058
|
+
addOption(option) {
|
|
1059
|
+
this._registerOption(option);
|
|
1060
|
+
const oname = option.name();
|
|
1061
|
+
const name = option.attributeName();
|
|
1062
|
+
if (option.negate) {
|
|
1063
|
+
const positiveLongFlag = option.long.replace(/^--no-/, "--");
|
|
1064
|
+
if (!this._findOption(positiveLongFlag)) {
|
|
1065
|
+
this.setOptionValueWithSource(name, option.defaultValue === undefined ? true : option.defaultValue, "default");
|
|
1066
|
+
}
|
|
1067
|
+
} else if (option.defaultValue !== undefined) {
|
|
1068
|
+
this.setOptionValueWithSource(name, option.defaultValue, "default");
|
|
1069
|
+
}
|
|
1070
|
+
const handleOptionValue = (val, invalidValueMessage, valueSource) => {
|
|
1071
|
+
if (val == null && option.presetArg !== undefined) {
|
|
1072
|
+
val = option.presetArg;
|
|
1073
|
+
}
|
|
1074
|
+
const oldValue = this.getOptionValue(name);
|
|
1075
|
+
if (val !== null && option.parseArg) {
|
|
1076
|
+
val = this._callParseArg(option, val, oldValue, invalidValueMessage);
|
|
1077
|
+
} else if (val !== null && option.variadic) {
|
|
1078
|
+
val = option._collectValue(val, oldValue);
|
|
1079
|
+
}
|
|
1080
|
+
if (val == null) {
|
|
1081
|
+
if (option.negate) {
|
|
1082
|
+
val = false;
|
|
1083
|
+
} else if (option.isBoolean() || option.optional) {
|
|
1084
|
+
val = true;
|
|
1085
|
+
} else {
|
|
1086
|
+
val = "";
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1089
|
+
this.setOptionValueWithSource(name, val, valueSource);
|
|
1090
|
+
};
|
|
1091
|
+
this.on("option:" + oname, (val) => {
|
|
1092
|
+
const invalidValueMessage = `error: option '${option.flags}' argument '${val}' is invalid.`;
|
|
1093
|
+
handleOptionValue(val, invalidValueMessage, "cli");
|
|
1094
|
+
});
|
|
1095
|
+
if (option.envVar) {
|
|
1096
|
+
this.on("optionEnv:" + oname, (val) => {
|
|
1097
|
+
const invalidValueMessage = `error: option '${option.flags}' value '${val}' from env '${option.envVar}' is invalid.`;
|
|
1098
|
+
handleOptionValue(val, invalidValueMessage, "env");
|
|
1099
|
+
});
|
|
1100
|
+
}
|
|
1101
|
+
return this;
|
|
1102
|
+
}
|
|
1103
|
+
_optionEx(config, flags, description, fn, defaultValue) {
|
|
1104
|
+
if (typeof flags === "object" && flags instanceof Option) {
|
|
1105
|
+
throw new Error("To add an Option object use addOption() instead of option() or requiredOption()");
|
|
1106
|
+
}
|
|
1107
|
+
const option = this.createOption(flags, description);
|
|
1108
|
+
option.makeOptionMandatory(!!config.mandatory);
|
|
1109
|
+
if (typeof fn === "function") {
|
|
1110
|
+
option.default(defaultValue).argParser(fn);
|
|
1111
|
+
} else if (fn instanceof RegExp) {
|
|
1112
|
+
const regex = fn;
|
|
1113
|
+
fn = (val, def) => {
|
|
1114
|
+
const m = regex.exec(val);
|
|
1115
|
+
return m ? m[0] : def;
|
|
1116
|
+
};
|
|
1117
|
+
option.default(defaultValue).argParser(fn);
|
|
1118
|
+
} else {
|
|
1119
|
+
option.default(fn);
|
|
1120
|
+
}
|
|
1121
|
+
return this.addOption(option);
|
|
1122
|
+
}
|
|
1123
|
+
option(flags, description, parseArg, defaultValue) {
|
|
1124
|
+
return this._optionEx({}, flags, description, parseArg, defaultValue);
|
|
1125
|
+
}
|
|
1126
|
+
requiredOption(flags, description, parseArg, defaultValue) {
|
|
1127
|
+
return this._optionEx({ mandatory: true }, flags, description, parseArg, defaultValue);
|
|
1128
|
+
}
|
|
1129
|
+
combineFlagAndOptionalValue(combine = true) {
|
|
1130
|
+
this._combineFlagAndOptionalValue = !!combine;
|
|
1131
|
+
return this;
|
|
1132
|
+
}
|
|
1133
|
+
allowUnknownOption(allowUnknown = true) {
|
|
1134
|
+
this._allowUnknownOption = !!allowUnknown;
|
|
1135
|
+
return this;
|
|
1136
|
+
}
|
|
1137
|
+
allowExcessArguments(allowExcess = true) {
|
|
1138
|
+
this._allowExcessArguments = !!allowExcess;
|
|
1139
|
+
return this;
|
|
1140
|
+
}
|
|
1141
|
+
enablePositionalOptions(positional = true) {
|
|
1142
|
+
this._enablePositionalOptions = !!positional;
|
|
1143
|
+
return this;
|
|
1144
|
+
}
|
|
1145
|
+
passThroughOptions(passThrough = true) {
|
|
1146
|
+
this._passThroughOptions = !!passThrough;
|
|
1147
|
+
this._checkForBrokenPassThrough();
|
|
1148
|
+
return this;
|
|
1149
|
+
}
|
|
1150
|
+
_checkForBrokenPassThrough() {
|
|
1151
|
+
if (this.parent && this._passThroughOptions && !this.parent._enablePositionalOptions) {
|
|
1152
|
+
throw new Error(`passThroughOptions cannot be used for '${this._name}' without turning on enablePositionalOptions for parent command(s)`);
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
storeOptionsAsProperties(storeAsProperties = true) {
|
|
1156
|
+
if (this.options.length) {
|
|
1157
|
+
throw new Error("call .storeOptionsAsProperties() before adding options");
|
|
1158
|
+
}
|
|
1159
|
+
if (Object.keys(this._optionValues).length) {
|
|
1160
|
+
throw new Error("call .storeOptionsAsProperties() before setting option values");
|
|
1161
|
+
}
|
|
1162
|
+
this._storeOptionsAsProperties = !!storeAsProperties;
|
|
1163
|
+
return this;
|
|
1164
|
+
}
|
|
1165
|
+
getOptionValue(key) {
|
|
1166
|
+
if (this._storeOptionsAsProperties) {
|
|
1167
|
+
return this[key];
|
|
1168
|
+
}
|
|
1169
|
+
return this._optionValues[key];
|
|
1170
|
+
}
|
|
1171
|
+
setOptionValue(key, value) {
|
|
1172
|
+
return this.setOptionValueWithSource(key, value, undefined);
|
|
1173
|
+
}
|
|
1174
|
+
setOptionValueWithSource(key, value, source) {
|
|
1175
|
+
if (this._storeOptionsAsProperties) {
|
|
1176
|
+
this[key] = value;
|
|
1177
|
+
} else {
|
|
1178
|
+
this._optionValues[key] = value;
|
|
1179
|
+
}
|
|
1180
|
+
this._optionValueSources[key] = source;
|
|
1181
|
+
return this;
|
|
1182
|
+
}
|
|
1183
|
+
getOptionValueSource(key) {
|
|
1184
|
+
return this._optionValueSources[key];
|
|
1185
|
+
}
|
|
1186
|
+
getOptionValueSourceWithGlobals(key) {
|
|
1187
|
+
let source;
|
|
1188
|
+
this._getCommandAndAncestors().forEach((cmd) => {
|
|
1189
|
+
if (cmd.getOptionValueSource(key) !== undefined) {
|
|
1190
|
+
source = cmd.getOptionValueSource(key);
|
|
1191
|
+
}
|
|
1192
|
+
});
|
|
1193
|
+
return source;
|
|
1194
|
+
}
|
|
1195
|
+
_prepareUserArgs(argv, parseOptions) {
|
|
1196
|
+
if (argv !== undefined && !Array.isArray(argv)) {
|
|
1197
|
+
throw new Error("first parameter to parse must be array or undefined");
|
|
1198
|
+
}
|
|
1199
|
+
parseOptions = parseOptions || {};
|
|
1200
|
+
if (argv === undefined && parseOptions.from === undefined) {
|
|
1201
|
+
if (process2.versions?.electron) {
|
|
1202
|
+
parseOptions.from = "electron";
|
|
1203
|
+
}
|
|
1204
|
+
const execArgv = process2.execArgv ?? [];
|
|
1205
|
+
if (execArgv.includes("-e") || execArgv.includes("--eval") || execArgv.includes("-p") || execArgv.includes("--print")) {
|
|
1206
|
+
parseOptions.from = "eval";
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
if (argv === undefined) {
|
|
1210
|
+
argv = process2.argv;
|
|
1211
|
+
}
|
|
1212
|
+
this.rawArgs = argv.slice();
|
|
1213
|
+
let userArgs;
|
|
1214
|
+
switch (parseOptions.from) {
|
|
1215
|
+
case undefined:
|
|
1216
|
+
case "node":
|
|
1217
|
+
this._scriptPath = argv[1];
|
|
1218
|
+
userArgs = argv.slice(2);
|
|
1219
|
+
break;
|
|
1220
|
+
case "electron":
|
|
1221
|
+
if (process2.defaultApp) {
|
|
1222
|
+
this._scriptPath = argv[1];
|
|
1223
|
+
userArgs = argv.slice(2);
|
|
1224
|
+
} else {
|
|
1225
|
+
userArgs = argv.slice(1);
|
|
1226
|
+
}
|
|
1227
|
+
break;
|
|
1228
|
+
case "user":
|
|
1229
|
+
userArgs = argv.slice(0);
|
|
1230
|
+
break;
|
|
1231
|
+
case "eval":
|
|
1232
|
+
userArgs = argv.slice(1);
|
|
1233
|
+
break;
|
|
1234
|
+
default:
|
|
1235
|
+
throw new Error(`unexpected parse option { from: '${parseOptions.from}' }`);
|
|
1236
|
+
}
|
|
1237
|
+
if (!this._name && this._scriptPath)
|
|
1238
|
+
this.nameFromFilename(this._scriptPath);
|
|
1239
|
+
this._name = this._name || "program";
|
|
1240
|
+
return userArgs;
|
|
1241
|
+
}
|
|
1242
|
+
parse(argv, parseOptions) {
|
|
1243
|
+
this._prepareForParse();
|
|
1244
|
+
const userArgs = this._prepareUserArgs(argv, parseOptions);
|
|
1245
|
+
this._parseCommand([], userArgs);
|
|
1246
|
+
return this;
|
|
1247
|
+
}
|
|
1248
|
+
async parseAsync(argv, parseOptions) {
|
|
1249
|
+
this._prepareForParse();
|
|
1250
|
+
const userArgs = this._prepareUserArgs(argv, parseOptions);
|
|
1251
|
+
await this._parseCommand([], userArgs);
|
|
1252
|
+
return this;
|
|
1253
|
+
}
|
|
1254
|
+
_prepareForParse() {
|
|
1255
|
+
if (this._savedState === null) {
|
|
1256
|
+
this.saveStateBeforeParse();
|
|
1257
|
+
} else {
|
|
1258
|
+
this.restoreStateBeforeParse();
|
|
1259
|
+
}
|
|
1260
|
+
}
|
|
1261
|
+
saveStateBeforeParse() {
|
|
1262
|
+
this._savedState = {
|
|
1263
|
+
_name: this._name,
|
|
1264
|
+
_optionValues: { ...this._optionValues },
|
|
1265
|
+
_optionValueSources: { ...this._optionValueSources }
|
|
1266
|
+
};
|
|
1267
|
+
}
|
|
1268
|
+
restoreStateBeforeParse() {
|
|
1269
|
+
if (this._storeOptionsAsProperties)
|
|
1270
|
+
throw new Error(`Can not call parse again when storeOptionsAsProperties is true.
|
|
1271
|
+
- either make a new Command for each call to parse, or stop storing options as properties`);
|
|
1272
|
+
this._name = this._savedState._name;
|
|
1273
|
+
this._scriptPath = null;
|
|
1274
|
+
this.rawArgs = [];
|
|
1275
|
+
this._optionValues = { ...this._savedState._optionValues };
|
|
1276
|
+
this._optionValueSources = { ...this._savedState._optionValueSources };
|
|
1277
|
+
this.args = [];
|
|
1278
|
+
this.processedArgs = [];
|
|
1279
|
+
}
|
|
1280
|
+
_checkForMissingExecutable(executableFile, executableDir, subcommandName) {
|
|
1281
|
+
if (fs.existsSync(executableFile))
|
|
1282
|
+
return;
|
|
1283
|
+
const executableDirMessage = executableDir ? `searched for local subcommand relative to directory '${executableDir}'` : "no directory for search for local subcommand, use .executableDir() to supply a custom directory";
|
|
1284
|
+
const executableMissing = `'${executableFile}' does not exist
|
|
1285
|
+
- if '${subcommandName}' is not meant to be an executable command, remove description parameter from '.command()' and use '.description()' instead
|
|
1286
|
+
- if the default executable name is not suitable, use the executableFile option to supply a custom name or path
|
|
1287
|
+
- ${executableDirMessage}`;
|
|
1288
|
+
throw new Error(executableMissing);
|
|
1289
|
+
}
|
|
1290
|
+
_executeSubCommand(subcommand, args) {
|
|
1291
|
+
args = args.slice();
|
|
1292
|
+
let launchWithNode = false;
|
|
1293
|
+
const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
|
|
1294
|
+
function findFile(baseDir, baseName) {
|
|
1295
|
+
const localBin = path.resolve(baseDir, baseName);
|
|
1296
|
+
if (fs.existsSync(localBin))
|
|
1297
|
+
return localBin;
|
|
1298
|
+
if (sourceExt.includes(path.extname(baseName)))
|
|
1299
|
+
return;
|
|
1300
|
+
const foundExt = sourceExt.find((ext) => fs.existsSync(`${localBin}${ext}`));
|
|
1301
|
+
if (foundExt)
|
|
1302
|
+
return `${localBin}${foundExt}`;
|
|
1303
|
+
return;
|
|
1304
|
+
}
|
|
1305
|
+
this._checkForMissingMandatoryOptions();
|
|
1306
|
+
this._checkForConflictingOptions();
|
|
1307
|
+
let executableFile = subcommand._executableFile || `${this._name}-${subcommand._name}`;
|
|
1308
|
+
let executableDir = this._executableDir || "";
|
|
1309
|
+
if (this._scriptPath) {
|
|
1310
|
+
let resolvedScriptPath;
|
|
1311
|
+
try {
|
|
1312
|
+
resolvedScriptPath = fs.realpathSync(this._scriptPath);
|
|
1313
|
+
} catch {
|
|
1314
|
+
resolvedScriptPath = this._scriptPath;
|
|
1315
|
+
}
|
|
1316
|
+
executableDir = path.resolve(path.dirname(resolvedScriptPath), executableDir);
|
|
1317
|
+
}
|
|
1318
|
+
if (executableDir) {
|
|
1319
|
+
let localFile = findFile(executableDir, executableFile);
|
|
1320
|
+
if (!localFile && !subcommand._executableFile && this._scriptPath) {
|
|
1321
|
+
const legacyName = path.basename(this._scriptPath, path.extname(this._scriptPath));
|
|
1322
|
+
if (legacyName !== this._name) {
|
|
1323
|
+
localFile = findFile(executableDir, `${legacyName}-${subcommand._name}`);
|
|
1324
|
+
}
|
|
1325
|
+
}
|
|
1326
|
+
executableFile = localFile || executableFile;
|
|
1327
|
+
}
|
|
1328
|
+
launchWithNode = sourceExt.includes(path.extname(executableFile));
|
|
1329
|
+
let proc;
|
|
1330
|
+
if (process2.platform !== "win32") {
|
|
1331
|
+
if (launchWithNode) {
|
|
1332
|
+
args.unshift(executableFile);
|
|
1333
|
+
args = incrementNodeInspectorPort(process2.execArgv).concat(args);
|
|
1334
|
+
proc = childProcess.spawn(process2.argv[0], args, { stdio: "inherit" });
|
|
1335
|
+
} else {
|
|
1336
|
+
proc = childProcess.spawn(executableFile, args, { stdio: "inherit" });
|
|
1337
|
+
}
|
|
1338
|
+
} else {
|
|
1339
|
+
this._checkForMissingExecutable(executableFile, executableDir, subcommand._name);
|
|
1340
|
+
args.unshift(executableFile);
|
|
1341
|
+
args = incrementNodeInspectorPort(process2.execArgv).concat(args);
|
|
1342
|
+
proc = childProcess.spawn(process2.execPath, args, { stdio: "inherit" });
|
|
1343
|
+
}
|
|
1344
|
+
if (!proc.killed) {
|
|
1345
|
+
const signals = ["SIGUSR1", "SIGUSR2", "SIGTERM", "SIGINT", "SIGHUP"];
|
|
1346
|
+
signals.forEach((signal) => {
|
|
1347
|
+
process2.on(signal, () => {
|
|
1348
|
+
if (proc.killed === false && proc.exitCode === null) {
|
|
1349
|
+
proc.kill(signal);
|
|
1350
|
+
}
|
|
1351
|
+
});
|
|
1352
|
+
});
|
|
1353
|
+
}
|
|
1354
|
+
const exitCallback = this._exitCallback;
|
|
1355
|
+
proc.on("close", (code) => {
|
|
1356
|
+
code = code ?? 1;
|
|
1357
|
+
if (!exitCallback) {
|
|
1358
|
+
process2.exit(code);
|
|
1359
|
+
} else {
|
|
1360
|
+
exitCallback(new CommanderError(code, "commander.executeSubCommandAsync", "(close)"));
|
|
1361
|
+
}
|
|
1362
|
+
});
|
|
1363
|
+
proc.on("error", (err) => {
|
|
1364
|
+
if (err.code === "ENOENT") {
|
|
1365
|
+
this._checkForMissingExecutable(executableFile, executableDir, subcommand._name);
|
|
1366
|
+
} else if (err.code === "EACCES") {
|
|
1367
|
+
throw new Error(`'${executableFile}' not executable`);
|
|
1368
|
+
}
|
|
1369
|
+
if (!exitCallback) {
|
|
1370
|
+
process2.exit(1);
|
|
1371
|
+
} else {
|
|
1372
|
+
const wrappedError = new CommanderError(1, "commander.executeSubCommandAsync", "(error)");
|
|
1373
|
+
wrappedError.nestedError = err;
|
|
1374
|
+
exitCallback(wrappedError);
|
|
1375
|
+
}
|
|
1376
|
+
});
|
|
1377
|
+
this.runningCommand = proc;
|
|
1378
|
+
}
|
|
1379
|
+
_dispatchSubcommand(commandName, operands, unknown) {
|
|
1380
|
+
const subCommand = this._findCommand(commandName);
|
|
1381
|
+
if (!subCommand)
|
|
1382
|
+
this.help({ error: true });
|
|
1383
|
+
subCommand._prepareForParse();
|
|
1384
|
+
let promiseChain;
|
|
1385
|
+
promiseChain = this._chainOrCallSubCommandHook(promiseChain, subCommand, "preSubcommand");
|
|
1386
|
+
promiseChain = this._chainOrCall(promiseChain, () => {
|
|
1387
|
+
if (subCommand._executableHandler) {
|
|
1388
|
+
this._executeSubCommand(subCommand, operands.concat(unknown));
|
|
1389
|
+
} else {
|
|
1390
|
+
return subCommand._parseCommand(operands, unknown);
|
|
1391
|
+
}
|
|
1392
|
+
});
|
|
1393
|
+
return promiseChain;
|
|
1394
|
+
}
|
|
1395
|
+
_dispatchHelpCommand(subcommandName) {
|
|
1396
|
+
if (!subcommandName) {
|
|
1397
|
+
this.help();
|
|
1398
|
+
}
|
|
1399
|
+
const subCommand = this._findCommand(subcommandName);
|
|
1400
|
+
if (subCommand && !subCommand._executableHandler) {
|
|
1401
|
+
subCommand.help();
|
|
1402
|
+
}
|
|
1403
|
+
return this._dispatchSubcommand(subcommandName, [], [this._getHelpOption()?.long ?? this._getHelpOption()?.short ?? "--help"]);
|
|
1404
|
+
}
|
|
1405
|
+
_checkNumberOfArguments() {
|
|
1406
|
+
this.registeredArguments.forEach((arg, i) => {
|
|
1407
|
+
if (arg.required && this.args[i] == null) {
|
|
1408
|
+
this.missingArgument(arg.name());
|
|
1409
|
+
}
|
|
1410
|
+
});
|
|
1411
|
+
if (this.registeredArguments.length > 0 && this.registeredArguments[this.registeredArguments.length - 1].variadic) {
|
|
1412
|
+
return;
|
|
1413
|
+
}
|
|
1414
|
+
if (this.args.length > this.registeredArguments.length) {
|
|
1415
|
+
this._excessArguments(this.args);
|
|
1416
|
+
}
|
|
1417
|
+
}
|
|
1418
|
+
_processArguments() {
|
|
1419
|
+
const myParseArg = (argument, value, previous) => {
|
|
1420
|
+
let parsedValue = value;
|
|
1421
|
+
if (value !== null && argument.parseArg) {
|
|
1422
|
+
const invalidValueMessage = `error: command-argument value '${value}' is invalid for argument '${argument.name()}'.`;
|
|
1423
|
+
parsedValue = this._callParseArg(argument, value, previous, invalidValueMessage);
|
|
1424
|
+
}
|
|
1425
|
+
return parsedValue;
|
|
1426
|
+
};
|
|
1427
|
+
this._checkNumberOfArguments();
|
|
1428
|
+
const processedArgs = [];
|
|
1429
|
+
this.registeredArguments.forEach((declaredArg, index) => {
|
|
1430
|
+
let value = declaredArg.defaultValue;
|
|
1431
|
+
if (declaredArg.variadic) {
|
|
1432
|
+
if (index < this.args.length) {
|
|
1433
|
+
value = this.args.slice(index);
|
|
1434
|
+
if (declaredArg.parseArg) {
|
|
1435
|
+
value = value.reduce((processed, v) => {
|
|
1436
|
+
return myParseArg(declaredArg, v, processed);
|
|
1437
|
+
}, declaredArg.defaultValue);
|
|
1438
|
+
}
|
|
1439
|
+
} else if (value === undefined) {
|
|
1440
|
+
value = [];
|
|
1441
|
+
}
|
|
1442
|
+
} else if (index < this.args.length) {
|
|
1443
|
+
value = this.args[index];
|
|
1444
|
+
if (declaredArg.parseArg) {
|
|
1445
|
+
value = myParseArg(declaredArg, value, declaredArg.defaultValue);
|
|
1446
|
+
}
|
|
1447
|
+
}
|
|
1448
|
+
processedArgs[index] = value;
|
|
1449
|
+
});
|
|
1450
|
+
this.processedArgs = processedArgs;
|
|
1451
|
+
}
|
|
1452
|
+
_chainOrCall(promise, fn) {
|
|
1453
|
+
if (promise?.then && typeof promise.then === "function") {
|
|
1454
|
+
return promise.then(() => fn());
|
|
1455
|
+
}
|
|
1456
|
+
return fn();
|
|
1457
|
+
}
|
|
1458
|
+
_chainOrCallHooks(promise, event) {
|
|
1459
|
+
let result = promise;
|
|
1460
|
+
const hooks = [];
|
|
1461
|
+
this._getCommandAndAncestors().reverse().filter((cmd) => cmd._lifeCycleHooks[event] !== undefined).forEach((hookedCommand) => {
|
|
1462
|
+
hookedCommand._lifeCycleHooks[event].forEach((callback) => {
|
|
1463
|
+
hooks.push({ hookedCommand, callback });
|
|
1464
|
+
});
|
|
1465
|
+
});
|
|
1466
|
+
if (event === "postAction") {
|
|
1467
|
+
hooks.reverse();
|
|
1468
|
+
}
|
|
1469
|
+
hooks.forEach((hookDetail) => {
|
|
1470
|
+
result = this._chainOrCall(result, () => {
|
|
1471
|
+
return hookDetail.callback(hookDetail.hookedCommand, this);
|
|
1472
|
+
});
|
|
1473
|
+
});
|
|
1474
|
+
return result;
|
|
1475
|
+
}
|
|
1476
|
+
_chainOrCallSubCommandHook(promise, subCommand, event) {
|
|
1477
|
+
let result = promise;
|
|
1478
|
+
if (this._lifeCycleHooks[event] !== undefined) {
|
|
1479
|
+
this._lifeCycleHooks[event].forEach((hook) => {
|
|
1480
|
+
result = this._chainOrCall(result, () => {
|
|
1481
|
+
return hook(this, subCommand);
|
|
1482
|
+
});
|
|
1483
|
+
});
|
|
1484
|
+
}
|
|
1485
|
+
return result;
|
|
1486
|
+
}
|
|
1487
|
+
_parseCommand(operands, unknown) {
|
|
1488
|
+
const parsed = this.parseOptions(unknown);
|
|
1489
|
+
this._parseOptionsEnv();
|
|
1490
|
+
this._parseOptionsImplied();
|
|
1491
|
+
operands = operands.concat(parsed.operands);
|
|
1492
|
+
unknown = parsed.unknown;
|
|
1493
|
+
this.args = operands.concat(unknown);
|
|
1494
|
+
if (operands && this._findCommand(operands[0])) {
|
|
1495
|
+
return this._dispatchSubcommand(operands[0], operands.slice(1), unknown);
|
|
1496
|
+
}
|
|
1497
|
+
if (this._getHelpCommand() && operands[0] === this._getHelpCommand().name()) {
|
|
1498
|
+
return this._dispatchHelpCommand(operands[1]);
|
|
1499
|
+
}
|
|
1500
|
+
if (this._defaultCommandName) {
|
|
1501
|
+
this._outputHelpIfRequested(unknown);
|
|
1502
|
+
return this._dispatchSubcommand(this._defaultCommandName, operands, unknown);
|
|
1503
|
+
}
|
|
1504
|
+
if (this.commands.length && this.args.length === 0 && !this._actionHandler && !this._defaultCommandName) {
|
|
1505
|
+
this.help({ error: true });
|
|
1506
|
+
}
|
|
1507
|
+
this._outputHelpIfRequested(parsed.unknown);
|
|
1508
|
+
this._checkForMissingMandatoryOptions();
|
|
1509
|
+
this._checkForConflictingOptions();
|
|
1510
|
+
const checkForUnknownOptions = () => {
|
|
1511
|
+
if (parsed.unknown.length > 0) {
|
|
1512
|
+
this.unknownOption(parsed.unknown[0]);
|
|
1513
|
+
}
|
|
1514
|
+
};
|
|
1515
|
+
const commandEvent = `command:${this.name()}`;
|
|
1516
|
+
if (this._actionHandler) {
|
|
1517
|
+
checkForUnknownOptions();
|
|
1518
|
+
this._processArguments();
|
|
1519
|
+
let promiseChain;
|
|
1520
|
+
promiseChain = this._chainOrCallHooks(promiseChain, "preAction");
|
|
1521
|
+
promiseChain = this._chainOrCall(promiseChain, () => this._actionHandler(this.processedArgs));
|
|
1522
|
+
if (this.parent) {
|
|
1523
|
+
promiseChain = this._chainOrCall(promiseChain, () => {
|
|
1524
|
+
this.parent.emit(commandEvent, operands, unknown);
|
|
1525
|
+
});
|
|
1526
|
+
}
|
|
1527
|
+
promiseChain = this._chainOrCallHooks(promiseChain, "postAction");
|
|
1528
|
+
return promiseChain;
|
|
1529
|
+
}
|
|
1530
|
+
if (this.parent?.listenerCount(commandEvent)) {
|
|
1531
|
+
checkForUnknownOptions();
|
|
1532
|
+
this._processArguments();
|
|
1533
|
+
this.parent.emit(commandEvent, operands, unknown);
|
|
1534
|
+
} else if (operands.length) {
|
|
1535
|
+
if (this._findCommand("*")) {
|
|
1536
|
+
return this._dispatchSubcommand("*", operands, unknown);
|
|
1537
|
+
}
|
|
1538
|
+
if (this.listenerCount("command:*")) {
|
|
1539
|
+
this.emit("command:*", operands, unknown);
|
|
1540
|
+
} else if (this.commands.length) {
|
|
1541
|
+
this.unknownCommand();
|
|
1542
|
+
} else {
|
|
1543
|
+
checkForUnknownOptions();
|
|
1544
|
+
this._processArguments();
|
|
1545
|
+
}
|
|
1546
|
+
} else if (this.commands.length) {
|
|
1547
|
+
checkForUnknownOptions();
|
|
1548
|
+
this.help({ error: true });
|
|
1549
|
+
} else {
|
|
1550
|
+
checkForUnknownOptions();
|
|
1551
|
+
this._processArguments();
|
|
1552
|
+
}
|
|
1553
|
+
}
|
|
1554
|
+
_findCommand(name) {
|
|
1555
|
+
if (!name)
|
|
1556
|
+
return;
|
|
1557
|
+
return this.commands.find((cmd) => cmd._name === name || cmd._aliases.includes(name));
|
|
1558
|
+
}
|
|
1559
|
+
_findOption(arg) {
|
|
1560
|
+
return this.options.find((option) => option.is(arg));
|
|
1561
|
+
}
|
|
1562
|
+
_checkForMissingMandatoryOptions() {
|
|
1563
|
+
this._getCommandAndAncestors().forEach((cmd) => {
|
|
1564
|
+
cmd.options.forEach((anOption) => {
|
|
1565
|
+
if (anOption.mandatory && cmd.getOptionValue(anOption.attributeName()) === undefined) {
|
|
1566
|
+
cmd.missingMandatoryOptionValue(anOption);
|
|
1567
|
+
}
|
|
1568
|
+
});
|
|
1569
|
+
});
|
|
1570
|
+
}
|
|
1571
|
+
_checkForConflictingLocalOptions() {
|
|
1572
|
+
const definedNonDefaultOptions = this.options.filter((option) => {
|
|
1573
|
+
const optionKey = option.attributeName();
|
|
1574
|
+
if (this.getOptionValue(optionKey) === undefined) {
|
|
1575
|
+
return false;
|
|
1576
|
+
}
|
|
1577
|
+
return this.getOptionValueSource(optionKey) !== "default";
|
|
1578
|
+
});
|
|
1579
|
+
const optionsWithConflicting = definedNonDefaultOptions.filter((option) => option.conflictsWith.length > 0);
|
|
1580
|
+
optionsWithConflicting.forEach((option) => {
|
|
1581
|
+
const conflictingAndDefined = definedNonDefaultOptions.find((defined) => option.conflictsWith.includes(defined.attributeName()));
|
|
1582
|
+
if (conflictingAndDefined) {
|
|
1583
|
+
this._conflictingOption(option, conflictingAndDefined);
|
|
1584
|
+
}
|
|
1585
|
+
});
|
|
1586
|
+
}
|
|
1587
|
+
_checkForConflictingOptions() {
|
|
1588
|
+
this._getCommandAndAncestors().forEach((cmd) => {
|
|
1589
|
+
cmd._checkForConflictingLocalOptions();
|
|
1590
|
+
});
|
|
1591
|
+
}
|
|
1592
|
+
parseOptions(args) {
|
|
1593
|
+
const operands = [];
|
|
1594
|
+
const unknown = [];
|
|
1595
|
+
let dest = operands;
|
|
1596
|
+
function maybeOption(arg) {
|
|
1597
|
+
return arg.length > 1 && arg[0] === "-";
|
|
1598
|
+
}
|
|
1599
|
+
const negativeNumberArg = (arg) => {
|
|
1600
|
+
if (!/^-(\d+|\d*\.\d+)(e[+-]?\d+)?$/.test(arg))
|
|
1601
|
+
return false;
|
|
1602
|
+
return !this._getCommandAndAncestors().some((cmd) => cmd.options.map((opt) => opt.short).some((short) => /^-\d$/.test(short)));
|
|
1603
|
+
};
|
|
1604
|
+
let activeVariadicOption = null;
|
|
1605
|
+
let activeGroup = null;
|
|
1606
|
+
let i = 0;
|
|
1607
|
+
while (i < args.length || activeGroup) {
|
|
1608
|
+
const arg = activeGroup ?? args[i++];
|
|
1609
|
+
activeGroup = null;
|
|
1610
|
+
if (arg === "--") {
|
|
1611
|
+
if (dest === unknown)
|
|
1612
|
+
dest.push(arg);
|
|
1613
|
+
dest.push(...args.slice(i));
|
|
1614
|
+
break;
|
|
1615
|
+
}
|
|
1616
|
+
if (activeVariadicOption && (!maybeOption(arg) || negativeNumberArg(arg))) {
|
|
1617
|
+
this.emit(`option:${activeVariadicOption.name()}`, arg);
|
|
1618
|
+
continue;
|
|
1619
|
+
}
|
|
1620
|
+
activeVariadicOption = null;
|
|
1621
|
+
if (maybeOption(arg)) {
|
|
1622
|
+
const option = this._findOption(arg);
|
|
1623
|
+
if (option) {
|
|
1624
|
+
if (option.required) {
|
|
1625
|
+
const value = args[i++];
|
|
1626
|
+
if (value === undefined)
|
|
1627
|
+
this.optionMissingArgument(option);
|
|
1628
|
+
this.emit(`option:${option.name()}`, value);
|
|
1629
|
+
} else if (option.optional) {
|
|
1630
|
+
let value = null;
|
|
1631
|
+
if (i < args.length && (!maybeOption(args[i]) || negativeNumberArg(args[i]))) {
|
|
1632
|
+
value = args[i++];
|
|
1633
|
+
}
|
|
1634
|
+
this.emit(`option:${option.name()}`, value);
|
|
1635
|
+
} else {
|
|
1636
|
+
this.emit(`option:${option.name()}`);
|
|
1637
|
+
}
|
|
1638
|
+
activeVariadicOption = option.variadic ? option : null;
|
|
1639
|
+
continue;
|
|
1640
|
+
}
|
|
1641
|
+
}
|
|
1642
|
+
if (arg.length > 2 && arg[0] === "-" && arg[1] !== "-") {
|
|
1643
|
+
const option = this._findOption(`-${arg[1]}`);
|
|
1644
|
+
if (option) {
|
|
1645
|
+
if (option.required || option.optional && this._combineFlagAndOptionalValue) {
|
|
1646
|
+
this.emit(`option:${option.name()}`, arg.slice(2));
|
|
1647
|
+
} else {
|
|
1648
|
+
this.emit(`option:${option.name()}`);
|
|
1649
|
+
activeGroup = `-${arg.slice(2)}`;
|
|
1650
|
+
}
|
|
1651
|
+
continue;
|
|
1652
|
+
}
|
|
1653
|
+
}
|
|
1654
|
+
if (/^--[^=]+=/.test(arg)) {
|
|
1655
|
+
const index = arg.indexOf("=");
|
|
1656
|
+
const option = this._findOption(arg.slice(0, index));
|
|
1657
|
+
if (option && (option.required || option.optional)) {
|
|
1658
|
+
this.emit(`option:${option.name()}`, arg.slice(index + 1));
|
|
1659
|
+
continue;
|
|
1660
|
+
}
|
|
1661
|
+
}
|
|
1662
|
+
if (dest === operands && maybeOption(arg) && !(this.commands.length === 0 && negativeNumberArg(arg))) {
|
|
1663
|
+
dest = unknown;
|
|
1664
|
+
}
|
|
1665
|
+
if ((this._enablePositionalOptions || this._passThroughOptions) && operands.length === 0 && unknown.length === 0) {
|
|
1666
|
+
if (this._findCommand(arg)) {
|
|
1667
|
+
operands.push(arg);
|
|
1668
|
+
unknown.push(...args.slice(i));
|
|
1669
|
+
break;
|
|
1670
|
+
} else if (this._getHelpCommand() && arg === this._getHelpCommand().name()) {
|
|
1671
|
+
operands.push(arg, ...args.slice(i));
|
|
1672
|
+
break;
|
|
1673
|
+
} else if (this._defaultCommandName) {
|
|
1674
|
+
unknown.push(arg, ...args.slice(i));
|
|
1675
|
+
break;
|
|
1676
|
+
}
|
|
1677
|
+
}
|
|
1678
|
+
if (this._passThroughOptions) {
|
|
1679
|
+
dest.push(arg, ...args.slice(i));
|
|
1680
|
+
break;
|
|
1681
|
+
}
|
|
1682
|
+
dest.push(arg);
|
|
1683
|
+
}
|
|
1684
|
+
return { operands, unknown };
|
|
1685
|
+
}
|
|
1686
|
+
opts() {
|
|
1687
|
+
if (this._storeOptionsAsProperties) {
|
|
1688
|
+
const result = {};
|
|
1689
|
+
const len = this.options.length;
|
|
1690
|
+
for (let i = 0;i < len; i++) {
|
|
1691
|
+
const key = this.options[i].attributeName();
|
|
1692
|
+
result[key] = key === this._versionOptionName ? this._version : this[key];
|
|
1693
|
+
}
|
|
1694
|
+
return result;
|
|
1695
|
+
}
|
|
1696
|
+
return this._optionValues;
|
|
1697
|
+
}
|
|
1698
|
+
optsWithGlobals() {
|
|
1699
|
+
return this._getCommandAndAncestors().reduce((combinedOptions, cmd) => Object.assign(combinedOptions, cmd.opts()), {});
|
|
1700
|
+
}
|
|
1701
|
+
error(message, errorOptions) {
|
|
1702
|
+
this._outputConfiguration.outputError(`${message}
|
|
1703
|
+
`, this._outputConfiguration.writeErr);
|
|
1704
|
+
if (typeof this._showHelpAfterError === "string") {
|
|
1705
|
+
this._outputConfiguration.writeErr(`${this._showHelpAfterError}
|
|
1706
|
+
`);
|
|
1707
|
+
} else if (this._showHelpAfterError) {
|
|
1708
|
+
this._outputConfiguration.writeErr(`
|
|
1709
|
+
`);
|
|
1710
|
+
this.outputHelp({ error: true });
|
|
1711
|
+
}
|
|
1712
|
+
const config = errorOptions || {};
|
|
1713
|
+
const exitCode = config.exitCode || 1;
|
|
1714
|
+
const code = config.code || "commander.error";
|
|
1715
|
+
this._exit(exitCode, code, message);
|
|
1716
|
+
}
|
|
1717
|
+
_parseOptionsEnv() {
|
|
1718
|
+
this.options.forEach((option) => {
|
|
1719
|
+
if (option.envVar && option.envVar in process2.env) {
|
|
1720
|
+
const optionKey = option.attributeName();
|
|
1721
|
+
if (this.getOptionValue(optionKey) === undefined || ["default", "config", "env"].includes(this.getOptionValueSource(optionKey))) {
|
|
1722
|
+
if (option.required || option.optional) {
|
|
1723
|
+
this.emit(`optionEnv:${option.name()}`, process2.env[option.envVar]);
|
|
1724
|
+
} else {
|
|
1725
|
+
this.emit(`optionEnv:${option.name()}`);
|
|
1726
|
+
}
|
|
1727
|
+
}
|
|
1728
|
+
}
|
|
1729
|
+
});
|
|
1730
|
+
}
|
|
1731
|
+
_parseOptionsImplied() {
|
|
1732
|
+
const dualHelper = new DualOptions(this.options);
|
|
1733
|
+
const hasCustomOptionValue = (optionKey) => {
|
|
1734
|
+
return this.getOptionValue(optionKey) !== undefined && !["default", "implied"].includes(this.getOptionValueSource(optionKey));
|
|
1735
|
+
};
|
|
1736
|
+
this.options.filter((option) => option.implied !== undefined && hasCustomOptionValue(option.attributeName()) && dualHelper.valueFromOption(this.getOptionValue(option.attributeName()), option)).forEach((option) => {
|
|
1737
|
+
Object.keys(option.implied).filter((impliedKey) => !hasCustomOptionValue(impliedKey)).forEach((impliedKey) => {
|
|
1738
|
+
this.setOptionValueWithSource(impliedKey, option.implied[impliedKey], "implied");
|
|
1739
|
+
});
|
|
1740
|
+
});
|
|
1741
|
+
}
|
|
1742
|
+
missingArgument(name) {
|
|
1743
|
+
const message = `error: missing required argument '${name}'`;
|
|
1744
|
+
this.error(message, { code: "commander.missingArgument" });
|
|
1745
|
+
}
|
|
1746
|
+
optionMissingArgument(option) {
|
|
1747
|
+
const message = `error: option '${option.flags}' argument missing`;
|
|
1748
|
+
this.error(message, { code: "commander.optionMissingArgument" });
|
|
1749
|
+
}
|
|
1750
|
+
missingMandatoryOptionValue(option) {
|
|
1751
|
+
const message = `error: required option '${option.flags}' not specified`;
|
|
1752
|
+
this.error(message, { code: "commander.missingMandatoryOptionValue" });
|
|
1753
|
+
}
|
|
1754
|
+
_conflictingOption(option, conflictingOption) {
|
|
1755
|
+
const findBestOptionFromValue = (option2) => {
|
|
1756
|
+
const optionKey = option2.attributeName();
|
|
1757
|
+
const optionValue = this.getOptionValue(optionKey);
|
|
1758
|
+
const negativeOption = this.options.find((target) => target.negate && optionKey === target.attributeName());
|
|
1759
|
+
const positiveOption = this.options.find((target) => !target.negate && optionKey === target.attributeName());
|
|
1760
|
+
if (negativeOption && (negativeOption.presetArg === undefined && optionValue === false || negativeOption.presetArg !== undefined && optionValue === negativeOption.presetArg)) {
|
|
1761
|
+
return negativeOption;
|
|
1762
|
+
}
|
|
1763
|
+
return positiveOption || option2;
|
|
1764
|
+
};
|
|
1765
|
+
const getErrorMessage = (option2) => {
|
|
1766
|
+
const bestOption = findBestOptionFromValue(option2);
|
|
1767
|
+
const optionKey = bestOption.attributeName();
|
|
1768
|
+
const source = this.getOptionValueSource(optionKey);
|
|
1769
|
+
if (source === "env") {
|
|
1770
|
+
return `environment variable '${bestOption.envVar}'`;
|
|
1771
|
+
}
|
|
1772
|
+
return `option '${bestOption.flags}'`;
|
|
1773
|
+
};
|
|
1774
|
+
const message = `error: ${getErrorMessage(option)} cannot be used with ${getErrorMessage(conflictingOption)}`;
|
|
1775
|
+
this.error(message, { code: "commander.conflictingOption" });
|
|
1776
|
+
}
|
|
1777
|
+
unknownOption(flag) {
|
|
1778
|
+
if (this._allowUnknownOption)
|
|
1779
|
+
return;
|
|
1780
|
+
let suggestion = "";
|
|
1781
|
+
if (flag.startsWith("--") && this._showSuggestionAfterError) {
|
|
1782
|
+
let candidateFlags = [];
|
|
1783
|
+
let command = this;
|
|
1784
|
+
do {
|
|
1785
|
+
const moreFlags = command.createHelp().visibleOptions(command).filter((option) => option.long).map((option) => option.long);
|
|
1786
|
+
candidateFlags = candidateFlags.concat(moreFlags);
|
|
1787
|
+
command = command.parent;
|
|
1788
|
+
} while (command && !command._enablePositionalOptions);
|
|
1789
|
+
suggestion = suggestSimilar(flag, candidateFlags);
|
|
1790
|
+
}
|
|
1791
|
+
const message = `error: unknown option '${flag}'${suggestion}`;
|
|
1792
|
+
this.error(message, { code: "commander.unknownOption" });
|
|
1793
|
+
}
|
|
1794
|
+
_excessArguments(receivedArgs) {
|
|
1795
|
+
if (this._allowExcessArguments)
|
|
1796
|
+
return;
|
|
1797
|
+
const expected = this.registeredArguments.length;
|
|
1798
|
+
const s = expected === 1 ? "" : "s";
|
|
1799
|
+
const forSubcommand = this.parent ? ` for '${this.name()}'` : "";
|
|
1800
|
+
const message = `error: too many arguments${forSubcommand}. Expected ${expected} argument${s} but got ${receivedArgs.length}.`;
|
|
1801
|
+
this.error(message, { code: "commander.excessArguments" });
|
|
1802
|
+
}
|
|
1803
|
+
unknownCommand() {
|
|
1804
|
+
const unknownName = this.args[0];
|
|
1805
|
+
let suggestion = "";
|
|
1806
|
+
if (this._showSuggestionAfterError) {
|
|
1807
|
+
const candidateNames = [];
|
|
1808
|
+
this.createHelp().visibleCommands(this).forEach((command) => {
|
|
1809
|
+
candidateNames.push(command.name());
|
|
1810
|
+
if (command.alias())
|
|
1811
|
+
candidateNames.push(command.alias());
|
|
1812
|
+
});
|
|
1813
|
+
suggestion = suggestSimilar(unknownName, candidateNames);
|
|
1814
|
+
}
|
|
1815
|
+
const message = `error: unknown command '${unknownName}'${suggestion}`;
|
|
1816
|
+
this.error(message, { code: "commander.unknownCommand" });
|
|
1817
|
+
}
|
|
1818
|
+
version(str, flags, description) {
|
|
1819
|
+
if (str === undefined)
|
|
1820
|
+
return this._version;
|
|
1821
|
+
this._version = str;
|
|
1822
|
+
flags = flags || "-V, --version";
|
|
1823
|
+
description = description || "output the version number";
|
|
1824
|
+
const versionOption = this.createOption(flags, description);
|
|
1825
|
+
this._versionOptionName = versionOption.attributeName();
|
|
1826
|
+
this._registerOption(versionOption);
|
|
1827
|
+
this.on("option:" + versionOption.name(), () => {
|
|
1828
|
+
this._outputConfiguration.writeOut(`${str}
|
|
1829
|
+
`);
|
|
1830
|
+
this._exit(0, "commander.version", str);
|
|
1831
|
+
});
|
|
1832
|
+
return this;
|
|
1833
|
+
}
|
|
1834
|
+
description(str, argsDescription) {
|
|
1835
|
+
if (str === undefined && argsDescription === undefined)
|
|
1836
|
+
return this._description;
|
|
1837
|
+
this._description = str;
|
|
1838
|
+
if (argsDescription) {
|
|
1839
|
+
this._argsDescription = argsDescription;
|
|
1840
|
+
}
|
|
1841
|
+
return this;
|
|
1842
|
+
}
|
|
1843
|
+
summary(str) {
|
|
1844
|
+
if (str === undefined)
|
|
1845
|
+
return this._summary;
|
|
1846
|
+
this._summary = str;
|
|
1847
|
+
return this;
|
|
1848
|
+
}
|
|
1849
|
+
alias(alias) {
|
|
1850
|
+
if (alias === undefined)
|
|
1851
|
+
return this._aliases[0];
|
|
1852
|
+
let command = this;
|
|
1853
|
+
if (this.commands.length !== 0 && this.commands[this.commands.length - 1]._executableHandler) {
|
|
1854
|
+
command = this.commands[this.commands.length - 1];
|
|
1855
|
+
}
|
|
1856
|
+
if (alias === command._name)
|
|
1857
|
+
throw new Error("Command alias can't be the same as its name");
|
|
1858
|
+
const matchingCommand = this.parent?._findCommand(alias);
|
|
1859
|
+
if (matchingCommand) {
|
|
1860
|
+
const existingCmd = [matchingCommand.name()].concat(matchingCommand.aliases()).join("|");
|
|
1861
|
+
throw new Error(`cannot add alias '${alias}' to command '${this.name()}' as already have command '${existingCmd}'`);
|
|
1862
|
+
}
|
|
1863
|
+
command._aliases.push(alias);
|
|
1864
|
+
return this;
|
|
1865
|
+
}
|
|
1866
|
+
aliases(aliases) {
|
|
1867
|
+
if (aliases === undefined)
|
|
1868
|
+
return this._aliases;
|
|
1869
|
+
aliases.forEach((alias) => this.alias(alias));
|
|
1870
|
+
return this;
|
|
1871
|
+
}
|
|
1872
|
+
usage(str) {
|
|
1873
|
+
if (str === undefined) {
|
|
1874
|
+
if (this._usage)
|
|
1875
|
+
return this._usage;
|
|
1876
|
+
const args = this.registeredArguments.map((arg) => {
|
|
1877
|
+
return humanReadableArgName(arg);
|
|
1878
|
+
});
|
|
1879
|
+
return [].concat(this.options.length || this._helpOption !== null ? "[options]" : [], this.commands.length ? "[command]" : [], this.registeredArguments.length ? args : []).join(" ");
|
|
1880
|
+
}
|
|
1881
|
+
this._usage = str;
|
|
1882
|
+
return this;
|
|
1883
|
+
}
|
|
1884
|
+
name(str) {
|
|
1885
|
+
if (str === undefined)
|
|
1886
|
+
return this._name;
|
|
1887
|
+
this._name = str;
|
|
1888
|
+
return this;
|
|
1889
|
+
}
|
|
1890
|
+
helpGroup(heading) {
|
|
1891
|
+
if (heading === undefined)
|
|
1892
|
+
return this._helpGroupHeading ?? "";
|
|
1893
|
+
this._helpGroupHeading = heading;
|
|
1894
|
+
return this;
|
|
1895
|
+
}
|
|
1896
|
+
commandsGroup(heading) {
|
|
1897
|
+
if (heading === undefined)
|
|
1898
|
+
return this._defaultCommandGroup ?? "";
|
|
1899
|
+
this._defaultCommandGroup = heading;
|
|
1900
|
+
return this;
|
|
1901
|
+
}
|
|
1902
|
+
optionsGroup(heading) {
|
|
1903
|
+
if (heading === undefined)
|
|
1904
|
+
return this._defaultOptionGroup ?? "";
|
|
1905
|
+
this._defaultOptionGroup = heading;
|
|
1906
|
+
return this;
|
|
1907
|
+
}
|
|
1908
|
+
_initOptionGroup(option) {
|
|
1909
|
+
if (this._defaultOptionGroup && !option.helpGroupHeading)
|
|
1910
|
+
option.helpGroup(this._defaultOptionGroup);
|
|
1911
|
+
}
|
|
1912
|
+
_initCommandGroup(cmd) {
|
|
1913
|
+
if (this._defaultCommandGroup && !cmd.helpGroup())
|
|
1914
|
+
cmd.helpGroup(this._defaultCommandGroup);
|
|
1915
|
+
}
|
|
1916
|
+
nameFromFilename(filename) {
|
|
1917
|
+
this._name = path.basename(filename, path.extname(filename));
|
|
1918
|
+
return this;
|
|
1919
|
+
}
|
|
1920
|
+
executableDir(path2) {
|
|
1921
|
+
if (path2 === undefined)
|
|
1922
|
+
return this._executableDir;
|
|
1923
|
+
this._executableDir = path2;
|
|
1924
|
+
return this;
|
|
1925
|
+
}
|
|
1926
|
+
helpInformation(contextOptions) {
|
|
1927
|
+
const helper = this.createHelp();
|
|
1928
|
+
const context = this._getOutputContext(contextOptions);
|
|
1929
|
+
helper.prepareContext({
|
|
1930
|
+
error: context.error,
|
|
1931
|
+
helpWidth: context.helpWidth,
|
|
1932
|
+
outputHasColors: context.hasColors
|
|
1933
|
+
});
|
|
1934
|
+
const text = helper.formatHelp(this, helper);
|
|
1935
|
+
if (context.hasColors)
|
|
1936
|
+
return text;
|
|
1937
|
+
return this._outputConfiguration.stripColor(text);
|
|
1938
|
+
}
|
|
1939
|
+
_getOutputContext(contextOptions) {
|
|
1940
|
+
contextOptions = contextOptions || {};
|
|
1941
|
+
const error = !!contextOptions.error;
|
|
1942
|
+
let baseWrite;
|
|
1943
|
+
let hasColors;
|
|
1944
|
+
let helpWidth;
|
|
1945
|
+
if (error) {
|
|
1946
|
+
baseWrite = (str) => this._outputConfiguration.writeErr(str);
|
|
1947
|
+
hasColors = this._outputConfiguration.getErrHasColors();
|
|
1948
|
+
helpWidth = this._outputConfiguration.getErrHelpWidth();
|
|
1949
|
+
} else {
|
|
1950
|
+
baseWrite = (str) => this._outputConfiguration.writeOut(str);
|
|
1951
|
+
hasColors = this._outputConfiguration.getOutHasColors();
|
|
1952
|
+
helpWidth = this._outputConfiguration.getOutHelpWidth();
|
|
1953
|
+
}
|
|
1954
|
+
const write = (str) => {
|
|
1955
|
+
if (!hasColors)
|
|
1956
|
+
str = this._outputConfiguration.stripColor(str);
|
|
1957
|
+
return baseWrite(str);
|
|
1958
|
+
};
|
|
1959
|
+
return { error, write, hasColors, helpWidth };
|
|
1960
|
+
}
|
|
1961
|
+
outputHelp(contextOptions) {
|
|
1962
|
+
let deprecatedCallback;
|
|
1963
|
+
if (typeof contextOptions === "function") {
|
|
1964
|
+
deprecatedCallback = contextOptions;
|
|
1965
|
+
contextOptions = undefined;
|
|
1966
|
+
}
|
|
1967
|
+
const outputContext = this._getOutputContext(contextOptions);
|
|
1968
|
+
const eventContext = {
|
|
1969
|
+
error: outputContext.error,
|
|
1970
|
+
write: outputContext.write,
|
|
1971
|
+
command: this
|
|
1972
|
+
};
|
|
1973
|
+
this._getCommandAndAncestors().reverse().forEach((command) => command.emit("beforeAllHelp", eventContext));
|
|
1974
|
+
this.emit("beforeHelp", eventContext);
|
|
1975
|
+
let helpInformation = this.helpInformation({ error: outputContext.error });
|
|
1976
|
+
if (deprecatedCallback) {
|
|
1977
|
+
helpInformation = deprecatedCallback(helpInformation);
|
|
1978
|
+
if (typeof helpInformation !== "string" && !Buffer.isBuffer(helpInformation)) {
|
|
1979
|
+
throw new Error("outputHelp callback must return a string or a Buffer");
|
|
1980
|
+
}
|
|
1981
|
+
}
|
|
1982
|
+
outputContext.write(helpInformation);
|
|
1983
|
+
if (this._getHelpOption()?.long) {
|
|
1984
|
+
this.emit(this._getHelpOption().long);
|
|
1985
|
+
}
|
|
1986
|
+
this.emit("afterHelp", eventContext);
|
|
1987
|
+
this._getCommandAndAncestors().forEach((command) => command.emit("afterAllHelp", eventContext));
|
|
1988
|
+
}
|
|
1989
|
+
helpOption(flags, description) {
|
|
1990
|
+
if (typeof flags === "boolean") {
|
|
1991
|
+
if (flags) {
|
|
1992
|
+
if (this._helpOption === null)
|
|
1993
|
+
this._helpOption = undefined;
|
|
1994
|
+
if (this._defaultOptionGroup) {
|
|
1995
|
+
this._initOptionGroup(this._getHelpOption());
|
|
1996
|
+
}
|
|
1997
|
+
} else {
|
|
1998
|
+
this._helpOption = null;
|
|
1999
|
+
}
|
|
2000
|
+
return this;
|
|
2001
|
+
}
|
|
2002
|
+
this._helpOption = this.createOption(flags ?? "-h, --help", description ?? "display help for command");
|
|
2003
|
+
if (flags || description)
|
|
2004
|
+
this._initOptionGroup(this._helpOption);
|
|
2005
|
+
return this;
|
|
2006
|
+
}
|
|
2007
|
+
_getHelpOption() {
|
|
2008
|
+
if (this._helpOption === undefined) {
|
|
2009
|
+
this.helpOption(undefined, undefined);
|
|
2010
|
+
}
|
|
2011
|
+
return this._helpOption;
|
|
2012
|
+
}
|
|
2013
|
+
addHelpOption(option) {
|
|
2014
|
+
this._helpOption = option;
|
|
2015
|
+
this._initOptionGroup(option);
|
|
2016
|
+
return this;
|
|
2017
|
+
}
|
|
2018
|
+
help(contextOptions) {
|
|
2019
|
+
this.outputHelp(contextOptions);
|
|
2020
|
+
let exitCode = Number(process2.exitCode ?? 0);
|
|
2021
|
+
if (exitCode === 0 && contextOptions && typeof contextOptions !== "function" && contextOptions.error) {
|
|
2022
|
+
exitCode = 1;
|
|
2023
|
+
}
|
|
2024
|
+
this._exit(exitCode, "commander.help", "(outputHelp)");
|
|
2025
|
+
}
|
|
2026
|
+
addHelpText(position, text) {
|
|
2027
|
+
const allowedValues = ["beforeAll", "before", "after", "afterAll"];
|
|
2028
|
+
if (!allowedValues.includes(position)) {
|
|
2029
|
+
throw new Error(`Unexpected value for position to addHelpText.
|
|
2030
|
+
Expecting one of '${allowedValues.join("', '")}'`);
|
|
2031
|
+
}
|
|
2032
|
+
const helpEvent = `${position}Help`;
|
|
2033
|
+
this.on(helpEvent, (context) => {
|
|
2034
|
+
let helpStr;
|
|
2035
|
+
if (typeof text === "function") {
|
|
2036
|
+
helpStr = text({ error: context.error, command: context.command });
|
|
2037
|
+
} else {
|
|
2038
|
+
helpStr = text;
|
|
2039
|
+
}
|
|
2040
|
+
if (helpStr) {
|
|
2041
|
+
context.write(`${helpStr}
|
|
2042
|
+
`);
|
|
2043
|
+
}
|
|
2044
|
+
});
|
|
2045
|
+
return this;
|
|
2046
|
+
}
|
|
2047
|
+
_outputHelpIfRequested(args) {
|
|
2048
|
+
const helpOption = this._getHelpOption();
|
|
2049
|
+
const helpRequested = helpOption && args.find((arg) => helpOption.is(arg));
|
|
2050
|
+
if (helpRequested) {
|
|
2051
|
+
this.outputHelp();
|
|
2052
|
+
this._exit(0, "commander.helpDisplayed", "(outputHelp)");
|
|
2053
|
+
}
|
|
2054
|
+
}
|
|
2055
|
+
}
|
|
2056
|
+
function incrementNodeInspectorPort(args) {
|
|
2057
|
+
return args.map((arg) => {
|
|
2058
|
+
if (!arg.startsWith("--inspect")) {
|
|
2059
|
+
return arg;
|
|
2060
|
+
}
|
|
2061
|
+
let debugOption;
|
|
2062
|
+
let debugHost = "127.0.0.1";
|
|
2063
|
+
let debugPort = "9229";
|
|
2064
|
+
let match;
|
|
2065
|
+
if ((match = arg.match(/^(--inspect(-brk)?)$/)) !== null) {
|
|
2066
|
+
debugOption = match[1];
|
|
2067
|
+
} else if ((match = arg.match(/^(--inspect(-brk|-port)?)=([^:]+)$/)) !== null) {
|
|
2068
|
+
debugOption = match[1];
|
|
2069
|
+
if (/^\d+$/.test(match[3])) {
|
|
2070
|
+
debugPort = match[3];
|
|
2071
|
+
} else {
|
|
2072
|
+
debugHost = match[3];
|
|
2073
|
+
}
|
|
2074
|
+
} else if ((match = arg.match(/^(--inspect(-brk|-port)?)=([^:]+):(\d+)$/)) !== null) {
|
|
2075
|
+
debugOption = match[1];
|
|
2076
|
+
debugHost = match[3];
|
|
2077
|
+
debugPort = match[4];
|
|
2078
|
+
}
|
|
2079
|
+
if (debugOption && debugPort !== "0") {
|
|
2080
|
+
return `${debugOption}=${debugHost}:${parseInt(debugPort) + 1}`;
|
|
2081
|
+
}
|
|
2082
|
+
return arg;
|
|
2083
|
+
});
|
|
2084
|
+
}
|
|
2085
|
+
function useColor() {
|
|
2086
|
+
if (process2.env.NO_COLOR || process2.env.FORCE_COLOR === "0" || process2.env.FORCE_COLOR === "false")
|
|
2087
|
+
return false;
|
|
2088
|
+
if (process2.env.FORCE_COLOR || process2.env.CLICOLOR_FORCE !== undefined)
|
|
2089
|
+
return true;
|
|
2090
|
+
return;
|
|
2091
|
+
}
|
|
2092
|
+
exports.Command = Command;
|
|
2093
|
+
exports.useColor = useColor;
|
|
2094
|
+
});
|
|
2095
|
+
|
|
2096
|
+
// ../../node_modules/.bun/commander@14.0.2/node_modules/commander/index.js
|
|
2097
|
+
var require_commander = __commonJS((exports) => {
|
|
2098
|
+
var { Argument } = require_argument();
|
|
2099
|
+
var { Command } = require_command();
|
|
2100
|
+
var { CommanderError, InvalidArgumentError } = require_error();
|
|
2101
|
+
var { Help } = require_help();
|
|
2102
|
+
var { Option } = require_option();
|
|
2103
|
+
exports.program = new Command;
|
|
2104
|
+
exports.createCommand = (name) => new Command(name);
|
|
2105
|
+
exports.createOption = (flags, description) => new Option(flags, description);
|
|
2106
|
+
exports.createArgument = (name, description) => new Argument(name, description);
|
|
2107
|
+
exports.Command = Command;
|
|
2108
|
+
exports.Option = Option;
|
|
2109
|
+
exports.Argument = Argument;
|
|
2110
|
+
exports.Help = Help;
|
|
2111
|
+
exports.CommanderError = CommanderError;
|
|
2112
|
+
exports.InvalidArgumentError = InvalidArgumentError;
|
|
2113
|
+
exports.InvalidOptionArgumentError = InvalidArgumentError;
|
|
2114
|
+
});
|
|
2115
|
+
|
|
2116
|
+
// ../../node_modules/.bun/commander@14.0.2/node_modules/commander/esm.mjs
|
|
2117
|
+
var import__ = __toESM(require_commander(), 1);
|
|
2118
|
+
var {
|
|
2119
|
+
program,
|
|
2120
|
+
createCommand,
|
|
2121
|
+
createArgument,
|
|
2122
|
+
createOption,
|
|
2123
|
+
CommanderError,
|
|
2124
|
+
InvalidArgumentError,
|
|
2125
|
+
InvalidOptionArgumentError,
|
|
2126
|
+
Command,
|
|
2127
|
+
Argument,
|
|
2128
|
+
Option,
|
|
2129
|
+
Help
|
|
2130
|
+
} = import__.default;
|
|
2131
|
+
|
|
2132
|
+
// ../../node_modules/.bun/commander@14.0.2/node_modules/commander/esm.mjs
|
|
2133
|
+
var import__2 = __toESM(require_commander(), 1);
|
|
2134
|
+
var {
|
|
2135
|
+
program: program2,
|
|
2136
|
+
createCommand: createCommand2,
|
|
2137
|
+
createArgument: createArgument2,
|
|
2138
|
+
createOption: createOption2,
|
|
2139
|
+
CommanderError: CommanderError2,
|
|
2140
|
+
InvalidArgumentError: InvalidArgumentError2,
|
|
2141
|
+
InvalidOptionArgumentError: InvalidOptionArgumentError2,
|
|
2142
|
+
Command: Command2,
|
|
2143
|
+
Argument: Argument2,
|
|
2144
|
+
Option: Option2,
|
|
2145
|
+
Help: Help2
|
|
2146
|
+
} = import__2.default;
|
|
2147
|
+
|
|
2148
|
+
// ../../node_modules/.bun/open@11.0.0/node_modules/open/index.js
|
|
2149
|
+
import process8 from "node:process";
|
|
2150
|
+
import path from "node:path";
|
|
2151
|
+
import { fileURLToPath } from "node:url";
|
|
2152
|
+
import childProcess3 from "node:child_process";
|
|
2153
|
+
import fs5, { constants as fsConstants2 } from "node:fs/promises";
|
|
2154
|
+
|
|
2155
|
+
// ../../node_modules/.bun/wsl-utils@0.3.0/node_modules/wsl-utils/index.js
|
|
2156
|
+
import { promisify as promisify2 } from "node:util";
|
|
2157
|
+
import childProcess2 from "node:child_process";
|
|
2158
|
+
import fs4, { constants as fsConstants } from "node:fs/promises";
|
|
2159
|
+
|
|
2160
|
+
// ../../node_modules/.bun/is-wsl@3.1.0/node_modules/is-wsl/index.js
|
|
2161
|
+
import process2 from "node:process";
|
|
2162
|
+
import os from "node:os";
|
|
2163
|
+
import fs3 from "node:fs";
|
|
2164
|
+
|
|
2165
|
+
// ../../node_modules/.bun/is-inside-container@1.0.0/node_modules/is-inside-container/index.js
|
|
2166
|
+
import fs2 from "node:fs";
|
|
2167
|
+
|
|
2168
|
+
// ../../node_modules/.bun/is-docker@3.0.0/node_modules/is-docker/index.js
|
|
2169
|
+
import fs from "node:fs";
|
|
2170
|
+
var isDockerCached;
|
|
2171
|
+
function hasDockerEnv() {
|
|
2172
|
+
try {
|
|
2173
|
+
fs.statSync("/.dockerenv");
|
|
2174
|
+
return true;
|
|
2175
|
+
} catch {
|
|
2176
|
+
return false;
|
|
2177
|
+
}
|
|
2178
|
+
}
|
|
2179
|
+
function hasDockerCGroup() {
|
|
2180
|
+
try {
|
|
2181
|
+
return fs.readFileSync("/proc/self/cgroup", "utf8").includes("docker");
|
|
2182
|
+
} catch {
|
|
2183
|
+
return false;
|
|
2184
|
+
}
|
|
2185
|
+
}
|
|
2186
|
+
function isDocker() {
|
|
2187
|
+
if (isDockerCached === undefined) {
|
|
2188
|
+
isDockerCached = hasDockerEnv() || hasDockerCGroup();
|
|
2189
|
+
}
|
|
2190
|
+
return isDockerCached;
|
|
2191
|
+
}
|
|
2192
|
+
|
|
2193
|
+
// ../../node_modules/.bun/is-inside-container@1.0.0/node_modules/is-inside-container/index.js
|
|
2194
|
+
var cachedResult;
|
|
2195
|
+
var hasContainerEnv = () => {
|
|
2196
|
+
try {
|
|
2197
|
+
fs2.statSync("/run/.containerenv");
|
|
2198
|
+
return true;
|
|
2199
|
+
} catch {
|
|
2200
|
+
return false;
|
|
2201
|
+
}
|
|
2202
|
+
};
|
|
2203
|
+
function isInsideContainer() {
|
|
2204
|
+
if (cachedResult === undefined) {
|
|
2205
|
+
cachedResult = hasContainerEnv() || isDocker();
|
|
2206
|
+
}
|
|
2207
|
+
return cachedResult;
|
|
2208
|
+
}
|
|
2209
|
+
|
|
2210
|
+
// ../../node_modules/.bun/is-wsl@3.1.0/node_modules/is-wsl/index.js
|
|
2211
|
+
var isWsl = () => {
|
|
2212
|
+
if (process2.platform !== "linux") {
|
|
2213
|
+
return false;
|
|
2214
|
+
}
|
|
2215
|
+
if (os.release().toLowerCase().includes("microsoft")) {
|
|
2216
|
+
if (isInsideContainer()) {
|
|
2217
|
+
return false;
|
|
2218
|
+
}
|
|
2219
|
+
return true;
|
|
2220
|
+
}
|
|
2221
|
+
try {
|
|
2222
|
+
return fs3.readFileSync("/proc/version", "utf8").toLowerCase().includes("microsoft") ? !isInsideContainer() : false;
|
|
2223
|
+
} catch {
|
|
2224
|
+
return false;
|
|
2225
|
+
}
|
|
2226
|
+
};
|
|
2227
|
+
var is_wsl_default = process2.env.__IS_WSL_TEST__ ? isWsl : isWsl();
|
|
2228
|
+
|
|
2229
|
+
// ../../node_modules/.bun/powershell-utils@0.1.0/node_modules/powershell-utils/index.js
|
|
2230
|
+
import process3 from "node:process";
|
|
2231
|
+
import { Buffer as Buffer2 } from "node:buffer";
|
|
2232
|
+
import { promisify } from "node:util";
|
|
2233
|
+
import childProcess from "node:child_process";
|
|
2234
|
+
var execFile = promisify(childProcess.execFile);
|
|
2235
|
+
var powerShellPath = () => `${process3.env.SYSTEMROOT || process3.env.windir || String.raw`C:\Windows`}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe`;
|
|
2236
|
+
var executePowerShell = async (command, options = {}) => {
|
|
2237
|
+
const {
|
|
2238
|
+
powerShellPath: psPath,
|
|
2239
|
+
...execFileOptions
|
|
2240
|
+
} = options;
|
|
2241
|
+
const encodedCommand = executePowerShell.encodeCommand(command);
|
|
2242
|
+
return execFile(psPath ?? powerShellPath(), [
|
|
2243
|
+
...executePowerShell.argumentsPrefix,
|
|
2244
|
+
encodedCommand
|
|
2245
|
+
], {
|
|
2246
|
+
encoding: "utf8",
|
|
2247
|
+
...execFileOptions
|
|
2248
|
+
});
|
|
2249
|
+
};
|
|
2250
|
+
executePowerShell.argumentsPrefix = [
|
|
2251
|
+
"-NoProfile",
|
|
2252
|
+
"-NonInteractive",
|
|
2253
|
+
"-ExecutionPolicy",
|
|
2254
|
+
"Bypass",
|
|
2255
|
+
"-EncodedCommand"
|
|
2256
|
+
];
|
|
2257
|
+
executePowerShell.encodeCommand = (command) => Buffer2.from(command, "utf16le").toString("base64");
|
|
2258
|
+
executePowerShell.escapeArgument = (value) => `'${String(value).replaceAll("'", "''")}'`;
|
|
2259
|
+
|
|
2260
|
+
// ../../node_modules/.bun/wsl-utils@0.3.0/node_modules/wsl-utils/index.js
|
|
2261
|
+
var execFile2 = promisify2(childProcess2.execFile);
|
|
2262
|
+
var wslDrivesMountPoint = (() => {
|
|
2263
|
+
const defaultMountPoint = "/mnt/";
|
|
2264
|
+
let mountPoint;
|
|
2265
|
+
return async function() {
|
|
2266
|
+
if (mountPoint) {
|
|
2267
|
+
return mountPoint;
|
|
2268
|
+
}
|
|
2269
|
+
const configFilePath = "/etc/wsl.conf";
|
|
2270
|
+
let isConfigFileExists = false;
|
|
2271
|
+
try {
|
|
2272
|
+
await fs4.access(configFilePath, fsConstants.F_OK);
|
|
2273
|
+
isConfigFileExists = true;
|
|
2274
|
+
} catch {}
|
|
2275
|
+
if (!isConfigFileExists) {
|
|
2276
|
+
return defaultMountPoint;
|
|
2277
|
+
}
|
|
2278
|
+
const configContent = await fs4.readFile(configFilePath, { encoding: "utf8" });
|
|
2279
|
+
const configMountPoint = /(?<!#.*)root\s*=\s*(?<mountPoint>.*)/g.exec(configContent);
|
|
2280
|
+
if (!configMountPoint) {
|
|
2281
|
+
return defaultMountPoint;
|
|
2282
|
+
}
|
|
2283
|
+
mountPoint = configMountPoint.groups.mountPoint.trim();
|
|
2284
|
+
mountPoint = mountPoint.endsWith("/") ? mountPoint : `${mountPoint}/`;
|
|
2285
|
+
return mountPoint;
|
|
2286
|
+
};
|
|
2287
|
+
})();
|
|
2288
|
+
var powerShellPathFromWsl = async () => {
|
|
2289
|
+
const mountPoint = await wslDrivesMountPoint();
|
|
2290
|
+
return `${mountPoint}c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe`;
|
|
2291
|
+
};
|
|
2292
|
+
var powerShellPath2 = is_wsl_default ? powerShellPathFromWsl : powerShellPath;
|
|
2293
|
+
var canAccessPowerShellPromise;
|
|
2294
|
+
var canAccessPowerShell = async () => {
|
|
2295
|
+
canAccessPowerShellPromise ??= (async () => {
|
|
2296
|
+
try {
|
|
2297
|
+
const psPath = await powerShellPath2();
|
|
2298
|
+
await fs4.access(psPath, fsConstants.X_OK);
|
|
2299
|
+
return true;
|
|
2300
|
+
} catch {
|
|
2301
|
+
return false;
|
|
2302
|
+
}
|
|
2303
|
+
})();
|
|
2304
|
+
return canAccessPowerShellPromise;
|
|
2305
|
+
};
|
|
2306
|
+
var wslDefaultBrowser = async () => {
|
|
2307
|
+
const psPath = await powerShellPath2();
|
|
2308
|
+
const command = String.raw`(Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice").ProgId`;
|
|
2309
|
+
const { stdout } = await executePowerShell(command, { powerShellPath: psPath });
|
|
2310
|
+
return stdout.trim();
|
|
2311
|
+
};
|
|
2312
|
+
var convertWslPathToWindows = async (path) => {
|
|
2313
|
+
if (/^[a-z]+:\/\//i.test(path)) {
|
|
2314
|
+
return path;
|
|
2315
|
+
}
|
|
2316
|
+
try {
|
|
2317
|
+
const { stdout } = await execFile2("wslpath", ["-aw", path], { encoding: "utf8" });
|
|
2318
|
+
return stdout.trim();
|
|
2319
|
+
} catch {
|
|
2320
|
+
return path;
|
|
2321
|
+
}
|
|
2322
|
+
};
|
|
2323
|
+
|
|
2324
|
+
// ../../node_modules/.bun/define-lazy-prop@3.0.0/node_modules/define-lazy-prop/index.js
|
|
2325
|
+
function defineLazyProperty(object, propertyName, valueGetter) {
|
|
2326
|
+
const define = (value) => Object.defineProperty(object, propertyName, { value, enumerable: true, writable: true });
|
|
2327
|
+
Object.defineProperty(object, propertyName, {
|
|
2328
|
+
configurable: true,
|
|
2329
|
+
enumerable: true,
|
|
2330
|
+
get() {
|
|
2331
|
+
const result = valueGetter();
|
|
2332
|
+
define(result);
|
|
2333
|
+
return result;
|
|
2334
|
+
},
|
|
2335
|
+
set(value) {
|
|
2336
|
+
define(value);
|
|
2337
|
+
}
|
|
2338
|
+
});
|
|
2339
|
+
return object;
|
|
2340
|
+
}
|
|
2341
|
+
|
|
2342
|
+
// ../../node_modules/.bun/default-browser@5.4.0/node_modules/default-browser/index.js
|
|
2343
|
+
import { promisify as promisify6 } from "node:util";
|
|
2344
|
+
import process6 from "node:process";
|
|
2345
|
+
import { execFile as execFile6 } from "node:child_process";
|
|
2346
|
+
|
|
2347
|
+
// ../../node_modules/.bun/default-browser-id@5.0.1/node_modules/default-browser-id/index.js
|
|
2348
|
+
import { promisify as promisify3 } from "node:util";
|
|
2349
|
+
import process4 from "node:process";
|
|
2350
|
+
import { execFile as execFile3 } from "node:child_process";
|
|
2351
|
+
var execFileAsync = promisify3(execFile3);
|
|
2352
|
+
async function defaultBrowserId() {
|
|
2353
|
+
if (process4.platform !== "darwin") {
|
|
2354
|
+
throw new Error("macOS only");
|
|
2355
|
+
}
|
|
2356
|
+
const { stdout } = await execFileAsync("defaults", ["read", "com.apple.LaunchServices/com.apple.launchservices.secure", "LSHandlers"]);
|
|
2357
|
+
const match = /LSHandlerRoleAll = "(?!-)(?<id>[^"]+?)";\s+?LSHandlerURLScheme = (?:http|https);/.exec(stdout);
|
|
2358
|
+
const browserId = match?.groups.id ?? "com.apple.Safari";
|
|
2359
|
+
if (browserId === "com.apple.safari") {
|
|
2360
|
+
return "com.apple.Safari";
|
|
2361
|
+
}
|
|
2362
|
+
return browserId;
|
|
2363
|
+
}
|
|
2364
|
+
|
|
2365
|
+
// ../../node_modules/.bun/run-applescript@7.1.0/node_modules/run-applescript/index.js
|
|
2366
|
+
import process5 from "node:process";
|
|
2367
|
+
import { promisify as promisify4 } from "node:util";
|
|
2368
|
+
import { execFile as execFile4, execFileSync } from "node:child_process";
|
|
2369
|
+
var execFileAsync2 = promisify4(execFile4);
|
|
2370
|
+
async function runAppleScript(script, { humanReadableOutput = true, signal } = {}) {
|
|
2371
|
+
if (process5.platform !== "darwin") {
|
|
2372
|
+
throw new Error("macOS only");
|
|
2373
|
+
}
|
|
2374
|
+
const outputArguments = humanReadableOutput ? [] : ["-ss"];
|
|
2375
|
+
const execOptions = {};
|
|
2376
|
+
if (signal) {
|
|
2377
|
+
execOptions.signal = signal;
|
|
2378
|
+
}
|
|
2379
|
+
const { stdout } = await execFileAsync2("osascript", ["-e", script, outputArguments], execOptions);
|
|
2380
|
+
return stdout.trim();
|
|
2381
|
+
}
|
|
2382
|
+
|
|
2383
|
+
// ../../node_modules/.bun/bundle-name@4.1.0/node_modules/bundle-name/index.js
|
|
2384
|
+
async function bundleName(bundleId) {
|
|
2385
|
+
return runAppleScript(`tell application "Finder" to set app_path to application file id "${bundleId}" as string
|
|
2386
|
+
tell application "System Events" to get value of property list item "CFBundleName" of property list file (app_path & ":Contents:Info.plist")`);
|
|
2387
|
+
}
|
|
2388
|
+
|
|
2389
|
+
// ../../node_modules/.bun/default-browser@5.4.0/node_modules/default-browser/windows.js
|
|
2390
|
+
import { promisify as promisify5 } from "node:util";
|
|
2391
|
+
import { execFile as execFile5 } from "node:child_process";
|
|
2392
|
+
var execFileAsync3 = promisify5(execFile5);
|
|
2393
|
+
var windowsBrowserProgIds = {
|
|
2394
|
+
MSEdgeHTM: { name: "Edge", id: "com.microsoft.edge" },
|
|
2395
|
+
MSEdgeBHTML: { name: "Edge Beta", id: "com.microsoft.edge.beta" },
|
|
2396
|
+
MSEdgeDHTML: { name: "Edge Dev", id: "com.microsoft.edge.dev" },
|
|
2397
|
+
AppXq0fevzme2pys62n3e0fbqa7peapykr8v: { name: "Edge", id: "com.microsoft.edge.old" },
|
|
2398
|
+
ChromeHTML: { name: "Chrome", id: "com.google.chrome" },
|
|
2399
|
+
ChromeBHTML: { name: "Chrome Beta", id: "com.google.chrome.beta" },
|
|
2400
|
+
ChromeDHTML: { name: "Chrome Dev", id: "com.google.chrome.dev" },
|
|
2401
|
+
ChromiumHTM: { name: "Chromium", id: "org.chromium.Chromium" },
|
|
2402
|
+
BraveHTML: { name: "Brave", id: "com.brave.Browser" },
|
|
2403
|
+
BraveBHTML: { name: "Brave Beta", id: "com.brave.Browser.beta" },
|
|
2404
|
+
BraveDHTML: { name: "Brave Dev", id: "com.brave.Browser.dev" },
|
|
2405
|
+
BraveSSHTM: { name: "Brave Nightly", id: "com.brave.Browser.nightly" },
|
|
2406
|
+
FirefoxURL: { name: "Firefox", id: "org.mozilla.firefox" },
|
|
2407
|
+
OperaStable: { name: "Opera", id: "com.operasoftware.Opera" },
|
|
2408
|
+
VivaldiHTM: { name: "Vivaldi", id: "com.vivaldi.Vivaldi" },
|
|
2409
|
+
"IE.HTTP": { name: "Internet Explorer", id: "com.microsoft.ie" }
|
|
2410
|
+
};
|
|
2411
|
+
var _windowsBrowserProgIdMap = new Map(Object.entries(windowsBrowserProgIds));
|
|
2412
|
+
|
|
2413
|
+
class UnknownBrowserError extends Error {
|
|
2414
|
+
}
|
|
2415
|
+
async function defaultBrowser(_execFileAsync = execFileAsync3) {
|
|
2416
|
+
const { stdout } = await _execFileAsync("reg", [
|
|
2417
|
+
"QUERY",
|
|
2418
|
+
" HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\http\\UserChoice",
|
|
2419
|
+
"/v",
|
|
2420
|
+
"ProgId"
|
|
2421
|
+
]);
|
|
2422
|
+
const match = /ProgId\s*REG_SZ\s*(?<id>\S+)/.exec(stdout);
|
|
2423
|
+
if (!match) {
|
|
2424
|
+
throw new UnknownBrowserError(`Cannot find Windows browser in stdout: ${JSON.stringify(stdout)}`);
|
|
2425
|
+
}
|
|
2426
|
+
const { id } = match.groups;
|
|
2427
|
+
const browser = windowsBrowserProgIds[id];
|
|
2428
|
+
if (!browser) {
|
|
2429
|
+
throw new UnknownBrowserError(`Unknown browser ID: ${id}`);
|
|
2430
|
+
}
|
|
2431
|
+
return browser;
|
|
2432
|
+
}
|
|
2433
|
+
|
|
2434
|
+
// ../../node_modules/.bun/default-browser@5.4.0/node_modules/default-browser/index.js
|
|
2435
|
+
var execFileAsync4 = promisify6(execFile6);
|
|
2436
|
+
var titleize = (string) => string.toLowerCase().replaceAll(/(?:^|\s|-)\S/g, (x) => x.toUpperCase());
|
|
2437
|
+
async function defaultBrowser2() {
|
|
2438
|
+
if (process6.platform === "darwin") {
|
|
2439
|
+
const id = await defaultBrowserId();
|
|
2440
|
+
const name = await bundleName(id);
|
|
2441
|
+
return { name, id };
|
|
2442
|
+
}
|
|
2443
|
+
if (process6.platform === "linux") {
|
|
2444
|
+
const { stdout } = await execFileAsync4("xdg-mime", ["query", "default", "x-scheme-handler/http"]);
|
|
2445
|
+
const id = stdout.trim();
|
|
2446
|
+
const name = titleize(id.replace(/.desktop$/, "").replace("-", " "));
|
|
2447
|
+
return { name, id };
|
|
2448
|
+
}
|
|
2449
|
+
if (process6.platform === "win32") {
|
|
2450
|
+
return defaultBrowser();
|
|
2451
|
+
}
|
|
2452
|
+
throw new Error("Only macOS, Linux, and Windows are supported");
|
|
2453
|
+
}
|
|
2454
|
+
|
|
2455
|
+
// ../../node_modules/.bun/is-in-ssh@1.0.0/node_modules/is-in-ssh/index.js
|
|
2456
|
+
import process7 from "node:process";
|
|
2457
|
+
var isInSsh = Boolean(process7.env.SSH_CONNECTION || process7.env.SSH_CLIENT || process7.env.SSH_TTY);
|
|
2458
|
+
var is_in_ssh_default = isInSsh;
|
|
2459
|
+
|
|
2460
|
+
// ../../node_modules/.bun/open@11.0.0/node_modules/open/index.js
|
|
2461
|
+
var fallbackAttemptSymbol = Symbol("fallbackAttempt");
|
|
2462
|
+
var __dirname2 = import.meta.url ? path.dirname(fileURLToPath(import.meta.url)) : "";
|
|
2463
|
+
var localXdgOpenPath = path.join(__dirname2, "xdg-open");
|
|
2464
|
+
var { platform, arch } = process8;
|
|
2465
|
+
var tryEachApp = async (apps, opener) => {
|
|
2466
|
+
if (apps.length === 0) {
|
|
2467
|
+
return;
|
|
2468
|
+
}
|
|
2469
|
+
const errors = [];
|
|
2470
|
+
for (const app of apps) {
|
|
2471
|
+
try {
|
|
2472
|
+
return await opener(app);
|
|
2473
|
+
} catch (error) {
|
|
2474
|
+
errors.push(error);
|
|
2475
|
+
}
|
|
2476
|
+
}
|
|
2477
|
+
throw new AggregateError(errors, "Failed to open in all supported apps");
|
|
2478
|
+
};
|
|
2479
|
+
var baseOpen = async (options) => {
|
|
2480
|
+
options = {
|
|
2481
|
+
wait: false,
|
|
2482
|
+
background: false,
|
|
2483
|
+
newInstance: false,
|
|
2484
|
+
allowNonzeroExitCode: false,
|
|
2485
|
+
...options
|
|
2486
|
+
};
|
|
2487
|
+
const isFallbackAttempt = options[fallbackAttemptSymbol] === true;
|
|
2488
|
+
delete options[fallbackAttemptSymbol];
|
|
2489
|
+
if (Array.isArray(options.app)) {
|
|
2490
|
+
return tryEachApp(options.app, (singleApp) => baseOpen({
|
|
2491
|
+
...options,
|
|
2492
|
+
app: singleApp,
|
|
2493
|
+
[fallbackAttemptSymbol]: true
|
|
2494
|
+
}));
|
|
2495
|
+
}
|
|
2496
|
+
let { name: app, arguments: appArguments = [] } = options.app ?? {};
|
|
2497
|
+
appArguments = [...appArguments];
|
|
2498
|
+
if (Array.isArray(app)) {
|
|
2499
|
+
return tryEachApp(app, (appName) => baseOpen({
|
|
2500
|
+
...options,
|
|
2501
|
+
app: {
|
|
2502
|
+
name: appName,
|
|
2503
|
+
arguments: appArguments
|
|
2504
|
+
},
|
|
2505
|
+
[fallbackAttemptSymbol]: true
|
|
2506
|
+
}));
|
|
2507
|
+
}
|
|
2508
|
+
if (app === "browser" || app === "browserPrivate") {
|
|
2509
|
+
const ids = {
|
|
2510
|
+
"com.google.chrome": "chrome",
|
|
2511
|
+
"google-chrome.desktop": "chrome",
|
|
2512
|
+
"com.brave.browser": "brave",
|
|
2513
|
+
"org.mozilla.firefox": "firefox",
|
|
2514
|
+
"firefox.desktop": "firefox",
|
|
2515
|
+
"com.microsoft.msedge": "edge",
|
|
2516
|
+
"com.microsoft.edge": "edge",
|
|
2517
|
+
"com.microsoft.edgemac": "edge",
|
|
2518
|
+
"microsoft-edge.desktop": "edge",
|
|
2519
|
+
"com.apple.safari": "safari"
|
|
2520
|
+
};
|
|
2521
|
+
const flags = {
|
|
2522
|
+
chrome: "--incognito",
|
|
2523
|
+
brave: "--incognito",
|
|
2524
|
+
firefox: "--private-window",
|
|
2525
|
+
edge: "--inPrivate"
|
|
2526
|
+
};
|
|
2527
|
+
let browser;
|
|
2528
|
+
if (is_wsl_default) {
|
|
2529
|
+
const progId = await wslDefaultBrowser();
|
|
2530
|
+
const browserInfo = _windowsBrowserProgIdMap.get(progId);
|
|
2531
|
+
browser = browserInfo ?? {};
|
|
2532
|
+
} else {
|
|
2533
|
+
browser = await defaultBrowser2();
|
|
2534
|
+
}
|
|
2535
|
+
if (browser.id in ids) {
|
|
2536
|
+
const browserName = ids[browser.id.toLowerCase()];
|
|
2537
|
+
if (app === "browserPrivate") {
|
|
2538
|
+
if (browserName === "safari") {
|
|
2539
|
+
throw new Error("Safari doesn't support opening in private mode via command line");
|
|
2540
|
+
}
|
|
2541
|
+
appArguments.push(flags[browserName]);
|
|
2542
|
+
}
|
|
2543
|
+
return baseOpen({
|
|
2544
|
+
...options,
|
|
2545
|
+
app: {
|
|
2546
|
+
name: apps[browserName],
|
|
2547
|
+
arguments: appArguments
|
|
2548
|
+
}
|
|
2549
|
+
});
|
|
2550
|
+
}
|
|
2551
|
+
throw new Error(`${browser.name} is not supported as a default browser`);
|
|
2552
|
+
}
|
|
2553
|
+
let command;
|
|
2554
|
+
const cliArguments = [];
|
|
2555
|
+
const childProcessOptions = {};
|
|
2556
|
+
let shouldUseWindowsInWsl = false;
|
|
2557
|
+
if (is_wsl_default && !isInsideContainer() && !is_in_ssh_default && !app) {
|
|
2558
|
+
shouldUseWindowsInWsl = await canAccessPowerShell();
|
|
2559
|
+
}
|
|
2560
|
+
if (platform === "darwin") {
|
|
2561
|
+
command = "open";
|
|
2562
|
+
if (options.wait) {
|
|
2563
|
+
cliArguments.push("--wait-apps");
|
|
2564
|
+
}
|
|
2565
|
+
if (options.background) {
|
|
2566
|
+
cliArguments.push("--background");
|
|
2567
|
+
}
|
|
2568
|
+
if (options.newInstance) {
|
|
2569
|
+
cliArguments.push("--new");
|
|
2570
|
+
}
|
|
2571
|
+
if (app) {
|
|
2572
|
+
cliArguments.push("-a", app);
|
|
2573
|
+
}
|
|
2574
|
+
} else if (platform === "win32" || shouldUseWindowsInWsl) {
|
|
2575
|
+
command = await powerShellPath2();
|
|
2576
|
+
cliArguments.push(...executePowerShell.argumentsPrefix);
|
|
2577
|
+
if (!is_wsl_default) {
|
|
2578
|
+
childProcessOptions.windowsVerbatimArguments = true;
|
|
2579
|
+
}
|
|
2580
|
+
if (is_wsl_default && options.target) {
|
|
2581
|
+
options.target = await convertWslPathToWindows(options.target);
|
|
2582
|
+
}
|
|
2583
|
+
const encodedArguments = ["$ProgressPreference = 'SilentlyContinue';", "Start"];
|
|
2584
|
+
if (options.wait) {
|
|
2585
|
+
encodedArguments.push("-Wait");
|
|
2586
|
+
}
|
|
2587
|
+
if (app) {
|
|
2588
|
+
encodedArguments.push(executePowerShell.escapeArgument(app));
|
|
2589
|
+
if (options.target) {
|
|
2590
|
+
appArguments.push(options.target);
|
|
2591
|
+
}
|
|
2592
|
+
} else if (options.target) {
|
|
2593
|
+
encodedArguments.push(executePowerShell.escapeArgument(options.target));
|
|
2594
|
+
}
|
|
2595
|
+
if (appArguments.length > 0) {
|
|
2596
|
+
appArguments = appArguments.map((argument) => executePowerShell.escapeArgument(argument));
|
|
2597
|
+
encodedArguments.push("-ArgumentList", appArguments.join(","));
|
|
2598
|
+
}
|
|
2599
|
+
options.target = executePowerShell.encodeCommand(encodedArguments.join(" "));
|
|
2600
|
+
if (!options.wait) {
|
|
2601
|
+
childProcessOptions.stdio = "ignore";
|
|
2602
|
+
}
|
|
2603
|
+
} else {
|
|
2604
|
+
if (app) {
|
|
2605
|
+
command = app;
|
|
2606
|
+
} else {
|
|
2607
|
+
const isBundled = !__dirname2 || __dirname2 === "/";
|
|
2608
|
+
let exeLocalXdgOpen = false;
|
|
2609
|
+
try {
|
|
2610
|
+
await fs5.access(localXdgOpenPath, fsConstants2.X_OK);
|
|
2611
|
+
exeLocalXdgOpen = true;
|
|
2612
|
+
} catch {}
|
|
2613
|
+
const useSystemXdgOpen = process8.versions.electron ?? (platform === "android" || isBundled || !exeLocalXdgOpen);
|
|
2614
|
+
command = useSystemXdgOpen ? "xdg-open" : localXdgOpenPath;
|
|
2615
|
+
}
|
|
2616
|
+
if (appArguments.length > 0) {
|
|
2617
|
+
cliArguments.push(...appArguments);
|
|
2618
|
+
}
|
|
2619
|
+
if (!options.wait) {
|
|
2620
|
+
childProcessOptions.stdio = "ignore";
|
|
2621
|
+
childProcessOptions.detached = true;
|
|
2622
|
+
}
|
|
2623
|
+
}
|
|
2624
|
+
if (platform === "darwin" && appArguments.length > 0) {
|
|
2625
|
+
cliArguments.push("--args", ...appArguments);
|
|
2626
|
+
}
|
|
2627
|
+
if (options.target) {
|
|
2628
|
+
cliArguments.push(options.target);
|
|
2629
|
+
}
|
|
2630
|
+
const subprocess = childProcess3.spawn(command, cliArguments, childProcessOptions);
|
|
2631
|
+
if (options.wait) {
|
|
2632
|
+
return new Promise((resolve, reject) => {
|
|
2633
|
+
subprocess.once("error", reject);
|
|
2634
|
+
subprocess.once("close", (exitCode) => {
|
|
2635
|
+
if (!options.allowNonzeroExitCode && exitCode !== 0) {
|
|
2636
|
+
reject(new Error(`Exited with code ${exitCode}`));
|
|
2637
|
+
return;
|
|
2638
|
+
}
|
|
2639
|
+
resolve(subprocess);
|
|
2640
|
+
});
|
|
2641
|
+
});
|
|
2642
|
+
}
|
|
2643
|
+
if (isFallbackAttempt) {
|
|
2644
|
+
return new Promise((resolve, reject) => {
|
|
2645
|
+
subprocess.once("error", reject);
|
|
2646
|
+
subprocess.once("spawn", () => {
|
|
2647
|
+
subprocess.once("close", (exitCode) => {
|
|
2648
|
+
subprocess.off("error", reject);
|
|
2649
|
+
if (exitCode !== 0) {
|
|
2650
|
+
reject(new Error(`Exited with code ${exitCode}`));
|
|
2651
|
+
return;
|
|
2652
|
+
}
|
|
2653
|
+
subprocess.unref();
|
|
2654
|
+
resolve(subprocess);
|
|
2655
|
+
});
|
|
2656
|
+
});
|
|
2657
|
+
});
|
|
2658
|
+
}
|
|
2659
|
+
subprocess.unref();
|
|
2660
|
+
return new Promise((resolve, reject) => {
|
|
2661
|
+
subprocess.once("error", reject);
|
|
2662
|
+
subprocess.once("spawn", () => {
|
|
2663
|
+
subprocess.off("error", reject);
|
|
2664
|
+
resolve(subprocess);
|
|
2665
|
+
});
|
|
2666
|
+
});
|
|
2667
|
+
};
|
|
2668
|
+
var open = (target, options) => {
|
|
2669
|
+
if (typeof target !== "string") {
|
|
2670
|
+
throw new TypeError("Expected a `target`");
|
|
2671
|
+
}
|
|
2672
|
+
return baseOpen({
|
|
2673
|
+
...options,
|
|
2674
|
+
target
|
|
2675
|
+
});
|
|
2676
|
+
};
|
|
2677
|
+
function detectArchBinary(binary) {
|
|
2678
|
+
if (typeof binary === "string" || Array.isArray(binary)) {
|
|
2679
|
+
return binary;
|
|
2680
|
+
}
|
|
2681
|
+
const { [arch]: archBinary } = binary;
|
|
2682
|
+
if (!archBinary) {
|
|
2683
|
+
throw new Error(`${arch} is not supported`);
|
|
2684
|
+
}
|
|
2685
|
+
return archBinary;
|
|
2686
|
+
}
|
|
2687
|
+
function detectPlatformBinary({ [platform]: platformBinary }, { wsl } = {}) {
|
|
2688
|
+
if (wsl && is_wsl_default) {
|
|
2689
|
+
return detectArchBinary(wsl);
|
|
2690
|
+
}
|
|
2691
|
+
if (!platformBinary) {
|
|
2692
|
+
throw new Error(`${platform} is not supported`);
|
|
2693
|
+
}
|
|
2694
|
+
return detectArchBinary(platformBinary);
|
|
2695
|
+
}
|
|
2696
|
+
var apps = {
|
|
2697
|
+
browser: "browser",
|
|
2698
|
+
browserPrivate: "browserPrivate"
|
|
2699
|
+
};
|
|
2700
|
+
defineLazyProperty(apps, "chrome", () => detectPlatformBinary({
|
|
2701
|
+
darwin: "google chrome",
|
|
2702
|
+
win32: "chrome",
|
|
2703
|
+
linux: ["google-chrome", "google-chrome-stable", "chromium", "chromium-browser"]
|
|
2704
|
+
}, {
|
|
2705
|
+
wsl: {
|
|
2706
|
+
ia32: "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe",
|
|
2707
|
+
x64: ["/mnt/c/Program Files/Google/Chrome/Application/chrome.exe", "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe"]
|
|
2708
|
+
}
|
|
2709
|
+
}));
|
|
2710
|
+
defineLazyProperty(apps, "brave", () => detectPlatformBinary({
|
|
2711
|
+
darwin: "brave browser",
|
|
2712
|
+
win32: "brave",
|
|
2713
|
+
linux: ["brave-browser", "brave"]
|
|
2714
|
+
}, {
|
|
2715
|
+
wsl: {
|
|
2716
|
+
ia32: "/mnt/c/Program Files (x86)/BraveSoftware/Brave-Browser/Application/brave.exe",
|
|
2717
|
+
x64: ["/mnt/c/Program Files/BraveSoftware/Brave-Browser/Application/brave.exe", "/mnt/c/Program Files (x86)/BraveSoftware/Brave-Browser/Application/brave.exe"]
|
|
2718
|
+
}
|
|
2719
|
+
}));
|
|
2720
|
+
defineLazyProperty(apps, "firefox", () => detectPlatformBinary({
|
|
2721
|
+
darwin: "firefox",
|
|
2722
|
+
win32: String.raw`C:\Program Files\Mozilla Firefox\firefox.exe`,
|
|
2723
|
+
linux: "firefox"
|
|
2724
|
+
}, {
|
|
2725
|
+
wsl: "/mnt/c/Program Files/Mozilla Firefox/firefox.exe"
|
|
2726
|
+
}));
|
|
2727
|
+
defineLazyProperty(apps, "edge", () => detectPlatformBinary({
|
|
2728
|
+
darwin: "microsoft edge",
|
|
2729
|
+
win32: "msedge",
|
|
2730
|
+
linux: ["microsoft-edge", "microsoft-edge-dev"]
|
|
2731
|
+
}, {
|
|
2732
|
+
wsl: "/mnt/c/Program Files (x86)/Microsoft/Edge/Application/msedge.exe"
|
|
2733
|
+
}));
|
|
2734
|
+
defineLazyProperty(apps, "safari", () => detectPlatformBinary({
|
|
2735
|
+
darwin: "Safari"
|
|
2736
|
+
}));
|
|
2737
|
+
var open_default = open;
|
|
2738
|
+
|
|
2739
|
+
// src/commands/login.ts
|
|
2740
|
+
import http from "node:http";
|
|
2741
|
+
|
|
2742
|
+
// src/auth/token.ts
|
|
2743
|
+
import fs6 from "fs";
|
|
2744
|
+
import os2 from "os";
|
|
2745
|
+
import path2 from "path";
|
|
2746
|
+
var DIR = path2.join(os2.homedir(), ".zerodeploy");
|
|
2747
|
+
var TOKEN_PATH = path2.join(DIR, "token");
|
|
2748
|
+
function saveToken(token) {
|
|
2749
|
+
if (!fs6.existsSync(DIR)) {
|
|
2750
|
+
fs6.mkdirSync(DIR);
|
|
2751
|
+
}
|
|
2752
|
+
fs6.writeFileSync(TOKEN_PATH, token, "utf8");
|
|
2753
|
+
}
|
|
2754
|
+
function loadToken() {
|
|
2755
|
+
const envToken = process.env.ZERODEPLOY_TOKEN;
|
|
2756
|
+
if (envToken)
|
|
2757
|
+
return envToken;
|
|
2758
|
+
if (!fs6.existsSync(TOKEN_PATH))
|
|
2759
|
+
return null;
|
|
2760
|
+
return fs6.readFileSync(TOKEN_PATH, "utf8");
|
|
2761
|
+
}
|
|
2762
|
+
function deleteToken() {
|
|
2763
|
+
try {
|
|
2764
|
+
if (fs6.existsSync(TOKEN_PATH))
|
|
2765
|
+
fs6.unlinkSync(TOKEN_PATH);
|
|
2766
|
+
} catch (err) {
|
|
2767
|
+
console.error("Failed to delete token:", err);
|
|
2768
|
+
}
|
|
2769
|
+
}
|
|
2770
|
+
|
|
2771
|
+
// src/utils/config.ts
|
|
2772
|
+
var API_URL = process.env.ZERODEPLOY_API_URL || "https://api.zerodeploy.dev";
|
|
2773
|
+
|
|
2774
|
+
// src/commands/login.ts
|
|
2775
|
+
var loginCommand = new Command2("login").description("Login via GitHub OAuth with local server").action(async () => {
|
|
2776
|
+
const PORT = 3001;
|
|
2777
|
+
const CALLBACK_PATH = "/callback";
|
|
2778
|
+
const CLI_REDIRECT_URI = `http://localhost:${PORT}${CALLBACK_PATH}`;
|
|
2779
|
+
const server = http.createServer((req, res) => {
|
|
2780
|
+
if (req.url?.startsWith(CALLBACK_PATH)) {
|
|
2781
|
+
const url = new URL(req.url, `http://localhost:${PORT}`);
|
|
2782
|
+
const token = url.searchParams.get("token");
|
|
2783
|
+
if (!token) {
|
|
2784
|
+
res.writeHead(400);
|
|
2785
|
+
res.end("Login failed: missing token");
|
|
2786
|
+
console.error("Login failed: no token received");
|
|
2787
|
+
process.exit(1);
|
|
2788
|
+
}
|
|
2789
|
+
saveToken(token);
|
|
2790
|
+
res.writeHead(200, { "Content-Type": "text/plain" });
|
|
2791
|
+
res.end("✅ Login successful! You can close this window.");
|
|
2792
|
+
console.log("✅ Login successful! Token saved locally.");
|
|
2793
|
+
server.close();
|
|
2794
|
+
} else {
|
|
2795
|
+
res.writeHead(404);
|
|
2796
|
+
res.end("Not Found");
|
|
2797
|
+
}
|
|
2798
|
+
});
|
|
2799
|
+
server.listen(PORT, async () => {
|
|
2800
|
+
const oauthUrl = `${API_URL}/auth/github?cli_redirect=${encodeURIComponent(CLI_REDIRECT_URI)}`;
|
|
2801
|
+
console.log("Opening GitHub login page in your browser...");
|
|
2802
|
+
await open_default(oauthUrl);
|
|
2803
|
+
});
|
|
2804
|
+
});
|
|
2805
|
+
|
|
2806
|
+
// src/commands/logout.ts
|
|
2807
|
+
var logoutCommand = new Command2("logout").description("Logout from ZeroDeploy").action(() => {
|
|
2808
|
+
deleteToken();
|
|
2809
|
+
console.log("✅ Logged out. Token removed.");
|
|
2810
|
+
});
|
|
2811
|
+
|
|
2812
|
+
// ../../node_modules/.bun/hono@4.11.0/node_modules/hono/dist/utils/cookie.js
|
|
2813
|
+
var _serialize = (name, value, opt = {}) => {
|
|
2814
|
+
let cookie = `${name}=${value}`;
|
|
2815
|
+
if (name.startsWith("__Secure-") && !opt.secure) {
|
|
2816
|
+
throw new Error("__Secure- Cookie must have Secure attributes");
|
|
2817
|
+
}
|
|
2818
|
+
if (name.startsWith("__Host-")) {
|
|
2819
|
+
if (!opt.secure) {
|
|
2820
|
+
throw new Error("__Host- Cookie must have Secure attributes");
|
|
2821
|
+
}
|
|
2822
|
+
if (opt.path !== "/") {
|
|
2823
|
+
throw new Error('__Host- Cookie must have Path attributes with "/"');
|
|
2824
|
+
}
|
|
2825
|
+
if (opt.domain) {
|
|
2826
|
+
throw new Error("__Host- Cookie must not have Domain attributes");
|
|
2827
|
+
}
|
|
2828
|
+
}
|
|
2829
|
+
if (opt && typeof opt.maxAge === "number" && opt.maxAge >= 0) {
|
|
2830
|
+
if (opt.maxAge > 34560000) {
|
|
2831
|
+
throw new Error("Cookies Max-Age SHOULD NOT be greater than 400 days (34560000 seconds) in duration.");
|
|
2832
|
+
}
|
|
2833
|
+
cookie += `; Max-Age=${opt.maxAge | 0}`;
|
|
2834
|
+
}
|
|
2835
|
+
if (opt.domain && opt.prefix !== "host") {
|
|
2836
|
+
cookie += `; Domain=${opt.domain}`;
|
|
2837
|
+
}
|
|
2838
|
+
if (opt.path) {
|
|
2839
|
+
cookie += `; Path=${opt.path}`;
|
|
2840
|
+
}
|
|
2841
|
+
if (opt.expires) {
|
|
2842
|
+
if (opt.expires.getTime() - Date.now() > 34560000000) {
|
|
2843
|
+
throw new Error("Cookies Expires SHOULD NOT be greater than 400 days (34560000 seconds) in the future.");
|
|
2844
|
+
}
|
|
2845
|
+
cookie += `; Expires=${opt.expires.toUTCString()}`;
|
|
2846
|
+
}
|
|
2847
|
+
if (opt.httpOnly) {
|
|
2848
|
+
cookie += "; HttpOnly";
|
|
2849
|
+
}
|
|
2850
|
+
if (opt.secure) {
|
|
2851
|
+
cookie += "; Secure";
|
|
2852
|
+
}
|
|
2853
|
+
if (opt.sameSite) {
|
|
2854
|
+
cookie += `; SameSite=${opt.sameSite.charAt(0).toUpperCase() + opt.sameSite.slice(1)}`;
|
|
2855
|
+
}
|
|
2856
|
+
if (opt.priority) {
|
|
2857
|
+
cookie += `; Priority=${opt.priority.charAt(0).toUpperCase() + opt.priority.slice(1)}`;
|
|
2858
|
+
}
|
|
2859
|
+
if (opt.partitioned) {
|
|
2860
|
+
if (!opt.secure) {
|
|
2861
|
+
throw new Error("Partitioned Cookie must have Secure attributes");
|
|
2862
|
+
}
|
|
2863
|
+
cookie += "; Partitioned";
|
|
2864
|
+
}
|
|
2865
|
+
return cookie;
|
|
2866
|
+
};
|
|
2867
|
+
var serialize = (name, value, opt) => {
|
|
2868
|
+
value = encodeURIComponent(value);
|
|
2869
|
+
return _serialize(name, value, opt);
|
|
2870
|
+
};
|
|
2871
|
+
|
|
2872
|
+
// ../../node_modules/.bun/hono@4.11.0/node_modules/hono/dist/client/utils.js
|
|
2873
|
+
var mergePath = (base, path3) => {
|
|
2874
|
+
base = base.replace(/\/+$/, "");
|
|
2875
|
+
base = base + "/";
|
|
2876
|
+
path3 = path3.replace(/^\/+/, "");
|
|
2877
|
+
return base + path3;
|
|
2878
|
+
};
|
|
2879
|
+
var replaceUrlParam = (urlString, params) => {
|
|
2880
|
+
for (const [k, v] of Object.entries(params)) {
|
|
2881
|
+
const reg = new RegExp("/:" + k + "(?:{[^/]+})?\\??");
|
|
2882
|
+
urlString = urlString.replace(reg, v ? `/${v}` : "");
|
|
2883
|
+
}
|
|
2884
|
+
return urlString;
|
|
2885
|
+
};
|
|
2886
|
+
var buildSearchParams = (query) => {
|
|
2887
|
+
const searchParams = new URLSearchParams;
|
|
2888
|
+
for (const [k, v] of Object.entries(query)) {
|
|
2889
|
+
if (v === undefined) {
|
|
2890
|
+
continue;
|
|
2891
|
+
}
|
|
2892
|
+
if (Array.isArray(v)) {
|
|
2893
|
+
for (const v2 of v) {
|
|
2894
|
+
searchParams.append(k, v2);
|
|
2895
|
+
}
|
|
2896
|
+
} else {
|
|
2897
|
+
searchParams.set(k, v);
|
|
2898
|
+
}
|
|
2899
|
+
}
|
|
2900
|
+
return searchParams;
|
|
2901
|
+
};
|
|
2902
|
+
var replaceUrlProtocol = (urlString, protocol) => {
|
|
2903
|
+
switch (protocol) {
|
|
2904
|
+
case "ws":
|
|
2905
|
+
return urlString.replace(/^http/, "ws");
|
|
2906
|
+
case "http":
|
|
2907
|
+
return urlString.replace(/^ws/, "http");
|
|
2908
|
+
}
|
|
2909
|
+
};
|
|
2910
|
+
var removeIndexString = (urlString) => {
|
|
2911
|
+
if (/^https?:\/\/[^\/]+?\/index(?=\?|$)/.test(urlString)) {
|
|
2912
|
+
return urlString.replace(/\/index(?=\?|$)/, "/");
|
|
2913
|
+
}
|
|
2914
|
+
return urlString.replace(/\/index(?=\?|$)/, "");
|
|
2915
|
+
};
|
|
2916
|
+
function isObject(item) {
|
|
2917
|
+
return typeof item === "object" && item !== null && !Array.isArray(item);
|
|
2918
|
+
}
|
|
2919
|
+
function deepMerge(target, source) {
|
|
2920
|
+
if (!isObject(target) && !isObject(source)) {
|
|
2921
|
+
return source;
|
|
2922
|
+
}
|
|
2923
|
+
const merged = { ...target };
|
|
2924
|
+
for (const key in source) {
|
|
2925
|
+
const value = source[key];
|
|
2926
|
+
if (isObject(merged[key]) && isObject(value)) {
|
|
2927
|
+
merged[key] = deepMerge(merged[key], value);
|
|
2928
|
+
} else {
|
|
2929
|
+
merged[key] = value;
|
|
2930
|
+
}
|
|
2931
|
+
}
|
|
2932
|
+
return merged;
|
|
2933
|
+
}
|
|
2934
|
+
|
|
2935
|
+
// ../../node_modules/.bun/hono@4.11.0/node_modules/hono/dist/client/client.js
|
|
2936
|
+
var createProxy = (callback, path3) => {
|
|
2937
|
+
const proxy = new Proxy(() => {}, {
|
|
2938
|
+
get(_obj, key) {
|
|
2939
|
+
if (typeof key !== "string" || key === "then") {
|
|
2940
|
+
return;
|
|
2941
|
+
}
|
|
2942
|
+
return createProxy(callback, [...path3, key]);
|
|
2943
|
+
},
|
|
2944
|
+
apply(_1, _2, args) {
|
|
2945
|
+
return callback({
|
|
2946
|
+
path: path3,
|
|
2947
|
+
args
|
|
2948
|
+
});
|
|
2949
|
+
}
|
|
2950
|
+
});
|
|
2951
|
+
return proxy;
|
|
2952
|
+
};
|
|
2953
|
+
var ClientRequestImpl = class {
|
|
2954
|
+
url;
|
|
2955
|
+
method;
|
|
2956
|
+
buildSearchParams;
|
|
2957
|
+
queryParams = undefined;
|
|
2958
|
+
pathParams = {};
|
|
2959
|
+
rBody;
|
|
2960
|
+
cType = undefined;
|
|
2961
|
+
constructor(url, method, options) {
|
|
2962
|
+
this.url = url;
|
|
2963
|
+
this.method = method;
|
|
2964
|
+
this.buildSearchParams = options.buildSearchParams;
|
|
2965
|
+
}
|
|
2966
|
+
fetch = async (args, opt) => {
|
|
2967
|
+
if (args) {
|
|
2968
|
+
if (args.query) {
|
|
2969
|
+
this.queryParams = this.buildSearchParams(args.query);
|
|
2970
|
+
}
|
|
2971
|
+
if (args.form) {
|
|
2972
|
+
const form = new FormData;
|
|
2973
|
+
for (const [k, v] of Object.entries(args.form)) {
|
|
2974
|
+
if (Array.isArray(v)) {
|
|
2975
|
+
for (const v2 of v) {
|
|
2976
|
+
form.append(k, v2);
|
|
2977
|
+
}
|
|
2978
|
+
} else {
|
|
2979
|
+
form.append(k, v);
|
|
2980
|
+
}
|
|
2981
|
+
}
|
|
2982
|
+
this.rBody = form;
|
|
2983
|
+
}
|
|
2984
|
+
if (args.json) {
|
|
2985
|
+
this.rBody = JSON.stringify(args.json);
|
|
2986
|
+
this.cType = "application/json";
|
|
2987
|
+
}
|
|
2988
|
+
if (args.param) {
|
|
2989
|
+
this.pathParams = args.param;
|
|
2990
|
+
}
|
|
2991
|
+
}
|
|
2992
|
+
let methodUpperCase = this.method.toUpperCase();
|
|
2993
|
+
const headerValues = {
|
|
2994
|
+
...args?.header,
|
|
2995
|
+
...typeof opt?.headers === "function" ? await opt.headers() : opt?.headers
|
|
2996
|
+
};
|
|
2997
|
+
if (args?.cookie) {
|
|
2998
|
+
const cookies = [];
|
|
2999
|
+
for (const [key, value] of Object.entries(args.cookie)) {
|
|
3000
|
+
cookies.push(serialize(key, value, { path: "/" }));
|
|
3001
|
+
}
|
|
3002
|
+
headerValues["Cookie"] = cookies.join(",");
|
|
3003
|
+
}
|
|
3004
|
+
if (this.cType) {
|
|
3005
|
+
headerValues["Content-Type"] = this.cType;
|
|
3006
|
+
}
|
|
3007
|
+
const headers = new Headers(headerValues ?? undefined);
|
|
3008
|
+
let url = this.url;
|
|
3009
|
+
url = removeIndexString(url);
|
|
3010
|
+
url = replaceUrlParam(url, this.pathParams);
|
|
3011
|
+
if (this.queryParams) {
|
|
3012
|
+
url = url + "?" + this.queryParams.toString();
|
|
3013
|
+
}
|
|
3014
|
+
methodUpperCase = this.method.toUpperCase();
|
|
3015
|
+
const setBody = !(methodUpperCase === "GET" || methodUpperCase === "HEAD");
|
|
3016
|
+
return (opt?.fetch || fetch)(url, {
|
|
3017
|
+
body: setBody ? this.rBody : undefined,
|
|
3018
|
+
method: methodUpperCase,
|
|
3019
|
+
headers,
|
|
3020
|
+
...opt?.init
|
|
3021
|
+
});
|
|
3022
|
+
};
|
|
3023
|
+
};
|
|
3024
|
+
var hc = (baseUrl, options) => createProxy(function proxyCallback(opts) {
|
|
3025
|
+
const buildSearchParamsOption = options?.buildSearchParams ?? buildSearchParams;
|
|
3026
|
+
const parts = [...opts.path];
|
|
3027
|
+
const lastParts = parts.slice(-3).reverse();
|
|
3028
|
+
if (lastParts[0] === "toString") {
|
|
3029
|
+
if (lastParts[1] === "name") {
|
|
3030
|
+
return lastParts[2] || "";
|
|
3031
|
+
}
|
|
3032
|
+
return proxyCallback.toString();
|
|
3033
|
+
}
|
|
3034
|
+
if (lastParts[0] === "valueOf") {
|
|
3035
|
+
if (lastParts[1] === "name") {
|
|
3036
|
+
return lastParts[2] || "";
|
|
3037
|
+
}
|
|
3038
|
+
return proxyCallback;
|
|
3039
|
+
}
|
|
3040
|
+
let method = "";
|
|
3041
|
+
if (/^\$/.test(lastParts[0])) {
|
|
3042
|
+
const last = parts.pop();
|
|
3043
|
+
if (last) {
|
|
3044
|
+
method = last.replace(/^\$/, "");
|
|
3045
|
+
}
|
|
3046
|
+
}
|
|
3047
|
+
const path3 = parts.join("/");
|
|
3048
|
+
const url = mergePath(baseUrl, path3);
|
|
3049
|
+
if (method === "url") {
|
|
3050
|
+
let result = url;
|
|
3051
|
+
if (opts.args[0]) {
|
|
3052
|
+
if (opts.args[0].param) {
|
|
3053
|
+
result = replaceUrlParam(url, opts.args[0].param);
|
|
3054
|
+
}
|
|
3055
|
+
if (opts.args[0].query) {
|
|
3056
|
+
result = result + "?" + buildSearchParamsOption(opts.args[0].query).toString();
|
|
3057
|
+
}
|
|
3058
|
+
}
|
|
3059
|
+
result = removeIndexString(result);
|
|
3060
|
+
return new URL(result);
|
|
3061
|
+
}
|
|
3062
|
+
if (method === "ws") {
|
|
3063
|
+
const webSocketUrl = replaceUrlProtocol(opts.args[0] && opts.args[0].param ? replaceUrlParam(url, opts.args[0].param) : url, "ws");
|
|
3064
|
+
const targetUrl = new URL(webSocketUrl);
|
|
3065
|
+
const queryParams = opts.args[0]?.query;
|
|
3066
|
+
if (queryParams) {
|
|
3067
|
+
Object.entries(queryParams).forEach(([key, value]) => {
|
|
3068
|
+
if (Array.isArray(value)) {
|
|
3069
|
+
value.forEach((item) => targetUrl.searchParams.append(key, item));
|
|
3070
|
+
} else {
|
|
3071
|
+
targetUrl.searchParams.set(key, value);
|
|
3072
|
+
}
|
|
3073
|
+
});
|
|
3074
|
+
}
|
|
3075
|
+
const establishWebSocket = (...args) => {
|
|
3076
|
+
if (options?.webSocket !== undefined && typeof options.webSocket === "function") {
|
|
3077
|
+
return options.webSocket(...args);
|
|
3078
|
+
}
|
|
3079
|
+
return new WebSocket(...args);
|
|
3080
|
+
};
|
|
3081
|
+
return establishWebSocket(targetUrl.toString());
|
|
3082
|
+
}
|
|
3083
|
+
const req = new ClientRequestImpl(url, method, {
|
|
3084
|
+
buildSearchParams: buildSearchParamsOption
|
|
3085
|
+
});
|
|
3086
|
+
if (method) {
|
|
3087
|
+
options ??= {};
|
|
3088
|
+
const args = deepMerge(options, { ...opts.args[1] });
|
|
3089
|
+
return req.fetch(opts.args[0], args);
|
|
3090
|
+
}
|
|
3091
|
+
return req;
|
|
3092
|
+
}, []);
|
|
3093
|
+
|
|
3094
|
+
// ../../packages/api-client/src/index.ts
|
|
3095
|
+
function createClient(baseUrl, token) {
|
|
3096
|
+
return hc(baseUrl, {
|
|
3097
|
+
headers: token ? { Authorization: `Bearer ${token}` } : undefined
|
|
3098
|
+
});
|
|
3099
|
+
}
|
|
3100
|
+
|
|
3101
|
+
// src/auth/http.ts
|
|
3102
|
+
function getClient(token) {
|
|
3103
|
+
return createClient(API_URL, token);
|
|
3104
|
+
}
|
|
3105
|
+
|
|
3106
|
+
// src/commands/whoami.ts
|
|
3107
|
+
var whoamiCommand = new Command2("whoami").description("Show the currently logged-in user").action(async () => {
|
|
3108
|
+
const token = loadToken();
|
|
3109
|
+
if (!token) {
|
|
3110
|
+
console.log("❌ You are not logged in. Run `zerodeploy login` first.");
|
|
3111
|
+
process.exit(1);
|
|
3112
|
+
}
|
|
3113
|
+
try {
|
|
3114
|
+
const client = getClient(token);
|
|
3115
|
+
const res = await client.auth.me.$get();
|
|
3116
|
+
if (!res.ok)
|
|
3117
|
+
throw new Error(`API Error ${res.status}`);
|
|
3118
|
+
const data = await res.json();
|
|
3119
|
+
console.log("Logged in as:");
|
|
3120
|
+
console.log(` Username: ${data.username}`);
|
|
3121
|
+
console.log(` User ID: ${data.id}`);
|
|
3122
|
+
console.log(` Admin: ${data.isAdmin ? "Yes" : "No"}`);
|
|
3123
|
+
} catch (err) {
|
|
3124
|
+
console.error("❌ Failed to fetch user info:", err.message || err);
|
|
3125
|
+
process.exit(1);
|
|
3126
|
+
}
|
|
3127
|
+
});
|
|
3128
|
+
|
|
3129
|
+
// src/commands/org/list.ts
|
|
3130
|
+
var orgListCommand = new Command2("list").description("List your organizations").action(async () => {
|
|
3131
|
+
const token = loadToken();
|
|
3132
|
+
if (!token) {
|
|
3133
|
+
console.log("❌ Not logged in. Run `zerodeploy login` first.");
|
|
3134
|
+
return;
|
|
3135
|
+
}
|
|
3136
|
+
try {
|
|
3137
|
+
const client = getClient(token);
|
|
3138
|
+
const res = await client.orgs.$get();
|
|
3139
|
+
if (!res.ok)
|
|
3140
|
+
throw new Error(`API Error ${res.status}`);
|
|
3141
|
+
const orgs = await res.json();
|
|
3142
|
+
if (orgs.length === 0) {
|
|
3143
|
+
console.log("No organizations found.");
|
|
3144
|
+
} else {
|
|
3145
|
+
console.log("Organizations:");
|
|
3146
|
+
for (const o of orgs) {
|
|
3147
|
+
console.log(` ${o.slug.padEnd(20)} ${o.name} [${o.plan}]`);
|
|
3148
|
+
}
|
|
3149
|
+
}
|
|
3150
|
+
} catch (err) {
|
|
3151
|
+
console.error("Failed to fetch orgs:", err.message || err);
|
|
3152
|
+
}
|
|
3153
|
+
});
|
|
3154
|
+
|
|
3155
|
+
// src/commands/org/create.ts
|
|
3156
|
+
var orgCreateCommand = new Command2("create").description("Create a new organization").argument("<name>", "Organization name").action(async (name) => {
|
|
3157
|
+
const token = loadToken();
|
|
3158
|
+
if (!token) {
|
|
3159
|
+
console.log("❌ Not logged in. Run `zerodeploy login` first.");
|
|
3160
|
+
return;
|
|
3161
|
+
}
|
|
3162
|
+
try {
|
|
3163
|
+
const client = getClient(token);
|
|
3164
|
+
const res = await client.orgs.$post({ json: { name } });
|
|
3165
|
+
if (!res.ok) {
|
|
3166
|
+
const body = await res.json();
|
|
3167
|
+
const message = body.error || `API Error ${res.status}`;
|
|
3168
|
+
console.error(`❌ ${message}`);
|
|
3169
|
+
return;
|
|
3170
|
+
}
|
|
3171
|
+
const org = await res.json();
|
|
3172
|
+
console.log(`✅ Created org: ${org.name}`);
|
|
3173
|
+
console.log(` Slug: ${org.slug}`);
|
|
3174
|
+
console.log(` ID: ${org.id}`);
|
|
3175
|
+
} catch (err) {
|
|
3176
|
+
console.error("Failed to create org:", err.message || err);
|
|
3177
|
+
}
|
|
3178
|
+
});
|
|
3179
|
+
|
|
3180
|
+
// src/commands/org/delete.ts
|
|
3181
|
+
import * as readline from "readline";
|
|
3182
|
+
function prompt(question) {
|
|
3183
|
+
const rl = readline.createInterface({
|
|
3184
|
+
input: process.stdin,
|
|
3185
|
+
output: process.stdout
|
|
3186
|
+
});
|
|
3187
|
+
return new Promise((resolve) => {
|
|
3188
|
+
rl.question(question, (answer) => {
|
|
3189
|
+
rl.close();
|
|
3190
|
+
resolve(answer);
|
|
3191
|
+
});
|
|
3192
|
+
});
|
|
3193
|
+
}
|
|
3194
|
+
var orgDeleteCommand = new Command2("delete").description("Delete an organization (must have no sites)").argument("<orgSlug>", "Organization slug").option("--force", "Skip confirmation prompt").action(async (orgSlug, options) => {
|
|
3195
|
+
const token = loadToken();
|
|
3196
|
+
if (!token) {
|
|
3197
|
+
console.log("Not logged in. Run: zerodeploy login");
|
|
3198
|
+
return;
|
|
3199
|
+
}
|
|
3200
|
+
if (!options.force) {
|
|
3201
|
+
const answer = await prompt(`Are you sure you want to delete organization "${orgSlug}"? This cannot be undone. (y/N) `);
|
|
3202
|
+
if (answer.toLowerCase() !== "y") {
|
|
3203
|
+
console.log("Cancelled.");
|
|
3204
|
+
return;
|
|
3205
|
+
}
|
|
3206
|
+
}
|
|
3207
|
+
try {
|
|
3208
|
+
const client = getClient(token);
|
|
3209
|
+
const res = await client.orgs[":orgSlug"].$delete({
|
|
3210
|
+
param: { orgSlug }
|
|
3211
|
+
});
|
|
3212
|
+
if (!res.ok) {
|
|
3213
|
+
const error = await res.json();
|
|
3214
|
+
if (error.hint) {
|
|
3215
|
+
console.error(`Error: ${error.error}`);
|
|
3216
|
+
console.error(`Hint: ${error.hint}`);
|
|
3217
|
+
return;
|
|
3218
|
+
}
|
|
3219
|
+
throw new Error(error.error || `API Error ${res.status}`);
|
|
3220
|
+
}
|
|
3221
|
+
const result = await res.json();
|
|
3222
|
+
console.log(`✅ ${result.message}`);
|
|
3223
|
+
} catch (err) {
|
|
3224
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
3225
|
+
console.error("Failed to delete organization:", message);
|
|
3226
|
+
}
|
|
3227
|
+
});
|
|
3228
|
+
|
|
3229
|
+
// src/commands/org/index.ts
|
|
3230
|
+
var orgCommand = new Command2("org").description("Manage organizations").addCommand(orgListCommand).addCommand(orgCreateCommand).addCommand(orgDeleteCommand);
|
|
3231
|
+
|
|
3232
|
+
// src/commands/site/list.ts
|
|
3233
|
+
var siteListCommand = new Command2("list").description("List sites in an organization").argument("<orgSlug>", "Organization slug").action(async (orgSlug) => {
|
|
3234
|
+
const token = loadToken();
|
|
3235
|
+
if (!token) {
|
|
3236
|
+
console.log("Not logged in. Run: zerodeploy login");
|
|
3237
|
+
return;
|
|
3238
|
+
}
|
|
3239
|
+
try {
|
|
3240
|
+
const client = getClient(token);
|
|
3241
|
+
const res = await client.orgs[":orgSlug"].sites.$get({ param: { orgSlug } });
|
|
3242
|
+
if (!res.ok)
|
|
3243
|
+
throw new Error(`API Error ${res.status}`);
|
|
3244
|
+
const sites = await res.json();
|
|
3245
|
+
if (sites.length === 0) {
|
|
3246
|
+
console.log("No sites found.");
|
|
3247
|
+
return;
|
|
3248
|
+
}
|
|
3249
|
+
console.log("Sites:");
|
|
3250
|
+
for (const s of sites) {
|
|
3251
|
+
const repo = s.github_repo ? ` -> ${s.github_repo}` : "";
|
|
3252
|
+
console.log(` ${s.slug.padEnd(20)} ${s.name}${repo}`);
|
|
3253
|
+
}
|
|
3254
|
+
} catch (err) {
|
|
3255
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
3256
|
+
console.error("Failed to list sites:", message);
|
|
3257
|
+
}
|
|
3258
|
+
});
|
|
3259
|
+
|
|
3260
|
+
// src/commands/site/create.ts
|
|
3261
|
+
var siteCreateCommand = new Command2("create").description("Create a site in an organization").argument("<orgSlug>", "Organization slug").argument("<name>", "Site name").requiredOption("--subdomain <subdomain>", 'Subdomain for the site (e.g., "my-site" for my-site.zerodeploy.app)').option("--repo <owner/repo>", 'Link to GitHub repository (e.g., "vercel/next.js")').action(async (orgSlug, name, options) => {
|
|
3262
|
+
const token = loadToken();
|
|
3263
|
+
if (!token) {
|
|
3264
|
+
console.log("Not logged in. Run: zerodeploy login");
|
|
3265
|
+
return;
|
|
3266
|
+
}
|
|
3267
|
+
try {
|
|
3268
|
+
const client = getClient(token);
|
|
3269
|
+
const res = await client.orgs[":orgSlug"].sites.$post({
|
|
3270
|
+
param: { orgSlug },
|
|
3271
|
+
json: { name, subdomain: options.subdomain, githubRepo: options.repo }
|
|
3272
|
+
});
|
|
3273
|
+
if (!res.ok) {
|
|
3274
|
+
const error = await res.json();
|
|
3275
|
+
throw new Error(error.error || `API Error ${res.status}`);
|
|
3276
|
+
}
|
|
3277
|
+
const site = await res.json();
|
|
3278
|
+
console.log(`✅ Created site: ${site.name}`);
|
|
3279
|
+
console.log(` Subdomain: ${site.subdomain}.zerodeploy.app`);
|
|
3280
|
+
console.log(` Slug: ${site.slug}`);
|
|
3281
|
+
console.log(` ID: ${site.id}`);
|
|
3282
|
+
if (site.github_repo) {
|
|
3283
|
+
console.log(` Repo: ${site.github_repo}`);
|
|
3284
|
+
}
|
|
3285
|
+
} catch (err) {
|
|
3286
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
3287
|
+
console.error("Failed to create site:", message);
|
|
3288
|
+
}
|
|
3289
|
+
});
|
|
3290
|
+
|
|
3291
|
+
// src/commands/site/delete.ts
|
|
3292
|
+
import * as readline2 from "readline";
|
|
3293
|
+
function prompt2(question) {
|
|
3294
|
+
const rl = readline2.createInterface({
|
|
3295
|
+
input: process.stdin,
|
|
3296
|
+
output: process.stdout
|
|
3297
|
+
});
|
|
3298
|
+
return new Promise((resolve) => {
|
|
3299
|
+
rl.question(question, (answer) => {
|
|
3300
|
+
rl.close();
|
|
3301
|
+
resolve(answer);
|
|
3302
|
+
});
|
|
3303
|
+
});
|
|
3304
|
+
}
|
|
3305
|
+
var siteDeleteCommand = new Command2("delete").description("Delete a site and all its deployments").argument("<siteSlug>", "Site slug").requiredOption("--org <orgSlug>", "Organization slug").option("--force", "Skip confirmation prompt").action(async (siteSlug, options) => {
|
|
3306
|
+
const token = loadToken();
|
|
3307
|
+
if (!token) {
|
|
3308
|
+
console.log("Not logged in. Run: zerodeploy login");
|
|
3309
|
+
return;
|
|
3310
|
+
}
|
|
3311
|
+
if (!options.force) {
|
|
3312
|
+
const answer = await prompt2(`Are you sure you want to delete site "${siteSlug}" and all its deployments? This cannot be undone. (y/N) `);
|
|
3313
|
+
if (answer.toLowerCase() !== "y") {
|
|
3314
|
+
console.log("Cancelled.");
|
|
3315
|
+
return;
|
|
3316
|
+
}
|
|
3317
|
+
}
|
|
3318
|
+
try {
|
|
3319
|
+
const client = getClient(token);
|
|
3320
|
+
const res = await client.orgs[":orgSlug"].sites[":siteSlug"].$delete({
|
|
3321
|
+
param: { orgSlug: options.org, siteSlug }
|
|
3322
|
+
});
|
|
3323
|
+
if (!res.ok) {
|
|
3324
|
+
const error = await res.json();
|
|
3325
|
+
throw new Error(error.error || `API Error ${res.status}`);
|
|
3326
|
+
}
|
|
3327
|
+
const result = await res.json();
|
|
3328
|
+
console.log(`✅ ${result.message}`);
|
|
3329
|
+
} catch (err) {
|
|
3330
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
3331
|
+
console.error("Failed to delete site:", message);
|
|
3332
|
+
}
|
|
3333
|
+
});
|
|
3334
|
+
|
|
3335
|
+
// src/commands/site/link.ts
|
|
3336
|
+
var siteLinkCommand = new Command2("link").description("Link a site to a GitHub repository").argument("<orgSlug>", "Organization slug").argument("<siteSlug>", "Site slug").argument("<repo>", 'GitHub repository (e.g., "owner/repo")').action(async (orgSlug, siteSlug, repo) => {
|
|
3337
|
+
const token = loadToken();
|
|
3338
|
+
if (!token) {
|
|
3339
|
+
console.log("Not logged in. Run: zerodeploy login");
|
|
3340
|
+
return;
|
|
3341
|
+
}
|
|
3342
|
+
try {
|
|
3343
|
+
const res = await fetch(`${API_URL}/orgs/${orgSlug}/sites/${siteSlug}`, {
|
|
3344
|
+
method: "PATCH",
|
|
3345
|
+
headers: {
|
|
3346
|
+
"Content-Type": "application/json",
|
|
3347
|
+
Authorization: `Bearer ${token}`
|
|
3348
|
+
},
|
|
3349
|
+
body: JSON.stringify({ githubRepo: repo })
|
|
3350
|
+
});
|
|
3351
|
+
if (!res.ok) {
|
|
3352
|
+
const error = await res.json();
|
|
3353
|
+
console.log(`Error: ${error.error || "Failed to link repository"}`);
|
|
3354
|
+
return;
|
|
3355
|
+
}
|
|
3356
|
+
const site = await res.json();
|
|
3357
|
+
console.log(`Site "${site.name}" linked to ${site.github_repo}`);
|
|
3358
|
+
} catch (err) {
|
|
3359
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
3360
|
+
console.error("Failed to link repository:", message);
|
|
3361
|
+
}
|
|
3362
|
+
});
|
|
3363
|
+
var siteUnlinkCommand = new Command2("unlink").description("Unlink a site from its GitHub repository").argument("<orgSlug>", "Organization slug").argument("<siteSlug>", "Site slug").action(async (orgSlug, siteSlug) => {
|
|
3364
|
+
const token = loadToken();
|
|
3365
|
+
if (!token) {
|
|
3366
|
+
console.log("Not logged in. Run: zerodeploy login");
|
|
3367
|
+
return;
|
|
3368
|
+
}
|
|
3369
|
+
try {
|
|
3370
|
+
const res = await fetch(`${API_URL}/orgs/${orgSlug}/sites/${siteSlug}`, {
|
|
3371
|
+
method: "PATCH",
|
|
3372
|
+
headers: {
|
|
3373
|
+
"Content-Type": "application/json",
|
|
3374
|
+
Authorization: `Bearer ${token}`
|
|
3375
|
+
},
|
|
3376
|
+
body: JSON.stringify({ githubRepo: null })
|
|
3377
|
+
});
|
|
3378
|
+
if (!res.ok) {
|
|
3379
|
+
const error = await res.json();
|
|
3380
|
+
console.log(`Error: ${error.error || "Failed to unlink repository"}`);
|
|
3381
|
+
return;
|
|
3382
|
+
}
|
|
3383
|
+
const site = await res.json();
|
|
3384
|
+
console.log(`Site "${site.name}" unlinked from GitHub repository`);
|
|
3385
|
+
} catch (err) {
|
|
3386
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
3387
|
+
console.error("Failed to unlink repository:", message);
|
|
3388
|
+
}
|
|
3389
|
+
});
|
|
3390
|
+
|
|
3391
|
+
// src/commands/site/subdomain.ts
|
|
3392
|
+
var siteSubdomainCommand = new Command2("subdomain").description("Update the subdomain for a site").argument("<orgSlug>", "Organization slug").argument("<siteSlug>", "Site slug").argument("<subdomain>", "New subdomain").action(async (orgSlug, siteSlug, subdomain) => {
|
|
3393
|
+
const token = loadToken();
|
|
3394
|
+
if (!token) {
|
|
3395
|
+
console.log("Not logged in. Run: zerodeploy login");
|
|
3396
|
+
return;
|
|
3397
|
+
}
|
|
3398
|
+
try {
|
|
3399
|
+
const client = getClient(token);
|
|
3400
|
+
const res = await client.orgs[":orgSlug"].sites[":siteSlug"].subdomain.$patch({
|
|
3401
|
+
param: { orgSlug, siteSlug },
|
|
3402
|
+
json: { subdomain }
|
|
3403
|
+
});
|
|
3404
|
+
if (!res.ok) {
|
|
3405
|
+
const error = await res.json();
|
|
3406
|
+
throw new Error(error.error || `API Error ${res.status}`);
|
|
3407
|
+
}
|
|
3408
|
+
const site = await res.json();
|
|
3409
|
+
console.log(`✅ Updated subdomain for ${site.name}`);
|
|
3410
|
+
console.log(` New URL: ${site.subdomain}.zerodeploy.app`);
|
|
3411
|
+
} catch (err) {
|
|
3412
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
3413
|
+
console.error("Failed to update subdomain:", message);
|
|
3414
|
+
}
|
|
3415
|
+
});
|
|
3416
|
+
|
|
3417
|
+
// src/commands/site/index.ts
|
|
3418
|
+
var siteCommand = new Command2("site").description("Manage sites").addCommand(siteListCommand).addCommand(siteCreateCommand).addCommand(siteDeleteCommand).addCommand(siteLinkCommand).addCommand(siteUnlinkCommand).addCommand(siteSubdomainCommand);
|
|
3419
|
+
|
|
3420
|
+
// src/commands/domain/add.ts
|
|
3421
|
+
var domainAddCommand = new Command2("add").description("Add a custom domain to a site").argument("<domain>", "Domain to add (e.g., www.example.com)").requiredOption("--org <orgSlug>", "Organization slug").requiredOption("--site <siteSlug>", "Site slug").action(async (domain, options) => {
|
|
3422
|
+
const token = loadToken();
|
|
3423
|
+
if (!token) {
|
|
3424
|
+
console.log("Not logged in. Run: zerodeploy login");
|
|
3425
|
+
return;
|
|
3426
|
+
}
|
|
3427
|
+
try {
|
|
3428
|
+
const res = await fetch(`${API_URL}/orgs/${options.org}/sites/${options.site}/domains`, {
|
|
3429
|
+
method: "POST",
|
|
3430
|
+
headers: {
|
|
3431
|
+
Authorization: `Bearer ${token}`,
|
|
3432
|
+
"Content-Type": "application/json"
|
|
3433
|
+
},
|
|
3434
|
+
body: JSON.stringify({ domain })
|
|
3435
|
+
});
|
|
3436
|
+
if (!res.ok) {
|
|
3437
|
+
const error = await res.json();
|
|
3438
|
+
throw new Error(error.error || `API Error ${res.status}`);
|
|
3439
|
+
}
|
|
3440
|
+
const data = await res.json();
|
|
3441
|
+
console.log(`
|
|
3442
|
+
✅ Domain added: ${data.domain}`);
|
|
3443
|
+
console.log(` ID: ${data.id}`);
|
|
3444
|
+
console.log(` Status: ${data.verification_status}`);
|
|
3445
|
+
console.log();
|
|
3446
|
+
console.log("\uD83D\uDCCB DNS Verification Required");
|
|
3447
|
+
console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
|
|
3448
|
+
console.log();
|
|
3449
|
+
console.log("Add the following TXT record to your DNS:");
|
|
3450
|
+
console.log();
|
|
3451
|
+
console.log(` Type: ${data.verification.recordType}`);
|
|
3452
|
+
console.log(` Name: ${data.verification.recordName}`);
|
|
3453
|
+
console.log(` Value: ${data.verification.recordValue}`);
|
|
3454
|
+
console.log();
|
|
3455
|
+
console.log("After adding the record, run:");
|
|
3456
|
+
console.log(` zerodeploy domain verify ${data.id} --org ${options.org} --site ${options.site}`);
|
|
3457
|
+
console.log();
|
|
3458
|
+
} catch (err) {
|
|
3459
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
3460
|
+
console.error("Failed to add domain:", message);
|
|
3461
|
+
}
|
|
3462
|
+
});
|
|
3463
|
+
|
|
3464
|
+
// src/commands/domain/list.ts
|
|
3465
|
+
function formatStatus(status) {
|
|
3466
|
+
switch (status) {
|
|
3467
|
+
case "verified":
|
|
3468
|
+
return "✅ verified";
|
|
3469
|
+
case "pending":
|
|
3470
|
+
return "⏳ pending";
|
|
3471
|
+
case "failed":
|
|
3472
|
+
return "❌ failed";
|
|
3473
|
+
default:
|
|
3474
|
+
return status;
|
|
3475
|
+
}
|
|
3476
|
+
}
|
|
3477
|
+
var domainListCommand = new Command2("list").description("List custom domains for a site").requiredOption("--org <orgSlug>", "Organization slug").requiredOption("--site <siteSlug>", "Site slug").action(async (options) => {
|
|
3478
|
+
const token = loadToken();
|
|
3479
|
+
if (!token) {
|
|
3480
|
+
console.log("Not logged in. Run: zerodeploy login");
|
|
3481
|
+
return;
|
|
3482
|
+
}
|
|
3483
|
+
try {
|
|
3484
|
+
const res = await fetch(`${API_URL}/orgs/${options.org}/sites/${options.site}/domains`, {
|
|
3485
|
+
headers: {
|
|
3486
|
+
Authorization: `Bearer ${token}`
|
|
3487
|
+
}
|
|
3488
|
+
});
|
|
3489
|
+
if (!res.ok) {
|
|
3490
|
+
const error = await res.json();
|
|
3491
|
+
throw new Error(error.error || `API Error ${res.status}`);
|
|
3492
|
+
}
|
|
3493
|
+
const domains = await res.json();
|
|
3494
|
+
if (domains.length === 0) {
|
|
3495
|
+
console.log("No custom domains configured.");
|
|
3496
|
+
console.log();
|
|
3497
|
+
console.log("Add a domain with:");
|
|
3498
|
+
console.log(` zerodeploy domain add <domain> --org ${options.org} --site ${options.site}`);
|
|
3499
|
+
return;
|
|
3500
|
+
}
|
|
3501
|
+
console.log("Custom Domains:");
|
|
3502
|
+
console.log();
|
|
3503
|
+
for (const d of domains) {
|
|
3504
|
+
console.log(` ${d.domain.padEnd(30)} ${formatStatus(d.verification_status).padEnd(15)} ${d.id}`);
|
|
3505
|
+
}
|
|
3506
|
+
console.log();
|
|
3507
|
+
} catch (err) {
|
|
3508
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
3509
|
+
console.error("Failed to list domains:", message);
|
|
3510
|
+
}
|
|
3511
|
+
});
|
|
3512
|
+
|
|
3513
|
+
// src/commands/domain/verify.ts
|
|
3514
|
+
var domainVerifyCommand = new Command2("verify").description("Verify ownership of a custom domain").argument("<domainId>", "Domain ID to verify").requiredOption("--org <orgSlug>", "Organization slug").requiredOption("--site <siteSlug>", "Site slug").action(async (domainId, options) => {
|
|
3515
|
+
const token = loadToken();
|
|
3516
|
+
if (!token) {
|
|
3517
|
+
console.log("Not logged in. Run: zerodeploy login");
|
|
3518
|
+
return;
|
|
3519
|
+
}
|
|
3520
|
+
try {
|
|
3521
|
+
const res = await fetch(`${API_URL}/orgs/${options.org}/sites/${options.site}/domains/${domainId}/verify`, {
|
|
3522
|
+
method: "POST",
|
|
3523
|
+
headers: {
|
|
3524
|
+
Authorization: `Bearer ${token}`,
|
|
3525
|
+
"Content-Type": "application/json"
|
|
3526
|
+
}
|
|
3527
|
+
});
|
|
3528
|
+
const data = await res.json();
|
|
3529
|
+
if (!res.ok) {
|
|
3530
|
+
console.error(`
|
|
3531
|
+
❌ Verification failed for domain`);
|
|
3532
|
+
if (data.message) {
|
|
3533
|
+
console.log();
|
|
3534
|
+
console.log(data.message);
|
|
3535
|
+
}
|
|
3536
|
+
console.log();
|
|
3537
|
+
console.log("Tips:");
|
|
3538
|
+
console.log(" • DNS changes can take up to 48 hours to propagate");
|
|
3539
|
+
console.log(" • Verify the TXT record is set correctly using: dig TXT _zerodeploy.<domain>");
|
|
3540
|
+
console.log(" • Try again in a few minutes");
|
|
3541
|
+
return;
|
|
3542
|
+
}
|
|
3543
|
+
console.log(`
|
|
3544
|
+
✅ Domain verified: ${data.domain}`);
|
|
3545
|
+
console.log();
|
|
3546
|
+
if (data.cloudflare) {
|
|
3547
|
+
console.log(` Cloudflare SSL: ${data.cloudflare.status}`);
|
|
3548
|
+
console.log();
|
|
3549
|
+
}
|
|
3550
|
+
const domainParts = data.domain.split(".");
|
|
3551
|
+
const isApexDomain = domainParts.length === 2;
|
|
3552
|
+
const target = `${data.siteSubdomain || "your-site"}.zerodeploy.app`;
|
|
3553
|
+
console.log("\uD83D\uDCCB Final DNS Setup");
|
|
3554
|
+
console.log("━━━━━━━━━━━━━━━━━━━");
|
|
3555
|
+
console.log();
|
|
3556
|
+
if (isApexDomain) {
|
|
3557
|
+
console.log("For apex domains, DNS setup depends on your provider:");
|
|
3558
|
+
console.log();
|
|
3559
|
+
console.log("If using Cloudflare (recommended):");
|
|
3560
|
+
console.log(` Type: CNAME`);
|
|
3561
|
+
console.log(` Name: @ (or ${data.domain})`);
|
|
3562
|
+
console.log(` Target: ${target}`);
|
|
3563
|
+
console.log(` Proxy: ON (orange cloud)`);
|
|
3564
|
+
console.log();
|
|
3565
|
+
console.log(" Cloudflare supports CNAME flattening for apex domains.");
|
|
3566
|
+
console.log();
|
|
3567
|
+
console.log("If NOT using Cloudflare:");
|
|
3568
|
+
console.log(" Use ALIAS or ANAME record if your provider supports it,");
|
|
3569
|
+
console.log(` pointing to: ${target}`);
|
|
3570
|
+
console.log();
|
|
3571
|
+
} else {
|
|
3572
|
+
console.log("Add this CNAME record to point your domain to ZeroDeploy:");
|
|
3573
|
+
console.log();
|
|
3574
|
+
console.log(` Type: CNAME`);
|
|
3575
|
+
console.log(` Name: ${domainParts[0]}`);
|
|
3576
|
+
console.log(` Target: ${target}`);
|
|
3577
|
+
console.log(` Proxy: ON (orange cloud) - recommended if using Cloudflare`);
|
|
3578
|
+
console.log();
|
|
3579
|
+
}
|
|
3580
|
+
console.log(`Once DNS propagates, your site will be live at:`);
|
|
3581
|
+
console.log(` https://${data.domain}`);
|
|
3582
|
+
console.log();
|
|
3583
|
+
} catch (err) {
|
|
3584
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
3585
|
+
console.error("Failed to verify domain:", message);
|
|
3586
|
+
}
|
|
3587
|
+
});
|
|
3588
|
+
|
|
3589
|
+
// src/commands/domain/remove.ts
|
|
3590
|
+
var domainRemoveCommand = new Command2("remove").description("Remove a custom domain from a site").argument("<domainId>", "Domain ID to remove").requiredOption("--org <orgSlug>", "Organization slug").requiredOption("--site <siteSlug>", "Site slug").action(async (domainId, options) => {
|
|
3591
|
+
const token = loadToken();
|
|
3592
|
+
if (!token) {
|
|
3593
|
+
console.log("Not logged in. Run: zerodeploy login");
|
|
3594
|
+
return;
|
|
3595
|
+
}
|
|
3596
|
+
try {
|
|
3597
|
+
const res = await fetch(`${API_URL}/orgs/${options.org}/sites/${options.site}/domains/${domainId}`, {
|
|
3598
|
+
method: "DELETE",
|
|
3599
|
+
headers: {
|
|
3600
|
+
Authorization: `Bearer ${token}`
|
|
3601
|
+
}
|
|
3602
|
+
});
|
|
3603
|
+
if (!res.ok) {
|
|
3604
|
+
const error = await res.json();
|
|
3605
|
+
throw new Error(error.error || `API Error ${res.status}`);
|
|
3606
|
+
}
|
|
3607
|
+
const data = await res.json();
|
|
3608
|
+
console.log(`✅ ${data.message}`);
|
|
3609
|
+
} catch (err) {
|
|
3610
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
3611
|
+
console.error("Failed to remove domain:", message);
|
|
3612
|
+
}
|
|
3613
|
+
});
|
|
3614
|
+
|
|
3615
|
+
// src/commands/domain/index.ts
|
|
3616
|
+
var domainCommand = new Command2("domain").description("Manage custom domains").addCommand(domainAddCommand).addCommand(domainListCommand).addCommand(domainVerifyCommand).addCommand(domainRemoveCommand);
|
|
3617
|
+
|
|
3618
|
+
// src/commands/deploy/index.ts
|
|
3619
|
+
import { resolve as resolve3 } from "node:path";
|
|
3620
|
+
import { stat as stat2 } from "node:fs/promises";
|
|
3621
|
+
import { spawn } from "node:child_process";
|
|
3622
|
+
|
|
3623
|
+
// src/utils/files.ts
|
|
3624
|
+
import { readdir, stat, readFile } from "node:fs/promises";
|
|
3625
|
+
import { join, relative } from "node:path";
|
|
3626
|
+
var IGNORE_PATTERNS = [
|
|
3627
|
+
/^\.git$/,
|
|
3628
|
+
/^\.DS_Store$/,
|
|
3629
|
+
/^node_modules$/,
|
|
3630
|
+
/^\.env/,
|
|
3631
|
+
/^\.wrangler$/
|
|
3632
|
+
];
|
|
3633
|
+
function shouldIgnore(name) {
|
|
3634
|
+
return IGNORE_PATTERNS.some((pattern) => pattern.test(name));
|
|
3635
|
+
}
|
|
3636
|
+
async function scanDirectory(rootDir) {
|
|
3637
|
+
const files = [];
|
|
3638
|
+
async function scan(dir) {
|
|
3639
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
3640
|
+
for (const entry of entries) {
|
|
3641
|
+
if (shouldIgnore(entry.name))
|
|
3642
|
+
continue;
|
|
3643
|
+
const absolutePath = join(dir, entry.name);
|
|
3644
|
+
if (entry.isDirectory()) {
|
|
3645
|
+
await scan(absolutePath);
|
|
3646
|
+
} else if (entry.isFile()) {
|
|
3647
|
+
const stats = await stat(absolutePath);
|
|
3648
|
+
const relativePath = relative(rootDir, absolutePath);
|
|
3649
|
+
files.push({
|
|
3650
|
+
path: relativePath,
|
|
3651
|
+
absolutePath,
|
|
3652
|
+
size: stats.size
|
|
3653
|
+
});
|
|
3654
|
+
}
|
|
3655
|
+
}
|
|
3656
|
+
}
|
|
3657
|
+
await scan(rootDir);
|
|
3658
|
+
return files;
|
|
3659
|
+
}
|
|
3660
|
+
function formatBytes(bytes) {
|
|
3661
|
+
if (bytes === 0)
|
|
3662
|
+
return "0 B";
|
|
3663
|
+
const k = 1024;
|
|
3664
|
+
const sizes = ["B", "KB", "MB", "GB"];
|
|
3665
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
3666
|
+
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(1))} ${sizes[i]}`;
|
|
3667
|
+
}
|
|
3668
|
+
|
|
3669
|
+
// src/utils/framework.ts
|
|
3670
|
+
import { readFile as readFile2 } from "node:fs/promises";
|
|
3671
|
+
import { resolve } from "node:path";
|
|
3672
|
+
var FRAMEWORKS = [
|
|
3673
|
+
{
|
|
3674
|
+
name: "Vite",
|
|
3675
|
+
detect: (pkg) => hasDep(pkg, "vite"),
|
|
3676
|
+
buildCommand: "vite build",
|
|
3677
|
+
outputDir: "dist"
|
|
3678
|
+
},
|
|
3679
|
+
{
|
|
3680
|
+
name: "Next.js (Static)",
|
|
3681
|
+
detect: (pkg) => hasDep(pkg, "next"),
|
|
3682
|
+
buildCommand: "next build",
|
|
3683
|
+
outputDir: "out"
|
|
3684
|
+
},
|
|
3685
|
+
{
|
|
3686
|
+
name: "Create React App",
|
|
3687
|
+
detect: (pkg) => hasDep(pkg, "react-scripts"),
|
|
3688
|
+
buildCommand: "react-scripts build",
|
|
3689
|
+
outputDir: "build"
|
|
3690
|
+
},
|
|
3691
|
+
{
|
|
3692
|
+
name: "Vue CLI",
|
|
3693
|
+
detect: (pkg) => hasDep(pkg, "@vue/cli-service"),
|
|
3694
|
+
buildCommand: "vue-cli-service build",
|
|
3695
|
+
outputDir: "dist"
|
|
3696
|
+
},
|
|
3697
|
+
{
|
|
3698
|
+
name: "Nuxt",
|
|
3699
|
+
detect: (pkg) => hasDep(pkg, "nuxt"),
|
|
3700
|
+
buildCommand: "nuxt generate",
|
|
3701
|
+
outputDir: "dist"
|
|
3702
|
+
},
|
|
3703
|
+
{
|
|
3704
|
+
name: "Astro",
|
|
3705
|
+
detect: (pkg) => hasDep(pkg, "astro"),
|
|
3706
|
+
buildCommand: "astro build",
|
|
3707
|
+
outputDir: "dist"
|
|
3708
|
+
},
|
|
3709
|
+
{
|
|
3710
|
+
name: "SvelteKit",
|
|
3711
|
+
detect: (pkg) => hasDep(pkg, "@sveltejs/kit"),
|
|
3712
|
+
buildCommand: "vite build",
|
|
3713
|
+
outputDir: "build"
|
|
3714
|
+
},
|
|
3715
|
+
{
|
|
3716
|
+
name: "Gatsby",
|
|
3717
|
+
detect: (pkg) => hasDep(pkg, "gatsby"),
|
|
3718
|
+
buildCommand: "gatsby build",
|
|
3719
|
+
outputDir: "public"
|
|
3720
|
+
},
|
|
3721
|
+
{
|
|
3722
|
+
name: "Remix",
|
|
3723
|
+
detect: (pkg) => hasDep(pkg, "@remix-run/dev"),
|
|
3724
|
+
buildCommand: "remix build",
|
|
3725
|
+
outputDir: "public/build"
|
|
3726
|
+
},
|
|
3727
|
+
{
|
|
3728
|
+
name: "Parcel",
|
|
3729
|
+
detect: (pkg) => hasDep(pkg, "parcel"),
|
|
3730
|
+
buildCommand: "parcel build",
|
|
3731
|
+
outputDir: "dist"
|
|
3732
|
+
},
|
|
3733
|
+
{
|
|
3734
|
+
name: "Webpack",
|
|
3735
|
+
detect: (pkg) => hasDep(pkg, "webpack") && !hasDep(pkg, "react-scripts"),
|
|
3736
|
+
buildCommand: "webpack --mode production",
|
|
3737
|
+
outputDir: "dist"
|
|
3738
|
+
}
|
|
3739
|
+
];
|
|
3740
|
+
function hasDep(pkg, dep) {
|
|
3741
|
+
return !!(pkg.dependencies?.[dep] || pkg.devDependencies?.[dep]);
|
|
3742
|
+
}
|
|
3743
|
+
async function detectFramework(cwd) {
|
|
3744
|
+
try {
|
|
3745
|
+
const pkgPath = resolve(cwd, "package.json");
|
|
3746
|
+
const pkgContent = await readFile2(pkgPath, "utf-8");
|
|
3747
|
+
const pkg = JSON.parse(pkgContent);
|
|
3748
|
+
for (const framework of FRAMEWORKS) {
|
|
3749
|
+
if (framework.detect(pkg)) {
|
|
3750
|
+
const buildScript = pkg.scripts?.build;
|
|
3751
|
+
const buildCommand = buildScript ? "npm run build" : `npx ${framework.buildCommand}`;
|
|
3752
|
+
return {
|
|
3753
|
+
name: framework.name,
|
|
3754
|
+
buildCommand,
|
|
3755
|
+
outputDir: framework.outputDir,
|
|
3756
|
+
installCommand: detectPackageManager(cwd)
|
|
3757
|
+
};
|
|
3758
|
+
}
|
|
3759
|
+
}
|
|
3760
|
+
if (pkg.scripts?.build) {
|
|
3761
|
+
return {
|
|
3762
|
+
name: "Generic",
|
|
3763
|
+
buildCommand: "npm run build",
|
|
3764
|
+
outputDir: "dist",
|
|
3765
|
+
installCommand: detectPackageManager(cwd)
|
|
3766
|
+
};
|
|
3767
|
+
}
|
|
3768
|
+
return null;
|
|
3769
|
+
} catch {
|
|
3770
|
+
return null;
|
|
3771
|
+
}
|
|
3772
|
+
}
|
|
3773
|
+
function detectPackageManager(cwd) {
|
|
3774
|
+
return "bun install";
|
|
3775
|
+
}
|
|
3776
|
+
|
|
3777
|
+
// ../../node_modules/.bun/fflate@0.8.2/node_modules/fflate/esm/index.mjs
|
|
3778
|
+
import { createRequire as createRequire2 } from "module";
|
|
3779
|
+
var require2 = createRequire2("/");
|
|
3780
|
+
var Worker;
|
|
3781
|
+
try {
|
|
3782
|
+
Worker = require2("worker_threads").Worker;
|
|
3783
|
+
} catch (e) {}
|
|
3784
|
+
var u8 = Uint8Array;
|
|
3785
|
+
var u16 = Uint16Array;
|
|
3786
|
+
var i32 = Int32Array;
|
|
3787
|
+
var fleb = new u8([0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 0, 0, 0]);
|
|
3788
|
+
var fdeb = new u8([0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 0, 0]);
|
|
3789
|
+
var clim = new u8([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]);
|
|
3790
|
+
var freb = function(eb, start) {
|
|
3791
|
+
var b = new u16(31);
|
|
3792
|
+
for (var i = 0;i < 31; ++i) {
|
|
3793
|
+
b[i] = start += 1 << eb[i - 1];
|
|
3794
|
+
}
|
|
3795
|
+
var r = new i32(b[30]);
|
|
3796
|
+
for (var i = 1;i < 30; ++i) {
|
|
3797
|
+
for (var j = b[i];j < b[i + 1]; ++j) {
|
|
3798
|
+
r[j] = j - b[i] << 5 | i;
|
|
3799
|
+
}
|
|
3800
|
+
}
|
|
3801
|
+
return { b, r };
|
|
3802
|
+
};
|
|
3803
|
+
var _a = freb(fleb, 2);
|
|
3804
|
+
var fl = _a.b;
|
|
3805
|
+
var revfl = _a.r;
|
|
3806
|
+
fl[28] = 258, revfl[258] = 28;
|
|
3807
|
+
var _b = freb(fdeb, 0);
|
|
3808
|
+
var fd = _b.b;
|
|
3809
|
+
var revfd = _b.r;
|
|
3810
|
+
var rev = new u16(32768);
|
|
3811
|
+
for (i = 0;i < 32768; ++i) {
|
|
3812
|
+
x = (i & 43690) >> 1 | (i & 21845) << 1;
|
|
3813
|
+
x = (x & 52428) >> 2 | (x & 13107) << 2;
|
|
3814
|
+
x = (x & 61680) >> 4 | (x & 3855) << 4;
|
|
3815
|
+
rev[i] = ((x & 65280) >> 8 | (x & 255) << 8) >> 1;
|
|
3816
|
+
}
|
|
3817
|
+
var x;
|
|
3818
|
+
var i;
|
|
3819
|
+
var hMap = function(cd, mb, r) {
|
|
3820
|
+
var s = cd.length;
|
|
3821
|
+
var i2 = 0;
|
|
3822
|
+
var l = new u16(mb);
|
|
3823
|
+
for (;i2 < s; ++i2) {
|
|
3824
|
+
if (cd[i2])
|
|
3825
|
+
++l[cd[i2] - 1];
|
|
3826
|
+
}
|
|
3827
|
+
var le = new u16(mb);
|
|
3828
|
+
for (i2 = 1;i2 < mb; ++i2) {
|
|
3829
|
+
le[i2] = le[i2 - 1] + l[i2 - 1] << 1;
|
|
3830
|
+
}
|
|
3831
|
+
var co;
|
|
3832
|
+
if (r) {
|
|
3833
|
+
co = new u16(1 << mb);
|
|
3834
|
+
var rvb = 15 - mb;
|
|
3835
|
+
for (i2 = 0;i2 < s; ++i2) {
|
|
3836
|
+
if (cd[i2]) {
|
|
3837
|
+
var sv = i2 << 4 | cd[i2];
|
|
3838
|
+
var r_1 = mb - cd[i2];
|
|
3839
|
+
var v = le[cd[i2] - 1]++ << r_1;
|
|
3840
|
+
for (var m = v | (1 << r_1) - 1;v <= m; ++v) {
|
|
3841
|
+
co[rev[v] >> rvb] = sv;
|
|
3842
|
+
}
|
|
3843
|
+
}
|
|
3844
|
+
}
|
|
3845
|
+
} else {
|
|
3846
|
+
co = new u16(s);
|
|
3847
|
+
for (i2 = 0;i2 < s; ++i2) {
|
|
3848
|
+
if (cd[i2]) {
|
|
3849
|
+
co[i2] = rev[le[cd[i2] - 1]++] >> 15 - cd[i2];
|
|
3850
|
+
}
|
|
3851
|
+
}
|
|
3852
|
+
}
|
|
3853
|
+
return co;
|
|
3854
|
+
};
|
|
3855
|
+
var flt = new u8(288);
|
|
3856
|
+
for (i = 0;i < 144; ++i)
|
|
3857
|
+
flt[i] = 8;
|
|
3858
|
+
var i;
|
|
3859
|
+
for (i = 144;i < 256; ++i)
|
|
3860
|
+
flt[i] = 9;
|
|
3861
|
+
var i;
|
|
3862
|
+
for (i = 256;i < 280; ++i)
|
|
3863
|
+
flt[i] = 7;
|
|
3864
|
+
var i;
|
|
3865
|
+
for (i = 280;i < 288; ++i)
|
|
3866
|
+
flt[i] = 8;
|
|
3867
|
+
var i;
|
|
3868
|
+
var fdt = new u8(32);
|
|
3869
|
+
for (i = 0;i < 32; ++i)
|
|
3870
|
+
fdt[i] = 5;
|
|
3871
|
+
var i;
|
|
3872
|
+
var flm = /* @__PURE__ */ hMap(flt, 9, 0);
|
|
3873
|
+
var fdm = /* @__PURE__ */ hMap(fdt, 5, 0);
|
|
3874
|
+
var shft = function(p) {
|
|
3875
|
+
return (p + 7) / 8 | 0;
|
|
3876
|
+
};
|
|
3877
|
+
var slc = function(v, s, e) {
|
|
3878
|
+
if (s == null || s < 0)
|
|
3879
|
+
s = 0;
|
|
3880
|
+
if (e == null || e > v.length)
|
|
3881
|
+
e = v.length;
|
|
3882
|
+
return new u8(v.subarray(s, e));
|
|
3883
|
+
};
|
|
3884
|
+
var wbits = function(d, p, v) {
|
|
3885
|
+
v <<= p & 7;
|
|
3886
|
+
var o = p / 8 | 0;
|
|
3887
|
+
d[o] |= v;
|
|
3888
|
+
d[o + 1] |= v >> 8;
|
|
3889
|
+
};
|
|
3890
|
+
var wbits16 = function(d, p, v) {
|
|
3891
|
+
v <<= p & 7;
|
|
3892
|
+
var o = p / 8 | 0;
|
|
3893
|
+
d[o] |= v;
|
|
3894
|
+
d[o + 1] |= v >> 8;
|
|
3895
|
+
d[o + 2] |= v >> 16;
|
|
3896
|
+
};
|
|
3897
|
+
var hTree = function(d, mb) {
|
|
3898
|
+
var t = [];
|
|
3899
|
+
for (var i2 = 0;i2 < d.length; ++i2) {
|
|
3900
|
+
if (d[i2])
|
|
3901
|
+
t.push({ s: i2, f: d[i2] });
|
|
3902
|
+
}
|
|
3903
|
+
var s = t.length;
|
|
3904
|
+
var t2 = t.slice();
|
|
3905
|
+
if (!s)
|
|
3906
|
+
return { t: et, l: 0 };
|
|
3907
|
+
if (s == 1) {
|
|
3908
|
+
var v = new u8(t[0].s + 1);
|
|
3909
|
+
v[t[0].s] = 1;
|
|
3910
|
+
return { t: v, l: 1 };
|
|
3911
|
+
}
|
|
3912
|
+
t.sort(function(a, b) {
|
|
3913
|
+
return a.f - b.f;
|
|
3914
|
+
});
|
|
3915
|
+
t.push({ s: -1, f: 25001 });
|
|
3916
|
+
var l = t[0], r = t[1], i0 = 0, i1 = 1, i22 = 2;
|
|
3917
|
+
t[0] = { s: -1, f: l.f + r.f, l, r };
|
|
3918
|
+
while (i1 != s - 1) {
|
|
3919
|
+
l = t[t[i0].f < t[i22].f ? i0++ : i22++];
|
|
3920
|
+
r = t[i0 != i1 && t[i0].f < t[i22].f ? i0++ : i22++];
|
|
3921
|
+
t[i1++] = { s: -1, f: l.f + r.f, l, r };
|
|
3922
|
+
}
|
|
3923
|
+
var maxSym = t2[0].s;
|
|
3924
|
+
for (var i2 = 1;i2 < s; ++i2) {
|
|
3925
|
+
if (t2[i2].s > maxSym)
|
|
3926
|
+
maxSym = t2[i2].s;
|
|
3927
|
+
}
|
|
3928
|
+
var tr = new u16(maxSym + 1);
|
|
3929
|
+
var mbt = ln(t[i1 - 1], tr, 0);
|
|
3930
|
+
if (mbt > mb) {
|
|
3931
|
+
var i2 = 0, dt = 0;
|
|
3932
|
+
var lft = mbt - mb, cst = 1 << lft;
|
|
3933
|
+
t2.sort(function(a, b) {
|
|
3934
|
+
return tr[b.s] - tr[a.s] || a.f - b.f;
|
|
3935
|
+
});
|
|
3936
|
+
for (;i2 < s; ++i2) {
|
|
3937
|
+
var i2_1 = t2[i2].s;
|
|
3938
|
+
if (tr[i2_1] > mb) {
|
|
3939
|
+
dt += cst - (1 << mbt - tr[i2_1]);
|
|
3940
|
+
tr[i2_1] = mb;
|
|
3941
|
+
} else
|
|
3942
|
+
break;
|
|
3943
|
+
}
|
|
3944
|
+
dt >>= lft;
|
|
3945
|
+
while (dt > 0) {
|
|
3946
|
+
var i2_2 = t2[i2].s;
|
|
3947
|
+
if (tr[i2_2] < mb)
|
|
3948
|
+
dt -= 1 << mb - tr[i2_2]++ - 1;
|
|
3949
|
+
else
|
|
3950
|
+
++i2;
|
|
3951
|
+
}
|
|
3952
|
+
for (;i2 >= 0 && dt; --i2) {
|
|
3953
|
+
var i2_3 = t2[i2].s;
|
|
3954
|
+
if (tr[i2_3] == mb) {
|
|
3955
|
+
--tr[i2_3];
|
|
3956
|
+
++dt;
|
|
3957
|
+
}
|
|
3958
|
+
}
|
|
3959
|
+
mbt = mb;
|
|
3960
|
+
}
|
|
3961
|
+
return { t: new u8(tr), l: mbt };
|
|
3962
|
+
};
|
|
3963
|
+
var ln = function(n, l, d) {
|
|
3964
|
+
return n.s == -1 ? Math.max(ln(n.l, l, d + 1), ln(n.r, l, d + 1)) : l[n.s] = d;
|
|
3965
|
+
};
|
|
3966
|
+
var lc = function(c) {
|
|
3967
|
+
var s = c.length;
|
|
3968
|
+
while (s && !c[--s])
|
|
3969
|
+
;
|
|
3970
|
+
var cl = new u16(++s);
|
|
3971
|
+
var cli = 0, cln = c[0], cls = 1;
|
|
3972
|
+
var w = function(v) {
|
|
3973
|
+
cl[cli++] = v;
|
|
3974
|
+
};
|
|
3975
|
+
for (var i2 = 1;i2 <= s; ++i2) {
|
|
3976
|
+
if (c[i2] == cln && i2 != s)
|
|
3977
|
+
++cls;
|
|
3978
|
+
else {
|
|
3979
|
+
if (!cln && cls > 2) {
|
|
3980
|
+
for (;cls > 138; cls -= 138)
|
|
3981
|
+
w(32754);
|
|
3982
|
+
if (cls > 2) {
|
|
3983
|
+
w(cls > 10 ? cls - 11 << 5 | 28690 : cls - 3 << 5 | 12305);
|
|
3984
|
+
cls = 0;
|
|
3985
|
+
}
|
|
3986
|
+
} else if (cls > 3) {
|
|
3987
|
+
w(cln), --cls;
|
|
3988
|
+
for (;cls > 6; cls -= 6)
|
|
3989
|
+
w(8304);
|
|
3990
|
+
if (cls > 2)
|
|
3991
|
+
w(cls - 3 << 5 | 8208), cls = 0;
|
|
3992
|
+
}
|
|
3993
|
+
while (cls--)
|
|
3994
|
+
w(cln);
|
|
3995
|
+
cls = 1;
|
|
3996
|
+
cln = c[i2];
|
|
3997
|
+
}
|
|
3998
|
+
}
|
|
3999
|
+
return { c: cl.subarray(0, cli), n: s };
|
|
4000
|
+
};
|
|
4001
|
+
var clen = function(cf, cl) {
|
|
4002
|
+
var l = 0;
|
|
4003
|
+
for (var i2 = 0;i2 < cl.length; ++i2)
|
|
4004
|
+
l += cf[i2] * cl[i2];
|
|
4005
|
+
return l;
|
|
4006
|
+
};
|
|
4007
|
+
var wfblk = function(out, pos, dat) {
|
|
4008
|
+
var s = dat.length;
|
|
4009
|
+
var o = shft(pos + 2);
|
|
4010
|
+
out[o] = s & 255;
|
|
4011
|
+
out[o + 1] = s >> 8;
|
|
4012
|
+
out[o + 2] = out[o] ^ 255;
|
|
4013
|
+
out[o + 3] = out[o + 1] ^ 255;
|
|
4014
|
+
for (var i2 = 0;i2 < s; ++i2)
|
|
4015
|
+
out[o + i2 + 4] = dat[i2];
|
|
4016
|
+
return (o + 4 + s) * 8;
|
|
4017
|
+
};
|
|
4018
|
+
var wblk = function(dat, out, final, syms, lf, df, eb, li, bs, bl, p) {
|
|
4019
|
+
wbits(out, p++, final);
|
|
4020
|
+
++lf[256];
|
|
4021
|
+
var _a2 = hTree(lf, 15), dlt = _a2.t, mlb = _a2.l;
|
|
4022
|
+
var _b2 = hTree(df, 15), ddt = _b2.t, mdb = _b2.l;
|
|
4023
|
+
var _c = lc(dlt), lclt = _c.c, nlc = _c.n;
|
|
4024
|
+
var _d = lc(ddt), lcdt = _d.c, ndc = _d.n;
|
|
4025
|
+
var lcfreq = new u16(19);
|
|
4026
|
+
for (var i2 = 0;i2 < lclt.length; ++i2)
|
|
4027
|
+
++lcfreq[lclt[i2] & 31];
|
|
4028
|
+
for (var i2 = 0;i2 < lcdt.length; ++i2)
|
|
4029
|
+
++lcfreq[lcdt[i2] & 31];
|
|
4030
|
+
var _e = hTree(lcfreq, 7), lct = _e.t, mlcb = _e.l;
|
|
4031
|
+
var nlcc = 19;
|
|
4032
|
+
for (;nlcc > 4 && !lct[clim[nlcc - 1]]; --nlcc)
|
|
4033
|
+
;
|
|
4034
|
+
var flen = bl + 5 << 3;
|
|
4035
|
+
var ftlen = clen(lf, flt) + clen(df, fdt) + eb;
|
|
4036
|
+
var dtlen = clen(lf, dlt) + clen(df, ddt) + eb + 14 + 3 * nlcc + clen(lcfreq, lct) + 2 * lcfreq[16] + 3 * lcfreq[17] + 7 * lcfreq[18];
|
|
4037
|
+
if (bs >= 0 && flen <= ftlen && flen <= dtlen)
|
|
4038
|
+
return wfblk(out, p, dat.subarray(bs, bs + bl));
|
|
4039
|
+
var lm, ll, dm, dl;
|
|
4040
|
+
wbits(out, p, 1 + (dtlen < ftlen)), p += 2;
|
|
4041
|
+
if (dtlen < ftlen) {
|
|
4042
|
+
lm = hMap(dlt, mlb, 0), ll = dlt, dm = hMap(ddt, mdb, 0), dl = ddt;
|
|
4043
|
+
var llm = hMap(lct, mlcb, 0);
|
|
4044
|
+
wbits(out, p, nlc - 257);
|
|
4045
|
+
wbits(out, p + 5, ndc - 1);
|
|
4046
|
+
wbits(out, p + 10, nlcc - 4);
|
|
4047
|
+
p += 14;
|
|
4048
|
+
for (var i2 = 0;i2 < nlcc; ++i2)
|
|
4049
|
+
wbits(out, p + 3 * i2, lct[clim[i2]]);
|
|
4050
|
+
p += 3 * nlcc;
|
|
4051
|
+
var lcts = [lclt, lcdt];
|
|
4052
|
+
for (var it = 0;it < 2; ++it) {
|
|
4053
|
+
var clct = lcts[it];
|
|
4054
|
+
for (var i2 = 0;i2 < clct.length; ++i2) {
|
|
4055
|
+
var len = clct[i2] & 31;
|
|
4056
|
+
wbits(out, p, llm[len]), p += lct[len];
|
|
4057
|
+
if (len > 15)
|
|
4058
|
+
wbits(out, p, clct[i2] >> 5 & 127), p += clct[i2] >> 12;
|
|
4059
|
+
}
|
|
4060
|
+
}
|
|
4061
|
+
} else {
|
|
4062
|
+
lm = flm, ll = flt, dm = fdm, dl = fdt;
|
|
4063
|
+
}
|
|
4064
|
+
for (var i2 = 0;i2 < li; ++i2) {
|
|
4065
|
+
var sym = syms[i2];
|
|
4066
|
+
if (sym > 255) {
|
|
4067
|
+
var len = sym >> 18 & 31;
|
|
4068
|
+
wbits16(out, p, lm[len + 257]), p += ll[len + 257];
|
|
4069
|
+
if (len > 7)
|
|
4070
|
+
wbits(out, p, sym >> 23 & 31), p += fleb[len];
|
|
4071
|
+
var dst = sym & 31;
|
|
4072
|
+
wbits16(out, p, dm[dst]), p += dl[dst];
|
|
4073
|
+
if (dst > 3)
|
|
4074
|
+
wbits16(out, p, sym >> 5 & 8191), p += fdeb[dst];
|
|
4075
|
+
} else {
|
|
4076
|
+
wbits16(out, p, lm[sym]), p += ll[sym];
|
|
4077
|
+
}
|
|
4078
|
+
}
|
|
4079
|
+
wbits16(out, p, lm[256]);
|
|
4080
|
+
return p + ll[256];
|
|
4081
|
+
};
|
|
4082
|
+
var deo = /* @__PURE__ */ new i32([65540, 131080, 131088, 131104, 262176, 1048704, 1048832, 2114560, 2117632]);
|
|
4083
|
+
var et = /* @__PURE__ */ new u8(0);
|
|
4084
|
+
var dflt = function(dat, lvl, plvl, pre, post, st) {
|
|
4085
|
+
var s = st.z || dat.length;
|
|
4086
|
+
var o = new u8(pre + s + 5 * (1 + Math.ceil(s / 7000)) + post);
|
|
4087
|
+
var w = o.subarray(pre, o.length - post);
|
|
4088
|
+
var lst = st.l;
|
|
4089
|
+
var pos = (st.r || 0) & 7;
|
|
4090
|
+
if (lvl) {
|
|
4091
|
+
if (pos)
|
|
4092
|
+
w[0] = st.r >> 3;
|
|
4093
|
+
var opt = deo[lvl - 1];
|
|
4094
|
+
var n = opt >> 13, c = opt & 8191;
|
|
4095
|
+
var msk_1 = (1 << plvl) - 1;
|
|
4096
|
+
var prev = st.p || new u16(32768), head = st.h || new u16(msk_1 + 1);
|
|
4097
|
+
var bs1_1 = Math.ceil(plvl / 3), bs2_1 = 2 * bs1_1;
|
|
4098
|
+
var hsh = function(i3) {
|
|
4099
|
+
return (dat[i3] ^ dat[i3 + 1] << bs1_1 ^ dat[i3 + 2] << bs2_1) & msk_1;
|
|
4100
|
+
};
|
|
4101
|
+
var syms = new i32(25000);
|
|
4102
|
+
var lf = new u16(288), df = new u16(32);
|
|
4103
|
+
var lc_1 = 0, eb = 0, i2 = st.i || 0, li = 0, wi = st.w || 0, bs = 0;
|
|
4104
|
+
for (;i2 + 2 < s; ++i2) {
|
|
4105
|
+
var hv = hsh(i2);
|
|
4106
|
+
var imod = i2 & 32767, pimod = head[hv];
|
|
4107
|
+
prev[imod] = pimod;
|
|
4108
|
+
head[hv] = imod;
|
|
4109
|
+
if (wi <= i2) {
|
|
4110
|
+
var rem = s - i2;
|
|
4111
|
+
if ((lc_1 > 7000 || li > 24576) && (rem > 423 || !lst)) {
|
|
4112
|
+
pos = wblk(dat, w, 0, syms, lf, df, eb, li, bs, i2 - bs, pos);
|
|
4113
|
+
li = lc_1 = eb = 0, bs = i2;
|
|
4114
|
+
for (var j = 0;j < 286; ++j)
|
|
4115
|
+
lf[j] = 0;
|
|
4116
|
+
for (var j = 0;j < 30; ++j)
|
|
4117
|
+
df[j] = 0;
|
|
4118
|
+
}
|
|
4119
|
+
var l = 2, d = 0, ch_1 = c, dif = imod - pimod & 32767;
|
|
4120
|
+
if (rem > 2 && hv == hsh(i2 - dif)) {
|
|
4121
|
+
var maxn = Math.min(n, rem) - 1;
|
|
4122
|
+
var maxd = Math.min(32767, i2);
|
|
4123
|
+
var ml = Math.min(258, rem);
|
|
4124
|
+
while (dif <= maxd && --ch_1 && imod != pimod) {
|
|
4125
|
+
if (dat[i2 + l] == dat[i2 + l - dif]) {
|
|
4126
|
+
var nl = 0;
|
|
4127
|
+
for (;nl < ml && dat[i2 + nl] == dat[i2 + nl - dif]; ++nl)
|
|
4128
|
+
;
|
|
4129
|
+
if (nl > l) {
|
|
4130
|
+
l = nl, d = dif;
|
|
4131
|
+
if (nl > maxn)
|
|
4132
|
+
break;
|
|
4133
|
+
var mmd = Math.min(dif, nl - 2);
|
|
4134
|
+
var md = 0;
|
|
4135
|
+
for (var j = 0;j < mmd; ++j) {
|
|
4136
|
+
var ti = i2 - dif + j & 32767;
|
|
4137
|
+
var pti = prev[ti];
|
|
4138
|
+
var cd = ti - pti & 32767;
|
|
4139
|
+
if (cd > md)
|
|
4140
|
+
md = cd, pimod = ti;
|
|
4141
|
+
}
|
|
4142
|
+
}
|
|
4143
|
+
}
|
|
4144
|
+
imod = pimod, pimod = prev[imod];
|
|
4145
|
+
dif += imod - pimod & 32767;
|
|
4146
|
+
}
|
|
4147
|
+
}
|
|
4148
|
+
if (d) {
|
|
4149
|
+
syms[li++] = 268435456 | revfl[l] << 18 | revfd[d];
|
|
4150
|
+
var lin = revfl[l] & 31, din = revfd[d] & 31;
|
|
4151
|
+
eb += fleb[lin] + fdeb[din];
|
|
4152
|
+
++lf[257 + lin];
|
|
4153
|
+
++df[din];
|
|
4154
|
+
wi = i2 + l;
|
|
4155
|
+
++lc_1;
|
|
4156
|
+
} else {
|
|
4157
|
+
syms[li++] = dat[i2];
|
|
4158
|
+
++lf[dat[i2]];
|
|
4159
|
+
}
|
|
4160
|
+
}
|
|
4161
|
+
}
|
|
4162
|
+
for (i2 = Math.max(i2, wi);i2 < s; ++i2) {
|
|
4163
|
+
syms[li++] = dat[i2];
|
|
4164
|
+
++lf[dat[i2]];
|
|
4165
|
+
}
|
|
4166
|
+
pos = wblk(dat, w, lst, syms, lf, df, eb, li, bs, i2 - bs, pos);
|
|
4167
|
+
if (!lst) {
|
|
4168
|
+
st.r = pos & 7 | w[pos / 8 | 0] << 3;
|
|
4169
|
+
pos -= 7;
|
|
4170
|
+
st.h = head, st.p = prev, st.i = i2, st.w = wi;
|
|
4171
|
+
}
|
|
4172
|
+
} else {
|
|
4173
|
+
for (var i2 = st.w || 0;i2 < s + lst; i2 += 65535) {
|
|
4174
|
+
var e = i2 + 65535;
|
|
4175
|
+
if (e >= s) {
|
|
4176
|
+
w[pos / 8 | 0] = lst;
|
|
4177
|
+
e = s;
|
|
4178
|
+
}
|
|
4179
|
+
pos = wfblk(w, pos + 1, dat.subarray(i2, e));
|
|
4180
|
+
}
|
|
4181
|
+
st.i = s;
|
|
4182
|
+
}
|
|
4183
|
+
return slc(o, 0, pre + shft(pos) + post);
|
|
4184
|
+
};
|
|
4185
|
+
var crct = /* @__PURE__ */ function() {
|
|
4186
|
+
var t = new Int32Array(256);
|
|
4187
|
+
for (var i2 = 0;i2 < 256; ++i2) {
|
|
4188
|
+
var c = i2, k = 9;
|
|
4189
|
+
while (--k)
|
|
4190
|
+
c = (c & 1 && -306674912) ^ c >>> 1;
|
|
4191
|
+
t[i2] = c;
|
|
4192
|
+
}
|
|
4193
|
+
return t;
|
|
4194
|
+
}();
|
|
4195
|
+
var crc = function() {
|
|
4196
|
+
var c = -1;
|
|
4197
|
+
return {
|
|
4198
|
+
p: function(d) {
|
|
4199
|
+
var cr = c;
|
|
4200
|
+
for (var i2 = 0;i2 < d.length; ++i2)
|
|
4201
|
+
cr = crct[cr & 255 ^ d[i2]] ^ cr >>> 8;
|
|
4202
|
+
c = cr;
|
|
4203
|
+
},
|
|
4204
|
+
d: function() {
|
|
4205
|
+
return ~c;
|
|
4206
|
+
}
|
|
4207
|
+
};
|
|
4208
|
+
};
|
|
4209
|
+
var dopt = function(dat, opt, pre, post, st) {
|
|
4210
|
+
if (!st) {
|
|
4211
|
+
st = { l: 1 };
|
|
4212
|
+
if (opt.dictionary) {
|
|
4213
|
+
var dict = opt.dictionary.subarray(-32768);
|
|
4214
|
+
var newDat = new u8(dict.length + dat.length);
|
|
4215
|
+
newDat.set(dict);
|
|
4216
|
+
newDat.set(dat, dict.length);
|
|
4217
|
+
dat = newDat;
|
|
4218
|
+
st.w = dict.length;
|
|
4219
|
+
}
|
|
4220
|
+
}
|
|
4221
|
+
return dflt(dat, opt.level == null ? 6 : opt.level, opt.mem == null ? st.l ? Math.ceil(Math.max(8, Math.min(13, Math.log(dat.length))) * 1.5) : 20 : 12 + opt.mem, pre, post, st);
|
|
4222
|
+
};
|
|
4223
|
+
var wbytes = function(d, b, v) {
|
|
4224
|
+
for (;v; ++b)
|
|
4225
|
+
d[b] = v, v >>>= 8;
|
|
4226
|
+
};
|
|
4227
|
+
var gzh = function(c, o) {
|
|
4228
|
+
var fn = o.filename;
|
|
4229
|
+
c[0] = 31, c[1] = 139, c[2] = 8, c[8] = o.level < 2 ? 4 : o.level == 9 ? 2 : 0, c[9] = 3;
|
|
4230
|
+
if (o.mtime != 0)
|
|
4231
|
+
wbytes(c, 4, Math.floor(new Date(o.mtime || Date.now()) / 1000));
|
|
4232
|
+
if (fn) {
|
|
4233
|
+
c[3] = 8;
|
|
4234
|
+
for (var i2 = 0;i2 <= fn.length; ++i2)
|
|
4235
|
+
c[i2 + 10] = fn.charCodeAt(i2);
|
|
4236
|
+
}
|
|
4237
|
+
};
|
|
4238
|
+
var gzhl = function(o) {
|
|
4239
|
+
return 10 + (o.filename ? o.filename.length + 1 : 0);
|
|
4240
|
+
};
|
|
4241
|
+
function gzipSync(data, opts) {
|
|
4242
|
+
if (!opts)
|
|
4243
|
+
opts = {};
|
|
4244
|
+
var c = crc(), l = data.length;
|
|
4245
|
+
c.p(data);
|
|
4246
|
+
var d = dopt(data, opts, gzhl(opts), 8), s = d.length;
|
|
4247
|
+
return gzh(d, opts), wbytes(d, s - 8, c.d()), wbytes(d, s - 4, l), d;
|
|
4248
|
+
}
|
|
4249
|
+
var td = typeof TextDecoder != "undefined" && /* @__PURE__ */ new TextDecoder;
|
|
4250
|
+
var tds = 0;
|
|
4251
|
+
try {
|
|
4252
|
+
td.decode(et, { stream: true });
|
|
4253
|
+
tds = 1;
|
|
4254
|
+
} catch (e) {}
|
|
4255
|
+
|
|
4256
|
+
// src/utils/tar.ts
|
|
4257
|
+
import { readFile as readFile3 } from "node:fs/promises";
|
|
4258
|
+
var TAR_BLOCK_SIZE = 512;
|
|
4259
|
+
function createTarHeader(name, size) {
|
|
4260
|
+
const header = new Uint8Array(TAR_BLOCK_SIZE);
|
|
4261
|
+
const nameBytes = new TextEncoder().encode(name);
|
|
4262
|
+
header.set(nameBytes.slice(0, 100), 0);
|
|
4263
|
+
header.set(new TextEncoder().encode("0000644\x00"), 100);
|
|
4264
|
+
header.set(new TextEncoder().encode("0000000\x00"), 108);
|
|
4265
|
+
header.set(new TextEncoder().encode("0000000\x00"), 116);
|
|
4266
|
+
const sizeOctal = size.toString(8).padStart(11, "0");
|
|
4267
|
+
header.set(new TextEncoder().encode(sizeOctal + "\x00"), 124);
|
|
4268
|
+
const mtime = Math.floor(Date.now() / 1000).toString(8).padStart(11, "0");
|
|
4269
|
+
header.set(new TextEncoder().encode(mtime + "\x00"), 136);
|
|
4270
|
+
header.set(new TextEncoder().encode(" "), 148);
|
|
4271
|
+
header[156] = 48;
|
|
4272
|
+
let checksum = 0;
|
|
4273
|
+
for (let i2 = 0;i2 < TAR_BLOCK_SIZE; i2++) {
|
|
4274
|
+
checksum += header[i2];
|
|
4275
|
+
}
|
|
4276
|
+
const checksumStr = checksum.toString(8).padStart(6, "0") + "\x00 ";
|
|
4277
|
+
header.set(new TextEncoder().encode(checksumStr), 148);
|
|
4278
|
+
return header;
|
|
4279
|
+
}
|
|
4280
|
+
function padToBlock(data) {
|
|
4281
|
+
const remainder = data.length % TAR_BLOCK_SIZE;
|
|
4282
|
+
if (remainder === 0)
|
|
4283
|
+
return data;
|
|
4284
|
+
const padded = new Uint8Array(data.length + TAR_BLOCK_SIZE - remainder);
|
|
4285
|
+
padded.set(data);
|
|
4286
|
+
return padded;
|
|
4287
|
+
}
|
|
4288
|
+
async function createTarArchive(files) {
|
|
4289
|
+
const parts = [];
|
|
4290
|
+
for (const file of files) {
|
|
4291
|
+
const content = await readFile3(file.absolutePath);
|
|
4292
|
+
const header = createTarHeader(file.path, content.length);
|
|
4293
|
+
const paddedContent = padToBlock(new Uint8Array(content));
|
|
4294
|
+
parts.push(header);
|
|
4295
|
+
parts.push(paddedContent);
|
|
4296
|
+
}
|
|
4297
|
+
parts.push(new Uint8Array(TAR_BLOCK_SIZE * 2));
|
|
4298
|
+
const totalSize = parts.reduce((sum, p) => sum + p.length, 0);
|
|
4299
|
+
const tar = new Uint8Array(totalSize);
|
|
4300
|
+
let offset = 0;
|
|
4301
|
+
for (const part of parts) {
|
|
4302
|
+
tar.set(part, offset);
|
|
4303
|
+
offset += part.length;
|
|
4304
|
+
}
|
|
4305
|
+
return tar;
|
|
4306
|
+
}
|
|
4307
|
+
async function createTarGz(files) {
|
|
4308
|
+
const tar = await createTarArchive(files);
|
|
4309
|
+
return gzipSync(tar, { level: 6 });
|
|
4310
|
+
}
|
|
4311
|
+
function formatCompression(original, compressed) {
|
|
4312
|
+
const ratio = ((1 - compressed / original) * 100).toFixed(1);
|
|
4313
|
+
return `${ratio}% smaller`;
|
|
4314
|
+
}
|
|
4315
|
+
|
|
4316
|
+
// src/utils/project-config.ts
|
|
4317
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
4318
|
+
import { resolve as resolve2 } from "node:path";
|
|
4319
|
+
var CONFIG_FILENAME = "zerodeploy.json";
|
|
4320
|
+
function loadProjectConfig(cwd = process.cwd()) {
|
|
4321
|
+
const configPath = resolve2(cwd, CONFIG_FILENAME);
|
|
4322
|
+
if (!existsSync(configPath)) {
|
|
4323
|
+
return {};
|
|
4324
|
+
}
|
|
4325
|
+
try {
|
|
4326
|
+
const content = readFileSync(configPath, "utf-8");
|
|
4327
|
+
const config = JSON.parse(content);
|
|
4328
|
+
return config;
|
|
4329
|
+
} catch (err) {
|
|
4330
|
+
console.warn(`Warning: Failed to parse ${CONFIG_FILENAME}`);
|
|
4331
|
+
return {};
|
|
4332
|
+
}
|
|
4333
|
+
}
|
|
4334
|
+
function getConfigPath(cwd = process.cwd()) {
|
|
4335
|
+
return resolve2(cwd, CONFIG_FILENAME);
|
|
4336
|
+
}
|
|
4337
|
+
|
|
4338
|
+
// src/commands/deploy/list.ts
|
|
4339
|
+
var deployListCommand = new Command2("list").description("List deployments for a site").argument("<siteSlug>", "Site slug").requiredOption("--org <orgSlug>", "Organization slug").option("--limit <number>", "Number of deployments to show", "10").action(async (siteSlug, options) => {
|
|
4340
|
+
const token = loadToken();
|
|
4341
|
+
if (!token) {
|
|
4342
|
+
console.log("❌ Not logged in. Run: zerodeploy login");
|
|
4343
|
+
return;
|
|
4344
|
+
}
|
|
4345
|
+
try {
|
|
4346
|
+
const client = getClient(token);
|
|
4347
|
+
const res = await client.orgs[":orgSlug"].sites[":siteSlug"].deployments.$get({
|
|
4348
|
+
param: { orgSlug: options.org, siteSlug }
|
|
4349
|
+
});
|
|
4350
|
+
if (!res.ok) {
|
|
4351
|
+
const error = await res.json();
|
|
4352
|
+
console.error(`❌ ${error.error}`);
|
|
4353
|
+
return;
|
|
4354
|
+
}
|
|
4355
|
+
const deployments = await res.json();
|
|
4356
|
+
const limit = parseInt(options.limit, 10);
|
|
4357
|
+
const shown = deployments.slice(0, limit);
|
|
4358
|
+
if (shown.length === 0) {
|
|
4359
|
+
console.log("No deployments found");
|
|
4360
|
+
return;
|
|
4361
|
+
}
|
|
4362
|
+
console.log(`
|
|
4363
|
+
Deployments for ${options.org}/${siteSlug}:
|
|
4364
|
+
`);
|
|
4365
|
+
for (const d of shown) {
|
|
4366
|
+
const current = d.isCurrent ? " ← current" : "";
|
|
4367
|
+
const status = formatStatus2(d.status);
|
|
4368
|
+
const date = new Date(d.created_at).toLocaleString();
|
|
4369
|
+
console.log(` ${d.id.slice(0, 8)} ${status} ${date}${current}`);
|
|
4370
|
+
}
|
|
4371
|
+
if (deployments.length > limit) {
|
|
4372
|
+
console.log(`
|
|
4373
|
+
... and ${deployments.length - limit} more`);
|
|
4374
|
+
}
|
|
4375
|
+
console.log("");
|
|
4376
|
+
} catch (err) {
|
|
4377
|
+
console.error("Failed to list deployments:", err.message);
|
|
4378
|
+
}
|
|
4379
|
+
});
|
|
4380
|
+
function formatStatus2(status) {
|
|
4381
|
+
const statusMap = {
|
|
4382
|
+
pending: "⏳ pending ",
|
|
4383
|
+
uploading: "\uD83D\uDCE4 uploading ",
|
|
4384
|
+
processing: "⚙️ processing",
|
|
4385
|
+
ready: "✅ ready ",
|
|
4386
|
+
failed: "❌ failed "
|
|
4387
|
+
};
|
|
4388
|
+
return statusMap[status] || status.padEnd(11);
|
|
4389
|
+
}
|
|
4390
|
+
|
|
4391
|
+
// src/commands/deploy/rollback.ts
|
|
4392
|
+
var deployRollbackCommand = new Command2("rollback").description("Rollback to a previous deployment").argument("<deploymentId>", "Deployment ID to rollback to").action(async (deploymentId) => {
|
|
4393
|
+
const token = loadToken();
|
|
4394
|
+
if (!token) {
|
|
4395
|
+
console.log("❌ Not logged in. Run: zerodeploy login");
|
|
4396
|
+
return;
|
|
4397
|
+
}
|
|
4398
|
+
try {
|
|
4399
|
+
const client = getClient(token);
|
|
4400
|
+
const res = await client.deployments[":id"].rollback.$post({
|
|
4401
|
+
param: { id: deploymentId }
|
|
4402
|
+
});
|
|
4403
|
+
if (!res.ok) {
|
|
4404
|
+
const error = await res.json();
|
|
4405
|
+
console.error(`❌ ${error.error}`);
|
|
4406
|
+
return;
|
|
4407
|
+
}
|
|
4408
|
+
const result = await res.json();
|
|
4409
|
+
console.log(`✅ ${result.message}`);
|
|
4410
|
+
console.log(` Deployment: ${result.deployment.id}`);
|
|
4411
|
+
console.log(` URL: ${result.deployment.url}`);
|
|
4412
|
+
} catch (err) {
|
|
4413
|
+
console.error("Failed to rollback:", err.message);
|
|
4414
|
+
}
|
|
4415
|
+
});
|
|
4416
|
+
|
|
4417
|
+
// src/commands/deploy/index.ts
|
|
4418
|
+
async function runCommand(command, cwd) {
|
|
4419
|
+
return new Promise((promiseResolve) => {
|
|
4420
|
+
const [cmd, ...args] = command.split(" ");
|
|
4421
|
+
const proc = spawn(cmd, args, {
|
|
4422
|
+
cwd,
|
|
4423
|
+
shell: true,
|
|
4424
|
+
stdio: ["inherit", "pipe", "pipe"]
|
|
4425
|
+
});
|
|
4426
|
+
let output = "";
|
|
4427
|
+
proc.stdout?.on("data", (data) => {
|
|
4428
|
+
const text = data.toString();
|
|
4429
|
+
output += text;
|
|
4430
|
+
process.stdout.write(text);
|
|
4431
|
+
});
|
|
4432
|
+
proc.stderr?.on("data", (data) => {
|
|
4433
|
+
const text = data.toString();
|
|
4434
|
+
output += text;
|
|
4435
|
+
process.stderr.write(text);
|
|
4436
|
+
});
|
|
4437
|
+
proc.on("close", (code) => {
|
|
4438
|
+
promiseResolve({ success: code === 0, output });
|
|
4439
|
+
});
|
|
4440
|
+
proc.on("error", (err) => {
|
|
4441
|
+
promiseResolve({ success: false, output: err.message });
|
|
4442
|
+
});
|
|
4443
|
+
});
|
|
4444
|
+
}
|
|
4445
|
+
async function findBuildDirectory(cwd) {
|
|
4446
|
+
const candidates = ["dist", "build", "out", "public", "."];
|
|
4447
|
+
for (const dir of candidates) {
|
|
4448
|
+
const fullPath = resolve3(cwd, dir);
|
|
4449
|
+
try {
|
|
4450
|
+
const stats = await stat2(fullPath);
|
|
4451
|
+
if (stats.isDirectory()) {
|
|
4452
|
+
try {
|
|
4453
|
+
await stat2(resolve3(fullPath, "index.html"));
|
|
4454
|
+
return fullPath;
|
|
4455
|
+
} catch {
|
|
4456
|
+
if (dir !== ".")
|
|
4457
|
+
continue;
|
|
4458
|
+
return fullPath;
|
|
4459
|
+
}
|
|
4460
|
+
}
|
|
4461
|
+
} catch {}
|
|
4462
|
+
}
|
|
4463
|
+
return null;
|
|
4464
|
+
}
|
|
4465
|
+
async function uploadArchive(token, uploadUrl, archive) {
|
|
4466
|
+
const res = await fetch(uploadUrl, {
|
|
4467
|
+
method: "POST",
|
|
4468
|
+
headers: {
|
|
4469
|
+
"Content-Type": "application/gzip",
|
|
4470
|
+
Authorization: `Bearer ${token}`
|
|
4471
|
+
},
|
|
4472
|
+
body: archive
|
|
4473
|
+
});
|
|
4474
|
+
return res.ok;
|
|
4475
|
+
}
|
|
4476
|
+
var deployCommand = new Command2("deploy").description("Deploy a site").argument("[site]", "Site slug").option("--org <org>", "Organization slug").option("--dir <directory>", "Directory to deploy (default: auto-detect)").option("--build", "Run build command before deploying").option("--no-build", "Skip build step").option("--build-command <command>", "Override build command").option("--install", "Run install command before building").option("--pr <number>", "PR number (for GitHub Actions)").option("--pr-title <title>", "PR title").option("--commit <sha>", "Commit SHA").option("--commit-message <message>", "Commit message").option("--branch <branch>", "Branch name").option("--github-output", "Output deployment info in GitHub Actions format").enablePositionalOptions().addCommand(deployListCommand).addCommand(deployRollbackCommand).action(async (siteSlugArg, options) => {
|
|
4477
|
+
const cwd = process.cwd();
|
|
4478
|
+
const config = loadProjectConfig(cwd);
|
|
4479
|
+
const siteSlug = siteSlugArg || config.site;
|
|
4480
|
+
const orgSlug = options.org || config.org;
|
|
4481
|
+
const dirOption = options.dir || config.dir;
|
|
4482
|
+
if (!siteSlug) {
|
|
4483
|
+
console.log("Error: Site is required. Provide as argument or in zerodeploy.json");
|
|
4484
|
+
deployCommand.help();
|
|
4485
|
+
return;
|
|
4486
|
+
}
|
|
4487
|
+
if (!orgSlug) {
|
|
4488
|
+
console.log('Error: --org is required (or set "org" in zerodeploy.json)');
|
|
4489
|
+
return;
|
|
4490
|
+
}
|
|
4491
|
+
const token = loadToken();
|
|
4492
|
+
if (!token) {
|
|
4493
|
+
console.log("Not logged in. Run: zerodeploy login");
|
|
4494
|
+
return;
|
|
4495
|
+
}
|
|
4496
|
+
const framework = await detectFramework(cwd);
|
|
4497
|
+
if (framework) {
|
|
4498
|
+
console.log(`Detected: ${framework.name}`);
|
|
4499
|
+
}
|
|
4500
|
+
const shouldBuild = options.build === true;
|
|
4501
|
+
if (options.install) {
|
|
4502
|
+
const installCmd = config.install || framework?.installCommand || "npm install";
|
|
4503
|
+
console.log(`
|
|
4504
|
+
Installing dependencies...`);
|
|
4505
|
+
console.log(`> ${installCmd}
|
|
4506
|
+
`);
|
|
4507
|
+
const installResult = await runCommand(installCmd, cwd);
|
|
4508
|
+
if (!installResult.success) {
|
|
4509
|
+
console.log(`
|
|
4510
|
+
Error: Install failed`);
|
|
4511
|
+
return;
|
|
4512
|
+
}
|
|
4513
|
+
console.log("");
|
|
4514
|
+
}
|
|
4515
|
+
if (shouldBuild) {
|
|
4516
|
+
const buildCmd = options.buildCommand || config.build || framework?.buildCommand || "npm run build";
|
|
4517
|
+
console.log(`
|
|
4518
|
+
Building...`);
|
|
4519
|
+
console.log(`> ${buildCmd}
|
|
4520
|
+
`);
|
|
4521
|
+
const buildResult = await runCommand(buildCmd, cwd);
|
|
4522
|
+
if (!buildResult.success) {
|
|
4523
|
+
console.log(`
|
|
4524
|
+
Error: Build failed`);
|
|
4525
|
+
return;
|
|
4526
|
+
}
|
|
4527
|
+
console.log("");
|
|
4528
|
+
}
|
|
4529
|
+
let deployDir;
|
|
4530
|
+
if (dirOption) {
|
|
4531
|
+
deployDir = resolve3(cwd, dirOption);
|
|
4532
|
+
try {
|
|
4533
|
+
const stats = await stat2(deployDir);
|
|
4534
|
+
if (!stats.isDirectory()) {
|
|
4535
|
+
console.log(`Error: ${dirOption} is not a directory`);
|
|
4536
|
+
return;
|
|
4537
|
+
}
|
|
4538
|
+
} catch {
|
|
4539
|
+
console.log(`Error: Directory ${dirOption} not found`);
|
|
4540
|
+
return;
|
|
4541
|
+
}
|
|
4542
|
+
} else {
|
|
4543
|
+
const detected = framework ? resolve3(cwd, framework.outputDir) : await findBuildDirectory(cwd);
|
|
4544
|
+
if (!detected) {
|
|
4545
|
+
console.log("Error: Could not find build directory. Use --dir to specify.");
|
|
4546
|
+
return;
|
|
4547
|
+
}
|
|
4548
|
+
try {
|
|
4549
|
+
await stat2(detected);
|
|
4550
|
+
deployDir = detected;
|
|
4551
|
+
} catch {
|
|
4552
|
+
if (framework) {
|
|
4553
|
+
console.log(`Error: Build output directory '${framework.outputDir}' not found.`);
|
|
4554
|
+
console.log(` Run with --build to build first, or --dir to specify output.`);
|
|
4555
|
+
} else {
|
|
4556
|
+
console.log("Error: Could not find build directory. Use --dir to specify.");
|
|
4557
|
+
}
|
|
4558
|
+
return;
|
|
4559
|
+
}
|
|
4560
|
+
}
|
|
4561
|
+
console.log(`Deploying: ${deployDir}`);
|
|
4562
|
+
const files = await scanDirectory(deployDir);
|
|
4563
|
+
if (files.length === 0) {
|
|
4564
|
+
console.log("Error: No files found to deploy");
|
|
4565
|
+
return;
|
|
4566
|
+
}
|
|
4567
|
+
const totalSize = files.reduce((sum, f) => sum + f.size, 0);
|
|
4568
|
+
console.log(`Found ${files.length} files (${formatBytes(totalSize)})`);
|
|
4569
|
+
try {
|
|
4570
|
+
const client = getClient(token);
|
|
4571
|
+
const deployPayload = { siteSlug, orgSlug };
|
|
4572
|
+
if (options.pr) {
|
|
4573
|
+
deployPayload.prNumber = parseInt(options.pr, 10);
|
|
4574
|
+
}
|
|
4575
|
+
if (options.prTitle) {
|
|
4576
|
+
deployPayload.prTitle = options.prTitle;
|
|
4577
|
+
}
|
|
4578
|
+
if (options.commit) {
|
|
4579
|
+
deployPayload.commitSha = options.commit;
|
|
4580
|
+
}
|
|
4581
|
+
if (options.commitMessage) {
|
|
4582
|
+
deployPayload.commitMessage = options.commitMessage;
|
|
4583
|
+
}
|
|
4584
|
+
if (options.branch) {
|
|
4585
|
+
deployPayload.branch = options.branch;
|
|
4586
|
+
}
|
|
4587
|
+
const createRes = await client.deployments.$post({
|
|
4588
|
+
json: deployPayload
|
|
4589
|
+
});
|
|
4590
|
+
if (!createRes.ok) {
|
|
4591
|
+
const body = await createRes.json();
|
|
4592
|
+
let message = "Failed to create deployment";
|
|
4593
|
+
if (typeof body.error === "string") {
|
|
4594
|
+
message = body.error;
|
|
4595
|
+
} else if (typeof body.message === "string") {
|
|
4596
|
+
message = body.message;
|
|
4597
|
+
} else if (body.success === false && body.error && typeof body.error === "object") {
|
|
4598
|
+
const zodError = body.error;
|
|
4599
|
+
if (zodError.issues?.[0]) {
|
|
4600
|
+
const issue = zodError.issues[0];
|
|
4601
|
+
const field = issue.path?.join(".") || "";
|
|
4602
|
+
message = field ? `${field}: ${issue.message}` : issue.message;
|
|
4603
|
+
} else if (zodError.message) {
|
|
4604
|
+
try {
|
|
4605
|
+
const issues = JSON.parse(zodError.message);
|
|
4606
|
+
if (issues[0]) {
|
|
4607
|
+
const field = issues[0].path?.join(".") || "";
|
|
4608
|
+
message = field ? `${field}: ${issues[0].message}` : issues[0].message;
|
|
4609
|
+
}
|
|
4610
|
+
} catch {
|
|
4611
|
+
message = zodError.message;
|
|
4612
|
+
}
|
|
4613
|
+
}
|
|
4614
|
+
}
|
|
4615
|
+
console.log(`Error: ${message}`);
|
|
4616
|
+
return;
|
|
4617
|
+
}
|
|
4618
|
+
const deployment = await createRes.json();
|
|
4619
|
+
console.log(`Created deployment: ${deployment.id}`);
|
|
4620
|
+
console.log("Creating archive...");
|
|
4621
|
+
const archive = await createTarGz(files);
|
|
4622
|
+
console.log(` ${formatBytes(totalSize)} -> ${formatBytes(archive.length)} (${formatCompression(totalSize, archive.length)})`);
|
|
4623
|
+
console.log("Uploading...");
|
|
4624
|
+
const uploadUrl = deployment.uploadUrl || `${API_URL}/deployments/${deployment.id}/upload`;
|
|
4625
|
+
const uploadSuccess = await uploadArchive(token, uploadUrl, archive);
|
|
4626
|
+
if (!uploadSuccess) {
|
|
4627
|
+
console.log("Error: Failed to upload archive");
|
|
4628
|
+
return;
|
|
4629
|
+
}
|
|
4630
|
+
console.log(` Uploaded ${formatBytes(archive.length)}`);
|
|
4631
|
+
console.log("Finalizing...");
|
|
4632
|
+
const finalizeRes = await fetch(`${API_URL}/deployments/${deployment.id}/finalize`, {
|
|
4633
|
+
method: "POST",
|
|
4634
|
+
headers: {
|
|
4635
|
+
"Content-Type": "application/json",
|
|
4636
|
+
Authorization: `Bearer ${token}`
|
|
4637
|
+
},
|
|
4638
|
+
body: JSON.stringify({})
|
|
4639
|
+
});
|
|
4640
|
+
if (!finalizeRes.ok) {
|
|
4641
|
+
console.log("Error: Failed to finalize deployment");
|
|
4642
|
+
return;
|
|
4643
|
+
}
|
|
4644
|
+
console.log("");
|
|
4645
|
+
console.log("Deployment successful!");
|
|
4646
|
+
console.log(`URL: ${deployment.url}`);
|
|
4647
|
+
console.log(`Preview: ${deployment.previewUrl}`);
|
|
4648
|
+
if (options.githubOutput) {
|
|
4649
|
+
const githubOutputFile = process.env.GITHUB_OUTPUT;
|
|
4650
|
+
if (githubOutputFile) {
|
|
4651
|
+
const { appendFileSync } = await import("node:fs");
|
|
4652
|
+
appendFileSync(githubOutputFile, `deployment_id=${deployment.id}
|
|
4653
|
+
`);
|
|
4654
|
+
appendFileSync(githubOutputFile, `deployment_url=${deployment.url}
|
|
4655
|
+
`);
|
|
4656
|
+
appendFileSync(githubOutputFile, `preview_url=${deployment.previewUrl}
|
|
4657
|
+
`);
|
|
4658
|
+
} else {
|
|
4659
|
+
console.log("");
|
|
4660
|
+
console.log("::set-output name=deployment_id::" + deployment.id);
|
|
4661
|
+
console.log("::set-output name=deployment_url::" + deployment.url);
|
|
4662
|
+
console.log("::set-output name=preview_url::" + deployment.previewUrl);
|
|
4663
|
+
}
|
|
4664
|
+
}
|
|
4665
|
+
} catch (err) {
|
|
4666
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
4667
|
+
console.log(`Deploy failed: ${message}`);
|
|
4668
|
+
}
|
|
4669
|
+
});
|
|
4670
|
+
|
|
4671
|
+
// src/commands/deployments/list.ts
|
|
4672
|
+
var deploymentsListCommand = new Command2("list").description("List deployments for a site").argument("<site>", "Site slug").requiredOption("--org <org>", "Organization slug").action(async (site, options) => {
|
|
4673
|
+
const token = loadToken();
|
|
4674
|
+
if (!token) {
|
|
4675
|
+
console.log("Not logged in. Run: zerodeploy login");
|
|
4676
|
+
return;
|
|
4677
|
+
}
|
|
4678
|
+
try {
|
|
4679
|
+
const client = getClient(token);
|
|
4680
|
+
const res = await client.orgs[":orgSlug"].sites[":siteSlug"].deployments.$get({
|
|
4681
|
+
param: { orgSlug: options.org, siteSlug: site }
|
|
4682
|
+
});
|
|
4683
|
+
if (!res.ok)
|
|
4684
|
+
throw new Error(`API Error ${res.status}`);
|
|
4685
|
+
const deployments = await res.json();
|
|
4686
|
+
if (deployments.length === 0) {
|
|
4687
|
+
console.log("No deployments found.");
|
|
4688
|
+
return;
|
|
4689
|
+
}
|
|
4690
|
+
console.log("Deployments:");
|
|
4691
|
+
console.log();
|
|
4692
|
+
for (const d of deployments) {
|
|
4693
|
+
const current = d.isCurrent ? " (current)" : "";
|
|
4694
|
+
const date = new Date(d.created_at).toLocaleString();
|
|
4695
|
+
const shortId = d.id.slice(0, 8);
|
|
4696
|
+
const commit = d.commit_sha ? ` [${d.commit_sha.slice(0, 7)}]` : "";
|
|
4697
|
+
const branch = d.branch ? ` (${d.branch})` : "";
|
|
4698
|
+
const message = d.commit_message ? ` - ${(d.commit_message.split(`
|
|
4699
|
+
`)[0] ?? "").slice(0, 50)}` : "";
|
|
4700
|
+
console.log(` ${shortId} ${d.status.padEnd(10)} ${date}${current}`);
|
|
4701
|
+
if (commit || message) {
|
|
4702
|
+
console.log(` ${commit}${branch}${message}`);
|
|
4703
|
+
}
|
|
4704
|
+
console.log();
|
|
4705
|
+
}
|
|
4706
|
+
} catch (err) {
|
|
4707
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
4708
|
+
console.error("Failed to list deployments:", message);
|
|
4709
|
+
}
|
|
4710
|
+
});
|
|
4711
|
+
|
|
4712
|
+
// src/commands/deployments/index.ts
|
|
4713
|
+
var deploymentsCommand = new Command2("deployments").description("Manage deployments").addCommand(deploymentsListCommand);
|
|
4714
|
+
|
|
4715
|
+
// src/commands/rollback.ts
|
|
4716
|
+
var rollbackCommand = new Command2("rollback").description("Rollback a site to a previous deployment").argument("<site>", "Site slug").requiredOption("--org <org>", "Organization slug").option("--to <deploymentId>", "Deployment ID to rollback to (defaults to previous deployment)").action(async (site, options) => {
|
|
4717
|
+
const token = loadToken();
|
|
4718
|
+
if (!token) {
|
|
4719
|
+
console.log("Not logged in. Run: zerodeploy login");
|
|
4720
|
+
return;
|
|
4721
|
+
}
|
|
4722
|
+
try {
|
|
4723
|
+
const client = getClient(token);
|
|
4724
|
+
let deploymentId = options.to;
|
|
4725
|
+
if (!deploymentId) {
|
|
4726
|
+
const listRes = await client.orgs[":orgSlug"].sites[":siteSlug"].deployments.$get({
|
|
4727
|
+
param: { orgSlug: options.org, siteSlug: site }
|
|
4728
|
+
});
|
|
4729
|
+
if (!listRes.ok)
|
|
4730
|
+
throw new Error(`API Error ${listRes.status}`);
|
|
4731
|
+
const deployments = await listRes.json();
|
|
4732
|
+
const readyDeployments = deployments.filter((d) => d.status === "ready");
|
|
4733
|
+
if (readyDeployments.length < 2) {
|
|
4734
|
+
console.log("No previous deployment to rollback to.");
|
|
4735
|
+
return;
|
|
4736
|
+
}
|
|
4737
|
+
const currentIndex = readyDeployments.findIndex((d) => d.isCurrent);
|
|
4738
|
+
if (currentIndex === -1 || currentIndex >= readyDeployments.length - 1) {
|
|
4739
|
+
deploymentId = readyDeployments[1].id;
|
|
4740
|
+
} else {
|
|
4741
|
+
deploymentId = readyDeployments[currentIndex + 1].id;
|
|
4742
|
+
}
|
|
4743
|
+
}
|
|
4744
|
+
const res = await client.deployments[":id"].rollback.$post({
|
|
4745
|
+
param: { id: deploymentId }
|
|
4746
|
+
});
|
|
4747
|
+
if (!res.ok) {
|
|
4748
|
+
const error = await res.json();
|
|
4749
|
+
throw new Error(error.error || `API Error ${res.status}`);
|
|
4750
|
+
}
|
|
4751
|
+
const result = await res.json();
|
|
4752
|
+
const shortId = result.deployment.id.slice(0, 8);
|
|
4753
|
+
const commit = result.deployment.commit_sha ? ` (${result.deployment.commit_sha.slice(0, 7)})` : "";
|
|
4754
|
+
console.log(`Rolled back to deployment ${shortId}${commit}`);
|
|
4755
|
+
console.log(`URL: ${result.deployment.url}`);
|
|
4756
|
+
} catch (err) {
|
|
4757
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
4758
|
+
console.error("Failed to rollback:", message);
|
|
4759
|
+
}
|
|
4760
|
+
});
|
|
4761
|
+
|
|
4762
|
+
// src/commands/token/create.ts
|
|
4763
|
+
var tokenCreateCommand = new Command2("create").description("Create a deploy token for a site").argument("<name>", 'Token name (e.g., "GitHub Actions")').requiredOption("--org <orgSlug>", "Organization slug").requiredOption("--site <siteSlug>", "Site slug").action(async (name, options) => {
|
|
4764
|
+
const token = loadToken();
|
|
4765
|
+
if (!token) {
|
|
4766
|
+
console.log("Not logged in. Run: zerodeploy login");
|
|
4767
|
+
return;
|
|
4768
|
+
}
|
|
4769
|
+
try {
|
|
4770
|
+
const res = await fetch(`${API_URL}/orgs/${options.org}/sites/${options.site}/tokens`, {
|
|
4771
|
+
method: "POST",
|
|
4772
|
+
headers: {
|
|
4773
|
+
"Content-Type": "application/json",
|
|
4774
|
+
Authorization: `Bearer ${token}`
|
|
4775
|
+
},
|
|
4776
|
+
body: JSON.stringify({ name })
|
|
4777
|
+
});
|
|
4778
|
+
if (!res.ok) {
|
|
4779
|
+
const error = await res.json();
|
|
4780
|
+
console.log(`Error: ${error.error || "Failed to create token"}`);
|
|
4781
|
+
return;
|
|
4782
|
+
}
|
|
4783
|
+
const result = await res.json();
|
|
4784
|
+
console.log("");
|
|
4785
|
+
console.log("Deploy token created successfully!");
|
|
4786
|
+
console.log("");
|
|
4787
|
+
console.log(`Name: ${result.name}`);
|
|
4788
|
+
console.log(`ID: ${result.id}`);
|
|
4789
|
+
console.log("");
|
|
4790
|
+
console.log("Token (save this - it will not be shown again):");
|
|
4791
|
+
console.log("");
|
|
4792
|
+
console.log(` ${result.token}`);
|
|
4793
|
+
console.log("");
|
|
4794
|
+
console.log("Usage in GitHub Actions:");
|
|
4795
|
+
console.log(" Add this token as a repository secret named ZERODEPLOY_TOKEN");
|
|
4796
|
+
console.log("");
|
|
4797
|
+
} catch (err) {
|
|
4798
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
4799
|
+
console.log(`Failed to create token: ${message}`);
|
|
4800
|
+
}
|
|
4801
|
+
});
|
|
4802
|
+
|
|
4803
|
+
// src/commands/token/list.ts
|
|
4804
|
+
var tokenListCommand = new Command2("list").description("List deploy tokens for a site").requiredOption("--org <orgSlug>", "Organization slug").requiredOption("--site <siteSlug>", "Site slug").action(async (options) => {
|
|
4805
|
+
const token = loadToken();
|
|
4806
|
+
if (!token) {
|
|
4807
|
+
console.log("Not logged in. Run: zerodeploy login");
|
|
4808
|
+
return;
|
|
4809
|
+
}
|
|
4810
|
+
try {
|
|
4811
|
+
const res = await fetch(`${API_URL}/orgs/${options.org}/sites/${options.site}/tokens`, {
|
|
4812
|
+
headers: {
|
|
4813
|
+
Authorization: `Bearer ${token}`
|
|
4814
|
+
}
|
|
4815
|
+
});
|
|
4816
|
+
if (!res.ok) {
|
|
4817
|
+
const error = await res.json();
|
|
4818
|
+
console.log(`Error: ${error.error || "Failed to list tokens"}`);
|
|
4819
|
+
return;
|
|
4820
|
+
}
|
|
4821
|
+
const tokens = await res.json();
|
|
4822
|
+
if (tokens.length === 0) {
|
|
4823
|
+
console.log(`No deploy tokens for ${options.org}/${options.site}`);
|
|
4824
|
+
return;
|
|
4825
|
+
}
|
|
4826
|
+
console.log(`Deploy tokens for ${options.org}/${options.site}:`);
|
|
4827
|
+
console.log("");
|
|
4828
|
+
for (const t of tokens) {
|
|
4829
|
+
const created = new Date(t.created_at).toLocaleDateString();
|
|
4830
|
+
const lastUsed = t.last_used_at ? new Date(t.last_used_at).toLocaleDateString() : "Never";
|
|
4831
|
+
console.log(` ${t.id.slice(0, 8)} ${t.name.padEnd(20)} Created: ${created} Last used: ${lastUsed}`);
|
|
4832
|
+
}
|
|
4833
|
+
console.log("");
|
|
4834
|
+
} catch (err) {
|
|
4835
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
4836
|
+
console.log(`Failed to list tokens: ${message}`);
|
|
4837
|
+
}
|
|
4838
|
+
});
|
|
4839
|
+
|
|
4840
|
+
// src/commands/token/delete.ts
|
|
4841
|
+
var tokenDeleteCommand = new Command2("delete").description("Delete a deploy token").argument("<tokenId>", "Token ID (or first 8 characters)").requiredOption("--org <orgSlug>", "Organization slug").requiredOption("--site <siteSlug>", "Site slug").action(async (tokenId, options) => {
|
|
4842
|
+
const token = loadToken();
|
|
4843
|
+
if (!token) {
|
|
4844
|
+
console.log("Not logged in. Run: zerodeploy login");
|
|
4845
|
+
return;
|
|
4846
|
+
}
|
|
4847
|
+
try {
|
|
4848
|
+
let fullTokenId = tokenId;
|
|
4849
|
+
if (tokenId.length < 36) {
|
|
4850
|
+
const listRes = await fetch(`${API_URL}/orgs/${options.org}/sites/${options.site}/tokens`, {
|
|
4851
|
+
headers: {
|
|
4852
|
+
Authorization: `Bearer ${token}`
|
|
4853
|
+
}
|
|
4854
|
+
});
|
|
4855
|
+
if (!listRes.ok) {
|
|
4856
|
+
const error = await listRes.json();
|
|
4857
|
+
console.log(`Error: ${error.error || "Failed to find token"}`);
|
|
4858
|
+
return;
|
|
4859
|
+
}
|
|
4860
|
+
const tokens = await listRes.json();
|
|
4861
|
+
const match = tokens.find((t) => t.id.startsWith(tokenId));
|
|
4862
|
+
if (!match) {
|
|
4863
|
+
console.log(`Error: No token found starting with "${tokenId}"`);
|
|
4864
|
+
return;
|
|
4865
|
+
}
|
|
4866
|
+
fullTokenId = match.id;
|
|
4867
|
+
}
|
|
4868
|
+
const res = await fetch(`${API_URL}/orgs/${options.org}/sites/${options.site}/tokens/${fullTokenId}`, {
|
|
4869
|
+
method: "DELETE",
|
|
4870
|
+
headers: {
|
|
4871
|
+
Authorization: `Bearer ${token}`
|
|
4872
|
+
}
|
|
4873
|
+
});
|
|
4874
|
+
if (!res.ok) {
|
|
4875
|
+
const error = await res.json();
|
|
4876
|
+
console.log(`Error: ${error.error || "Failed to delete token"}`);
|
|
4877
|
+
return;
|
|
4878
|
+
}
|
|
4879
|
+
console.log("Token deleted successfully");
|
|
4880
|
+
} catch (err) {
|
|
4881
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
4882
|
+
console.log(`Failed to delete token: ${message}`);
|
|
4883
|
+
}
|
|
4884
|
+
});
|
|
4885
|
+
|
|
4886
|
+
// src/commands/token/index.ts
|
|
4887
|
+
var tokenCommand = new Command2("token").description("Manage deploy tokens for CI/CD").addCommand(tokenCreateCommand).addCommand(tokenListCommand).addCommand(tokenDeleteCommand);
|
|
4888
|
+
|
|
4889
|
+
// src/commands/init.ts
|
|
4890
|
+
import { writeFileSync, existsSync as existsSync2 } from "node:fs";
|
|
4891
|
+
var initCommand = new Command2("init").description("Create a zerodeploy.json config file").option("--org <org>", "Organization slug").option("--site <site>", "Site slug").option("--dir <directory>", "Build output directory").option("--build <command>", "Build command").option("--force", "Overwrite existing config file").action(async (options) => {
|
|
4892
|
+
const cwd = process.cwd();
|
|
4893
|
+
const configPath = getConfigPath(cwd);
|
|
4894
|
+
if (existsSync2(configPath) && !options.force) {
|
|
4895
|
+
console.log("zerodeploy.json already exists. Use --force to overwrite.");
|
|
4896
|
+
return;
|
|
4897
|
+
}
|
|
4898
|
+
const framework = await detectFramework(cwd);
|
|
4899
|
+
if (framework) {
|
|
4900
|
+
console.log(`Detected: ${framework.name}`);
|
|
4901
|
+
}
|
|
4902
|
+
const config = {};
|
|
4903
|
+
if (options.org) {
|
|
4904
|
+
config.org = options.org;
|
|
4905
|
+
}
|
|
4906
|
+
if (options.site) {
|
|
4907
|
+
config.site = options.site;
|
|
4908
|
+
}
|
|
4909
|
+
if (options.dir) {
|
|
4910
|
+
config.dir = options.dir;
|
|
4911
|
+
} else if (framework) {
|
|
4912
|
+
config.dir = framework.outputDir;
|
|
4913
|
+
}
|
|
4914
|
+
if (options.build) {
|
|
4915
|
+
config.build = options.build;
|
|
4916
|
+
} else if (framework) {
|
|
4917
|
+
config.build = framework.buildCommand;
|
|
4918
|
+
}
|
|
4919
|
+
const content = JSON.stringify(config, null, 2);
|
|
4920
|
+
writeFileSync(configPath, content + `
|
|
4921
|
+
`);
|
|
4922
|
+
console.log("Created zerodeploy.json:");
|
|
4923
|
+
console.log(content);
|
|
4924
|
+
console.log("");
|
|
4925
|
+
if (!config.org || !config.site) {
|
|
4926
|
+
console.log("Next steps:");
|
|
4927
|
+
if (!config.org) {
|
|
4928
|
+
console.log(' - Add "org" to zerodeploy.json');
|
|
4929
|
+
}
|
|
4930
|
+
if (!config.site) {
|
|
4931
|
+
console.log(' - Add "site" to zerodeploy.json');
|
|
4932
|
+
}
|
|
4933
|
+
console.log("");
|
|
4934
|
+
}
|
|
4935
|
+
console.log("Then deploy with:");
|
|
4936
|
+
console.log(" zerodeploy deploy # deploy only");
|
|
4937
|
+
console.log(" zerodeploy deploy --build # build + deploy");
|
|
4938
|
+
});
|
|
4939
|
+
|
|
4940
|
+
// src/index.ts
|
|
4941
|
+
var program3 = new Command;
|
|
4942
|
+
program3.name("zerodeploy").description("ZeroDeploy CLI").version("0.1.0").enablePositionalOptions();
|
|
4943
|
+
program3.addCommand(loginCommand);
|
|
4944
|
+
program3.addCommand(logoutCommand);
|
|
4945
|
+
program3.addCommand(whoamiCommand);
|
|
4946
|
+
program3.addCommand(orgCommand);
|
|
4947
|
+
program3.addCommand(siteCommand);
|
|
4948
|
+
program3.addCommand(domainCommand);
|
|
4949
|
+
program3.addCommand(deployCommand);
|
|
4950
|
+
program3.addCommand(deploymentsCommand);
|
|
4951
|
+
program3.addCommand(rollbackCommand);
|
|
4952
|
+
program3.addCommand(tokenCommand);
|
|
4953
|
+
program3.addCommand(initCommand);
|
|
4954
|
+
program3.parse(process.argv);
|