@levr-one/cli 0.9.27 → 0.9.29
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/dist/cli.js +17 -12
- package/dist/{importHandler-B1CGwwkp.js → importHandler-B42PBtOB.js} +2 -2
- package/dist/{listHandler-Dymi1kt4.js → listHandler-DmG_OvBC.js} +1 -1
- package/dist/{loginHandler-CLyQKoYe.js → loginHandler-C2Ax94AS.js} +2 -2
- package/dist/{pushHandler-anBd1pkW.js → pushHandler-DEuoXQXJ.js} +23 -38
- package/dist/{resolve-workspace-CLhu0X0z.js → resolve-workspace-DmqApDw5.js} +1 -1
- package/dist/{sdk-client-DtubAZgv.js → sdk-client-CQa-x1zl.js} +29 -58
- package/dist/{selectHandler-DSNQdwPV.js → selectHandler-DmpxYqaN.js} +1 -1
- package/dist/{statusHandler-DUW3yPTK.js → statusHandler-BuAkYg-T.js} +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -213,7 +213,7 @@ Examples:
|
|
|
213
213
|
aliases: { d: "device-code" }
|
|
214
214
|
},
|
|
215
215
|
loader: async () => {
|
|
216
|
-
const { loginHandler } = await import("./loginHandler-
|
|
216
|
+
const { loginHandler } = await import("./loginHandler-C2Ax94AS.js");
|
|
217
217
|
return loginHandler;
|
|
218
218
|
}
|
|
219
219
|
});
|
|
@@ -252,7 +252,7 @@ Examples:
|
|
|
252
252
|
},
|
|
253
253
|
parameters: {},
|
|
254
254
|
loader: async () => {
|
|
255
|
-
const { statusHandler } = await import("./statusHandler-
|
|
255
|
+
const { statusHandler } = await import("./statusHandler-BuAkYg-T.js");
|
|
256
256
|
return statusHandler;
|
|
257
257
|
}
|
|
258
258
|
});
|
|
@@ -264,18 +264,23 @@ const pushCommand = buildCommand({
|
|
|
264
264
|
brief: "Push test results to Levr",
|
|
265
265
|
fullDescription: `Upload a test result file to Levr.
|
|
266
266
|
|
|
267
|
-
The backend auto-detects the file format (JUnit XML, Gherkin, Cucumber JSON).
|
|
267
|
+
The backend auto-detects the file format (JUnit XML, Gherkin, Cucumber JSON, CTRF JSON).
|
|
268
268
|
In CI environments, the automation source name and CI metadata are auto-detected.
|
|
269
269
|
|
|
270
|
+
An automation source is required: a name (--source, LEVR_SOURCE, or CI
|
|
271
|
+
auto-detection; created on first use) or the UUID of an existing source
|
|
272
|
+
(--automation-source or LEVR_AUTOMATION_SOURCE_ID). The UUID wins if both are set.
|
|
273
|
+
|
|
270
274
|
Team ID is optional. When omitted, the server resolves the team from:
|
|
271
275
|
1. The existing automation source's team (if --source matches a known source)
|
|
272
276
|
2. The workspace's default team
|
|
277
|
+
With --automation-source the team is always that source's team.
|
|
273
278
|
|
|
274
279
|
Examples:
|
|
275
|
-
levr push ./test-results.xml
|
|
276
280
|
levr push ./results.xml --source "backend-unit-tests"
|
|
277
|
-
levr push ./
|
|
278
|
-
levr push ./report.json
|
|
281
|
+
levr push ./results.xml --automation-source <uuid>
|
|
282
|
+
levr push ./report.json --source e2e --team-id <uuid> # explicit team
|
|
283
|
+
levr push ./test-results.xml # in CI: source auto-detected`
|
|
279
284
|
},
|
|
280
285
|
parameters: {
|
|
281
286
|
positional: {
|
|
@@ -312,7 +317,7 @@ Examples:
|
|
|
312
317
|
"automation-source": {
|
|
313
318
|
kind: "parsed",
|
|
314
319
|
parse: String,
|
|
315
|
-
brief: "
|
|
320
|
+
brief: "UUID of an existing automation source (never creates one). Used instead of --source.",
|
|
316
321
|
placeholder: "uuid",
|
|
317
322
|
optional: true
|
|
318
323
|
},
|
|
@@ -364,7 +369,7 @@ Examples:
|
|
|
364
369
|
}
|
|
365
370
|
},
|
|
366
371
|
loader: async () => {
|
|
367
|
-
const { pushHandler } = await import("./pushHandler-
|
|
372
|
+
const { pushHandler } = await import("./pushHandler-DEuoXQXJ.js");
|
|
368
373
|
return pushHandler;
|
|
369
374
|
}
|
|
370
375
|
});
|
|
@@ -484,7 +489,7 @@ Examples:
|
|
|
484
489
|
}
|
|
485
490
|
},
|
|
486
491
|
loader: async () => {
|
|
487
|
-
const { importHandler } = await import("./importHandler-
|
|
492
|
+
const { importHandler } = await import("./importHandler-B42PBtOB.js");
|
|
488
493
|
return importHandler;
|
|
489
494
|
}
|
|
490
495
|
});
|
|
@@ -505,7 +510,7 @@ Examples:
|
|
|
505
510
|
},
|
|
506
511
|
parameters: {},
|
|
507
512
|
loader: async () => {
|
|
508
|
-
const { listHandler } = await import("./listHandler-
|
|
513
|
+
const { listHandler } = await import("./listHandler-DmG_OvBC.js");
|
|
509
514
|
return listHandler;
|
|
510
515
|
}
|
|
511
516
|
});
|
|
@@ -538,7 +543,7 @@ Examples:
|
|
|
538
543
|
flags: {}
|
|
539
544
|
},
|
|
540
545
|
loader: async () => {
|
|
541
|
-
const { selectHandler } = await import("./selectHandler-
|
|
546
|
+
const { selectHandler } = await import("./selectHandler-DmpxYqaN.js");
|
|
542
547
|
return selectHandler;
|
|
543
548
|
}
|
|
544
549
|
});
|
|
@@ -562,7 +567,7 @@ Examples:
|
|
|
562
567
|
|
|
563
568
|
//#endregion
|
|
564
569
|
//#region package.json
|
|
565
|
-
var version = "0.9.
|
|
570
|
+
var version = "0.9.29";
|
|
566
571
|
|
|
567
572
|
//#endregion
|
|
568
573
|
//#region src/app.ts
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { getApiUrl, getTeamId } from "./env-CHeKHu5S.js";
|
|
2
|
-
import { authGetProfileV1, configureClient, teamFindAllV1, testCaseImportCommitV1, testCaseImportPreviewV1 } from "./sdk-client-
|
|
2
|
+
import { authGetProfileV1, configureClient, teamFindAllV1, testCaseImportCommitV1, testCaseImportPreviewV1 } from "./sdk-client-CQa-x1zl.js";
|
|
3
3
|
import "./workspace-store-DDOxnut1.js";
|
|
4
|
-
import { resolveWorkspace } from "./resolve-workspace-
|
|
4
|
+
import { resolveWorkspace } from "./resolve-workspace-DmqApDw5.js";
|
|
5
5
|
import "./token-refresh-Cu5RpkLJ.js";
|
|
6
6
|
import { resolveToken } from "./resolve-token-DbQsmn03.js";
|
|
7
7
|
import chalk from "chalk";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "./env-CHeKHu5S.js";
|
|
2
|
-
import { authGetSitesV1, configureClient } from "./sdk-client-
|
|
2
|
+
import { authGetSitesV1, configureClient } from "./sdk-client-CQa-x1zl.js";
|
|
3
3
|
import { loadWorkspace } from "./workspace-store-DDOxnut1.js";
|
|
4
4
|
import "./token-refresh-Cu5RpkLJ.js";
|
|
5
5
|
import { resolveToken } from "./resolve-token-DbQsmn03.js";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { CLI_CLIENT_ID, getApiUrl, getAuthUrl, setSessionApiUrl, writeCredentials } from "./env-CHeKHu5S.js";
|
|
2
|
-
import { configureClient } from "./sdk-client-
|
|
2
|
+
import { configureClient } from "./sdk-client-CQa-x1zl.js";
|
|
3
3
|
import "./workspace-store-DDOxnut1.js";
|
|
4
|
-
import { autoSelectWorkspace } from "./resolve-workspace-
|
|
4
|
+
import { autoSelectWorkspace } from "./resolve-workspace-DmqApDw5.js";
|
|
5
5
|
import chalk from "chalk";
|
|
6
6
|
import { createHash, randomBytes } from "node:crypto";
|
|
7
7
|
import { createServer } from "node:http";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { getApiUrl, getAutomationSourceIdOverride, getSourceOverride, getTeamId } from "./env-CHeKHu5S.js";
|
|
2
|
-
import { client, configureClient,
|
|
2
|
+
import { client, configureClient, uploadImport } from "./sdk-client-CQa-x1zl.js";
|
|
3
3
|
import "./workspace-store-DDOxnut1.js";
|
|
4
|
-
import { resolveWorkspace } from "./resolve-workspace-
|
|
4
|
+
import { resolveWorkspace } from "./resolve-workspace-DmqApDw5.js";
|
|
5
5
|
import "./token-refresh-Cu5RpkLJ.js";
|
|
6
6
|
import { resolveToken } from "./resolve-token-DbQsmn03.js";
|
|
7
7
|
import { readFileSync, statSync } from "node:fs";
|
|
@@ -412,24 +412,26 @@ async function pushHandler(flags, file) {
|
|
|
412
412
|
if (flags.source) sourceOrigin = "explicit";
|
|
413
413
|
else if (getSourceOverride()) sourceOrigin = "LEVR_SOURCE";
|
|
414
414
|
else if (sourceName) sourceOrigin = "auto-detected";
|
|
415
|
-
|
|
416
|
-
|
|
415
|
+
const automationSourceId = flags["automation-source"] ?? getAutomationSourceIdOverride();
|
|
416
|
+
const automationSourceOrigin = flags["automation-source"] ? "explicit" : automationSourceId ? "LEVR_AUTOMATION_SOURCE_ID" : void 0;
|
|
417
|
+
if (!sourceName && !automationSourceId) {
|
|
418
|
+
this.logger.error("Error: --source is required. Provide it explicitly with --source (or an existing source UUID with --automation-source), set the LEVR_SOURCE env var, or run in a supported CI environment for auto-detection.");
|
|
417
419
|
this.logger.error("");
|
|
418
420
|
this.logger.error("Example:");
|
|
419
421
|
this.logger.error(" levr push results.xml --source backend-unit-tests");
|
|
420
422
|
this.process.exitCode = 1;
|
|
421
423
|
return;
|
|
422
424
|
}
|
|
423
|
-
|
|
424
|
-
const
|
|
425
|
+
if (automationSourceId && sourceName && sourceOrigin !== "auto-detected") this.logger.warning(`--automation-source (${automationSourceOrigin}) takes precedence; ignoring source name "${sourceName}" (${sourceOrigin}).`);
|
|
426
|
+
const uploadTeamId = automationSourceId && !flags["team-id"] ? void 0 : teamId;
|
|
425
427
|
const ciMeta = getCiMetadata();
|
|
426
428
|
if (flags.verbose) {
|
|
427
|
-
this.logger.debug(`Team: ${
|
|
429
|
+
this.logger.debug(`Team: ${uploadTeamId ?? (automationSourceId ? "(automation source's team)" : "(server default)")}`);
|
|
428
430
|
this.logger.debug(`File: ${file} (${formatBytes(fileStat.size)})`);
|
|
429
431
|
if (flags.format) this.logger.debug(`Format: ${flags.format}`);
|
|
430
432
|
if (flags["update-mode"]) this.logger.debug(`Update mode: ${flags["update-mode"]}`);
|
|
431
|
-
if (
|
|
432
|
-
if (
|
|
433
|
+
if (automationSourceId) this.logger.debug(`Automation source: ${automationSourceId} (${automationSourceOrigin})`);
|
|
434
|
+
else if (sourceName) this.logger.debug(`Source: ${sourceName} (${sourceOrigin})`);
|
|
433
435
|
if (ciMeta) {
|
|
434
436
|
this.logger.debug(`CI detected: ${ciMeta.ci_provider?.replace(/_/g, " ") ?? "unknown"}`);
|
|
435
437
|
if (ciMeta.branch) this.logger.debug(`Branch: ${ciMeta.branch}`);
|
|
@@ -445,39 +447,15 @@ async function pushHandler(flags, file) {
|
|
|
445
447
|
}).start();
|
|
446
448
|
try {
|
|
447
449
|
const fileBuffer = readFileSync(file);
|
|
448
|
-
const fileObj = new File([fileBuffer], fileName);
|
|
449
|
-
if (automationSourceId) {
|
|
450
|
-
const ingestResult = await uploadAutomationIngest({
|
|
451
|
-
file: fileObj,
|
|
452
|
-
fileName,
|
|
453
|
-
automationSourceId,
|
|
454
|
-
runName: flags["run-name"],
|
|
455
|
-
format: flags.format,
|
|
456
|
-
externalRunKey: ciMeta?.ci_build_id,
|
|
457
|
-
importMetadata: ciMeta
|
|
458
|
-
});
|
|
459
|
-
spinner.stop();
|
|
460
|
-
this.process.stdout.write("\nAutomation run ingested!\n\n");
|
|
461
|
-
this.process.stdout.write(` Run ID: ${ingestResult.automation_run_id}\n`);
|
|
462
|
-
this.process.stdout.write(` Source: ${automationSourceId}\n`);
|
|
463
|
-
this.process.stdout.write(` Results: ${ingestResult.passed} passed, ${ingestResult.failed} failed, ${ingestResult.errored} errored, ${ingestResult.skipped} skipped\n`);
|
|
464
|
-
this.process.stdout.write(` Total: ${ingestResult.total_tests}\n`);
|
|
465
|
-
if (ciMeta) {
|
|
466
|
-
const prettyProvider = ciMeta.ci_provider?.replace(/_/g, " ") ?? "CI";
|
|
467
|
-
const ciLabel = ciMeta.ci_build_id ? `${prettyProvider} #${ciMeta.ci_build_id}` : prettyProvider;
|
|
468
|
-
this.process.stdout.write(` CI: ${ciLabel}\n`);
|
|
469
|
-
}
|
|
470
|
-
return;
|
|
471
|
-
}
|
|
472
450
|
const result = await uploadImport({
|
|
473
|
-
teamId,
|
|
474
|
-
file:
|
|
451
|
+
teamId: uploadTeamId,
|
|
452
|
+
file: new File([fileBuffer], fileName),
|
|
475
453
|
fileName,
|
|
476
454
|
format: flags.format,
|
|
477
455
|
parentFolderId: flags["parent-folder-id"],
|
|
478
456
|
runName: flags["run-name"],
|
|
479
457
|
updateMode: flags["update-mode"],
|
|
480
|
-
automationSource: sourceName,
|
|
458
|
+
...automationSourceId ? { automationSourceId } : { automationSource: sourceName },
|
|
481
459
|
importMetadata: ciMeta
|
|
482
460
|
});
|
|
483
461
|
spinner.stop();
|
|
@@ -491,12 +469,19 @@ async function pushHandler(flags, file) {
|
|
|
491
469
|
if (result) {
|
|
492
470
|
if (result.team_id) this.process.stdout.write(` Team: ${result.team_id}\n`);
|
|
493
471
|
if (result.format) this.process.stdout.write(` Format: ${result.format}\n`);
|
|
494
|
-
if (
|
|
472
|
+
if (automationSourceId) this.process.stdout.write(` Source: ${result.automation_source_name ?? automationSourceId} (${automationSourceOrigin})\n`);
|
|
473
|
+
else if (sourceName) this.process.stdout.write(` Source: ${sourceName}${sourceOrigin ? ` (${sourceOrigin})` : ""}\n`);
|
|
495
474
|
if (result.result?.stats) {
|
|
496
475
|
const { tests_created, tests_updated } = result.result.stats;
|
|
497
476
|
this.process.stdout.write(` Tests: ${tests_created} created, ${tests_updated} updated\n`);
|
|
498
477
|
}
|
|
499
|
-
if (result.result?.run_id)
|
|
478
|
+
if (result.result?.run_id) {
|
|
479
|
+
this.process.stdout.write(` Run: ${result.result.run_id}\n`);
|
|
480
|
+
if (result.result.stats) {
|
|
481
|
+
const s = result.result.stats;
|
|
482
|
+
this.process.stdout.write(` Results: ${s.passed} passed, ${s.failed} failed, ${s.errored} errored, ${s.skipped} skipped\n`);
|
|
483
|
+
}
|
|
484
|
+
}
|
|
500
485
|
if (result.status === "completed_with_warnings" && result.result?.warnings?.length) {
|
|
501
486
|
this.process.stdout.write("\n");
|
|
502
487
|
const warnings = result.result.warnings;
|
|
@@ -3166,30 +3166,6 @@ const zAutomationRunUnarchiveV1Data = z.object({
|
|
|
3166
3166
|
url: z.literal("/v1/automation-run/{id}/unarchive")
|
|
3167
3167
|
});
|
|
3168
3168
|
|
|
3169
|
-
//#endregion
|
|
3170
|
-
//#region ../sdk/dist/gen/automation-run-ingest/functions.js
|
|
3171
|
-
/**
|
|
3172
|
-
* Accepts a CTRF/JUnit file plus an automation_source_id and writes automation_run + automation_run_result rows directly. Bypasses the ImportJob queue used by POST /v1/imports — returns the created automation_run_id synchronously. Use this from CI when you want a direct, non-queued ingest.
|
|
3173
|
-
*/
|
|
3174
|
-
const automationRunIngestIngestV1 = (options) => {
|
|
3175
|
-
return (options?.client ?? client).post({
|
|
3176
|
-
security: [{
|
|
3177
|
-
scheme: "bearer",
|
|
3178
|
-
type: "http"
|
|
3179
|
-
}],
|
|
3180
|
-
url: "/v1/automation-run/ingest",
|
|
3181
|
-
bodySerializer: (body) => {
|
|
3182
|
-
const fd = new FormData();
|
|
3183
|
-
if (body && typeof body === "object") for (const [k, v] of Object.entries(body)) {
|
|
3184
|
-
if (v == null) continue;
|
|
3185
|
-
fd.append(k, v instanceof Blob ? v : String(v));
|
|
3186
|
-
}
|
|
3187
|
-
return fd;
|
|
3188
|
-
},
|
|
3189
|
-
...options
|
|
3190
|
-
});
|
|
3191
|
-
};
|
|
3192
|
-
|
|
3193
3169
|
//#endregion
|
|
3194
3170
|
//#region ../sdk/dist/gen/automation-run-ingest/zod.js
|
|
3195
3171
|
const zAutomationRunIngestIngestV1Body = z.object({
|
|
@@ -15152,6 +15128,7 @@ const zImportCreateV1Body = z.object({
|
|
|
15152
15128
|
run_name: z.string().optional().describe(""),
|
|
15153
15129
|
update_mode: z.enum(["update", "create_new"]).optional().describe(""),
|
|
15154
15130
|
automation_source: z.string().optional().describe(""),
|
|
15131
|
+
automation_source_id: z.string().optional().describe(""),
|
|
15155
15132
|
import_metadata: z.string().optional().describe("")
|
|
15156
15133
|
});
|
|
15157
15134
|
const zImportResponseDto = z.object({
|
|
@@ -27868,6 +27845,29 @@ const zIngestRequestDto = z.object({
|
|
|
27868
27845
|
advance_cursor_to: z.string().optional(),
|
|
27869
27846
|
force_upsert: z.boolean().optional()
|
|
27870
27847
|
});
|
|
27848
|
+
const zSyncRoleResponseDto = z.object({
|
|
27849
|
+
role: z.enum(["hub", "spoke"]),
|
|
27850
|
+
spoke_key: z.string().nullable(),
|
|
27851
|
+
claimed_spoke_key: z.string().nullable(),
|
|
27852
|
+
reason_code: z.enum([
|
|
27853
|
+
"spoke_registered",
|
|
27854
|
+
"not_set_up",
|
|
27855
|
+
"self_row_not_a_spoke",
|
|
27856
|
+
"no_hub_row",
|
|
27857
|
+
"spokes_registered_here"
|
|
27858
|
+
]),
|
|
27859
|
+
reason: z.string(),
|
|
27860
|
+
remedy: z.string().nullable(),
|
|
27861
|
+
instance_id: z.string(),
|
|
27862
|
+
sync_sequence_head: z.string(),
|
|
27863
|
+
caller_is_workspace_admin: z.boolean(),
|
|
27864
|
+
hub_peer: z.object({
|
|
27865
|
+
peer_url: z.string().nullable(),
|
|
27866
|
+
hub_instance_id: z.string().nullable(),
|
|
27867
|
+
pull_cursor: z.string().nullable(),
|
|
27868
|
+
push_cursor: z.string().nullable()
|
|
27869
|
+
}).nullable()
|
|
27870
|
+
});
|
|
27871
27871
|
const zSyncGetSseContextV1Data = z.object({ url: z.literal("/v1/sync/sse-context") });
|
|
27872
27872
|
const zSyncGetLastSyncIdV1Data = z.object({ url: z.literal("/v1/sync/last-sync-id") });
|
|
27873
27873
|
const zSyncBootstrapV1Data = z.object({
|
|
@@ -27904,6 +27904,8 @@ const zSyncAdvancePushCursorV1Data = z.object({ url: z.literal("/v1/sync/advance
|
|
|
27904
27904
|
const zSyncCheckSpokeKeyV1Data = z.object({ url: z.literal("/v1/sync/check-spoke-key") });
|
|
27905
27905
|
const zSyncRegisterSpokeV1Data = z.object({ url: z.literal("/v1/sync/register-spoke") });
|
|
27906
27906
|
const zSyncRegisterPeerV1Data = z.object({ url: z.literal("/v1/sync/register-peer") });
|
|
27907
|
+
const zSyncGetSyncRoleV1Data = z.object({ url: z.literal("/v1/sync/role") });
|
|
27908
|
+
const zSyncUnregisterSpokeV1Data = z.object({ url: z.literal("/v1/sync/unregister-spoke") });
|
|
27907
27909
|
const zSyncStampSpokeKeyV1Data = z.object({ url: z.literal("/v1/sync/stamp-spoke-key") });
|
|
27908
27910
|
const zSyncRewriteIdentifiersV1Data = z.object({ url: z.literal("/v1/sync/rewrite-identifiers") });
|
|
27909
27911
|
const zSyncGetStaticInventoryV1Data = z.object({ url: z.literal("/v1/sync/static-inventory") });
|
|
@@ -31991,6 +31993,7 @@ async function uploadImport(options) {
|
|
|
31991
31993
|
run_name: options.runName,
|
|
31992
31994
|
update_mode: options.updateMode,
|
|
31993
31995
|
automation_source: options.automationSource,
|
|
31996
|
+
automation_source_id: options.automationSourceId,
|
|
31994
31997
|
import_metadata: options.importMetadata ? JSON.stringify(options.importMetadata) : void 0
|
|
31995
31998
|
},
|
|
31996
31999
|
requestValidator: void 0
|
|
@@ -32000,6 +32003,7 @@ async function uploadImport(options) {
|
|
|
32000
32003
|
switch (status) {
|
|
32001
32004
|
case 401: throw new Error("Authentication failed. Check your token or run 'levr auth login'.");
|
|
32002
32005
|
case 403: throw new Error("Permission denied. Check your team access.");
|
|
32006
|
+
case 404: throw new Error(tryReadMessage(result.error) ?? "Not found. Check --automation-source and --team-id.");
|
|
32003
32007
|
case 422: throw new Error("File could not be processed. Check the file format.");
|
|
32004
32008
|
case 429: throw new Error("Rate limited. Please try again later.");
|
|
32005
32009
|
default: throw new Error(`Import failed (${String(status ?? "unknown")}): ${JSON.stringify(result.error)}`);
|
|
@@ -32007,39 +32011,6 @@ async function uploadImport(options) {
|
|
|
32007
32011
|
}
|
|
32008
32012
|
return result.data;
|
|
32009
32013
|
}
|
|
32010
|
-
/**
|
|
32011
|
-
* Direct synchronous automation run ingest. Bypasses the ImportJob queue
|
|
32012
|
-
* used by uploadImport — calls POST /v1/automation-run/ingest and returns
|
|
32013
|
-
* the created automation_run_id immediately. Use when an
|
|
32014
|
-
* automation_source_id is known (from --automation-source flag or
|
|
32015
|
-
* LEVR_AUTOMATION_SOURCE_ID env var).
|
|
32016
|
-
*/
|
|
32017
|
-
async function uploadAutomationIngest(options) {
|
|
32018
|
-
const result = await automationRunIngestIngestV1({
|
|
32019
|
-
body: {
|
|
32020
|
-
file: options.file,
|
|
32021
|
-
automation_source_id: options.automationSourceId,
|
|
32022
|
-
run_name: options.runName,
|
|
32023
|
-
format: options.format,
|
|
32024
|
-
external_run_key: options.externalRunKey,
|
|
32025
|
-
import_metadata: options.importMetadata ? JSON.stringify(options.importMetadata) : void 0
|
|
32026
|
-
},
|
|
32027
|
-
requestValidator: void 0
|
|
32028
|
-
});
|
|
32029
|
-
if (result.error) {
|
|
32030
|
-
const status = result.response?.status;
|
|
32031
|
-
switch (status) {
|
|
32032
|
-
case 400: throw new Error(`Bad request: ${tryReadMessage(result.error) ?? "check --automation-source value and file"}`);
|
|
32033
|
-
case 401: throw new Error("Authentication failed. Check your token or run 'levr auth login'.");
|
|
32034
|
-
case 403: throw new Error("Permission denied. Check your workspace access.");
|
|
32035
|
-
case 404: throw new Error(`automation_source ${options.automationSourceId} not found in your workspace.`);
|
|
32036
|
-
case 422: throw new Error(`File could not be parsed: ${tryReadMessage(result.error) ?? "check the file and --format hint"}`);
|
|
32037
|
-
case 429: throw new Error("Rate limited. Please try again later.");
|
|
32038
|
-
default: throw new Error(`Automation ingest failed (${String(status ?? "unknown")}): ${JSON.stringify(result.error)}`);
|
|
32039
|
-
}
|
|
32040
|
-
}
|
|
32041
|
-
return result.data;
|
|
32042
|
-
}
|
|
32043
32014
|
function tryReadMessage(err) {
|
|
32044
32015
|
if (err && typeof err === "object" && "message" in err) {
|
|
32045
32016
|
const m = err.message;
|
|
@@ -32048,4 +32019,4 @@ function tryReadMessage(err) {
|
|
|
32048
32019
|
}
|
|
32049
32020
|
|
|
32050
32021
|
//#endregion
|
|
32051
|
-
export { authGetProfileV1, authGetSitesV1, client, configureClient, teamFindAllV1, testCaseImportCommitV1, testCaseImportPreviewV1,
|
|
32022
|
+
export { authGetProfileV1, authGetSitesV1, client, configureClient, teamFindAllV1, testCaseImportCommitV1, testCaseImportPreviewV1, uploadImport };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import "./env-CHeKHu5S.js";
|
|
2
|
-
import { authGetSitesV1, configureClient } from "./sdk-client-
|
|
2
|
+
import { authGetSitesV1, configureClient } from "./sdk-client-CQa-x1zl.js";
|
|
3
3
|
import { saveWorkspace } from "./workspace-store-DDOxnut1.js";
|
|
4
4
|
import "./token-refresh-Cu5RpkLJ.js";
|
|
5
5
|
import { resolveToken } from "./resolve-token-DbQsmn03.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getApiUrl, getPatToken, readCredentials } from "./env-CHeKHu5S.js";
|
|
2
|
-
import { authGetProfileV1, configureClient } from "./sdk-client-
|
|
2
|
+
import { authGetProfileV1, configureClient } from "./sdk-client-CQa-x1zl.js";
|
|
3
3
|
import { isTokenExpired } from "./token-refresh-Cu5RpkLJ.js";
|
|
4
4
|
import chalk from "chalk";
|
|
5
5
|
|