@levr-one/cli 0.12.5 → 0.12.7
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/{addHandler-CAmLxnsF.js → addHandler-ybX54_3f.js} +6 -6
- package/dist/{appendHandler-CUmlIX6q.js → appendHandler-CKkl9ymw.js} +7 -7
- package/dist/{artifact-upload-BvBSevIx.js → artifact-upload-Ba801tb6.js} +1 -1
- package/dist/{attachHandler-DXZi2ILT.js → attachHandler-CfNvVAV2.js} +7 -7
- package/dist/cli.js +18 -18
- package/dist/{connect-DVjgyfls.js → connect-yq3fGXkW.js} +9 -8
- package/dist/{find-workspace-Bl4rfr73.js → find-workspace-4Us2vEb7.js} +1 -1
- package/dist/{importHandler-BhOznIQW.js → importHandler-bYBWYC_0.js} +8 -8
- package/dist/{listHandler-DjWj1D3H.js → listHandler-Du_YGzre.js} +4 -4
- package/dist/{loginHandler-C9Oi92IY.js → loginHandler-PbKmDAGo.js} +4 -4
- package/dist/{logoutHandler-Cf5aI1wq.js → logoutHandler-DxnzGPYx.js} +1 -1
- package/dist/{pushHandler-NvZYBz-H.js → pushHandler-BulraEwP.js} +15 -13
- package/dist/{refsHandler-DtcceTRP.js → refsHandler--ySvLjmX.js} +6 -4
- package/dist/{resolve-token-ByZq05Us.js → resolve-token-DKEXT7SA.js} +8 -5
- package/dist/{resolve-workspace-BbK3uYQc.js → resolve-workspace-D8y7twod.js} +37 -5
- package/dist/{runHandler-CTfUyBNW.js → runHandler-B-u-0eRk.js} +25 -13
- package/dist/{sdk-client-B4FMd_Fa.js → sdk-client-BgzKzVIR.js} +1 -1
- package/dist/{selectHandler-CrLuGY3d.js → selectHandler-C0gs-Q70.js} +9 -4
- package/dist/{statusHandler-BQXn93-r.js → statusHandler-Dnnh80ZN.js} +7 -5
- package/dist/{token-refresh-CJB7Qlxy.js → token-refresh-BpFuU4Ij.js} +26 -2
- package/package.json +1 -1
- /package/dist/{env-CvjMSRd7.js → env-DjeRwmZ7.js} +0 -0
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { configureClient } from "./sdk-client-
|
|
2
|
-
import
|
|
3
|
-
import "./
|
|
4
|
-
import { resolveToken } from "./resolve-token-
|
|
1
|
+
import { configureClient } from "./sdk-client-BgzKzVIR.js";
|
|
2
|
+
import "./token-refresh-BpFuU4Ij.js";
|
|
3
|
+
import { getApiUrl } from "./env-DjeRwmZ7.js";
|
|
4
|
+
import { resolveToken } from "./resolve-token-DKEXT7SA.js";
|
|
5
5
|
import "./workspace-store-Bmw104Qa.js";
|
|
6
|
-
import { fetchSites } from "./resolve-workspace-
|
|
7
|
-
import { describeWorkspaces, findWorkspaceByKeyOrName, isScopedMcpUrl, resolveMcpUrl, scopedMcpUrl, servedBySessionApi } from "./find-workspace-
|
|
6
|
+
import { fetchSites } from "./resolve-workspace-D8y7twod.js";
|
|
7
|
+
import { describeWorkspaces, findWorkspaceByKeyOrName, isScopedMcpUrl, resolveMcpUrl, scopedMcpUrl, servedBySessionApi } from "./find-workspace-4Us2vEb7.js";
|
|
8
8
|
import { chmodSync, copyFileSync, existsSync, mkdirSync, readFileSync, realpathSync, renameSync, statSync, unlinkSync, writeFileSync } from "node:fs";
|
|
9
9
|
import { basename, delimiter, dirname, join, resolve } from "node:path";
|
|
10
10
|
import { homedir } from "node:os";
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { appendActualResult } from "./sdk-client-
|
|
2
|
-
import "./
|
|
3
|
-
import "./
|
|
4
|
-
import "./resolve-token-
|
|
1
|
+
import { appendActualResult } from "./sdk-client-BgzKzVIR.js";
|
|
2
|
+
import "./token-refresh-BpFuU4Ij.js";
|
|
3
|
+
import "./env-DjeRwmZ7.js";
|
|
4
|
+
import "./resolve-token-DKEXT7SA.js";
|
|
5
5
|
import "./workspace-store-Bmw104Qa.js";
|
|
6
|
-
import "./resolve-workspace-
|
|
7
|
-
import { connect } from "./connect-
|
|
6
|
+
import "./resolve-workspace-D8y7twod.js";
|
|
7
|
+
import { connect } from "./connect-yq3fGXkW.js";
|
|
8
8
|
import "./sleep-CGBHjsj5.js";
|
|
9
|
-
import { embedMarkdown, parseTarget, uploadArtifactFile } from "./artifact-upload-
|
|
9
|
+
import { embedMarkdown, parseTarget, uploadArtifactFile } from "./artifact-upload-Ba801tb6.js";
|
|
10
10
|
import { readFileSync } from "node:fs";
|
|
11
11
|
import { basename } from "node:path";
|
|
12
12
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { uploadAttachment } from "./sdk-client-
|
|
1
|
+
import { uploadAttachment } from "./sdk-client-BgzKzVIR.js";
|
|
2
2
|
import { sleep } from "./sleep-CGBHjsj5.js";
|
|
3
3
|
import { constants, promises, readlinkSync, realpathSync, statSync } from "node:fs";
|
|
4
4
|
import path from "node:path";
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { appendActualResult, createComment } from "./sdk-client-
|
|
2
|
-
import "./
|
|
3
|
-
import "./
|
|
4
|
-
import "./resolve-token-
|
|
1
|
+
import { appendActualResult, createComment } from "./sdk-client-BgzKzVIR.js";
|
|
2
|
+
import "./token-refresh-BpFuU4Ij.js";
|
|
3
|
+
import "./env-DjeRwmZ7.js";
|
|
4
|
+
import "./resolve-token-DKEXT7SA.js";
|
|
5
5
|
import "./workspace-store-Bmw104Qa.js";
|
|
6
|
-
import "./resolve-workspace-
|
|
7
|
-
import { connect } from "./connect-
|
|
6
|
+
import "./resolve-workspace-D8y7twod.js";
|
|
7
|
+
import { connect } from "./connect-yq3fGXkW.js";
|
|
8
8
|
import "./sleep-CGBHjsj5.js";
|
|
9
|
-
import { TargetParseError, embedMarkdown, parseTarget, uploadArtifactFile } from "./artifact-upload-
|
|
9
|
+
import { TargetParseError, embedMarkdown, parseTarget, uploadArtifactFile } from "./artifact-upload-Ba801tb6.js";
|
|
10
10
|
import { readFileSync } from "node:fs";
|
|
11
11
|
import { basename } from "node:path";
|
|
12
12
|
|
package/dist/cli.js
CHANGED
|
@@ -224,7 +224,7 @@ Examples:
|
|
|
224
224
|
aliases: { y: "yes" }
|
|
225
225
|
},
|
|
226
226
|
loader: async () => {
|
|
227
|
-
const { mcpAddHandler } = await import("./addHandler-
|
|
227
|
+
const { mcpAddHandler } = await import("./addHandler-ybX54_3f.js");
|
|
228
228
|
return mcpAddHandler;
|
|
229
229
|
}
|
|
230
230
|
});
|
|
@@ -273,7 +273,7 @@ Examples:
|
|
|
273
273
|
aliases: { d: "device-code" }
|
|
274
274
|
},
|
|
275
275
|
loader: async () => {
|
|
276
|
-
const { loginHandler } = await import("./loginHandler-
|
|
276
|
+
const { loginHandler } = await import("./loginHandler-PbKmDAGo.js");
|
|
277
277
|
return loginHandler;
|
|
278
278
|
}
|
|
279
279
|
});
|
|
@@ -292,7 +292,7 @@ Examples:
|
|
|
292
292
|
},
|
|
293
293
|
parameters: {},
|
|
294
294
|
loader: async () => {
|
|
295
|
-
const { logoutHandler } = await import("./logoutHandler-
|
|
295
|
+
const { logoutHandler } = await import("./logoutHandler-DxnzGPYx.js");
|
|
296
296
|
return logoutHandler;
|
|
297
297
|
}
|
|
298
298
|
});
|
|
@@ -312,7 +312,7 @@ Examples:
|
|
|
312
312
|
},
|
|
313
313
|
parameters: {},
|
|
314
314
|
loader: async () => {
|
|
315
|
-
const { statusHandler } = await import("./statusHandler-
|
|
315
|
+
const { statusHandler } = await import("./statusHandler-Dnnh80ZN.js");
|
|
316
316
|
return statusHandler;
|
|
317
317
|
}
|
|
318
318
|
});
|
|
@@ -367,7 +367,7 @@ levr attach --manifest or later uploads.`
|
|
|
367
367
|
"workspace-id": {
|
|
368
368
|
kind: "parsed",
|
|
369
369
|
parse: String,
|
|
370
|
-
brief: "Workspace ID
|
|
370
|
+
brief: "Workspace ID: needed with a login token and several workspaces; a personal access token is bound to its own",
|
|
371
371
|
placeholder: "uuid",
|
|
372
372
|
optional: true
|
|
373
373
|
},
|
|
@@ -441,7 +441,7 @@ levr attach --manifest or later uploads.`
|
|
|
441
441
|
}
|
|
442
442
|
},
|
|
443
443
|
loader: async () => {
|
|
444
|
-
const { pushHandler } = await import("./pushHandler-
|
|
444
|
+
const { pushHandler } = await import("./pushHandler-BulraEwP.js");
|
|
445
445
|
return pushHandler;
|
|
446
446
|
}
|
|
447
447
|
});
|
|
@@ -482,7 +482,7 @@ Examples:
|
|
|
482
482
|
"workspace-id": {
|
|
483
483
|
kind: "parsed",
|
|
484
484
|
parse: String,
|
|
485
|
-
brief: "Workspace ID
|
|
485
|
+
brief: "Workspace ID: needed with a login token and several workspaces; a personal access token is bound to its own",
|
|
486
486
|
placeholder: "uuid",
|
|
487
487
|
optional: true
|
|
488
488
|
},
|
|
@@ -561,7 +561,7 @@ Examples:
|
|
|
561
561
|
}
|
|
562
562
|
},
|
|
563
563
|
loader: async () => {
|
|
564
|
-
const { importHandler } = await import("./importHandler-
|
|
564
|
+
const { importHandler } = await import("./importHandler-bYBWYC_0.js");
|
|
565
565
|
return importHandler;
|
|
566
566
|
}
|
|
567
567
|
});
|
|
@@ -582,7 +582,7 @@ Examples:
|
|
|
582
582
|
},
|
|
583
583
|
parameters: {},
|
|
584
584
|
loader: async () => {
|
|
585
|
-
const { listHandler } = await import("./listHandler-
|
|
585
|
+
const { listHandler } = await import("./listHandler-Du_YGzre.js");
|
|
586
586
|
return listHandler;
|
|
587
587
|
}
|
|
588
588
|
});
|
|
@@ -620,7 +620,7 @@ Examples:
|
|
|
620
620
|
flags: {}
|
|
621
621
|
},
|
|
622
622
|
loader: async () => {
|
|
623
|
-
const { selectHandler } = await import("./selectHandler-
|
|
623
|
+
const { selectHandler } = await import("./selectHandler-C0gs-Q70.js");
|
|
624
624
|
return selectHandler;
|
|
625
625
|
}
|
|
626
626
|
});
|
|
@@ -695,7 +695,7 @@ Examples:
|
|
|
695
695
|
}
|
|
696
696
|
} },
|
|
697
697
|
loader: async () => {
|
|
698
|
-
const { gatesRefsHandler } = await import("./refsHandler
|
|
698
|
+
const { gatesRefsHandler } = await import("./refsHandler--ySvLjmX.js");
|
|
699
699
|
return gatesRefsHandler;
|
|
700
700
|
}
|
|
701
701
|
});
|
|
@@ -745,7 +745,7 @@ Examples:
|
|
|
745
745
|
"workspace-id": {
|
|
746
746
|
kind: "parsed",
|
|
747
747
|
parse: String,
|
|
748
|
-
brief: "Workspace ID
|
|
748
|
+
brief: "Workspace ID: needed with a login token and several workspaces; a personal access token is bound to its own",
|
|
749
749
|
placeholder: "uuid",
|
|
750
750
|
optional: true
|
|
751
751
|
},
|
|
@@ -776,7 +776,7 @@ Examples:
|
|
|
776
776
|
}
|
|
777
777
|
},
|
|
778
778
|
loader: async () => {
|
|
779
|
-
const { gatesRunHandler } = await import("./runHandler-
|
|
779
|
+
const { gatesRunHandler } = await import("./runHandler-B-u-0eRk.js");
|
|
780
780
|
return gatesRunHandler;
|
|
781
781
|
}
|
|
782
782
|
});
|
|
@@ -842,7 +842,7 @@ Examples:
|
|
|
842
842
|
"workspace-id": {
|
|
843
843
|
kind: "parsed",
|
|
844
844
|
parse: String,
|
|
845
|
-
brief: "Workspace ID
|
|
845
|
+
brief: "Workspace ID: needed with a login token and several workspaces; a personal access token is bound to its own",
|
|
846
846
|
placeholder: "uuid",
|
|
847
847
|
optional: true
|
|
848
848
|
},
|
|
@@ -889,7 +889,7 @@ Examples:
|
|
|
889
889
|
}
|
|
890
890
|
},
|
|
891
891
|
loader: async () => {
|
|
892
|
-
const { attachHandler } = await import("./attachHandler-
|
|
892
|
+
const { attachHandler } = await import("./attachHandler-CfNvVAV2.js");
|
|
893
893
|
return attachHandler;
|
|
894
894
|
}
|
|
895
895
|
});
|
|
@@ -924,7 +924,7 @@ Examples:
|
|
|
924
924
|
"workspace-id": {
|
|
925
925
|
kind: "parsed",
|
|
926
926
|
parse: String,
|
|
927
|
-
brief: "Workspace ID
|
|
927
|
+
brief: "Workspace ID: needed with a login token and several workspaces; a personal access token is bound to its own",
|
|
928
928
|
placeholder: "uuid",
|
|
929
929
|
optional: true
|
|
930
930
|
},
|
|
@@ -965,14 +965,14 @@ Examples:
|
|
|
965
965
|
}
|
|
966
966
|
},
|
|
967
967
|
loader: async () => {
|
|
968
|
-
const { resultAppendHandler } = await import("./appendHandler-
|
|
968
|
+
const { resultAppendHandler } = await import("./appendHandler-CKkl9ymw.js");
|
|
969
969
|
return resultAppendHandler;
|
|
970
970
|
}
|
|
971
971
|
});
|
|
972
972
|
|
|
973
973
|
//#endregion
|
|
974
974
|
//#region package.json
|
|
975
|
-
var version = "0.12.
|
|
975
|
+
var version = "0.12.7";
|
|
976
976
|
|
|
977
977
|
//#endregion
|
|
978
978
|
//#region src/app.ts
|
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { client, configureClient } from "./sdk-client-
|
|
2
|
-
import { resolveToken } from "./resolve-token-
|
|
3
|
-
import {
|
|
1
|
+
import { client, configureClient } from "./sdk-client-BgzKzVIR.js";
|
|
2
|
+
import { resolveToken } from "./resolve-token-DKEXT7SA.js";
|
|
3
|
+
import { resolveWorkspaceFor } from "./resolve-workspace-D8y7twod.js";
|
|
4
4
|
|
|
5
5
|
//#region src/utils/connect.ts
|
|
6
6
|
/**
|
|
7
7
|
* Authenticate the SDK client for a command (ENG-6164): resolve the token,
|
|
8
|
-
*
|
|
9
|
-
*
|
|
8
|
+
* then the workspace — looked up for a JWT, taken from an explicit flag or
|
|
9
|
+
* `LEVR_WORKSPACE_ID` for a PAT (ENG-6068). Reports the failure and sets exit
|
|
10
|
+
* code 1; returns false when the command must stop.
|
|
10
11
|
*/
|
|
11
12
|
async function connect(ctx, workspaceIdFlag) {
|
|
12
13
|
let auth;
|
|
@@ -18,9 +19,9 @@ async function connect(ctx, workspaceIdFlag) {
|
|
|
18
19
|
return false;
|
|
19
20
|
}
|
|
20
21
|
configureClient(auth);
|
|
21
|
-
|
|
22
|
-
const ws = await
|
|
23
|
-
client.setConfig({
|
|
22
|
+
try {
|
|
23
|
+
const ws = await resolveWorkspaceFor(auth, workspaceIdFlag);
|
|
24
|
+
if (ws) client.setConfig({
|
|
24
25
|
...client.getConfig(),
|
|
25
26
|
workspaceId: ws.workspaceId
|
|
26
27
|
});
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { authGetProfileV1, client, configureClient } from "./sdk-client-
|
|
2
|
-
import
|
|
3
|
-
import "./
|
|
4
|
-
import { resolveToken } from "./resolve-token-
|
|
1
|
+
import { authGetProfileV1, client, configureClient } from "./sdk-client-BgzKzVIR.js";
|
|
2
|
+
import "./token-refresh-BpFuU4Ij.js";
|
|
3
|
+
import { getApiUrl, getTeamId } from "./env-DjeRwmZ7.js";
|
|
4
|
+
import { resolveToken } from "./resolve-token-DKEXT7SA.js";
|
|
5
5
|
import "./workspace-store-Bmw104Qa.js";
|
|
6
|
-
import {
|
|
6
|
+
import { resolveWorkspaceFor } from "./resolve-workspace-D8y7twod.js";
|
|
7
7
|
import chalk from "chalk";
|
|
8
8
|
import { createReadStream } from "node:fs";
|
|
9
9
|
import { basename } from "node:path";
|
|
@@ -373,16 +373,16 @@ async function importHandler(flags, file) {
|
|
|
373
373
|
this.logger.debug(`Auth: ${auth.type.toUpperCase()}`);
|
|
374
374
|
this.logger.debug(`API: ${getApiUrl()}`);
|
|
375
375
|
}
|
|
376
|
-
|
|
376
|
+
{
|
|
377
377
|
let workspace;
|
|
378
378
|
try {
|
|
379
|
-
workspace = await
|
|
379
|
+
workspace = await resolveWorkspaceFor(auth, flags["workspace-id"]);
|
|
380
380
|
} catch (err) {
|
|
381
381
|
this.logger.error(err instanceof Error ? err.message : "Could not resolve the workspace.");
|
|
382
382
|
this.process.exitCode = 1;
|
|
383
383
|
return;
|
|
384
384
|
}
|
|
385
|
-
configureClient(auth, workspace.workspaceId);
|
|
385
|
+
if (workspace) configureClient(auth, workspace.workspaceId);
|
|
386
386
|
}
|
|
387
387
|
let teamId;
|
|
388
388
|
try {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { authGetSitesV1, configureClient } from "./sdk-client-
|
|
2
|
-
import "./
|
|
3
|
-
import "./
|
|
4
|
-
import { resolveToken } from "./resolve-token-
|
|
1
|
+
import { authGetSitesV1, configureClient } from "./sdk-client-BgzKzVIR.js";
|
|
2
|
+
import "./token-refresh-BpFuU4Ij.js";
|
|
3
|
+
import "./env-DjeRwmZ7.js";
|
|
4
|
+
import { resolveToken } from "./resolve-token-DKEXT7SA.js";
|
|
5
5
|
import { loadWorkspace } from "./workspace-store-Bmw104Qa.js";
|
|
6
6
|
|
|
7
7
|
//#region src/commands/workspace/listHandler.ts
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { configureClient } from "./sdk-client-
|
|
2
|
-
import { CLI_CLIENT_ID, getApiUrl, getAuthUrl, setSessionApiUrl, writeCredentials } from "./env-
|
|
1
|
+
import { configureClient } from "./sdk-client-BgzKzVIR.js";
|
|
2
|
+
import { CLI_CLIENT_ID, getApiUrl, getAuthUrl, setSessionApiUrl, writeCredentials } from "./env-DjeRwmZ7.js";
|
|
3
3
|
import { saveWorkspace } from "./workspace-store-Bmw104Qa.js";
|
|
4
|
-
import { autoSelectWorkspace, fetchSites } from "./resolve-workspace-
|
|
4
|
+
import { autoSelectWorkspace, fetchSites } from "./resolve-workspace-D8y7twod.js";
|
|
5
5
|
import { sleep } from "./sleep-CGBHjsj5.js";
|
|
6
|
-
import { findWorkspaceByKeyOrName, looksLikeUrlKey, resolveMcpUrl, scopedMcpUrl } from "./find-workspace-
|
|
6
|
+
import { findWorkspaceByKeyOrName, looksLikeUrlKey, resolveMcpUrl, scopedMcpUrl } from "./find-workspace-4Us2vEb7.js";
|
|
7
7
|
import chalk from "chalk";
|
|
8
8
|
import { createHash, randomBytes } from "node:crypto";
|
|
9
9
|
import { createServer } from "node:http";
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { client, configureClient, uploadImport } from "./sdk-client-
|
|
2
|
-
import
|
|
3
|
-
import "./
|
|
4
|
-
import { resolveToken } from "./resolve-token-
|
|
1
|
+
import { client, configureClient, uploadImport } from "./sdk-client-BgzKzVIR.js";
|
|
2
|
+
import "./token-refresh-BpFuU4Ij.js";
|
|
3
|
+
import { getApiUrl, getAutomationSourceIdOverride, getSourceOverride, getTeamId } from "./env-DjeRwmZ7.js";
|
|
4
|
+
import { resolveToken } from "./resolve-token-DKEXT7SA.js";
|
|
5
5
|
import "./workspace-store-Bmw104Qa.js";
|
|
6
|
-
import {
|
|
6
|
+
import { resolveWorkspaceFor } from "./resolve-workspace-D8y7twod.js";
|
|
7
7
|
import "./sleep-CGBHjsj5.js";
|
|
8
|
-
import { resolveArtifactPath, uploadArtifactFile } from "./artifact-upload-
|
|
8
|
+
import { resolveArtifactPath, uploadArtifactFile } from "./artifact-upload-Ba801tb6.js";
|
|
9
9
|
import { readFileSync, statSync, writeFileSync } from "node:fs";
|
|
10
10
|
import { basename, dirname, resolve } from "node:path";
|
|
11
11
|
import { execSync } from "node:child_process";
|
|
@@ -474,13 +474,15 @@ async function pushHandler(flags, file) {
|
|
|
474
474
|
this.logger.debug(`Auth: ${auth.type.toUpperCase()}`);
|
|
475
475
|
this.logger.debug(`API: ${getApiUrl()}`);
|
|
476
476
|
}
|
|
477
|
-
|
|
478
|
-
const ws = await
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
477
|
+
try {
|
|
478
|
+
const ws = await resolveWorkspaceFor(auth, flags["workspace-id"]);
|
|
479
|
+
if (ws) {
|
|
480
|
+
client.setConfig({
|
|
481
|
+
...client.getConfig(),
|
|
482
|
+
workspaceId: ws.workspaceId
|
|
483
|
+
});
|
|
484
|
+
if (flags.verbose) this.logger.debug(`Workspace: ${ws.workspaceId} (${ws.source})`);
|
|
485
|
+
} else if (flags.verbose) this.logger.debug("Workspace: the token's own");
|
|
484
486
|
} catch (err) {
|
|
485
487
|
this.logger.error(err instanceof Error ? err.message : "Workspace resolution failed.");
|
|
486
488
|
this.process.exitCode = 1;
|
|
@@ -156,9 +156,11 @@ function notFound(filesScanned, tsConfigPath) {
|
|
|
156
156
|
* interpret. The gate framework exists to make "verified" and "not verified"
|
|
157
157
|
* distinguishable, and an OOM is neither.
|
|
158
158
|
*
|
|
159
|
-
*
|
|
160
|
-
*
|
|
161
|
-
*
|
|
159
|
+
* 10,000 sits above the largest legitimate single scope in this repo and below
|
|
160
|
+
* the whole-repo set that does not. `apps/backender/src` was 6,314 files when
|
|
161
|
+
* the cap was 8000, and reached 8,016 with ENG-6802, which made every gate
|
|
162
|
+
* scoped to it refuse. It counts test files even when `includeTests` is off
|
|
163
|
+
* (about 1,100 of them); excluding those is a separate follow-up. Override deliberately with `--max-files` if a
|
|
162
164
|
* genuinely larger scope is ever needed — and expect to raise Node's heap with
|
|
163
165
|
* `NODE_OPTIONS=--max-old-space-size=...` at the same time.
|
|
164
166
|
*
|
|
@@ -168,7 +170,7 @@ function notFound(filesScanned, tsConfigPath) {
|
|
|
168
170
|
* would change verdicts for reasons that have nothing to do with the code.
|
|
169
171
|
* (Moved from `scripts/gates/symbol-referenced.lib.ts`, ENG-7284 D5.)
|
|
170
172
|
*/
|
|
171
|
-
const DEFAULT_MAX_FILES =
|
|
173
|
+
const DEFAULT_MAX_FILES = 1e4;
|
|
172
174
|
/** Thrown when the requested scope holds more files than the resolver will load. */
|
|
173
175
|
var ScopeTooBroadError = class extends Error {
|
|
174
176
|
fileCount;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { classifyToken, isTokenExpired, refreshToken } from "./token-refresh-BpFuU4Ij.js";
|
|
2
|
+
import { getApiUrl, getPatToken, readCredentials } from "./env-DjeRwmZ7.js";
|
|
3
3
|
|
|
4
4
|
//#region src/auth/resolve-token.ts
|
|
5
5
|
/**
|
|
@@ -16,7 +16,8 @@ var CredentialsMismatchError = class extends Error {
|
|
|
16
16
|
};
|
|
17
17
|
/**
|
|
18
18
|
* Resolve auth token in priority order:
|
|
19
|
-
* 1. LEVR_TOKEN env var
|
|
19
|
+
* 1. LEVR_TOKEN env var — a PAT or an OAuth access token, told apart by
|
|
20
|
+
* shape (ENG-6068); never refreshed
|
|
20
21
|
* 2. Stored credentials (JWT) — auto-refresh if expired
|
|
21
22
|
* 3. Error — not authenticated
|
|
22
23
|
*/
|
|
@@ -24,7 +25,8 @@ async function resolveToken() {
|
|
|
24
25
|
const pat = getPatToken();
|
|
25
26
|
if (pat) return {
|
|
26
27
|
token: pat,
|
|
27
|
-
type:
|
|
28
|
+
type: classifyToken(pat),
|
|
29
|
+
source: "env"
|
|
28
30
|
};
|
|
29
31
|
let creds = readCredentials();
|
|
30
32
|
if (creds) {
|
|
@@ -38,7 +40,8 @@ async function resolveToken() {
|
|
|
38
40
|
}
|
|
39
41
|
return {
|
|
40
42
|
token: creds.access_token,
|
|
41
|
-
type: "jwt"
|
|
43
|
+
type: "jwt",
|
|
44
|
+
source: "stored"
|
|
42
45
|
};
|
|
43
46
|
}
|
|
44
47
|
throw new Error("Not authenticated. Run 'levr auth login' or set LEVR_TOKEN environment variable.");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { authGetSitesV1 } from "./sdk-client-
|
|
1
|
+
import { authGetSitesV1 } from "./sdk-client-BgzKzVIR.js";
|
|
2
2
|
import { clearWorkspace, loadWorkspace, saveWorkspace } from "./workspace-store-Bmw104Qa.js";
|
|
3
3
|
|
|
4
4
|
//#region src/workspace/resolve-workspace.ts
|
|
@@ -40,7 +40,8 @@ async function autoSelectWorkspace() {
|
|
|
40
40
|
};
|
|
41
41
|
return { kind: "none" };
|
|
42
42
|
}
|
|
43
|
-
async function resolveWorkspace(flagValue) {
|
|
43
|
+
async function resolveWorkspace(flagValue, options = {}) {
|
|
44
|
+
const persist = options.persist ?? true;
|
|
44
45
|
let sites = null;
|
|
45
46
|
const getSites = async () => {
|
|
46
47
|
if (!sites) sites = await fetchSites();
|
|
@@ -61,7 +62,7 @@ async function resolveWorkspace(flagValue) {
|
|
|
61
62
|
source: "env"
|
|
62
63
|
};
|
|
63
64
|
}
|
|
64
|
-
const cached = loadWorkspace();
|
|
65
|
+
const cached = persist ? loadWorkspace() : null;
|
|
65
66
|
if (cached) {
|
|
66
67
|
if ((await getSites()).some((site) => site.workspace_id === cached)) return {
|
|
67
68
|
workspaceId: cached,
|
|
@@ -73,7 +74,7 @@ async function resolveWorkspace(flagValue) {
|
|
|
73
74
|
if (s.length === 0) throw new Error("No workspaces available.");
|
|
74
75
|
if (s.length === 1) {
|
|
75
76
|
const single = s[0];
|
|
76
|
-
saveWorkspace(single.workspace_id);
|
|
77
|
+
if (persist) saveWorkspace(single.workspace_id);
|
|
77
78
|
return {
|
|
78
79
|
workspaceId: single.workspace_id,
|
|
79
80
|
source: "auto"
|
|
@@ -84,6 +85,37 @@ async function resolveWorkspace(flagValue) {
|
|
|
84
85
|
const overflow = s.length > maxList ? `\n ... and ${s.length - maxList} more` : "";
|
|
85
86
|
throw new Error(`Multiple workspaces. Select one:\n${list}${overflow}\n\nRun: levr workspace select <id>`);
|
|
86
87
|
}
|
|
88
|
+
/**
|
|
89
|
+
* The workspace a command runs in, for whichever credential it holds —
|
|
90
|
+
* [issue:ENG-6068].
|
|
91
|
+
*
|
|
92
|
+
* A JWT is not bound to a workspace, so one is resolved the usual way: the
|
|
93
|
+
* flag, `LEVR_WORKSPACE_ID`, the cached selection, then auto-select, each
|
|
94
|
+
* validated against the sites the account can see.
|
|
95
|
+
*
|
|
96
|
+
* A personal access token IS bound to one workspace, and the server scopes
|
|
97
|
+
* every request by it. An explicit `--workspace-id` or `LEVR_WORKSPACE_ID` is
|
|
98
|
+
* still sent as `Workspace-Id` — the server refuses one that is not the
|
|
99
|
+
* token's — but nothing is looked up or cached, and with neither set the
|
|
100
|
+
* answer is null: the token's own workspace applies. Until ENG-6068 both were
|
|
101
|
+
* silently dropped for every `LEVR_TOKEN`, including an OAuth access token,
|
|
102
|
+
* which was classified as a PAT by where it came from and has no workspace to
|
|
103
|
+
* fall back to. An OAuth token from LEVR_TOKEN is not the login session, so
|
|
104
|
+
* the saved workspace choice is left alone for it (`persist: false`).
|
|
105
|
+
*/
|
|
106
|
+
async function resolveWorkspaceFor(auth, flagValue) {
|
|
107
|
+
if (auth.type === "jwt") return resolveWorkspace(flagValue, { persist: auth.source !== "env" });
|
|
108
|
+
if (flagValue) return {
|
|
109
|
+
workspaceId: flagValue,
|
|
110
|
+
source: "flag"
|
|
111
|
+
};
|
|
112
|
+
const envWs = process.env["LEVR_WORKSPACE_ID"];
|
|
113
|
+
if (envWs) return {
|
|
114
|
+
workspaceId: envWs,
|
|
115
|
+
source: "env"
|
|
116
|
+
};
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
87
119
|
|
|
88
120
|
//#endregion
|
|
89
|
-
export { autoSelectWorkspace, fetchSites,
|
|
121
|
+
export { autoSelectWorkspace, fetchSites, resolveWorkspaceFor };
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { executeInspect } from "./inspect-BbL7kDe-.js";
|
|
2
|
-
import { client, configureClient } from "./sdk-client-
|
|
3
|
-
import "./
|
|
4
|
-
import "./
|
|
5
|
-
import { resolveToken } from "./resolve-token-
|
|
2
|
+
import { client, configureClient } from "./sdk-client-BgzKzVIR.js";
|
|
3
|
+
import "./token-refresh-BpFuU4Ij.js";
|
|
4
|
+
import "./env-DjeRwmZ7.js";
|
|
5
|
+
import { resolveToken } from "./resolve-token-DKEXT7SA.js";
|
|
6
6
|
import "./workspace-store-Bmw104Qa.js";
|
|
7
|
-
import {
|
|
7
|
+
import { resolveWorkspaceFor } from "./resolve-workspace-D8y7twod.js";
|
|
8
8
|
import { existsSync } from "node:fs";
|
|
9
9
|
import { constants as constants$1 } from "node:os";
|
|
10
10
|
import { spawnSync } from "node:child_process";
|
|
@@ -365,6 +365,15 @@ function delay(ms) {
|
|
|
365
365
|
|
|
366
366
|
//#endregion
|
|
367
367
|
//#region src/commands/gates/runHandler.ts
|
|
368
|
+
/** The server's own words for a failed SDK call, for an error line. */
|
|
369
|
+
function describeSdkError(error) {
|
|
370
|
+
if (typeof error === "string") return error.length > 200 ? `${error.slice(0, 200)}…` : error;
|
|
371
|
+
if (!error || typeof error !== "object") return "request failed";
|
|
372
|
+
const e = error;
|
|
373
|
+
const message = Array.isArray(e.message) ? e.message.map(String).join("; ") : typeof e.message === "string" ? e.message : typeof e.error === "string" ? e.error : "";
|
|
374
|
+
const text = [typeof e.statusCode === "number" ? `HTTP ${e.statusCode}` : "", message].filter(Boolean).join(": ") || "request failed";
|
|
375
|
+
return text.length > 200 ? `${text.slice(0, 200)}…` : text;
|
|
376
|
+
}
|
|
368
377
|
/** ENG-6070 review R5 M3 — dead gates are named, with their remedy. */
|
|
369
378
|
function printDeadGates(out, dead) {
|
|
370
379
|
for (const d of dead ?? []) out(` DEAD ${d.test_name ? `"${d.test_name}"` : d.link_id}${d.required === false ? " (advisory)" : ""}: ${d.reason === "test_deleted" ? "its test was deleted" : "the gate was removed"}${d.remedy ? ` — ${d.remedy}` : ""}`);
|
|
@@ -431,13 +440,15 @@ async function gatesRunHandler(flags, issue) {
|
|
|
431
440
|
};
|
|
432
441
|
if (flags.ci) setCiHeaders(null);
|
|
433
442
|
let workspaceId;
|
|
434
|
-
|
|
435
|
-
const ws = await
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
443
|
+
try {
|
|
444
|
+
const ws = await resolveWorkspaceFor(auth, flags["workspace-id"]);
|
|
445
|
+
if (ws) {
|
|
446
|
+
workspaceId = ws.workspaceId;
|
|
447
|
+
client.setConfig({
|
|
448
|
+
...client.getConfig(),
|
|
449
|
+
workspaceId: ws.workspaceId
|
|
450
|
+
});
|
|
451
|
+
}
|
|
441
452
|
} catch (err) {
|
|
442
453
|
this.logger.error(err instanceof Error ? err.message : "Workspace resolution failed.");
|
|
443
454
|
this.process.exitCode = 1;
|
|
@@ -451,7 +462,8 @@ async function gatesRunHandler(flags, issue) {
|
|
|
451
462
|
} });
|
|
452
463
|
const row = found.data?.data?.[0];
|
|
453
464
|
if (found.error || !row) {
|
|
454
|
-
|
|
465
|
+
const where = workspaceId ? `workspace ${workspaceId}` : "the token's workspace";
|
|
466
|
+
this.logger.error(found.error ? `Could not look up issue ${issue} in ${where} (${describeSdkError(found.error)}).` : `Issue ${issue} not found in ${where}.`);
|
|
455
467
|
this.process.exitCode = 1;
|
|
456
468
|
return;
|
|
457
469
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { authGetSitesV1, configureClient } from "./sdk-client-
|
|
2
|
-
import "./
|
|
3
|
-
import "./
|
|
4
|
-
import { resolveToken } from "./resolve-token-
|
|
1
|
+
import { authGetSitesV1, configureClient } from "./sdk-client-BgzKzVIR.js";
|
|
2
|
+
import "./token-refresh-BpFuU4Ij.js";
|
|
3
|
+
import "./env-DjeRwmZ7.js";
|
|
4
|
+
import { resolveToken } from "./resolve-token-DKEXT7SA.js";
|
|
5
5
|
import { saveWorkspace } from "./workspace-store-Bmw104Qa.js";
|
|
6
6
|
|
|
7
7
|
//#region src/commands/workspace/selectHandler.ts
|
|
@@ -19,6 +19,11 @@ async function selectHandler(_flags, workspaceId) {
|
|
|
19
19
|
this.process.exitCode = 1;
|
|
20
20
|
return;
|
|
21
21
|
}
|
|
22
|
+
if (auth.source === "env") {
|
|
23
|
+
this.logger.error("LEVR_TOKEN is set: a workspace selected here would be saved for your login session, not for that token. Pass --workspace-id or set LEVR_WORKSPACE_ID instead.");
|
|
24
|
+
this.process.exitCode = 1;
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
22
27
|
configureClient(auth);
|
|
23
28
|
const result = await authGetSitesV1();
|
|
24
29
|
if (result.error) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { authGetProfileV1, configureClient } from "./sdk-client-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { authGetProfileV1, configureClient } from "./sdk-client-BgzKzVIR.js";
|
|
2
|
+
import { classifyToken, isTokenExpired } from "./token-refresh-BpFuU4Ij.js";
|
|
3
|
+
import { getApiUrl, getPatToken, readCredentials } from "./env-DjeRwmZ7.js";
|
|
4
4
|
import chalk from "chalk";
|
|
5
5
|
|
|
6
6
|
//#region src/commands/auth/statusHandler.ts
|
|
@@ -8,8 +8,10 @@ async function statusHandler() {
|
|
|
8
8
|
const apiUrl = getApiUrl();
|
|
9
9
|
const pat = getPatToken();
|
|
10
10
|
if (pat) {
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
const type = classifyToken(pat);
|
|
12
|
+
const kind = type === "pat" ? "personal access token" : "OAuth access token";
|
|
13
|
+
if (await checkApiReachable(pat, type)) {
|
|
14
|
+
this.process.stdout.write(`${chalk.green("ok")} Authenticated via LEVR_TOKEN (${kind})\n`);
|
|
13
15
|
this.process.stdout.write(` API: ${apiUrl} (reachable)\n`);
|
|
14
16
|
} else {
|
|
15
17
|
this.process.stdout.write(`${chalk.yellow("warn")} LEVR_TOKEN is set but API is unreachable\n`);
|
|
@@ -1,5 +1,29 @@
|
|
|
1
|
-
import { CLI_CLIENT_ID, deleteCredentials, getApiUrl, writeCredentials } from "./env-
|
|
1
|
+
import { CLI_CLIENT_ID, deleteCredentials, getApiUrl, writeCredentials } from "./env-DjeRwmZ7.js";
|
|
2
2
|
|
|
3
|
+
//#region src/auth/token-shape.ts
|
|
4
|
+
/**
|
|
5
|
+
* Classify a bearer token by its SHAPE — [issue:ENG-6068].
|
|
6
|
+
*
|
|
7
|
+
* The server decides how to verify a token by looking at the token, not at
|
|
8
|
+
* where it came from (`isPersonalAccessToken` in the backend's auth
|
|
9
|
+
* middleware): a Levr personal access token starts with `tq_`, and anything
|
|
10
|
+
* else is handed to the JWT verifier. `LEVR_TOKEN` carries either kind — a
|
|
11
|
+
* PAT minted in Settings, or an OAuth access token a device-code login
|
|
12
|
+
* printed for CI — so the CLI must apply the same rule. Until ENG-6068 every
|
|
13
|
+
* `LEVR_TOKEN` was called a PAT, and the JWT-only steps (resolving
|
|
14
|
+
* `--workspace-id` / `LEVR_WORKSPACE_ID`, `levr workspace list|select`) were
|
|
15
|
+
* silently skipped for an OAuth token, which has no workspace of its own.
|
|
16
|
+
*
|
|
17
|
+
* Leaf module on purpose: no imports, so `resolve-token`, the handlers and
|
|
18
|
+
* their tests can all read it without pulling in credentials or the SDK.
|
|
19
|
+
*/
|
|
20
|
+
const PAT_PREFIX = "tq_";
|
|
21
|
+
/** `tq_…` is a personal access token; everything else is treated as a JWT. */
|
|
22
|
+
function classifyToken(token) {
|
|
23
|
+
return token.startsWith(PAT_PREFIX) ? "pat" : "jwt";
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
//#endregion
|
|
3
27
|
//#region src/auth/token-refresh.ts
|
|
4
28
|
const REFRESH_BUFFER_MS = 300 * 1e3;
|
|
5
29
|
/**
|
|
@@ -45,4 +69,4 @@ async function refreshToken(creds) {
|
|
|
45
69
|
}
|
|
46
70
|
|
|
47
71
|
//#endregion
|
|
48
|
-
export { isTokenExpired, refreshToken };
|
|
72
|
+
export { classifyToken, isTokenExpired, refreshToken };
|
package/package.json
CHANGED
|
File without changes
|