@dereekb/dbx-cli 13.11.11 → 13.11.13
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/firebase-api-manifest/package.json +1 -1
- package/index.cjs.js +1831 -1214
- package/index.esm.js +1815 -1215
- package/manifest-extract/package.json +1 -1
- package/package.json +11 -5
- package/src/lib/api/call-model.client.d.ts +12 -4
- package/src/lib/api/get-many.command.d.ts +7 -3
- package/src/lib/config/cli.config.d.ts +12 -0
- package/src/lib/config/env.resolve.d.ts +98 -0
- package/src/lib/config/index.d.ts +1 -0
- package/src/lib/context/cli.context.d.ts +1 -1
- package/src/lib/runner/run.d.ts +16 -0
- package/src/lib/util/handler.d.ts +18 -2
- package/src/lib/util/index.d.ts +1 -0
- package/src/lib/util/output.d.ts +65 -1
- package/src/lib/util/stdin.d.ts +28 -0
- package/test/index.cjs.default.js +1 -0
- package/test/index.cjs.js +381 -0
- package/test/index.cjs.mjs +2 -0
- package/test/index.d.ts +1 -0
- package/test/index.esm.js +377 -0
- package/test/package.json +30 -0
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
import { vi } from 'vitest';
|
|
2
|
+
import { createCliContext, createCli } from '@dereekb/dbx-cli';
|
|
3
|
+
|
|
4
|
+
function _array_like_to_array(arr, len) {
|
|
5
|
+
if (len == null || len > arr.length) len = arr.length;
|
|
6
|
+
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
7
|
+
return arr2;
|
|
8
|
+
}
|
|
9
|
+
function _array_without_holes(arr) {
|
|
10
|
+
if (Array.isArray(arr)) return _array_like_to_array(arr);
|
|
11
|
+
}
|
|
12
|
+
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
|
|
13
|
+
try {
|
|
14
|
+
var info = gen[key](arg);
|
|
15
|
+
var value = info.value;
|
|
16
|
+
} catch (error) {
|
|
17
|
+
reject(error);
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
if (info.done) {
|
|
21
|
+
resolve(value);
|
|
22
|
+
} else {
|
|
23
|
+
Promise.resolve(value).then(_next, _throw);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function _async_to_generator(fn) {
|
|
27
|
+
return function() {
|
|
28
|
+
var self = this, args = arguments;
|
|
29
|
+
return new Promise(function(resolve, reject) {
|
|
30
|
+
var gen = fn.apply(self, args);
|
|
31
|
+
function _next(value) {
|
|
32
|
+
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
|
|
33
|
+
}
|
|
34
|
+
function _throw(err) {
|
|
35
|
+
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
|
|
36
|
+
}
|
|
37
|
+
_next(undefined);
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
function _instanceof(left, right) {
|
|
42
|
+
"@swc/helpers - instanceof";
|
|
43
|
+
if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
|
|
44
|
+
return !!right[Symbol.hasInstance](left);
|
|
45
|
+
} else {
|
|
46
|
+
return left instanceof right;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function _iterable_to_array(iter) {
|
|
50
|
+
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
|
|
51
|
+
}
|
|
52
|
+
function _non_iterable_spread() {
|
|
53
|
+
throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
54
|
+
}
|
|
55
|
+
function _to_consumable_array(arr) {
|
|
56
|
+
return _array_without_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _non_iterable_spread();
|
|
57
|
+
}
|
|
58
|
+
function _type_of(obj) {
|
|
59
|
+
"@swc/helpers - typeof";
|
|
60
|
+
return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
|
|
61
|
+
}
|
|
62
|
+
function _unsupported_iterable_to_array(o, minLen) {
|
|
63
|
+
if (!o) return;
|
|
64
|
+
if (typeof o === "string") return _array_like_to_array(o, minLen);
|
|
65
|
+
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
66
|
+
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
67
|
+
if (n === "Map" || n === "Set") return Array.from(n);
|
|
68
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
|
|
69
|
+
}
|
|
70
|
+
function _ts_generator(thisArg, body) {
|
|
71
|
+
var f, y, t, _ = {
|
|
72
|
+
label: 0,
|
|
73
|
+
sent: function() {
|
|
74
|
+
if (t[0] & 1) throw t[1];
|
|
75
|
+
return t[1];
|
|
76
|
+
},
|
|
77
|
+
trys: [],
|
|
78
|
+
ops: []
|
|
79
|
+
}, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype), d = Object.defineProperty;
|
|
80
|
+
return d(g, "next", {
|
|
81
|
+
value: verb(0)
|
|
82
|
+
}), d(g, "throw", {
|
|
83
|
+
value: verb(1)
|
|
84
|
+
}), d(g, "return", {
|
|
85
|
+
value: verb(2)
|
|
86
|
+
}), typeof Symbol === "function" && d(g, Symbol.iterator, {
|
|
87
|
+
value: function() {
|
|
88
|
+
return this;
|
|
89
|
+
}
|
|
90
|
+
}), g;
|
|
91
|
+
function verb(n) {
|
|
92
|
+
return function(v) {
|
|
93
|
+
return step([
|
|
94
|
+
n,
|
|
95
|
+
v
|
|
96
|
+
]);
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
function step(op) {
|
|
100
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
101
|
+
while(g && (g = 0, op[0] && (_ = 0)), _)try {
|
|
102
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
103
|
+
if (y = 0, t) op = [
|
|
104
|
+
op[0] & 2,
|
|
105
|
+
t.value
|
|
106
|
+
];
|
|
107
|
+
switch(op[0]){
|
|
108
|
+
case 0:
|
|
109
|
+
case 1:
|
|
110
|
+
t = op;
|
|
111
|
+
break;
|
|
112
|
+
case 4:
|
|
113
|
+
_.label++;
|
|
114
|
+
return {
|
|
115
|
+
value: op[1],
|
|
116
|
+
done: false
|
|
117
|
+
};
|
|
118
|
+
case 5:
|
|
119
|
+
_.label++;
|
|
120
|
+
y = op[1];
|
|
121
|
+
op = [
|
|
122
|
+
0
|
|
123
|
+
];
|
|
124
|
+
continue;
|
|
125
|
+
case 7:
|
|
126
|
+
op = _.ops.pop();
|
|
127
|
+
_.trys.pop();
|
|
128
|
+
continue;
|
|
129
|
+
default:
|
|
130
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
|
|
131
|
+
_ = 0;
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
|
|
135
|
+
_.label = op[1];
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
if (op[0] === 6 && _.label < t[1]) {
|
|
139
|
+
_.label = t[1];
|
|
140
|
+
t = op;
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
if (t && _.label < t[2]) {
|
|
144
|
+
_.label = t[2];
|
|
145
|
+
_.ops.push(op);
|
|
146
|
+
break;
|
|
147
|
+
}
|
|
148
|
+
if (t[2]) _.ops.pop();
|
|
149
|
+
_.trys.pop();
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
op = body.call(thisArg, _);
|
|
153
|
+
} catch (e) {
|
|
154
|
+
op = [
|
|
155
|
+
6,
|
|
156
|
+
e
|
|
157
|
+
];
|
|
158
|
+
y = 0;
|
|
159
|
+
} finally{
|
|
160
|
+
f = t = 0;
|
|
161
|
+
}
|
|
162
|
+
if (op[0] & 5) throw op[1];
|
|
163
|
+
return {
|
|
164
|
+
value: op[0] ? op[1] : void 0,
|
|
165
|
+
done: true
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Builds a {@link CliContext} for use as `testCliContext` on {@link createCli}.
|
|
171
|
+
*
|
|
172
|
+
* Thin wrapper around {@link createCliContext} that exists so test code can import from a single
|
|
173
|
+
* test-only entry without pulling in production-only types.
|
|
174
|
+
*
|
|
175
|
+
* @param input - The context inputs (cliName, envName, env, accessToken, optional modelManifest).
|
|
176
|
+
* @returns The constructed {@link CliContext} that drives `callModel` / `getModel` / `getMultipleModels`
|
|
177
|
+
* against `input.env.apiBaseUrl` with `input.accessToken` as the Bearer token.
|
|
178
|
+
* @__NO_SIDE_EFFECTS__
|
|
179
|
+
*/ function buildTestCliContext(input) {
|
|
180
|
+
return createCliContext({
|
|
181
|
+
cliName: input.cliName,
|
|
182
|
+
envName: input.envName,
|
|
183
|
+
env: input.env,
|
|
184
|
+
accessToken: input.accessToken,
|
|
185
|
+
modelManifest: input.modelManifest
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Drives a CLI invocation in-process and captures all output.
|
|
190
|
+
*
|
|
191
|
+
* Creates a fresh yargs `Argv` per call (so middleware/option defaults can't leak across tests),
|
|
192
|
+
* parses `args`, and collects `process.stdout.write` / `process.stderr.write` / `console.log` /
|
|
193
|
+
* `console.error` output via `vi.spyOn`. The spies are always restored on completion.
|
|
194
|
+
*
|
|
195
|
+
* Always resolves — handler errors and yargs failures are surfaced in {@link RunCliCommandResult.error}
|
|
196
|
+
* instead of being thrown.
|
|
197
|
+
*
|
|
198
|
+
* @param input - The {@link CreateCliInput} used to build the CLI for this invocation. Pass a fresh
|
|
199
|
+
* object each call (or rely on the caller-side factory) — yargs `Argv` state is not reused across
|
|
200
|
+
* invocations.
|
|
201
|
+
* @param args - The argv vector to parse (e.g. `['get', 'p/abc']`).
|
|
202
|
+
* @returns The captured output envelope.
|
|
203
|
+
*/ function runCliCommand(input, args) {
|
|
204
|
+
return _async_to_generator(function() {
|
|
205
|
+
var stdoutChunks, stderrChunks, writeSpy, errSpy, logSpy, errLogSpy, capturedExitCode, exitSentinel, exitSpy, capturedArgv, capturedError, helpOutput, e, result;
|
|
206
|
+
return _ts_generator(this, function(_state) {
|
|
207
|
+
switch(_state.label){
|
|
208
|
+
case 0:
|
|
209
|
+
stdoutChunks = [];
|
|
210
|
+
stderrChunks = [];
|
|
211
|
+
writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation(function(chunk) {
|
|
212
|
+
stdoutChunks.push(toChunkString(chunk));
|
|
213
|
+
return true;
|
|
214
|
+
});
|
|
215
|
+
errSpy = vi.spyOn(process.stderr, 'write').mockImplementation(function(chunk) {
|
|
216
|
+
stderrChunks.push(toChunkString(chunk));
|
|
217
|
+
return true;
|
|
218
|
+
});
|
|
219
|
+
logSpy = vi.spyOn(console, 'log').mockImplementation(function() {
|
|
220
|
+
for(var _len = arguments.length, parts = new Array(_len), _key = 0; _key < _len; _key++){
|
|
221
|
+
parts[_key] = arguments[_key];
|
|
222
|
+
}
|
|
223
|
+
stdoutChunks.push(parts.map(function(p) {
|
|
224
|
+
return stringifyConsolePart(p);
|
|
225
|
+
}).join(' ') + '\n');
|
|
226
|
+
});
|
|
227
|
+
errLogSpy = vi.spyOn(console, 'error').mockImplementation(function() {
|
|
228
|
+
for(var _len = arguments.length, parts = new Array(_len), _key = 0; _key < _len; _key++){
|
|
229
|
+
parts[_key] = arguments[_key];
|
|
230
|
+
}
|
|
231
|
+
stderrChunks.push(parts.map(function(p) {
|
|
232
|
+
return stringifyConsolePart(p);
|
|
233
|
+
}).join(' ') + '\n');
|
|
234
|
+
});
|
|
235
|
+
exitSentinel = new Error('__cli_test_process_exit__');
|
|
236
|
+
exitSpy = vi.spyOn(process, 'exit').mockImplementation(function(code) {
|
|
237
|
+
capturedExitCode = typeof code === 'number' ? code : 0;
|
|
238
|
+
throw exitSentinel;
|
|
239
|
+
});
|
|
240
|
+
helpOutput = '';
|
|
241
|
+
_state.label = 1;
|
|
242
|
+
case 1:
|
|
243
|
+
_state.trys.push([
|
|
244
|
+
1,
|
|
245
|
+
3,
|
|
246
|
+
4,
|
|
247
|
+
5
|
|
248
|
+
]);
|
|
249
|
+
return [
|
|
250
|
+
4,
|
|
251
|
+
createCli(input).exitProcess(false).parse(_to_consumable_array(args), function(err, argv, output) {
|
|
252
|
+
capturedArgv = argv;
|
|
253
|
+
if (err) capturedError = err;
|
|
254
|
+
helpOutput = output;
|
|
255
|
+
})
|
|
256
|
+
];
|
|
257
|
+
case 2:
|
|
258
|
+
_state.sent();
|
|
259
|
+
return [
|
|
260
|
+
3,
|
|
261
|
+
5
|
|
262
|
+
];
|
|
263
|
+
case 3:
|
|
264
|
+
e = _state.sent();
|
|
265
|
+
if (e !== exitSentinel) {
|
|
266
|
+
capturedError = _instanceof(e, Error) ? e : new Error(String(e));
|
|
267
|
+
}
|
|
268
|
+
return [
|
|
269
|
+
3,
|
|
270
|
+
5
|
|
271
|
+
];
|
|
272
|
+
case 4:
|
|
273
|
+
writeSpy.mockRestore();
|
|
274
|
+
errSpy.mockRestore();
|
|
275
|
+
logSpy.mockRestore();
|
|
276
|
+
errLogSpy.mockRestore();
|
|
277
|
+
exitSpy.mockRestore();
|
|
278
|
+
return [
|
|
279
|
+
7
|
|
280
|
+
];
|
|
281
|
+
case 5:
|
|
282
|
+
result = {
|
|
283
|
+
stdout: stdoutChunks,
|
|
284
|
+
stderr: stderrChunks,
|
|
285
|
+
stdoutText: stdoutChunks.join(''),
|
|
286
|
+
stderrText: stderrChunks.join(''),
|
|
287
|
+
argv: capturedArgv,
|
|
288
|
+
helpOutput: helpOutput,
|
|
289
|
+
error: capturedError,
|
|
290
|
+
exitCode: capturedExitCode
|
|
291
|
+
};
|
|
292
|
+
return [
|
|
293
|
+
2,
|
|
294
|
+
result
|
|
295
|
+
];
|
|
296
|
+
}
|
|
297
|
+
});
|
|
298
|
+
})();
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Idempotently binds the fixture's NestJS application to `127.0.0.1:0` (or the supplied host) and
|
|
302
|
+
* returns the live `apiBaseUrl` so the CLI's `fetch` calls have a real socket to hit.
|
|
303
|
+
*
|
|
304
|
+
* Safe to call multiple times against the same app — when `app.getHttpServer().listening` is true,
|
|
305
|
+
* skips re-binding and just resolves the current address.
|
|
306
|
+
*
|
|
307
|
+
* The caller does NOT need to `.close()` explicitly: the demoApi/firebase-admin-nest fixture closes
|
|
308
|
+
* the underlying NestJS app at the end of its describe block, which closes the HTTP listener.
|
|
309
|
+
*
|
|
310
|
+
* @param input - The fixture app + optional global route prefix (defaults to `'api'` to match
|
|
311
|
+
* demo-api's production prefix) and host (defaults to `127.0.0.1`).
|
|
312
|
+
* @returns The bound `apiBaseUrl` (e.g. `http://127.0.0.1:54321/api`) and the resolved port.
|
|
313
|
+
*/ function listenOnNestAppForTest(input) {
|
|
314
|
+
return _async_to_generator(function() {
|
|
315
|
+
var _input_host, _input_apiPrefix, host, prefix, server, address, port, trimmedPrefix, apiBaseUrl;
|
|
316
|
+
return _ts_generator(this, function(_state) {
|
|
317
|
+
switch(_state.label){
|
|
318
|
+
case 0:
|
|
319
|
+
host = (_input_host = input.host) !== null && _input_host !== void 0 ? _input_host : '127.0.0.1';
|
|
320
|
+
prefix = (_input_apiPrefix = input.apiPrefix) !== null && _input_apiPrefix !== void 0 ? _input_apiPrefix : 'api';
|
|
321
|
+
server = input.app.getHttpServer();
|
|
322
|
+
if (!!server.listening) return [
|
|
323
|
+
3,
|
|
324
|
+
2
|
|
325
|
+
];
|
|
326
|
+
return [
|
|
327
|
+
4,
|
|
328
|
+
input.app.listen(0, host)
|
|
329
|
+
];
|
|
330
|
+
case 1:
|
|
331
|
+
_state.sent();
|
|
332
|
+
_state.label = 2;
|
|
333
|
+
case 2:
|
|
334
|
+
address = server.address();
|
|
335
|
+
port = (typeof address === "undefined" ? "undefined" : _type_of(address)) === 'object' && address ? address.port : 0;
|
|
336
|
+
trimmedPrefix = prefix.replace(/^\/+|\/+$/g, '');
|
|
337
|
+
apiBaseUrl = trimmedPrefix.length > 0 ? "http://".concat(host, ":").concat(port, "/").concat(trimmedPrefix) : "http://".concat(host, ":").concat(port);
|
|
338
|
+
return [
|
|
339
|
+
2,
|
|
340
|
+
{
|
|
341
|
+
apiBaseUrl: apiBaseUrl,
|
|
342
|
+
port: port
|
|
343
|
+
}
|
|
344
|
+
];
|
|
345
|
+
}
|
|
346
|
+
});
|
|
347
|
+
})();
|
|
348
|
+
}
|
|
349
|
+
function toChunkString(chunk) {
|
|
350
|
+
var result;
|
|
351
|
+
if (typeof chunk === 'string') {
|
|
352
|
+
result = chunk;
|
|
353
|
+
} else if (_instanceof(chunk, Uint8Array)) {
|
|
354
|
+
result = Buffer.from(chunk).toString('utf8');
|
|
355
|
+
} else {
|
|
356
|
+
result = String(chunk);
|
|
357
|
+
}
|
|
358
|
+
return result;
|
|
359
|
+
}
|
|
360
|
+
function stringifyConsolePart(part) {
|
|
361
|
+
var result;
|
|
362
|
+
if (typeof part === 'string') {
|
|
363
|
+
result = part;
|
|
364
|
+
} else if (_instanceof(part, Error)) {
|
|
365
|
+
var _part_stack;
|
|
366
|
+
result = (_part_stack = part.stack) !== null && _part_stack !== void 0 ? _part_stack : part.message;
|
|
367
|
+
} else {
|
|
368
|
+
try {
|
|
369
|
+
result = JSON.stringify(part);
|
|
370
|
+
} catch (unused) {
|
|
371
|
+
result = String(part);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
return result;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
export { buildTestCliContext, listenOnNestAppForTest, runCliCommand };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@dereekb/dbx-cli/test",
|
|
3
|
+
"version": "13.11.13",
|
|
4
|
+
"peerDependencies": {
|
|
5
|
+
"@dereekb/date": "13.11.13",
|
|
6
|
+
"@dereekb/dbx-cli": "13.11.13",
|
|
7
|
+
"@dereekb/firebase": "13.11.13",
|
|
8
|
+
"@dereekb/firebase-server/test": "13.11.13",
|
|
9
|
+
"@dereekb/model": "13.11.13",
|
|
10
|
+
"@dereekb/nestjs": "13.11.13",
|
|
11
|
+
"@dereekb/rxjs": "13.11.13",
|
|
12
|
+
"@dereekb/util": "13.11.13",
|
|
13
|
+
"@nestjs/common": "^11.1.19",
|
|
14
|
+
"arktype": "^2.2.0",
|
|
15
|
+
"yargs": "^18.0.0"
|
|
16
|
+
},
|
|
17
|
+
"devDependencies": {},
|
|
18
|
+
"exports": {
|
|
19
|
+
"./package.json": "./package.json",
|
|
20
|
+
".": {
|
|
21
|
+
"module": "./index.esm.js",
|
|
22
|
+
"types": "./index.d.ts",
|
|
23
|
+
"import": "./index.cjs.mjs",
|
|
24
|
+
"default": "./index.cjs.js"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"module": "./index.esm.js",
|
|
28
|
+
"main": "./index.cjs.js",
|
|
29
|
+
"types": "./index.d.ts"
|
|
30
|
+
}
|