bdy 1.25.3-dev → 1.25.4-dev
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/distTs/package.json +1 -1
- package/distTs/src/agent/socket/tunnel.js +2 -0
- package/distTs/src/command/agent/proxy/status.js +9 -2
- package/distTs/src/command/agent/status.js +22 -6
- package/distTs/src/command/agent/tags/get.js +9 -2
- package/distTs/src/command/agent/target/status.js +9 -2
- package/distTs/src/command/agent/tunnel/list.js +6 -1
- package/distTs/src/command/agent/tunnel/status.js +13 -1
- package/distTs/src/command/agent/version.js +7 -2
- package/distTs/src/command/api/info.js +50 -2
- package/distTs/src/command/api/list.js +18 -2
- package/distTs/src/command/artifact/create.js +5 -0
- package/distTs/src/command/artifact/publish.js +20 -22
- package/distTs/src/command/artifact/version/create.js +5 -0
- package/distTs/src/command/config/get/tunnel.js +8 -3
- package/distTs/src/command/config/get/tunnels.js +8 -3
- package/distTs/src/command/distro/create.js +5 -0
- package/distTs/src/command/distro/route/create.js +5 -0
- package/distTs/src/command/distro/route/update.js +5 -0
- package/distTs/src/command/distro/update.js +5 -0
- package/distTs/src/command/domain/search.js +31 -10
- package/distTs/src/command/environment/create.js +5 -0
- package/distTs/src/command/environment/update.js +5 -0
- package/distTs/src/command/sandbox/app/add.js +7 -1
- package/distTs/src/command/sandbox/app/logs.js +9 -4
- package/distTs/src/command/sandbox/create.js +13 -5
- package/distTs/src/command/sandbox/endpoint/add.js +5 -0
- package/distTs/src/command/sandbox/exec/command.js +15 -30
- package/distTs/src/command/sandbox/exec/logs.js +4 -29
- package/distTs/src/command/sandbox/finishExec.js +33 -0
- package/distTs/src/command/sandbox/logs.js +14 -1
- package/distTs/src/command/sandbox/snapshot/create.js +9 -1
- package/distTs/src/command/target/create.js +5 -0
- package/distTs/src/command/target/exec/logs.js +15 -2
- package/distTs/src/command/target/update.js +5 -0
- package/distTs/src/command/yaml/validate.js +111 -52
- package/distTs/src/openapi.js +8 -1
- package/distTs/src/output.js +39 -0
- package/distTs/src/texts.js +206 -1
- package/package.json +1 -1
|
@@ -22,9 +22,17 @@ function prettifyKey(key) {
|
|
|
22
22
|
.map((w) => w.charAt(0).toUpperCase() + w.slice(1))
|
|
23
23
|
.join(' ');
|
|
24
24
|
}
|
|
25
|
-
function
|
|
25
|
+
function recordError(context, path, message) {
|
|
26
|
+
context.errors.push({
|
|
27
|
+
pipeline: context.pipeline,
|
|
28
|
+
path: path.replace(/\.(\d+)(?=\.|$)/g, '[$1]'),
|
|
29
|
+
message,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
function outputErrors(result, indent, context, prefix = '') {
|
|
26
33
|
for (const err of result.errors) {
|
|
27
|
-
|
|
34
|
+
recordError(context, [prefix, err.path].filter(Boolean).join('.'), err.message);
|
|
35
|
+
context.output.muted(`${indent}${err.path}: ${err.message}`);
|
|
28
36
|
}
|
|
29
37
|
}
|
|
30
38
|
function valueType(value) {
|
|
@@ -34,9 +42,10 @@ function valueType(value) {
|
|
|
34
42
|
return 'array';
|
|
35
43
|
return typeof value;
|
|
36
44
|
}
|
|
37
|
-
function reportWrongContainer(header, expected, value) {
|
|
38
|
-
|
|
39
|
-
|
|
45
|
+
function reportWrongContainer(header, expected, value, context, path) {
|
|
46
|
+
recordError(context, path, (0, texts_1.ERR_YAML_MUST_BE)(expected, valueType(value)));
|
|
47
|
+
context.output.error(header);
|
|
48
|
+
context.output.muted(` ${(0, texts_1.ERR_YAML_MUST_BE)(expected, valueType(value))}`);
|
|
40
49
|
return 1;
|
|
41
50
|
}
|
|
42
51
|
// Array whose items reference a def — directly, or via a single $ref branch in
|
|
@@ -117,85 +126,101 @@ function itemLabel(value, index, discProp) {
|
|
|
117
126
|
name = `#${index + 1}`;
|
|
118
127
|
return discProp && value && value[discProp] ? `${name} (${value[discProp]})` : name;
|
|
119
128
|
}
|
|
120
|
-
function validateScalarItem(item, section) {
|
|
129
|
+
function validateScalarItem(item, section, context, path) {
|
|
121
130
|
// Null errors even where the section takes a string: coerceTypes cannot fix a root scalar.
|
|
122
131
|
if (item === null || !section.scalar) {
|
|
123
|
-
|
|
132
|
+
recordError(context, path, (0, texts_1.ERR_YAML_MUST_BE)('object', valueType(item)));
|
|
133
|
+
context.output.error(` ${String(item)}: ${(0, texts_1.ERR_YAML_MUST_BE)('object', valueType(item))}`);
|
|
124
134
|
return 1;
|
|
125
135
|
}
|
|
126
136
|
const result = (0, schemaUtils_1.validateAgainstSchema)({ ...section.scalar, $defs: (0, schemaUtils_1.loadRawSchema)().$defs }, item);
|
|
127
137
|
if (result.valid) {
|
|
128
|
-
|
|
138
|
+
context.output.green(` ${String(item)}`);
|
|
129
139
|
return 0;
|
|
130
140
|
}
|
|
131
|
-
|
|
132
|
-
outputErrors(result, ' ');
|
|
141
|
+
context.output.error(` ${String(item)}`);
|
|
142
|
+
outputErrors(result, ' ', context, path);
|
|
133
143
|
return result.errors.length;
|
|
134
144
|
}
|
|
135
|
-
function validateItemSection(unions, items, section) {
|
|
145
|
+
function validateItemSection(unions, items, section, context) {
|
|
136
146
|
const refName = section.defName;
|
|
137
147
|
const discProp = unions.get(refName)?.property ?? null;
|
|
138
148
|
let errors = 0;
|
|
139
149
|
for (let i = 0; i < items.length; i++) {
|
|
140
150
|
const item = items[i];
|
|
151
|
+
const path = `${section.key}[${i}]`;
|
|
141
152
|
if (item === null || typeof item !== 'object' || Array.isArray(item)) {
|
|
142
|
-
errors += validateScalarItem(item, section);
|
|
153
|
+
errors += validateScalarItem(item, section, context, path);
|
|
143
154
|
continue;
|
|
144
155
|
}
|
|
145
156
|
const label = itemLabel(item, i, discProp);
|
|
146
157
|
const resolved = resolveDef(unions, refName, item);
|
|
147
158
|
if ('missingType' in resolved) {
|
|
148
|
-
|
|
159
|
+
recordError(context, `${path}.${resolved.missingType}`, (0, texts_1.ERR_YAML_ITEM_MISSING)(resolved.missingType));
|
|
160
|
+
context.output.error(` ${label}: ${(0, texts_1.ERR_YAML_ITEM_MISSING)(resolved.missingType)}`);
|
|
149
161
|
errors++;
|
|
150
162
|
continue;
|
|
151
163
|
}
|
|
152
164
|
if ('unknownType' in resolved) {
|
|
153
|
-
|
|
165
|
+
recordError(context, `${path}.${resolved.prop}`, (0, texts_1.ERR_YAML_ITEM_UNKNOWN)(resolved.prop, resolved.unknownType));
|
|
166
|
+
context.output.error(` ${label}: ${(0, texts_1.ERR_YAML_ITEM_UNKNOWN)(resolved.prop, resolved.unknownType)}`);
|
|
154
167
|
errors++;
|
|
155
168
|
continue;
|
|
156
169
|
}
|
|
157
170
|
const result = (0, schemaUtils_1.validateAgainstDef)(resolved.defName, item);
|
|
158
171
|
if (result.valid) {
|
|
159
|
-
|
|
172
|
+
context.output.green(` ${label}`);
|
|
160
173
|
}
|
|
161
174
|
else {
|
|
162
175
|
errors += result.errors.length;
|
|
163
|
-
|
|
164
|
-
outputErrors(result, ' ');
|
|
176
|
+
context.output.error(` ${label}`);
|
|
177
|
+
outputErrors(result, ' ', context, path);
|
|
165
178
|
}
|
|
166
179
|
}
|
|
167
180
|
return errors;
|
|
168
181
|
}
|
|
169
|
-
function validateObjectSection(unions, label, value, refName) {
|
|
182
|
+
function validateObjectSection(unions, label, value, refName, context, path) {
|
|
170
183
|
const resolved = resolveDef(unions, refName, value);
|
|
171
184
|
if ('missingType' in resolved) {
|
|
172
|
-
|
|
173
|
-
|
|
185
|
+
context.output.error(label);
|
|
186
|
+
recordError(context, `${path}.${resolved.missingType}`, (0, texts_1.ERR_YAML_ITEM_MISSING)(resolved.missingType));
|
|
187
|
+
context.output.muted(` ${(0, texts_1.ERR_YAML_ITEM_MISSING)(resolved.missingType)}`);
|
|
174
188
|
return 1;
|
|
175
189
|
}
|
|
176
190
|
if ('unknownType' in resolved) {
|
|
177
|
-
|
|
178
|
-
|
|
191
|
+
context.output.error(label);
|
|
192
|
+
recordError(context, `${path}.${resolved.prop}`, (0, texts_1.ERR_YAML_ITEM_UNKNOWN)(resolved.prop, resolved.unknownType));
|
|
193
|
+
context.output.muted(` ${(0, texts_1.ERR_YAML_ITEM_UNKNOWN)(resolved.prop, resolved.unknownType)}`);
|
|
179
194
|
return 1;
|
|
180
195
|
}
|
|
181
196
|
const result = (0, schemaUtils_1.validateAgainstDef)(resolved.defName, value);
|
|
182
197
|
if (result.valid) {
|
|
183
|
-
|
|
198
|
+
context.output.green(label);
|
|
184
199
|
return 0;
|
|
185
200
|
}
|
|
186
|
-
|
|
187
|
-
outputErrors(result, ' ');
|
|
201
|
+
context.output.error(label);
|
|
202
|
+
outputErrors(result, ' ', context, path);
|
|
188
203
|
return result.errors.length;
|
|
189
204
|
}
|
|
190
|
-
function validateSinglePipeline(parsed, label, unions) {
|
|
205
|
+
function validateSinglePipeline(parsed, label, unions, context) {
|
|
191
206
|
let errors = 0;
|
|
192
207
|
const defs = (0, schemaUtils_1.getAllDefs)();
|
|
193
208
|
const pipelineDef = defs['PipelineYaml'];
|
|
194
209
|
const props = pipelineDef?.properties || {};
|
|
195
|
-
const allKnownKeys = new Set([
|
|
210
|
+
const allKnownKeys = new Set([
|
|
211
|
+
...Object.keys(props),
|
|
212
|
+
...SCHEMA_OMITTED_TOP_LEVEL_KEYS,
|
|
213
|
+
]);
|
|
196
214
|
const unknownKeys = Object.keys(parsed).filter((k) => !allKnownKeys.has(k));
|
|
197
215
|
if (unknownKeys.length > 0) {
|
|
198
|
-
|
|
216
|
+
for (const key of unknownKeys) {
|
|
217
|
+
context.warnings.push({
|
|
218
|
+
pipeline: context.pipeline,
|
|
219
|
+
path: key,
|
|
220
|
+
message: (0, texts_1.TXT_YAML_UNKNOWN_TOP_LEVEL_KEYS)(key),
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
context.output.yellow(`${label}${(0, texts_1.TXT_YAML_UNKNOWN_TOP_LEVEL_KEYS)(unknownKeys.join(', '))}`);
|
|
199
224
|
}
|
|
200
225
|
const { itemSections, objectSections, settingsProps } = classifySections(props);
|
|
201
226
|
if (Object.keys(settingsProps).length > 0) {
|
|
@@ -212,12 +237,12 @@ function validateSinglePipeline(parsed, label, unions) {
|
|
|
212
237
|
$defs: rawSchema.$defs,
|
|
213
238
|
}, settingsData);
|
|
214
239
|
if (result.valid) {
|
|
215
|
-
|
|
240
|
+
context.output.green(`${label}Pipeline settings`);
|
|
216
241
|
}
|
|
217
242
|
else {
|
|
218
243
|
errors += result.errors.length;
|
|
219
|
-
|
|
220
|
-
outputErrors(result, ' ');
|
|
244
|
+
context.output.error(`${label}Pipeline settings`);
|
|
245
|
+
outputErrors(result, ' ', context);
|
|
221
246
|
}
|
|
222
247
|
}
|
|
223
248
|
const itemByKey = new Map(itemSections.map((s) => [s.key, s]));
|
|
@@ -232,27 +257,52 @@ function validateSinglePipeline(parsed, label, unions) {
|
|
|
232
257
|
const header = `${label}${prettifyKey(key)}`;
|
|
233
258
|
if (itemByKey.has(key)) {
|
|
234
259
|
if (!Array.isArray(value)) {
|
|
235
|
-
errors += reportWrongContainer(header, 'array', value);
|
|
260
|
+
errors += reportWrongContainer(header, 'array', value, context, key);
|
|
236
261
|
continue;
|
|
237
262
|
}
|
|
238
|
-
|
|
239
|
-
errors += validateItemSection(unions, value, itemByKey.get(key));
|
|
263
|
+
context.output.blue(header);
|
|
264
|
+
errors += validateItemSection(unions, value, itemByKey.get(key), context);
|
|
240
265
|
}
|
|
241
266
|
else if (objByKey.has(key)) {
|
|
242
267
|
if (typeof value !== 'object' || Array.isArray(value)) {
|
|
243
|
-
errors += reportWrongContainer(header, 'object', value);
|
|
268
|
+
errors += reportWrongContainer(header, 'object', value, context, key);
|
|
244
269
|
continue;
|
|
245
270
|
}
|
|
246
|
-
errors += validateObjectSection(unions, header, value, objByKey.get(key));
|
|
271
|
+
errors += validateObjectSection(unions, header, value, objByKey.get(key), context, key);
|
|
247
272
|
}
|
|
248
273
|
}
|
|
249
274
|
return errors;
|
|
250
275
|
}
|
|
251
|
-
function validatePipelineFile(file, unions) {
|
|
276
|
+
function validatePipelineFile(file, unions, json) {
|
|
277
|
+
const context = {
|
|
278
|
+
output: {
|
|
279
|
+
normal: output_1.default.progress(json),
|
|
280
|
+
error: output_1.default.progress(json, output_1.default.error.bind(output_1.default)),
|
|
281
|
+
muted: output_1.default.progress(json, output_1.default.muted.bind(output_1.default)),
|
|
282
|
+
green: output_1.default.progress(json, output_1.default.green.bind(output_1.default)),
|
|
283
|
+
yellow: output_1.default.progress(json, output_1.default.yellow.bind(output_1.default)),
|
|
284
|
+
blue: output_1.default.progress(json, output_1.default.blue.bind(output_1.default)),
|
|
285
|
+
},
|
|
286
|
+
pipeline: 0,
|
|
287
|
+
errors: [],
|
|
288
|
+
warnings: [],
|
|
289
|
+
};
|
|
290
|
+
const invalidDocument = (message) => {
|
|
291
|
+
if (json) {
|
|
292
|
+
recordError(context, '', message);
|
|
293
|
+
output_1.default.json({
|
|
294
|
+
valid: false,
|
|
295
|
+
pipelines: 0,
|
|
296
|
+
errors: context.errors,
|
|
297
|
+
warnings: context.warnings,
|
|
298
|
+
});
|
|
299
|
+
output_1.default.exitCode(1);
|
|
300
|
+
}
|
|
301
|
+
output_1.default.exitError(message);
|
|
302
|
+
};
|
|
252
303
|
const filePath = (0, path_1.resolve)(file);
|
|
253
304
|
if (!(0, fs_1.existsSync)(filePath)) {
|
|
254
|
-
|
|
255
|
-
return;
|
|
305
|
+
invalidDocument((0, texts_1.ERR_YAML_VALIDATE_FILE_NOT_FOUND)(file));
|
|
256
306
|
}
|
|
257
307
|
const YAML = require('yaml');
|
|
258
308
|
const content = (0, fs_1.readFileSync)(filePath, 'utf8');
|
|
@@ -261,33 +311,40 @@ function validatePipelineFile(file, unions) {
|
|
|
261
311
|
parsed = YAML.parse(content);
|
|
262
312
|
}
|
|
263
313
|
catch (e) {
|
|
264
|
-
|
|
265
|
-
return;
|
|
314
|
+
invalidDocument((0, texts_1.ERR_YAML_PARSE)(e.message));
|
|
266
315
|
}
|
|
267
316
|
if (!parsed || typeof parsed !== 'object') {
|
|
268
|
-
|
|
269
|
-
return;
|
|
317
|
+
invalidDocument(texts_1.ERR_YAML_NOT_ARRAY);
|
|
270
318
|
}
|
|
271
319
|
if (!Array.isArray(parsed)) {
|
|
272
|
-
|
|
273
|
-
return;
|
|
320
|
+
invalidDocument(texts_1.ERR_YAML_PLAIN_OBJECT);
|
|
274
321
|
}
|
|
275
322
|
if (parsed.length === 0) {
|
|
276
|
-
|
|
277
|
-
return;
|
|
323
|
+
invalidDocument(texts_1.ERR_YAML_EMPTY_ARRAY);
|
|
278
324
|
}
|
|
279
325
|
let errors = 0;
|
|
280
326
|
for (let i = 0; i < parsed.length; i++) {
|
|
281
327
|
const pipeline = parsed[i];
|
|
328
|
+
context.pipeline = i + 1;
|
|
282
329
|
if (!pipeline || typeof pipeline !== 'object' || Array.isArray(pipeline)) {
|
|
283
|
-
|
|
330
|
+
recordError(context, '', (0, texts_1.ERR_YAML_PIPELINE_NOT_OBJECT)(i + 1));
|
|
331
|
+
context.output.error(` ${(0, texts_1.ERR_YAML_PIPELINE_NOT_OBJECT)(i + 1)}`);
|
|
284
332
|
errors++;
|
|
285
333
|
continue;
|
|
286
334
|
}
|
|
287
335
|
const pipelineLabel = parsed.length > 1 ? `[${pipeline.pipeline || i + 1}] ` : '';
|
|
288
|
-
errors += validateSinglePipeline(pipeline, pipelineLabel, unions);
|
|
336
|
+
errors += validateSinglePipeline(pipeline, pipelineLabel, unions, context);
|
|
337
|
+
}
|
|
338
|
+
if (json) {
|
|
339
|
+
output_1.default.json({
|
|
340
|
+
valid: errors === 0,
|
|
341
|
+
pipelines: parsed.length,
|
|
342
|
+
errors: context.errors,
|
|
343
|
+
warnings: context.warnings,
|
|
344
|
+
});
|
|
345
|
+
output_1.default.exitCode(errors > 0 ? 1 : 0);
|
|
289
346
|
}
|
|
290
|
-
|
|
347
|
+
context.output.normal('');
|
|
291
348
|
if (errors > 0) {
|
|
292
349
|
output_1.default.exitError((0, texts_1.ERR_YAML_VALIDATE_FAILED_COUNT)(errors));
|
|
293
350
|
}
|
|
@@ -296,11 +353,13 @@ function validatePipelineFile(file, unions) {
|
|
|
296
353
|
}
|
|
297
354
|
}
|
|
298
355
|
const commandYamlValidate = (0, utils_1.newCommand)('validate', texts_1.DESC_COMMAND_YAML_VALIDATE, {
|
|
356
|
+
helpText: texts_1.HELP_YAML_VALIDATE_JSON,
|
|
299
357
|
examples: texts_1.EXAMPLE_YAML_VALIDATE,
|
|
300
358
|
});
|
|
301
359
|
commandYamlValidate.argument('<file>', texts_1.OPTION_YAML_VALIDATE_FILE);
|
|
302
|
-
commandYamlValidate.
|
|
360
|
+
commandYamlValidate.option('--format <text|json>', texts_1.OPTION_FORMAT);
|
|
361
|
+
commandYamlValidate.action(async (file, options) => {
|
|
303
362
|
await (0, schemaUtils_1.ensureYamlSchema)();
|
|
304
|
-
validatePipelineFile(file, await unionMappings((0, schemaUtils_1.getAllDefs)()));
|
|
363
|
+
validatePipelineFile(file, await unionMappings((0, schemaUtils_1.getAllDefs)()), options.format === 'json');
|
|
305
364
|
});
|
|
306
365
|
exports.default = commandYamlValidate;
|
package/distTs/src/openapi.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.apiEndpoints = apiEndpoints;
|
|
4
|
+
exports.apiSpecification = apiSpecification;
|
|
4
5
|
const docs_schema_1 = require("@buddy-works/docs-schema");
|
|
5
6
|
const texts_1 = require("./texts");
|
|
6
7
|
const utils_1 = require("./utils");
|
|
7
8
|
const diskCache_1 = require("./diskCache");
|
|
8
9
|
let held = null;
|
|
10
|
+
let specification = null;
|
|
9
11
|
async function apiEndpoints(baseUrl) {
|
|
10
12
|
if (held)
|
|
11
13
|
return held;
|
|
@@ -18,10 +20,15 @@ async function apiEndpoints(baseUrl) {
|
|
|
18
20
|
if (!raw)
|
|
19
21
|
throw new Error(texts_1.ERR_SCHEMA_FETCH_FAILED);
|
|
20
22
|
try {
|
|
21
|
-
|
|
23
|
+
specification = JSON.parse(raw);
|
|
24
|
+
held = docs_schema_1.BuddySchema.from({ api: specification }).api;
|
|
22
25
|
}
|
|
23
26
|
catch {
|
|
24
27
|
throw new Error(texts_1.ERR_SCHEMA_FETCH_FAILED);
|
|
25
28
|
}
|
|
26
29
|
return held;
|
|
27
30
|
}
|
|
31
|
+
async function apiSpecification(baseUrl) {
|
|
32
|
+
await apiEndpoints(baseUrl);
|
|
33
|
+
return specification;
|
|
34
|
+
}
|
package/distTs/src/output.js
CHANGED
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
const texts_1 = require("./texts");
|
|
7
7
|
const utils_1 = require("./utils");
|
|
8
8
|
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
const node_readline_1 = require("node:readline");
|
|
9
10
|
let _terminal = null;
|
|
10
11
|
function getTerminal() {
|
|
11
12
|
if (!_terminal) {
|
|
@@ -134,6 +135,15 @@ class Output {
|
|
|
134
135
|
msg += '\n';
|
|
135
136
|
getTerminal()(msg);
|
|
136
137
|
}
|
|
138
|
+
static progress(quiet, output = this.normal.bind(this)) {
|
|
139
|
+
return (txt, newLine = true, replacePrevious = false) => {
|
|
140
|
+
if (quiet)
|
|
141
|
+
return;
|
|
142
|
+
if (replacePrevious)
|
|
143
|
+
this.clearPreviousLine();
|
|
144
|
+
output(txt, newLine);
|
|
145
|
+
};
|
|
146
|
+
}
|
|
137
147
|
// Payload output (command results, logs, JSON): bypasses terminal-kit,
|
|
138
148
|
// whose printf-style formatting and ^-markup corrupt data containing
|
|
139
149
|
// % or ^ sequences. newLine=false emits a mid-stream chunk, keeping
|
|
@@ -652,6 +662,35 @@ class Output {
|
|
|
652
662
|
static json(json) {
|
|
653
663
|
this.data(JSON.stringify(json));
|
|
654
664
|
}
|
|
665
|
+
static async streamCommandLogs(body, jsonl) {
|
|
666
|
+
// readline preserves UTF-8 and records split across transport chunks.
|
|
667
|
+
const lines = (0, node_readline_1.createInterface)({ input: body, crlfDelay: Infinity });
|
|
668
|
+
for await (const line of lines) {
|
|
669
|
+
if (!line.trim())
|
|
670
|
+
continue;
|
|
671
|
+
let record;
|
|
672
|
+
try {
|
|
673
|
+
record = JSON.parse(line);
|
|
674
|
+
}
|
|
675
|
+
catch {
|
|
676
|
+
continue;
|
|
677
|
+
}
|
|
678
|
+
if (typeof record?.data !== 'string')
|
|
679
|
+
continue;
|
|
680
|
+
if (jsonl) {
|
|
681
|
+
this.json({
|
|
682
|
+
type: 'log',
|
|
683
|
+
...(record.stream === 'stdout' || record.stream === 'stderr'
|
|
684
|
+
? { stream: record.stream }
|
|
685
|
+
: {}),
|
|
686
|
+
data: record.data,
|
|
687
|
+
});
|
|
688
|
+
}
|
|
689
|
+
else if (record.data) {
|
|
690
|
+
this.data(record.data);
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
}
|
|
655
694
|
static exitError(err) {
|
|
656
695
|
this.clearUndici();
|
|
657
696
|
this.clearTerminal();
|