@seliseblocks/cli-os 0.1.3 → 0.1.4
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/commands/deselect.d.ts +1 -0
- package/dist/commands/deselect.js +31 -0
- package/dist/commands/release/builds/list.js +4 -2
- package/dist/commands/release/deploy.js +5 -3
- package/dist/commands/release/status.js +4 -2
- package/dist/index.js +22 -4
- package/dist/lib/workspace.d.ts +1 -0
- package/dist/lib/workspace.js +17 -0
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function deselectProject(argv: string[]): Promise<void>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { normalizeAccountName, readConfig } from "../lib/config.js";
|
|
2
|
+
import { readTokenStore, writeTokenStore } from "../lib/token-store.js";
|
|
3
|
+
import { requestContext } from "../lib/request-context.js";
|
|
4
|
+
import { clearSelectedProject, parseCommand } from "../lib/workspace.js";
|
|
5
|
+
export async function deselectProject(argv) {
|
|
6
|
+
const { flags } = parseCommand(argv);
|
|
7
|
+
const config = await readConfig();
|
|
8
|
+
const { accountName } = requestContext(flags);
|
|
9
|
+
const account = normalizeAccountName(accountName ?? config.activeAccount);
|
|
10
|
+
const tenantId = await clearSelectedProject();
|
|
11
|
+
if (!tenantId) {
|
|
12
|
+
console.log("No project is currently selected.");
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
const store = await readTokenStore();
|
|
16
|
+
const projects = store.accounts[account]?.projects;
|
|
17
|
+
if (projects && tenantId in projects) {
|
|
18
|
+
const { [tenantId]: _removed, ...remainingProjects } = projects;
|
|
19
|
+
await writeTokenStore({
|
|
20
|
+
accounts: {
|
|
21
|
+
...store.accounts,
|
|
22
|
+
[account]: {
|
|
23
|
+
...store.accounts[account],
|
|
24
|
+
projects: remainingProjects
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
console.log(`Deselected project tenant ${tenantId}.`);
|
|
30
|
+
console.log("Run 'blocks-os use <tenantId>' to select a project again.");
|
|
31
|
+
}
|
|
@@ -2,13 +2,15 @@ import { stringFlag } from "../../../lib/args.js";
|
|
|
2
2
|
import { blocksRequest } from "../../../lib/api.js";
|
|
3
3
|
import { writeOutput } from "../../../lib/output.js";
|
|
4
4
|
import { requestContext } from "../../../lib/request-context.js";
|
|
5
|
-
import { parseCommand } from "../../../lib/workspace.js";
|
|
5
|
+
import { parseCommand, selectedProject } from "../../../lib/workspace.js";
|
|
6
6
|
export async function releaseBuildsList(argv) {
|
|
7
7
|
const { args, flags } = parseCommand(argv);
|
|
8
8
|
const repoId = args[0] || stringFlag(flags, "repo-id", { required: true });
|
|
9
|
+
const projectKey = await selectedProject(flags);
|
|
9
10
|
const result = await blocksRequest("/release/v4/api/Build/repo-details", {
|
|
10
|
-
|
|
11
|
+
impersonatedProjectAuth: true,
|
|
11
12
|
...requestContext(flags),
|
|
13
|
+
projectTenantId: projectKey,
|
|
12
14
|
query: { RepoId: repoId }
|
|
13
15
|
});
|
|
14
16
|
writeOutput(result, flags);
|
|
@@ -3,7 +3,7 @@ import { blocksRequest } from "../../lib/api.js";
|
|
|
3
3
|
import { confirmMutation } from "../../lib/confirm.js";
|
|
4
4
|
import { writeOutput } from "../../lib/output.js";
|
|
5
5
|
import { requestContext } from "../../lib/request-context.js";
|
|
6
|
-
import { parseCommand, pathsFromWorkspace, readWorkspaceConfig } from "../../lib/workspace.js";
|
|
6
|
+
import { parseCommand, pathsFromWorkspace, readWorkspaceConfig, selectedProject } from "../../lib/workspace.js";
|
|
7
7
|
import { readFile } from "node:fs/promises";
|
|
8
8
|
export async function releaseDeploy(argv) {
|
|
9
9
|
const { flags } = parseCommand(argv);
|
|
@@ -20,10 +20,12 @@ export async function releaseDeploy(argv) {
|
|
|
20
20
|
return;
|
|
21
21
|
}
|
|
22
22
|
await confirmMutation(flags, `Trigger configured release build for repo '${repoId}'.`);
|
|
23
|
+
const projectKey = await selectedProject(flags);
|
|
23
24
|
const result = await blocksRequest("/release/v4/api/Build/manual", {
|
|
24
|
-
|
|
25
|
+
impersonatedProjectAuth: true,
|
|
25
26
|
...requestContext(flags),
|
|
26
|
-
body
|
|
27
|
+
body,
|
|
28
|
+
projectTenantId: projectKey
|
|
27
29
|
});
|
|
28
30
|
writeOutput(result, flags);
|
|
29
31
|
}
|
|
@@ -2,13 +2,15 @@ import { stringFlag } from "../../lib/args.js";
|
|
|
2
2
|
import { blocksRequest } from "../../lib/api.js";
|
|
3
3
|
import { writeOutput } from "../../lib/output.js";
|
|
4
4
|
import { requestContext } from "../../lib/request-context.js";
|
|
5
|
-
import { parseCommand } from "../../lib/workspace.js";
|
|
5
|
+
import { parseCommand, selectedProject } from "../../lib/workspace.js";
|
|
6
6
|
export async function releaseStatus(argv) {
|
|
7
7
|
const { args, flags } = parseCommand(argv);
|
|
8
8
|
const buildId = args[0] || stringFlag(flags, "build-id", { required: true });
|
|
9
|
+
const projectKey = await selectedProject(flags);
|
|
9
10
|
const result = await blocksRequest("/release/v4/api/Build", {
|
|
10
|
-
|
|
11
|
+
impersonatedProjectAuth: true,
|
|
11
12
|
...requestContext(flags),
|
|
13
|
+
projectTenantId: projectKey,
|
|
12
14
|
query: { buildId }
|
|
13
15
|
});
|
|
14
16
|
writeOutput(result, flags);
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { authRefresh } from "./commands/auth/refresh.js";
|
|
2
2
|
import { authRemove } from "./commands/auth/remove.js";
|
|
3
3
|
import { authStatus } from "./commands/auth/status.js";
|
|
4
|
+
import { deselectProject } from "./commands/deselect.js";
|
|
4
5
|
import { doctor } from "./commands/doctor.js";
|
|
5
6
|
import { dataReload } from "./commands/data/reload.js";
|
|
6
7
|
import { dataValidate } from "./commands/data/validate.js";
|
|
@@ -79,6 +80,9 @@ try {
|
|
|
79
80
|
else if (command === "use") {
|
|
80
81
|
await useProject([subcommand, ...rest].filter(Boolean));
|
|
81
82
|
}
|
|
83
|
+
else if (command === "deselect") {
|
|
84
|
+
await deselectProject([subcommand, ...rest].filter(Boolean));
|
|
85
|
+
}
|
|
82
86
|
else if (command === "new" && subcommand === "web") {
|
|
83
87
|
await newWeb(rest);
|
|
84
88
|
}
|
|
@@ -226,6 +230,12 @@ Projects:
|
|
|
226
230
|
Save the selected project tenant globally and in blocks.json when present.
|
|
227
231
|
Does not call cloud APIs.
|
|
228
232
|
|
|
233
|
+
blocks-os deselect
|
|
234
|
+
Clear the selected project tenant (globally and in blocks.json) and drop
|
|
235
|
+
its cached impersonation token. Use this to recover when an impersonated
|
|
236
|
+
project token has expired or failed, then run 'blocks-os use <tenantId>'
|
|
237
|
+
again to reselect and re-impersonate.
|
|
238
|
+
|
|
229
239
|
IAM:
|
|
230
240
|
blocks-os iam:me [--json]
|
|
231
241
|
Read the current user from IAM using the account token. This is the only IAM
|
|
@@ -275,23 +285,31 @@ Localization:
|
|
|
275
285
|
|
|
276
286
|
Release:
|
|
277
287
|
blocks-os release:deploy --repo-id <repoId> [--dry-run] [--yes] [--json]
|
|
278
|
-
Trigger a manual Release build/deploy for a configured repository
|
|
279
|
-
no artifact upload is performed by
|
|
288
|
+
Trigger a manual Release build/deploy for a configured repository using an
|
|
289
|
+
impersonated project token. Mutating; no artifact upload is performed by
|
|
290
|
+
this CLI.
|
|
280
291
|
|
|
281
292
|
blocks-os release:status <buildId> [--json]
|
|
282
|
-
Read Release build status by build id
|
|
293
|
+
Read Release build status by build id using an impersonated project
|
|
294
|
+
token. Read-only.
|
|
283
295
|
|
|
284
296
|
blocks-os release:builds:list --repo-id <repoId> [--json]
|
|
285
|
-
List Release build details for a repository
|
|
297
|
+
List Release build details for a repository using an impersonated project
|
|
298
|
+
token. Read-only.
|
|
286
299
|
|
|
287
300
|
blocks-os release:builds:get <buildId> [--json]
|
|
288
301
|
Alias for release:status. Read-only.
|
|
289
302
|
|
|
290
303
|
Scaffold:
|
|
291
304
|
blocks-os new web <name> --x-blocks-key <tenantId> --app-domain <domain> [--client-id <oidcClientId>]
|
|
305
|
+
[--blocks-api-url <url>] [--oidc-url <url>]
|
|
292
306
|
Create a Vite React starter app with a real browser Authorization Code +
|
|
293
307
|
PKCE login flow against Blocks IAM (login page, /login/callback handler,
|
|
294
308
|
route guards), plus Data schema listing, Release build lookup, environment
|
|
295
309
|
config, and safe .gitignore defaults.
|
|
310
|
+
--blocks-api-url defaults to the OS API (os.seliseblocks.com) if omitted -
|
|
311
|
+
pass the runtime Data/IAM/Localization gateway URL explicitly (typically
|
|
312
|
+
https://api.seliseblocks.com) for the scaffolded app to work at runtime.
|
|
313
|
+
--oidc-url defaults to https://iam.seliseblocks.com.
|
|
296
314
|
`);
|
|
297
315
|
}
|
package/dist/lib/workspace.d.ts
CHANGED
|
@@ -20,6 +20,7 @@ export declare function readWorkspaceConfig(): Promise<BlocksWorkspaceConfig>;
|
|
|
20
20
|
export declare function writeWorkspaceConfig(config: BlocksWorkspaceConfig): Promise<void>;
|
|
21
21
|
export declare function selectedProject(flags: Record<string, string | boolean>): Promise<string>;
|
|
22
22
|
export declare function saveSelectedProject(tenantId: string): Promise<void>;
|
|
23
|
+
export declare function clearSelectedProject(): Promise<string | undefined>;
|
|
23
24
|
export declare function pathsFromWorkspace(config: BlocksWorkspaceConfig): {
|
|
24
25
|
dictionaries: string;
|
|
25
26
|
releaseConfig: string;
|
package/dist/lib/workspace.js
CHANGED
|
@@ -47,6 +47,23 @@ export async function saveSelectedProject(tenantId) {
|
|
|
47
47
|
});
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
|
+
export async function clearSelectedProject() {
|
|
51
|
+
const global = await readConfig();
|
|
52
|
+
const tenantId = global.selectedProject?.tenantId;
|
|
53
|
+
if (!tenantId)
|
|
54
|
+
return undefined;
|
|
55
|
+
const { selectedProject: _dropped, ...rest } = global;
|
|
56
|
+
await writeConfig(rest);
|
|
57
|
+
const local = await readWorkspaceConfig();
|
|
58
|
+
if (local.project?.tenantId) {
|
|
59
|
+
const { tenantId: _localTenantId, ...restProject } = local.project;
|
|
60
|
+
await writeWorkspaceConfig({
|
|
61
|
+
...local,
|
|
62
|
+
project: Object.keys(restProject).length > 0 ? restProject : undefined
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
return tenantId;
|
|
66
|
+
}
|
|
50
67
|
export function pathsFromWorkspace(config) {
|
|
51
68
|
return {
|
|
52
69
|
dictionaries: config.localization?.dictionaries ?? "blocks/localization",
|