@metabase/cli 0.1.0-alpha.workspaces-commands.818a8f1 → 0.1.0
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/README.md +0 -237
- package/dist/{archive-BPG5c88Y.mjs → archive-CsWeHXle.mjs} +4 -5
- package/dist/{auth--Hpjwlaf.mjs → auth-BF7IjZIH.mjs} +3 -3
- package/dist/{body-DwU2s6Pg.mjs → body-Dv9hQ0Qk.mjs} +2 -2
- package/dist/{branches-BbcoJXfp.mjs → branches-BujtceGr.mjs} +4 -5
- package/dist/{cancel-task-BDas45YO.mjs → cancel-task-CT2xUMRg.mjs} +4 -5
- package/dist/card-_Ta7zdYe.mjs +19 -0
- package/dist/cli.mjs +13 -17
- package/dist/{create-DpnjQvPw.mjs → create-B8ektf-R.mjs} +6 -7
- package/dist/{create-_UOeEXAj.mjs → create-CI2Cunq5.mjs} +6 -7
- package/dist/{create-CwVcoq0O.mjs → create-DdbU3TLX.mjs} +6 -7
- package/dist/{create-branch-sDttBORB.mjs → create-branch-goZBTNnr.mjs} +4 -5
- package/dist/{current-task-BGt1mqaX.mjs → current-task-DBjRNCFq.mjs} +4 -5
- package/dist/{db-Dm2u2ISJ.mjs → db-DMghzgb6.mjs} +2 -2
- package/dist/{delete-DRBTgyus.mjs → delete-8vGU35r3.mjs} +5 -6
- package/dist/{delete-DUC_stoL.mjs → delete-B27KLF5X.mjs} +5 -6
- package/dist/{delete-runtime-inOVw3IX.mjs → delete-runtime-Byr60cR3.mjs} +2 -4
- package/dist/{delete-table-9Is631O_.mjs → delete-table-BNaJ_gA4.mjs} +5 -6
- package/dist/{dirty-CLjHbz6J.mjs → dirty-aNUuph4I.mjs} +4 -5
- package/dist/{export-D2Anfu3p.mjs → export-QDkuuzSE.mjs} +5 -6
- package/dist/{field-Dhs2AND3.mjs → field-DaYo_90x.mjs} +1 -1
- package/dist/{get-DhIoNeOp.mjs → get-BGBIzMKY.mjs} +4 -5
- package/dist/{get-CAVVmdMX.mjs → get-COXHplHP.mjs} +4 -5
- package/dist/{get-CAPLfawI.mjs → get-Cl8-IauC.mjs} +4 -5
- package/dist/{get-DDWpubE8.mjs → get-Cwpj7lDe.mjs} +5 -6
- package/dist/{get-BHJA78zg.mjs → get-DI_IJvgk.mjs} +4 -5
- package/dist/{get-2po1uv9i.mjs → get-Dh_acl8q.mjs} +4 -5
- package/dist/{get-qPOsuTPw.mjs → get-i6LWOByV.mjs} +4 -5
- package/dist/{has-remote-changes-DAL5jetW.mjs → has-remote-changes-hjKoQuRy.mjs} +4 -5
- package/dist/{import-CUMxUfSF.mjs → import-HJsSKRYx.mjs} +5 -6
- package/dist/{input-BNqSFl38.mjs → input-Dojr-RTw.mjs} +1 -1
- package/dist/{is-dirty-B10S6MG0.mjs → is-dirty-1Qy7hiHB.mjs} +2 -3
- package/dist/is-dirty-DpKn9HJp.mjs +8 -0
- package/dist/{key-CyhOpgWt.mjs → key-DBxPSFwi.mjs} +1 -1
- package/dist/{license-DtsGJi3l.mjs → license-MoWse3ZI.mjs} +3 -3
- package/dist/{list-Y7iGsOfE.mjs → list-Bk6RsbJl.mjs} +3 -4
- package/dist/{list-DeFGwhhJ.mjs → list-C4Ajrw8f.mjs} +3 -4
- package/dist/{list-C5MGydGU.mjs → list-C8tdLOH5.mjs} +3 -4
- package/dist/{list-evtQS7jl.mjs → list-CBSBHtK-.mjs} +3 -4
- package/dist/{list-qetY9OIN.mjs → list-CWt3fqrZ.mjs} +3 -4
- package/dist/{list-OBx5B3gd.mjs → list-C_PRdL5e.mjs} +5 -6
- package/dist/{login-Dqw9ZtCx.mjs → login-C9WTwNn6.mjs} +4 -5
- package/dist/{logout-DwYJ5OUi.mjs → logout-oLszGCOg.mjs} +3 -4
- package/dist/{package-t8dKf4m_.mjs → package-BGfw4ZWJ.mjs} +1 -2
- package/dist/parse-id-BhmmfyCP.mjs +14 -0
- package/dist/{poll-D2sXM5rc.mjs → poll-ILanYysl.mjs} +1 -1
- package/dist/{poll-task-Byiunmaj.mjs → poll-task-DbpsiQhl.mjs} +2 -2
- package/dist/{prompt-fXeNtj0M.mjs → prompt-DpT8yAVy.mjs} +1 -1
- package/dist/{query-BnGVGeM3.mjs → query-PihYi-UZ.mjs} +4 -5
- package/dist/{remove-Bx48o-0S.mjs → remove-B2hVYn1v.mjs} +3 -4
- package/dist/{run-D4NgvaRh.mjs → run-C2so6Qp6.mjs} +27 -11
- package/dist/{runtime-DUgFfYkN.mjs → runtime-C9CEZhcn.mjs} +335 -203
- package/dist/{search-4wKx5ug2.mjs → search-CopOytXY.mjs} +4 -5
- package/dist/{set-BZnCRL4c.mjs → set-BcF7M1GQ.mjs} +4 -5
- package/dist/{set-DCjrmTFm.mjs → set-CbibegpA.mjs} +6 -7
- package/dist/{setting-C4vQSqer.mjs → setting-U3NtBMFo.mjs} +3 -3
- package/dist/{stash-ZZkmW_V7.mjs → stash-DOBbYozC.mjs} +5 -6
- package/dist/{status-DezF-PIM.mjs → status-Buf1ZbNR.mjs} +5 -6
- package/dist/{status-JH6BZppo.mjs → status-CUcs8XBH.mjs} +2 -3
- package/dist/{status-9KAPIpX8.mjs → status-D1F5XHae.mjs} +2 -3
- package/dist/sync-BPyGXfUk.mjs +26 -0
- package/dist/{table-BvAr2ixC.mjs → table-Cfk7oSvw.mjs} +1 -1
- package/dist/{table-D-Mb5Nvw.mjs → table-D7nJt7JO.mjs} +2 -2
- package/dist/transform-UbyewMxY.mjs +21 -0
- package/dist/transform-job-CrYkr-Ma.mjs +19 -0
- package/dist/{update-DxKlQ0hP.mjs → update-CL8tRbxr.mjs} +7 -8
- package/dist/{update-CDtm71m2.mjs → update-DU2oU2j-.mjs} +7 -8
- package/dist/{wait-Cj_8wu4y.mjs → wait-Bugr9eXD.mjs} +5 -6
- package/package.json +1 -2
- package/dist/api-key-D9XxErQn.mjs +0 -13
- package/dist/card-D4zZSPUb.mjs +0 -19
- package/dist/create-Bd_U1zWU.mjs +0 -124
- package/dist/create-CCzsCZMm.mjs +0 -47
- package/dist/credentials-C0xKke5D.mjs +0 -84
- package/dist/database-4V1iiPEx.mjs +0 -17
- package/dist/deprovision-BAMzZc6f.mjs +0 -60
- package/dist/docker-QWVMG2gl.mjs +0 -605
- package/dist/eid-BNhutC1U.mjs +0 -13
- package/dist/flag-pair-CWvvzDJ_.mjs +0 -17
- package/dist/is-dirty-CUuq-aB6.mjs +0 -9
- package/dist/list-B8s7Qnzk.mjs +0 -31
- package/dist/logs-B_lrY7Js.mjs +0 -57
- package/dist/parse-id-C1prc9US.mjs +0 -12
- package/dist/provision-DC4_HWZD.mjs +0 -80
- package/dist/ps-1bZKIwWh.mjs +0 -9
- package/dist/ps-BiOrecEe.mjs +0 -78
- package/dist/remove-DecoZzNd.mjs +0 -97
- package/dist/render-DlBijc5i.mjs +0 -179
- package/dist/setup-Dqh9hN6l.mjs +0 -70
- package/dist/start-xXQypG5L.mjs +0 -324
- package/dist/stop-br-ZOnve.mjs +0 -80
- package/dist/sync-C7VOWD00.mjs +0 -26
- package/dist/transform-CqxZwhGs.mjs +0 -21
- package/dist/transform-job-HjbqjEoP.mjs +0 -19
- package/dist/translate-DJxDVAE4.mjs +0 -110
- package/dist/update-DYVeVjk2.mjs +0 -76
- package/dist/url-DP88YHNo.mjs +0 -53
- package/dist/wait-DwZN3ZwR.mjs +0 -19
- package/dist/wait-flags-CjW4ogUJ.mjs +0 -35
- package/dist/workspace-CbwR0vX_.mjs +0 -24
- package/dist/workspace-Dr9lWU3D.mjs +0 -72
- package/dist/workspace-credentials-q5RRFMT8.mjs +0 -139
- /package/dist/{body-flags-7oqLhu5j.mjs → body-flags-BUA9XV1u.mjs} +0 -0
- /package/dist/{card-C31pGtBZ.mjs → card-CsXk8T6A.mjs} +0 -0
- /package/dist/{database-BTX5qbSv.mjs → database-PA9Goi25.mjs} +0 -0
- /package/dist/{field-QwBMAWsq.mjs → field-C8IVs6rp.mjs} +0 -0
- /package/dist/{manifest-wzEFG0JB.mjs → manifest-CAdjQYH8.mjs} +0 -0
- /package/dist/{setting-DM7pm7yh.mjs → setting-26ckqHAP.mjs} +0 -0
- /package/dist/{transform-DfVkUttP.mjs → transform-B5uRpg1G.mjs} +0 -0
- /package/dist/{transform-job-DuB_OjhO.mjs → transform-job-C7QXWTVE.mjs} +0 -0
package/dist/url-DP88YHNo.mjs
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import "./package-t8dKf4m_.mjs";
|
|
2
|
-
import "./command-augment-D9pI9Vbh.mjs";
|
|
3
|
-
import { renderItem } from "./render-DlBijc5i.mjs";
|
|
4
|
-
import { defineMetabaseCommand, localUrl, outputFlags } from "./runtime-DUgFfYkN.mjs";
|
|
5
|
-
import { parseId } from "./parse-id-C1prc9US.mjs";
|
|
6
|
-
import "./poll-D2sXM5rc.mjs";
|
|
7
|
-
import { checkDockerReady, requireWorkspaceContainerLocation } from "./docker-QWVMG2gl.mjs";
|
|
8
|
-
import { z } from "zod";
|
|
9
|
-
|
|
10
|
-
//#region src/commands/workspace/url.ts
|
|
11
|
-
const UrlResult = z.object({
|
|
12
|
-
workspace_id: z.number().int().positive(),
|
|
13
|
-
url: z.string()
|
|
14
|
-
});
|
|
15
|
-
const urlResultView = {
|
|
16
|
-
compactPick: UrlResult,
|
|
17
|
-
tableColumns: [{
|
|
18
|
-
key: "workspace_id",
|
|
19
|
-
label: "ID"
|
|
20
|
-
}, {
|
|
21
|
-
key: "url",
|
|
22
|
-
label: "URL"
|
|
23
|
-
}]
|
|
24
|
-
};
|
|
25
|
-
var url_default = defineMetabaseCommand({
|
|
26
|
-
meta: {
|
|
27
|
-
name: "url",
|
|
28
|
-
description: "Print the local URL the workspace's container is bound to"
|
|
29
|
-
},
|
|
30
|
-
args: {
|
|
31
|
-
...outputFlags,
|
|
32
|
-
id: {
|
|
33
|
-
type: "positional",
|
|
34
|
-
description: "Workspace id",
|
|
35
|
-
required: true
|
|
36
|
-
}
|
|
37
|
-
},
|
|
38
|
-
outputSchema: UrlResult,
|
|
39
|
-
examples: ["metabase workspace url 1", "metabase workspace url 1 --json"],
|
|
40
|
-
async run({ args, ctx }) {
|
|
41
|
-
const workspaceId = parseId(args.id);
|
|
42
|
-
await checkDockerReady();
|
|
43
|
-
const { hostPort } = await requireWorkspaceContainerLocation(workspaceId);
|
|
44
|
-
const result = {
|
|
45
|
-
workspace_id: workspaceId,
|
|
46
|
-
url: localUrl(hostPort)
|
|
47
|
-
};
|
|
48
|
-
renderItem(result, urlResultView, ctx);
|
|
49
|
-
}
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
//#endregion
|
|
53
|
-
export { url_default as default };
|
package/dist/wait-DwZN3ZwR.mjs
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { pollUntil } from "./poll-D2sXM5rc.mjs";
|
|
2
|
-
import { Workspace } from "./workspace-Dr9lWU3D.mjs";
|
|
3
|
-
|
|
4
|
-
//#region src/commands/workspace/database/wait.ts
|
|
5
|
-
async function waitForDatabaseProvisioned(client, workspaceId, databaseId, schedule) {
|
|
6
|
-
return pollUntil(() => client.requestParsed(Workspace, `/api/ee/workspace-manager/${workspaceId}`), (workspace) => {
|
|
7
|
-
const entry = workspace.databases?.find((row) => row.database_id === databaseId);
|
|
8
|
-
return entry !== void 0 && entry.status === "provisioned";
|
|
9
|
-
}, schedule);
|
|
10
|
-
}
|
|
11
|
-
async function waitForDatabaseGone(client, workspaceId, databaseId, schedule) {
|
|
12
|
-
await pollUntil(() => client.requestParsed(Workspace, `/api/ee/workspace-manager/${workspaceId}`), (workspace) => {
|
|
13
|
-
const entry = workspace.databases?.find((row) => row.database_id === databaseId);
|
|
14
|
-
return entry === void 0;
|
|
15
|
-
}, schedule);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
//#endregion
|
|
19
|
-
export { waitForDatabaseGone, waitForDatabaseProvisioned };
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { parseId } from "./parse-id-C1prc9US.mjs";
|
|
2
|
-
import { DEFAULT_INTERVAL_MS, DEFAULT_TIMEOUT_MS } from "./poll-D2sXM5rc.mjs";
|
|
3
|
-
|
|
4
|
-
//#region src/commands/wait-flags.ts
|
|
5
|
-
const waitFlags = {
|
|
6
|
-
wait: {
|
|
7
|
-
type: "boolean",
|
|
8
|
-
description: "Poll until the operation reaches a terminal state",
|
|
9
|
-
default: false
|
|
10
|
-
},
|
|
11
|
-
timeout: {
|
|
12
|
-
type: "string",
|
|
13
|
-
description: "Polling timeout in ms (used with --wait)",
|
|
14
|
-
default: String(DEFAULT_TIMEOUT_MS)
|
|
15
|
-
},
|
|
16
|
-
interval: {
|
|
17
|
-
type: "string",
|
|
18
|
-
description: "Polling interval in ms (used with --wait)",
|
|
19
|
-
default: String(DEFAULT_INTERVAL_MS)
|
|
20
|
-
}
|
|
21
|
-
};
|
|
22
|
-
function parseWaitFlags(args) {
|
|
23
|
-
const interval = args.interval ?? String(DEFAULT_INTERVAL_MS);
|
|
24
|
-
const timeout = args.timeout ?? String(DEFAULT_TIMEOUT_MS);
|
|
25
|
-
return {
|
|
26
|
-
enabled: args.wait === true,
|
|
27
|
-
schedule: {
|
|
28
|
-
intervalMs: parseId(interval, "interval"),
|
|
29
|
-
timeoutMs: parseId(timeout, "timeout")
|
|
30
|
-
}
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
//#endregion
|
|
35
|
-
export { parseWaitFlags, waitFlags };
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { defineCommand } from "citty";
|
|
2
|
-
|
|
3
|
-
//#region src/commands/workspace/index.ts
|
|
4
|
-
var workspace_default = defineCommand({
|
|
5
|
-
meta: {
|
|
6
|
-
name: "workspace",
|
|
7
|
-
description: "Manage Metabase workspaces (workspace-manager)"
|
|
8
|
-
},
|
|
9
|
-
subCommands: {
|
|
10
|
-
list: () => import("./list-B8s7Qnzk.mjs").then((mod) => mod.default),
|
|
11
|
-
create: () => import("./create-CCzsCZMm.mjs").then((mod) => mod.default),
|
|
12
|
-
database: () => import("./database-4V1iiPEx.mjs").then((mod) => mod.default),
|
|
13
|
-
start: () => import("./start-xXQypG5L.mjs").then((mod) => mod.default),
|
|
14
|
-
stop: () => import("./stop-br-ZOnve.mjs").then((mod) => mod.default),
|
|
15
|
-
remove: () => import("./remove-DecoZzNd.mjs").then((mod) => mod.default),
|
|
16
|
-
logs: () => import("./logs-B_lrY7Js.mjs").then((mod) => mod.default),
|
|
17
|
-
url: () => import("./url-DP88YHNo.mjs").then((mod) => mod.default),
|
|
18
|
-
credentials: () => import("./credentials-C0xKke5D.mjs").then((mod) => mod.default),
|
|
19
|
-
ps: () => import("./ps-1bZKIwWh.mjs").then((mod) => mod.default)
|
|
20
|
-
}
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
//#endregion
|
|
24
|
-
export { workspace_default as default };
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
|
|
3
|
-
//#region src/domain/workspace.ts
|
|
4
|
-
const WorkspaceDatabaseStatus = z.enum([
|
|
5
|
-
"unprovisioned",
|
|
6
|
-
"provisioning",
|
|
7
|
-
"provisioned",
|
|
8
|
-
"deprovisioning"
|
|
9
|
-
]);
|
|
10
|
-
const WorkspaceDatabase = z.object({
|
|
11
|
-
database_id: z.number().int(),
|
|
12
|
-
output_schema: z.string(),
|
|
13
|
-
input_schemas: z.array(z.string()),
|
|
14
|
-
status: WorkspaceDatabaseStatus
|
|
15
|
-
}).loose();
|
|
16
|
-
const WorkspaceCreator = z.object({
|
|
17
|
-
id: z.number().int(),
|
|
18
|
-
first_name: z.string().nullable(),
|
|
19
|
-
last_name: z.string().nullable(),
|
|
20
|
-
email: z.string(),
|
|
21
|
-
common_name: z.string().nullable().optional()
|
|
22
|
-
}).loose();
|
|
23
|
-
const Workspace = z.object({
|
|
24
|
-
id: z.number().int(),
|
|
25
|
-
name: z.string(),
|
|
26
|
-
creator: WorkspaceCreator.nullable(),
|
|
27
|
-
created_at: z.string(),
|
|
28
|
-
updated_at: z.string(),
|
|
29
|
-
databases: z.array(WorkspaceDatabase).optional()
|
|
30
|
-
}).loose();
|
|
31
|
-
const WorkspaceCompact = Workspace.pick({
|
|
32
|
-
id: true,
|
|
33
|
-
name: true,
|
|
34
|
-
databases: true
|
|
35
|
-
}).strip();
|
|
36
|
-
const WorkspaceDatabaseList = z.array(WorkspaceDatabase);
|
|
37
|
-
const workspaceView = {
|
|
38
|
-
compactPick: WorkspaceCompact,
|
|
39
|
-
tableColumns: [
|
|
40
|
-
{
|
|
41
|
-
key: "id",
|
|
42
|
-
label: "ID"
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
key: "name",
|
|
46
|
-
label: "Name"
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
key: "databases",
|
|
50
|
-
label: "Databases",
|
|
51
|
-
format: (value) => formatDatabases(value)
|
|
52
|
-
}
|
|
53
|
-
]
|
|
54
|
-
};
|
|
55
|
-
const WorkspaceCreateInput = z.object({ name: z.string().min(1) }).loose();
|
|
56
|
-
const WorkspaceProvisionInput = z.object({
|
|
57
|
-
database_id: z.number().int().positive(),
|
|
58
|
-
input_schemas: z.array(z.string().min(1)).min(1)
|
|
59
|
-
}).loose();
|
|
60
|
-
const WorkspaceUpdateDatabaseInput = z.object({ input_schemas: z.array(z.string().min(1)).min(1) }).loose();
|
|
61
|
-
function formatDatabases(value) {
|
|
62
|
-
if (value === void 0) return "";
|
|
63
|
-
const parsed = WorkspaceDatabaseList.safeParse(value);
|
|
64
|
-
if (!parsed.success || parsed.data.length === 0) return "(none)";
|
|
65
|
-
return parsed.data.map((entry) => {
|
|
66
|
-
const schemaList = entry.input_schemas.length === 0 ? "" : ` [${entry.input_schemas.join(", ")}]`;
|
|
67
|
-
return `${entry.database_id} (${entry.status})${schemaList}`;
|
|
68
|
-
}).join("; ");
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
//#endregion
|
|
72
|
-
export { Workspace, WorkspaceCompact, WorkspaceCreateInput, WorkspaceProvisionInput, WorkspaceUpdateDatabaseInput, workspaceView };
|
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
import { ConfigError, ValidationError, errorMessage } from "./runtime-DUgFfYkN.mjs";
|
|
2
|
-
import { z } from "zod";
|
|
3
|
-
import { randomBytes } from "node:crypto";
|
|
4
|
-
import { YAMLParseError, parse, stringify } from "yaml";
|
|
5
|
-
|
|
6
|
-
//#region src/runtime/yaml.ts
|
|
7
|
-
function parseYaml(input, schema, opts = {}) {
|
|
8
|
-
const result = parseYamlResult(input, schema, opts);
|
|
9
|
-
if (!result.ok) throw result.error;
|
|
10
|
-
return result.value;
|
|
11
|
-
}
|
|
12
|
-
function parseYamlResult(input, schema, opts = {}) {
|
|
13
|
-
const sourcePrefix = opts.source ? `${opts.source}: ` : "";
|
|
14
|
-
let raw;
|
|
15
|
-
try {
|
|
16
|
-
raw = parse(input);
|
|
17
|
-
} catch (error) {
|
|
18
|
-
if (error instanceof YAMLParseError) return {
|
|
19
|
-
ok: false,
|
|
20
|
-
error: new ConfigError(`${sourcePrefix}invalid YAML: ${error.message}`)
|
|
21
|
-
};
|
|
22
|
-
return {
|
|
23
|
-
ok: false,
|
|
24
|
-
error: new ConfigError(`${sourcePrefix}invalid YAML: ${errorMessage(error)}`)
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
const parsed = schema.safeParse(raw);
|
|
28
|
-
if (!parsed.success) return {
|
|
29
|
-
ok: false,
|
|
30
|
-
error: new ValidationError(`${sourcePrefix}value did not match expected schema`, {
|
|
31
|
-
source: opts.source ?? "<input>",
|
|
32
|
-
zodIssues: parsed.error.issues
|
|
33
|
-
})
|
|
34
|
-
};
|
|
35
|
-
return {
|
|
36
|
-
ok: true,
|
|
37
|
-
value: parsed.data
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
function stringifyYaml(value) {
|
|
41
|
-
return stringify(value, { lineWidth: 0 });
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
//#endregion
|
|
45
|
-
//#region src/core/workspace-credentials.ts
|
|
46
|
-
const API_KEY_NAME = "Workspace API Key";
|
|
47
|
-
const API_KEY_GROUP = "admin";
|
|
48
|
-
const PASSWORD_BYTE_LENGTH = 18;
|
|
49
|
-
const API_KEY_BYTE_LENGTH = 32;
|
|
50
|
-
const WorkspaceCredentials = z.object({
|
|
51
|
-
workspace_id: z.number().int().positive(),
|
|
52
|
-
user: z.object({
|
|
53
|
-
first_name: z.string().min(1),
|
|
54
|
-
last_name: z.string().min(1),
|
|
55
|
-
password: z.string().min(1),
|
|
56
|
-
email: z.string().min(1)
|
|
57
|
-
}),
|
|
58
|
-
api_key: z.object({
|
|
59
|
-
name: z.string().min(1),
|
|
60
|
-
group: z.enum(["admin", "all-users"]),
|
|
61
|
-
creator: z.string().min(1),
|
|
62
|
-
key: z.string().regex(/^mb_[A-Za-z0-9+/=]+$/)
|
|
63
|
-
})
|
|
64
|
-
});
|
|
65
|
-
function generateWorkspaceCredentials(workspaceId) {
|
|
66
|
-
const email = `workspace-${workspaceId}@workspace.local`;
|
|
67
|
-
return {
|
|
68
|
-
workspace_id: workspaceId,
|
|
69
|
-
user: {
|
|
70
|
-
first_name: "Workspace",
|
|
71
|
-
last_name: "Admin",
|
|
72
|
-
password: randomBase64Url(PASSWORD_BYTE_LENGTH),
|
|
73
|
-
email
|
|
74
|
-
},
|
|
75
|
-
api_key: {
|
|
76
|
-
name: API_KEY_NAME,
|
|
77
|
-
group: API_KEY_GROUP,
|
|
78
|
-
creator: email,
|
|
79
|
-
key: `mb_${randomBytes(API_KEY_BYTE_LENGTH).toString("base64")}`
|
|
80
|
-
}
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
const credentialsJsonEncoder = new TextEncoder();
|
|
84
|
-
function buildCredentialsJson(credentials) {
|
|
85
|
-
return credentialsJsonEncoder.encode(`${JSON.stringify(credentials, null, 2)}\n`);
|
|
86
|
-
}
|
|
87
|
-
const ConfigEnvelopeShape = z.object({
|
|
88
|
-
version: z.number().int(),
|
|
89
|
-
config: z.looseObject({})
|
|
90
|
-
}).loose();
|
|
91
|
-
function injectCredentialsIntoConfig(yamlInput, credentials) {
|
|
92
|
-
const envelope = parseYaml(yamlInput, ConfigEnvelopeShape, { source: "config.yml" });
|
|
93
|
-
if ("users" in envelope.config || "api-keys" in envelope.config) throw new ConfigError("config.yml already declares users or api-keys — refusing to overwrite parent-supplied credentials");
|
|
94
|
-
const merged = {
|
|
95
|
-
...envelope,
|
|
96
|
-
config: {
|
|
97
|
-
...envelope.config,
|
|
98
|
-
users: [credentials.user],
|
|
99
|
-
"api-keys": [credentials.api_key]
|
|
100
|
-
}
|
|
101
|
-
};
|
|
102
|
-
return stringifyYaml(merged);
|
|
103
|
-
}
|
|
104
|
-
const REPO_SYNC_MODES = ["read-write", "read-only"];
|
|
105
|
-
const RepoSyncMode = z.enum(REPO_SYNC_MODES);
|
|
106
|
-
const ConfigEnvelopeWithSettingsShape = z.object({
|
|
107
|
-
version: z.number().int(),
|
|
108
|
-
config: z.object({ settings: z.looseObject({}).optional() }).loose()
|
|
109
|
-
}).loose();
|
|
110
|
-
const REMOTE_SYNC_KEYS = [
|
|
111
|
-
"remote-sync-url",
|
|
112
|
-
"remote-sync-branch",
|
|
113
|
-
"remote-sync-type"
|
|
114
|
-
];
|
|
115
|
-
function injectRepoSettingsIntoConfig(yamlInput, repo) {
|
|
116
|
-
const envelope = parseYaml(yamlInput, ConfigEnvelopeWithSettingsShape, { source: "config.yml" });
|
|
117
|
-
const existingSettings = envelope.config.settings ?? {};
|
|
118
|
-
const conflicts = REMOTE_SYNC_KEYS.filter((key) => key in existingSettings);
|
|
119
|
-
if (conflicts.length > 0) throw new ConfigError(`config.yml already declares remote-sync settings (${conflicts.join(", ")}) — refusing to overwrite parent-supplied values`);
|
|
120
|
-
const merged = {
|
|
121
|
-
...envelope,
|
|
122
|
-
config: {
|
|
123
|
-
...envelope.config,
|
|
124
|
-
settings: {
|
|
125
|
-
...existingSettings,
|
|
126
|
-
"remote-sync-url": repo.url,
|
|
127
|
-
"remote-sync-branch": repo.branch,
|
|
128
|
-
"remote-sync-type": repo.mode
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
};
|
|
132
|
-
return stringifyYaml(merged);
|
|
133
|
-
}
|
|
134
|
-
function randomBase64Url(byteLength) {
|
|
135
|
-
return randomBytes(byteLength).toString("base64url");
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
//#endregion
|
|
139
|
-
export { REPO_SYNC_MODES, RepoSyncMode, WorkspaceCredentials, buildCredentialsJson, generateWorkspaceCredentials, injectCredentialsIntoConfig, injectRepoSettingsIntoConfig };
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|