@mesh-tech/mesh-cli 0.20.0 → 0.20.2
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 +13 -8
- package/dist/bin/mesh.js +272 -52
- package/dist/bin/mesh.js.map +4 -4
- package/dist/build-info.json +2 -2
- package/dist/src/commands/app-check.d.ts +1 -1
- package/dist/src/commands/app-check.d.ts.map +1 -1
- package/dist/src/commands/app-check.js +13 -0
- package/dist/src/commands/app-check.js.map +1 -1
- package/dist/src/commands/create-app.d.ts +14 -0
- package/dist/src/commands/create-app.d.ts.map +1 -1
- package/dist/src/commands/create-app.js +25 -2
- package/dist/src/commands/create-app.js.map +1 -1
- package/dist/src/commands/init/wizard.d.ts +21 -4
- package/dist/src/commands/init/wizard.d.ts.map +1 -1
- package/dist/src/commands/init/wizard.js +51 -10
- package/dist/src/commands/init/wizard.js.map +1 -1
- package/dist/src/commands/local/hub-local.d.ts +35 -0
- package/dist/src/commands/local/hub-local.d.ts.map +1 -1
- package/dist/src/commands/local/hub-local.js +61 -1
- package/dist/src/commands/local/hub-local.js.map +1 -1
- package/dist/src/commands/local/index.d.ts.map +1 -1
- package/dist/src/commands/local/index.js +15 -1
- package/dist/src/commands/local/index.js.map +1 -1
- package/dist/src/commands/local/seed-hub-catalog.d.ts +33 -0
- package/dist/src/commands/local/seed-hub-catalog.d.ts.map +1 -0
- package/dist/src/commands/local/seed-hub-catalog.js +90 -0
- package/dist/src/commands/local/seed-hub-catalog.js.map +1 -0
- package/dist/src/commands/login.d.ts +12 -0
- package/dist/src/commands/login.d.ts.map +1 -1
- package/dist/src/commands/login.js +52 -7
- package/dist/src/commands/login.js.map +1 -1
- package/dist/src/commands/registry.d.ts +22 -3
- package/dist/src/commands/registry.d.ts.map +1 -1
- package/dist/src/commands/registry.js +36 -4
- package/dist/src/commands/registry.js.map +1 -1
- package/dist/src/commands/temporal.js +20 -6
- package/dist/src/commands/temporal.js.map +2 -2
- package/dist/src/utils/aws-auth.d.ts +19 -0
- package/dist/src/utils/aws-auth.d.ts.map +1 -1
- package/dist/src/utils/aws-auth.js +30 -9
- package/dist/src/utils/aws-auth.js.map +1 -1
- package/dist/src/utils/registry-identity.d.ts +35 -0
- package/dist/src/utils/registry-identity.d.ts.map +1 -1
- package/dist/src/utils/registry-identity.js +47 -1
- package/dist/src/utils/registry-identity.js.map +1 -1
- package/package.json +2 -2
- package/skills/core/SKILL.md +2 -2
- package/templates/api-auth/index.ts.hbs +3 -1
- package/templates/api-role-gating/index.ts.hbs +3 -1
package/dist/bin/mesh.js
CHANGED
|
@@ -3274,6 +3274,7 @@ __export(login_exports, {
|
|
|
3274
3274
|
discoverConfigForContext: () => discoverConfigForContext,
|
|
3275
3275
|
discoverConfigFromWellKnown: () => discoverConfigFromWellKnown,
|
|
3276
3276
|
ensureLogin: () => ensureLogin,
|
|
3277
|
+
forceRefreshToken: () => forceRefreshToken,
|
|
3277
3278
|
getContextConfig: () => getContextConfig,
|
|
3278
3279
|
getValidToken: () => getValidToken,
|
|
3279
3280
|
isRemoteEnvironment: () => isRemoteEnvironment,
|
|
@@ -3993,22 +3994,43 @@ async function getValidToken(context, opts = {}) {
|
|
|
3993
3994
|
if (tokenStillValid(creds.expiresAt, opts.marginMs ?? 0)) {
|
|
3994
3995
|
return creds.idToken;
|
|
3995
3996
|
}
|
|
3997
|
+
return remintToken(context, config, creds);
|
|
3998
|
+
}
|
|
3999
|
+
async function remintToken(context, config, creds) {
|
|
3996
4000
|
if (!creds.refreshToken) return null;
|
|
4001
|
+
let tokens;
|
|
4002
|
+
try {
|
|
4003
|
+
tokens = await refreshTokens(config.issuer, config.clientId, creds.refreshToken);
|
|
4004
|
+
} catch {
|
|
4005
|
+
return null;
|
|
4006
|
+
}
|
|
4007
|
+
let email = creds.email;
|
|
4008
|
+
try {
|
|
4009
|
+
email = decodeJwtPayload(tokens.id_token).email ?? creds.email;
|
|
4010
|
+
} catch {
|
|
4011
|
+
}
|
|
3997
4012
|
try {
|
|
3998
|
-
const tokens = await refreshTokens(config.issuer, config.clientId, creds.refreshToken);
|
|
3999
|
-
const idPayload = decodeJwtPayload(tokens.id_token);
|
|
4000
4013
|
writeCredentials(context, {
|
|
4001
4014
|
...creds,
|
|
4002
4015
|
idToken: tokens.id_token,
|
|
4003
4016
|
accessToken: tokens.access_token,
|
|
4004
4017
|
refreshToken: tokens.refresh_token ?? creds.refreshToken,
|
|
4005
4018
|
expiresAt: new Date(Date.now() + tokens.expires_in * 1e3).toISOString(),
|
|
4006
|
-
email
|
|
4019
|
+
email
|
|
4007
4020
|
});
|
|
4008
|
-
|
|
4009
|
-
|
|
4010
|
-
|
|
4021
|
+
} catch (err) {
|
|
4022
|
+
logWarn(
|
|
4023
|
+
`The refreshed ${context} session could not be cached (${err instanceof Error ? err.message : String(err)}) \u2014 this run continues on the new token, but the next one may need a fresh sign-in.`
|
|
4024
|
+
);
|
|
4011
4025
|
}
|
|
4026
|
+
return tokens.id_token;
|
|
4027
|
+
}
|
|
4028
|
+
async function forceRefreshToken(context) {
|
|
4029
|
+
const config = getContextConfig(context);
|
|
4030
|
+
if (!config) return null;
|
|
4031
|
+
const creds = readCredentials(context);
|
|
4032
|
+
if (!creds) return null;
|
|
4033
|
+
return remintToken(context, config, creds);
|
|
4012
4034
|
}
|
|
4013
4035
|
async function probeCredentials(context, roleArn) {
|
|
4014
4036
|
const cached = readCredentials(context);
|
|
@@ -4376,7 +4398,9 @@ __export(registry_identity_exports, {
|
|
|
4376
4398
|
isReservedRegistryContext: () => isReservedRegistryContext,
|
|
4377
4399
|
logRegistryIdentity: () => logRegistryIdentity,
|
|
4378
4400
|
readRegistrySession: () => readRegistrySession,
|
|
4401
|
+
refreshRegistrySession: () => refreshRegistrySession,
|
|
4379
4402
|
registrySessionCandidates: () => registrySessionCandidates,
|
|
4403
|
+
registryTokenRoles: () => registryTokenRoles,
|
|
4380
4404
|
resolveRegistryIdentity: () => resolveRegistryIdentity
|
|
4381
4405
|
});
|
|
4382
4406
|
function isReservedRegistryContext(context) {
|
|
@@ -4480,6 +4504,22 @@ async function ensureRegistrySession(opts) {
|
|
|
4480
4504
|
expiresAt: creds.expiresAt
|
|
4481
4505
|
};
|
|
4482
4506
|
}
|
|
4507
|
+
function registryTokenRoles(idToken) {
|
|
4508
|
+
if (!idToken) return [];
|
|
4509
|
+
try {
|
|
4510
|
+
return projectRoleKeys(decodeJwtPayload(idToken)).sort();
|
|
4511
|
+
} catch {
|
|
4512
|
+
return [];
|
|
4513
|
+
}
|
|
4514
|
+
}
|
|
4515
|
+
async function refreshRegistrySession(context) {
|
|
4516
|
+
const before = registryTokenRoles(readCredentials(context)?.idToken);
|
|
4517
|
+
const idToken = await forceRefreshToken(context);
|
|
4518
|
+
if (!idToken) return { reminted: false, rolesChanged: false };
|
|
4519
|
+
const after = registryTokenRoles(idToken);
|
|
4520
|
+
const same = after.length === before.length && after.every((role, i) => role === before[i]);
|
|
4521
|
+
return { reminted: true, rolesChanged: !same };
|
|
4522
|
+
}
|
|
4483
4523
|
function clearRegistrySession() {
|
|
4484
4524
|
clearCredentials(REGISTRY_CREDENTIAL_KEY);
|
|
4485
4525
|
clearContextConfig(REGISTRY_CREDENTIAL_KEY);
|
|
@@ -4508,6 +4548,7 @@ var init_registry_identity = __esm({
|
|
|
4508
4548
|
"libs/mesh-cli/src/utils/registry-identity.ts"() {
|
|
4509
4549
|
"use strict";
|
|
4510
4550
|
init_login();
|
|
4551
|
+
init_aws_auth();
|
|
4511
4552
|
init_first_party_contexts();
|
|
4512
4553
|
init_registry_broker();
|
|
4513
4554
|
init_errors();
|
|
@@ -4985,16 +5026,20 @@ function selectRoleForCaller(idToken, options) {
|
|
|
4985
5026
|
const adminRoles = options.adminClaimRoles ?? ["mesh.platform:admin"];
|
|
4986
5027
|
const claims = decodeJwtPayload2(idToken);
|
|
4987
5028
|
if (!claims) return options.defaultRole;
|
|
5029
|
+
const claimedRoles = projectRoleKeys(claims);
|
|
5030
|
+
return adminRoles.some((target) => claimedRoles.includes(target)) ? options.adminRole : options.defaultRole;
|
|
5031
|
+
}
|
|
5032
|
+
function projectRoleKeys(claims) {
|
|
5033
|
+
const names = /* @__PURE__ */ new Set();
|
|
4988
5034
|
for (const [key, value] of Object.entries(claims)) {
|
|
4989
5035
|
if (!key.startsWith("urn:zitadel:iam:org:project:")) continue;
|
|
4990
5036
|
if (!key.endsWith(":roles")) continue;
|
|
4991
|
-
if (!value || typeof value !== "object") continue;
|
|
4992
|
-
const
|
|
4993
|
-
|
|
4994
|
-
if (claimedRoles.includes(target)) return options.adminRole;
|
|
5037
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) continue;
|
|
5038
|
+
for (const name of Object.keys(value)) {
|
|
5039
|
+
if (name) names.add(name);
|
|
4995
5040
|
}
|
|
4996
5041
|
}
|
|
4997
|
-
return
|
|
5042
|
+
return [...names];
|
|
4998
5043
|
}
|
|
4999
5044
|
async function resolveAwsCredentials(roleArn, appRoot, stack) {
|
|
5000
5045
|
const roleName = roleArn.split("/").pop() ?? roleArn;
|
|
@@ -10748,6 +10793,11 @@ function scanApp(root, appRel) {
|
|
|
10748
10793
|
for (const f of files) hit(code, rel(root, f), why);
|
|
10749
10794
|
};
|
|
10750
10795
|
anti("IAC_GRANTS", RE_IAC_GRANT, "per-user role grant baked into IaC \u2014 grants belong in the Hub (Access \u2192 People), not in a config redeploy");
|
|
10796
|
+
anti(
|
|
10797
|
+
"POINTER_PROJECT_OVERRIDE",
|
|
10798
|
+
RE_POINTER_OVERRIDE,
|
|
10799
|
+
"AppAuthzPointer is given a `zitadel:` override \u2014 an app binds its project with AppEnvironment's zitadelAppProjectId so every consumer of env.zitadel agrees; the override is reserved for the Hub"
|
|
10800
|
+
);
|
|
10751
10801
|
anti(
|
|
10752
10802
|
"PASSWORD_STORE",
|
|
10753
10803
|
RE_PASSWORD,
|
|
@@ -10857,7 +10907,7 @@ function registerAppCommands(program2) {
|
|
|
10857
10907
|
}
|
|
10858
10908
|
});
|
|
10859
10909
|
}
|
|
10860
|
-
var APP_CHECK_RULES, APP_CHECK_CODES, SRC_EXT, SKIP_DIRS, NON_SERVICE_DIRS, RE_HTML, RE_OIDC, RE_COOKIE, RE_LOGGER, RE_EXPOSURE, RE_POINTER, RE_METADATA, RE_IAC_GRANT, RE_PASSWORD, RE_ALLOWLIST, RE_USERS_TABLE;
|
|
10910
|
+
var APP_CHECK_RULES, APP_CHECK_CODES, SRC_EXT, SKIP_DIRS, NON_SERVICE_DIRS, RE_HTML, RE_OIDC, RE_COOKIE, RE_LOGGER, RE_EXPOSURE, RE_POINTER, RE_METADATA, RE_IAC_GRANT, RE_POINTER_OVERRIDE, RE_PASSWORD, RE_ALLOWLIST, RE_USERS_TABLE;
|
|
10861
10911
|
var init_app_check = __esm({
|
|
10862
10912
|
"libs/mesh-cli/src/commands/app-check.ts"() {
|
|
10863
10913
|
"use strict";
|
|
@@ -10929,6 +10979,13 @@ var init_app_check = __esm({
|
|
|
10929
10979
|
remediation: "remove the per-user grant map; grant roles from the Hub (App \u2192 Access \u2192 People)",
|
|
10930
10980
|
scope: "app"
|
|
10931
10981
|
},
|
|
10982
|
+
POINTER_PROJECT_OVERRIDE: {
|
|
10983
|
+
gate: "H",
|
|
10984
|
+
title: "Pointer publishes the env's project",
|
|
10985
|
+
severity: "advisory",
|
|
10986
|
+
remediation: "drop `zitadel:` from AppAuthzPointer and pass `zitadelAppProjectId: identity.projectId` to AppEnvironment \u2014 the override is the Hub's",
|
|
10987
|
+
scope: "app"
|
|
10988
|
+
},
|
|
10932
10989
|
PASSWORD_STORE: {
|
|
10933
10990
|
gate: "H",
|
|
10934
10991
|
title: "No app-side credentials",
|
|
@@ -10976,6 +11033,7 @@ var init_app_check = __esm({
|
|
|
10976
11033
|
RE_POINTER = /AppAuthzPointer/;
|
|
10977
11034
|
RE_METADATA = /compileOpsHubMetadata|ops-hub-metadata|SpiceDBSchema/;
|
|
10978
11035
|
RE_IAC_GRANT = /userId: *"[0-9]{6,}"/;
|
|
11036
|
+
RE_POINTER_OVERRIDE = /\bzitadel: *\{\s*projectId\b/;
|
|
10979
11037
|
RE_PASSWORD = /(^|[^a-z])(bcrypt|argon2)|password_hash|passwordHash|hashPassword|temporaryPassword.*(send|mail)|(send|mail).*temporaryPassword/;
|
|
10980
11038
|
RE_ALLOWLIST = /ADMIN_EMAILS|ALLOWED_EMAILS|allowedEmails|adminEmails/;
|
|
10981
11039
|
RE_USERS_TABLE = /create table (if not exists )?"?(users|roles|user_roles|permissions)"?/i;
|
|
@@ -12214,6 +12272,7 @@ __export(create_app_exports, {
|
|
|
12214
12272
|
PLATFORM_MONOREPO_NAME: () => PLATFORM_MONOREPO_NAME,
|
|
12215
12273
|
bootstrapAppsRepo: () => bootstrapAppsRepo,
|
|
12216
12274
|
copyTemplate: () => copyTemplate,
|
|
12275
|
+
describeNoAppsHome: () => describeNoAppsHome,
|
|
12217
12276
|
ensureRegistryAccess: () => ensureRegistryAccess,
|
|
12218
12277
|
ensureWorkspaceGlobs: () => ensureWorkspaceGlobs,
|
|
12219
12278
|
generateComposableApp: () => generateComposableApp,
|
|
@@ -12403,6 +12462,18 @@ function parsePrimitives(input2) {
|
|
|
12403
12462
|
}
|
|
12404
12463
|
return selected;
|
|
12405
12464
|
}
|
|
12465
|
+
function describeNoAppsHome(cwd, tenant, baseDir, test) {
|
|
12466
|
+
if (test || isInsidePlatformMonorepo(cwd)) {
|
|
12467
|
+
return {
|
|
12468
|
+
message: `Tenant directory not found: ${baseDir}/${tenant}/`,
|
|
12469
|
+
hint: "Create the tenant directory first, or run from within it."
|
|
12470
|
+
};
|
|
12471
|
+
}
|
|
12472
|
+
return {
|
|
12473
|
+
message: `This directory is not a Mesh apps repo \u2014 no apps/ here${fs23.existsSync(path25.join(cwd, ".git")) ? "" : " and it is not a git repo"}.`,
|
|
12474
|
+
hint: `Run: mesh init (turns this folder into your ${tenant}-mesh-apps repo), or cd into that repo and re-run mesh create-app.`
|
|
12475
|
+
};
|
|
12476
|
+
}
|
|
12406
12477
|
function resolveAppDir(cwd, tenant, name, test) {
|
|
12407
12478
|
const baseDir = test ? "tests/tenants" : "tenants";
|
|
12408
12479
|
const possiblePaths = test ? [path25.join(cwd, baseDir, tenant, "apps")] : [
|
|
@@ -12414,8 +12485,9 @@ function resolveAppDir(cwd, tenant, name, test) {
|
|
|
12414
12485
|
if (!appsDir) {
|
|
12415
12486
|
appsDir = path25.join(cwd, baseDir, tenant, "apps");
|
|
12416
12487
|
if (!fs23.existsSync(path25.join(cwd, baseDir, tenant))) {
|
|
12417
|
-
|
|
12418
|
-
|
|
12488
|
+
const { message, hint } = describeNoAppsHome(cwd, tenant, baseDir, test);
|
|
12489
|
+
logError(message);
|
|
12490
|
+
logInfo(hint);
|
|
12419
12491
|
process.exit(1);
|
|
12420
12492
|
}
|
|
12421
12493
|
if (!fs23.existsSync(appsDir)) {
|
|
@@ -16159,6 +16231,7 @@ __export(registry_exports, {
|
|
|
16159
16231
|
resolvePublisherRoleArn: () => resolvePublisherRoleArn,
|
|
16160
16232
|
runRegistryLogin: () => runRegistryLogin,
|
|
16161
16233
|
runRegistryStatus: () => runRegistryStatus,
|
|
16234
|
+
shouldRemintAfter: () => shouldRemintAfter,
|
|
16162
16235
|
shouldRepairUserNpmrc: () => shouldRepairUserNpmrc
|
|
16163
16236
|
});
|
|
16164
16237
|
import { execFileSync as execFileSync24 } from "child_process";
|
|
@@ -16422,6 +16495,9 @@ function describeBrokerFailure(failure) {
|
|
|
16422
16495
|
function registrySignInAllowed(opts, hasTty = Boolean(process.stdin.isTTY && process.stdout.isTTY)) {
|
|
16423
16496
|
return Boolean(opts.device) || hasTty;
|
|
16424
16497
|
}
|
|
16498
|
+
function shouldRemintAfter(failure) {
|
|
16499
|
+
return failure.kind === "not-authorized";
|
|
16500
|
+
}
|
|
16425
16501
|
async function tryBrokerLogin(opts) {
|
|
16426
16502
|
if (opts.broker === false) return { outcome: { kind: "skipped-flag", flag: "--no-broker" } };
|
|
16427
16503
|
if (opts.ci) return { outcome: { kind: "skipped-flag", flag: "--ci" } };
|
|
@@ -16461,6 +16537,13 @@ async function tryBrokerLogin(opts) {
|
|
|
16461
16537
|
result = await requestGrant(session.context, identity);
|
|
16462
16538
|
}
|
|
16463
16539
|
}
|
|
16540
|
+
if (!result.ok && shouldRemintAfter(result.failure)) {
|
|
16541
|
+
const { rolesChanged } = await refreshRegistrySession(session.context);
|
|
16542
|
+
if (rolesChanged) {
|
|
16543
|
+
logInfo("Your sign-in now carries a role it did not have \u2014 retrying\u2026");
|
|
16544
|
+
result = await requestGrant(session.context, identity);
|
|
16545
|
+
}
|
|
16546
|
+
}
|
|
16464
16547
|
if (result.ok) return { grant: result.grant };
|
|
16465
16548
|
const { message, hint, fatal } = describeBrokerFailure(result.failure);
|
|
16466
16549
|
if (fatal) {
|
|
@@ -16810,7 +16893,7 @@ var init_registry = __esm({
|
|
|
16810
16893
|
this.name = "RegistryNotAuthorizedError";
|
|
16811
16894
|
}
|
|
16812
16895
|
};
|
|
16813
|
-
NOT_AUTHORIZED_RERUN = "Once granted, run: mesh registry login (your sign-in
|
|
16896
|
+
NOT_AUTHORIZED_RERUN = "Once granted, run: mesh registry login (it re-mints your sign-in; still refused? mesh registry logout && mesh registry login)";
|
|
16814
16897
|
CONTEXT_IGNORED_NOTICE = "The registry is global \u2014 the context argument is no longer needed (ignored).";
|
|
16815
16898
|
}
|
|
16816
16899
|
});
|
|
@@ -16818,6 +16901,7 @@ var init_registry = __esm({
|
|
|
16818
16901
|
// libs/mesh-cli/src/commands/init/wizard.ts
|
|
16819
16902
|
var wizard_exports = {};
|
|
16820
16903
|
__export(wizard_exports, {
|
|
16904
|
+
INIT_REPO_FIX: () => INIT_REPO_FIX,
|
|
16821
16905
|
INTERRUPTED_EXIT_CODE: () => INTERRUPTED_EXIT_CODE,
|
|
16822
16906
|
NO_SESSION_NO_TTY_MESSAGE: () => NO_SESSION_NO_TTY_MESSAGE,
|
|
16823
16907
|
TENANT_REQUIRED_MESSAGE: () => TENANT_REQUIRED_MESSAGE,
|
|
@@ -16826,6 +16910,7 @@ __export(wizard_exports, {
|
|
|
16826
16910
|
describeMode: () => describeMode,
|
|
16827
16911
|
registryStep: () => registryStep,
|
|
16828
16912
|
renderWizardSummary: () => renderWizardSummary,
|
|
16913
|
+
repoStep: () => repoStep,
|
|
16829
16914
|
resolveAnswers: () => resolveAnswers,
|
|
16830
16915
|
runInitWizard: () => runInitWizard,
|
|
16831
16916
|
runWizardSteps: () => runWizardSteps,
|
|
@@ -16835,12 +16920,15 @@ __export(wizard_exports, {
|
|
|
16835
16920
|
});
|
|
16836
16921
|
import * as fs30 from "fs";
|
|
16837
16922
|
import * as path37 from "path";
|
|
16923
|
+
import { execFileSync as execFileSync25 } from "child_process";
|
|
16838
16924
|
import chalk4 from "chalk";
|
|
16839
16925
|
function wizardExitCode(steps) {
|
|
16840
16926
|
return steps.some((s) => s.status === "fail") ? 1 : 0;
|
|
16841
16927
|
}
|
|
16842
|
-
function wizardNextCommands(mode) {
|
|
16843
|
-
|
|
16928
|
+
function wizardNextCommands(mode, steps = []) {
|
|
16929
|
+
const repo = steps.find((s) => s.name === STEP_LABELS.repo);
|
|
16930
|
+
const first = repo && repo.status !== "pass" && repo.fix ? repo.fix : "mesh create-app";
|
|
16931
|
+
return mode === "local" ? [first] : [first, "mesh deploy up # from the app directory, once it exists"];
|
|
16844
16932
|
}
|
|
16845
16933
|
function stepBlocks(result) {
|
|
16846
16934
|
return result.status === "fail" && result.blocking !== false;
|
|
@@ -16889,12 +16977,18 @@ function classifyRepo(cwd) {
|
|
|
16889
16977
|
if (shouldBootstrapAppsRepo(cwd)) return { kind: "empty-apps-repo", root: cwd };
|
|
16890
16978
|
const root = resolveTargetRoot(cwd);
|
|
16891
16979
|
const inRepo = fs30.existsSync(path37.join(root, ".git"));
|
|
16892
|
-
if (!inRepo)
|
|
16980
|
+
if (!inRepo) {
|
|
16981
|
+
const hasContent = fs30.readdirSync(cwd).some((entry) => !entry.startsWith("."));
|
|
16982
|
+
return { kind: hasContent ? "no-repo" : "empty-dir", root: cwd };
|
|
16983
|
+
}
|
|
16893
16984
|
const hasWorkspace = fs30.existsSync(path37.join(root, "pnpm-workspace.yaml")) || fs30.existsSync(path37.join(root, "pnpm-lock.yaml"));
|
|
16894
16985
|
const hasApps = fs30.existsSync(path37.join(root, "apps")) || fs30.existsSync(path37.join(root, "tenants"));
|
|
16895
16986
|
if (hasWorkspace || hasApps) return { kind: "apps-repo", root };
|
|
16896
16987
|
return { kind: "other-repo", root };
|
|
16897
16988
|
}
|
|
16989
|
+
function gitInit(dir) {
|
|
16990
|
+
execFileSync25("git", ["init", "-q"], { cwd: dir, stdio: ["ignore", "ignore", "pipe"] });
|
|
16991
|
+
}
|
|
16898
16992
|
async function runWizardSteps(ctx, steps) {
|
|
16899
16993
|
const results = [];
|
|
16900
16994
|
for (const step of steps) {
|
|
@@ -16986,7 +17080,7 @@ async function runInitWizard(opts, deps = {}) {
|
|
|
16986
17080
|
const written = writeMeshJson(root, { tenant, platform: mode === "local" ? "local" : mode.platform });
|
|
16987
17081
|
logInfo(`Recorded tenant + mode in ${written}`);
|
|
16988
17082
|
}
|
|
16989
|
-
const outcome = { tenant, mode, steps, next: wizardNextCommands(mode) };
|
|
17083
|
+
const outcome = { tenant, mode, steps, next: wizardNextCommands(mode, steps) };
|
|
16990
17084
|
const code = wizardExitCode(steps);
|
|
16991
17085
|
if (opts.json) {
|
|
16992
17086
|
console.log = origLog;
|
|
@@ -17008,7 +17102,7 @@ async function runInitWizard(opts, deps = {}) {
|
|
|
17008
17102
|
console.log = origLog;
|
|
17009
17103
|
}
|
|
17010
17104
|
}
|
|
17011
|
-
var NO_SESSION_NO_TTY_MESSAGE, TENANT_REQUIRED_MESSAGE, INTERRUPTED_EXIT_CODE, STEP_LABELS, registryStep, platformStep, repoStep, skillsStep, WIZARD_STEPS;
|
|
17105
|
+
var NO_SESSION_NO_TTY_MESSAGE, TENANT_REQUIRED_MESSAGE, INTERRUPTED_EXIT_CODE, STEP_LABELS, registryStep, platformStep, INIT_REPO_FIX, repoStep, skillsStep, WIZARD_STEPS;
|
|
17012
17106
|
var init_wizard = __esm({
|
|
17013
17107
|
"libs/mesh-cli/src/commands/init/wizard.ts"() {
|
|
17014
17108
|
"use strict";
|
|
@@ -17112,6 +17206,7 @@ var init_wizard = __esm({
|
|
|
17112
17206
|
};
|
|
17113
17207
|
}
|
|
17114
17208
|
};
|
|
17209
|
+
INIT_REPO_FIX = "git init && mesh init";
|
|
17115
17210
|
repoStep = {
|
|
17116
17211
|
name: "repo",
|
|
17117
17212
|
async run(ctx) {
|
|
@@ -17121,11 +17216,34 @@ var init_wizard = __esm({
|
|
|
17121
17216
|
switch (kind) {
|
|
17122
17217
|
case "platform-monorepo":
|
|
17123
17218
|
return { name, status: "skip", detail: "inside mesh-platform \u2014 apps here link workspace packages; nothing to set up" };
|
|
17219
|
+
case "empty-dir": {
|
|
17220
|
+
const go = ctx.yes || !ctx.interactive ? true : await ctx.prompts.confirm({
|
|
17221
|
+
message: `This folder is not a git repo \u2014 initialize ${root} as your ${ctx.tenant}-mesh-apps repo here?`,
|
|
17222
|
+
default: true
|
|
17223
|
+
});
|
|
17224
|
+
if (!go) {
|
|
17225
|
+
return { name, status: "skip", detail: "folder left as is", fix: `cd <your ${ctx.tenant}-mesh-apps clone> && mesh init` };
|
|
17226
|
+
}
|
|
17227
|
+
try {
|
|
17228
|
+
(ctx.seams?.gitInit ?? gitInit)(root);
|
|
17229
|
+
} catch (err) {
|
|
17230
|
+
const why = err instanceof Error && "stderr" in err && err.stderr ? String(err.stderr).trim() : "";
|
|
17231
|
+
return {
|
|
17232
|
+
name,
|
|
17233
|
+
status: "fail",
|
|
17234
|
+
detail: `git init failed \u2014 is git installed and ${root} writable?${why ? ` (${why})` : ""}`,
|
|
17235
|
+
fix: INIT_REPO_FIX
|
|
17236
|
+
};
|
|
17237
|
+
}
|
|
17238
|
+
const created = bootstrapAppsRepo(root, ctx.tenant);
|
|
17239
|
+
return { name, status: "pass", detail: `initialized a git repo and bootstrapped the apps repo: ${created.join(", ")}` };
|
|
17240
|
+
}
|
|
17124
17241
|
case "no-repo":
|
|
17125
17242
|
return {
|
|
17126
17243
|
name,
|
|
17127
17244
|
status: "skip",
|
|
17128
|
-
detail: `not in a git repo \u2014 clone (or git init) your ${ctx.tenant}-mesh-apps repo and re-run mesh init there
|
|
17245
|
+
detail: `not in a git repo, and this folder already holds files \u2014 clone (or git init) your ${ctx.tenant}-mesh-apps repo and re-run mesh init there`,
|
|
17246
|
+
fix: INIT_REPO_FIX
|
|
17129
17247
|
};
|
|
17130
17248
|
case "other-repo":
|
|
17131
17249
|
return {
|
|
@@ -17464,7 +17582,7 @@ var init_init = __esm({
|
|
|
17464
17582
|
});
|
|
17465
17583
|
|
|
17466
17584
|
// libs/mesh-cli/src/commands/install-shim.ts
|
|
17467
|
-
import { execFileSync as
|
|
17585
|
+
import { execFileSync as execFileSync26 } from "child_process";
|
|
17468
17586
|
import * as fs32 from "fs";
|
|
17469
17587
|
import * as os10 from "os";
|
|
17470
17588
|
import * as path39 from "path";
|
|
@@ -17577,7 +17695,7 @@ function registerInstallShimCommand(program2) {
|
|
|
17577
17695
|
let status = 0;
|
|
17578
17696
|
let ok = true;
|
|
17579
17697
|
try {
|
|
17580
|
-
stdout =
|
|
17698
|
+
stdout = execFileSync26(target, ["--help"], {
|
|
17581
17699
|
cwd: process.cwd(),
|
|
17582
17700
|
encoding: "utf8",
|
|
17583
17701
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -17624,7 +17742,7 @@ var init_install_shim = __esm({
|
|
|
17624
17742
|
});
|
|
17625
17743
|
|
|
17626
17744
|
// libs/mesh-cli/src/commands/local/hub-local.ts
|
|
17627
|
-
import { execFile as execFile3, execFileSync as
|
|
17745
|
+
import { execFile as execFile3, execFileSync as execFileSync27 } from "child_process";
|
|
17628
17746
|
import * as fs33 from "fs";
|
|
17629
17747
|
import * as os11 from "os";
|
|
17630
17748
|
import * as path40 from "path";
|
|
@@ -17644,7 +17762,7 @@ function npmrcPath() {
|
|
|
17644
17762
|
}
|
|
17645
17763
|
function imageExists(tag) {
|
|
17646
17764
|
try {
|
|
17647
|
-
|
|
17765
|
+
execFileSync27("docker", ["image", "inspect", tag], { stdio: ["ignore", "pipe", "pipe"] });
|
|
17648
17766
|
return true;
|
|
17649
17767
|
} catch {
|
|
17650
17768
|
return false;
|
|
@@ -17654,7 +17772,7 @@ function ensureHubAuthImage() {
|
|
|
17654
17772
|
if (imageExists(HUB_AUTH_IMAGE)) return;
|
|
17655
17773
|
logInfo(`Building ${HUB_AUTH_IMAGE} (Hub auth proxy)\u2026`);
|
|
17656
17774
|
const hubStackDir = path40.join(findPackageRoot(), "stack", "hub");
|
|
17657
|
-
|
|
17775
|
+
execFileSync27(
|
|
17658
17776
|
"docker",
|
|
17659
17777
|
["build", "-f", path40.join(hubStackDir, "Dockerfile.auth"), "-t", HUB_AUTH_IMAGE, hubStackDir],
|
|
17660
17778
|
{ stdio: ["ignore", "inherit", "inherit"], env: { ...process.env, DOCKER_BUILDKIT: "1" } }
|
|
@@ -17668,7 +17786,7 @@ function hasRegistryAuth() {
|
|
|
17668
17786
|
function localHubVersion() {
|
|
17669
17787
|
const versions = HUB_IMAGES.map((name) => {
|
|
17670
17788
|
try {
|
|
17671
|
-
const out =
|
|
17789
|
+
const out = execFileSync27("docker", ["images", name, "--format", "{{.Tag}}"], {
|
|
17672
17790
|
encoding: "utf-8",
|
|
17673
17791
|
stdio: ["ignore", "pipe", "pipe"]
|
|
17674
17792
|
});
|
|
@@ -17747,7 +17865,7 @@ async function ensureHubImages() {
|
|
|
17747
17865
|
const context = path40.join(cacheDir(), `context-${version}`);
|
|
17748
17866
|
fs33.rmSync(context, { recursive: true, force: true });
|
|
17749
17867
|
fs33.mkdirSync(context, { recursive: true });
|
|
17750
|
-
|
|
17868
|
+
execFileSync27("tar", ["-xzf", tarball, "-C", context, "--strip-components", "1"], {
|
|
17751
17869
|
stdio: ["ignore", "pipe", "pipe"]
|
|
17752
17870
|
});
|
|
17753
17871
|
const hubStackDir = path40.join(findPackageRoot(), "stack", "hub");
|
|
@@ -17758,7 +17876,7 @@ async function ensureHubImages() {
|
|
|
17758
17876
|
const tag = `${name}:${version}`;
|
|
17759
17877
|
if (imageExists(tag)) continue;
|
|
17760
17878
|
logInfo(`Building ${tag} from the published tarball\u2026`);
|
|
17761
|
-
|
|
17879
|
+
execFileSync27(
|
|
17762
17880
|
"docker",
|
|
17763
17881
|
[
|
|
17764
17882
|
"build",
|
|
@@ -17776,6 +17894,32 @@ async function ensureHubImages() {
|
|
|
17776
17894
|
}
|
|
17777
17895
|
return version;
|
|
17778
17896
|
}
|
|
17897
|
+
function tarballNameForImageVersion(version) {
|
|
17898
|
+
if (version.endsWith("-src")) return null;
|
|
17899
|
+
return `mesh-tech-hub-${version.replace(/-r\d+$/, "")}.tgz`;
|
|
17900
|
+
}
|
|
17901
|
+
function readHubCompiledAuthz(version) {
|
|
17902
|
+
const context = path40.join(cacheDir(), `context-${version}`);
|
|
17903
|
+
const file = path40.join(context, HUB_COMPILED_AUTHZ_REL);
|
|
17904
|
+
if (!fs33.existsSync(file)) {
|
|
17905
|
+
const tarball = tarballNameForImageVersion(version);
|
|
17906
|
+
if (!tarball || !fs33.existsSync(path40.join(cacheDir(), tarball))) return null;
|
|
17907
|
+
fs33.mkdirSync(context, { recursive: true });
|
|
17908
|
+
try {
|
|
17909
|
+
execFileSync27(
|
|
17910
|
+
"tar",
|
|
17911
|
+
["-xzf", path40.join(cacheDir(), tarball), "-C", context, "--strip-components", "1", `package/${HUB_COMPILED_AUTHZ_REL}`],
|
|
17912
|
+
{ stdio: ["ignore", "pipe", "pipe"] }
|
|
17913
|
+
);
|
|
17914
|
+
} catch {
|
|
17915
|
+
return null;
|
|
17916
|
+
}
|
|
17917
|
+
if (!fs33.existsSync(file)) return null;
|
|
17918
|
+
}
|
|
17919
|
+
const parsed = JSON.parse(fs33.readFileSync(file, "utf-8"));
|
|
17920
|
+
if (typeof parsed.zed !== "string" || !parsed.metadata || typeof parsed.metadata !== "object") return null;
|
|
17921
|
+
return { zed: parsed.zed, metadata: parsed.metadata };
|
|
17922
|
+
}
|
|
17779
17923
|
function readWorkspaceCatalog(repoRoot2) {
|
|
17780
17924
|
const text = fs33.readFileSync(path40.join(repoRoot2, "pnpm-workspace.yaml"), "utf-8");
|
|
17781
17925
|
const marker = "\ncatalog:\n";
|
|
@@ -17790,7 +17934,7 @@ function readWorkspaceCatalog(repoRoot2) {
|
|
|
17790
17934
|
return catalog;
|
|
17791
17935
|
}
|
|
17792
17936
|
function normalizeHubManifests(contextDir, catalog) {
|
|
17793
|
-
const DEP_FIELDS = ["dependencies", "
|
|
17937
|
+
const DEP_FIELDS = ["dependencies", "optionalDependencies", "peerDependencies"];
|
|
17794
17938
|
const touched = [];
|
|
17795
17939
|
for (const entry of fs33.readdirSync(contextDir, { withFileTypes: true })) {
|
|
17796
17940
|
if (!entry.isDirectory()) continue;
|
|
@@ -17798,6 +17942,10 @@ function normalizeHubManifests(contextDir, catalog) {
|
|
|
17798
17942
|
if (!fs33.existsSync(manifest)) continue;
|
|
17799
17943
|
const pkg = JSON.parse(fs33.readFileSync(manifest, "utf-8"));
|
|
17800
17944
|
let changed = false;
|
|
17945
|
+
if (pkg.devDependencies) {
|
|
17946
|
+
delete pkg.devDependencies;
|
|
17947
|
+
changed = true;
|
|
17948
|
+
}
|
|
17801
17949
|
for (const field of DEP_FIELDS) {
|
|
17802
17950
|
const deps = pkg[field];
|
|
17803
17951
|
if (!deps) continue;
|
|
@@ -17852,7 +18000,7 @@ async function buildHubImagesFromSource(repoRoot2) {
|
|
|
17852
18000
|
await execFileAsync2("pnpm", ["pack", "--pack-destination", context], { cwd: hubDir, maxBuffer: 64 * 1024 * 1024 });
|
|
17853
18001
|
const tarball = fs33.readdirSync(context).find((f) => f.endsWith(".tgz"));
|
|
17854
18002
|
if (!tarball) throw new MeshCliError("pnpm pack produced no tarball for apps/hub");
|
|
17855
|
-
|
|
18003
|
+
execFileSync27("tar", ["-xzf", path40.join(context, tarball), "-C", context, "--strip-components", "1"], {
|
|
17856
18004
|
stdio: ["ignore", "pipe", "pipe"]
|
|
17857
18005
|
});
|
|
17858
18006
|
const rewritten = normalizeHubManifests(context, readWorkspaceCatalog(repoRoot2));
|
|
@@ -17864,7 +18012,7 @@ async function buildHubImagesFromSource(repoRoot2) {
|
|
|
17864
18012
|
]) {
|
|
17865
18013
|
const tag = `${name}:${version}`;
|
|
17866
18014
|
logInfo(`Building ${tag} from source\u2026`);
|
|
17867
|
-
|
|
18015
|
+
execFileSync27(
|
|
17868
18016
|
"docker",
|
|
17869
18017
|
["build", "-f", path40.join(hubStackDir, dockerfile), "-t", tag, "--secret", `id=npmrc,src=${npmrc}`, context],
|
|
17870
18018
|
{ stdio: ["ignore", "inherit", "inherit"], env: { ...process.env, DOCKER_BUILDKIT: "1" } }
|
|
@@ -17873,7 +18021,7 @@ async function buildHubImagesFromSource(repoRoot2) {
|
|
|
17873
18021
|
}
|
|
17874
18022
|
return version;
|
|
17875
18023
|
}
|
|
17876
|
-
var execFileAsync2, HUB_PACKAGE, HUB_IMAGES, LOCAL_IMAGE_REV, HUB_AUTH_IMAGE;
|
|
18024
|
+
var execFileAsync2, HUB_PACKAGE, HUB_IMAGES, LOCAL_IMAGE_REV, HUB_AUTH_IMAGE, HUB_COMPILED_AUTHZ_REL;
|
|
17877
18025
|
var init_hub_local = __esm({
|
|
17878
18026
|
"libs/mesh-cli/src/commands/local/hub-local.ts"() {
|
|
17879
18027
|
"use strict";
|
|
@@ -17887,6 +18035,66 @@ var init_hub_local = __esm({
|
|
|
17887
18035
|
HUB_IMAGES = ["mesh-local-hub-api", "mesh-local-hub-ui"];
|
|
17888
18036
|
LOCAL_IMAGE_REV = "r2";
|
|
17889
18037
|
HUB_AUTH_IMAGE = "mesh-local-hub-auth:v7.7.1-r1";
|
|
18038
|
+
HUB_COMPILED_AUTHZ_REL = "api/dist/authz/compiled.json";
|
|
18039
|
+
}
|
|
18040
|
+
});
|
|
18041
|
+
|
|
18042
|
+
// libs/mesh-cli/src/commands/local/seed-hub-catalog.ts
|
|
18043
|
+
function withHubCatalogRefs(pointer, metadataRef) {
|
|
18044
|
+
return {
|
|
18045
|
+
spicedb: { instanceRefs: [] },
|
|
18046
|
+
...pointer,
|
|
18047
|
+
opsHubMetadataRef: metadataRef,
|
|
18048
|
+
mode: typeof pointer.mode === "string" ? pointer.mode : "policy-engine"
|
|
18049
|
+
};
|
|
18050
|
+
}
|
|
18051
|
+
async function publishHubAuthzCatalog(compiled, awsConfig) {
|
|
18052
|
+
const { SSMClient: SSMClient5, GetParameterCommand: GetParameterCommand2, PutParameterCommand } = await import("@aws-sdk/client-ssm");
|
|
18053
|
+
const ssm = new SSMClient5(awsConfig);
|
|
18054
|
+
await ssm.send(
|
|
18055
|
+
new PutParameterCommand({
|
|
18056
|
+
Name: HUB_OPS_HUB_METADATA_PARAM,
|
|
18057
|
+
Type: "String",
|
|
18058
|
+
// The blob is ~7.5 KB — past the 4 KB standard tier, within Advanced (8 KB),
|
|
18059
|
+
// the tier the platform's Export uses for the same param.
|
|
18060
|
+
Tier: "Advanced",
|
|
18061
|
+
Overwrite: true,
|
|
18062
|
+
Value: JSON.stringify(compiled.metadata),
|
|
18063
|
+
Description: "Hub role catalog \u2014 ops-hub-metadata (local analog of MeshHub's SpiceDBSchema export)"
|
|
18064
|
+
})
|
|
18065
|
+
);
|
|
18066
|
+
let current = {};
|
|
18067
|
+
try {
|
|
18068
|
+
const existing = await ssm.send(new GetParameterCommand2({ Name: HUB_AUTHZ_POINTER_PARAM }));
|
|
18069
|
+
current = JSON.parse(existing.Parameter?.Value ?? "{}");
|
|
18070
|
+
} catch {
|
|
18071
|
+
}
|
|
18072
|
+
await ssm.send(
|
|
18073
|
+
new PutParameterCommand({
|
|
18074
|
+
Name: HUB_AUTHZ_POINTER_PARAM,
|
|
18075
|
+
Type: "String",
|
|
18076
|
+
Overwrite: true,
|
|
18077
|
+
Value: JSON.stringify(withHubCatalogRefs(current, HUB_OPS_HUB_METADATA_PARAM)),
|
|
18078
|
+
Description: "Hub authz pointer (local analog of the platform Pulumi program)"
|
|
18079
|
+
})
|
|
18080
|
+
);
|
|
18081
|
+
return { bundles: catalogBundleNames(compiled.metadata) };
|
|
18082
|
+
}
|
|
18083
|
+
function catalogBundleNames(metadata) {
|
|
18084
|
+
const bundles = metadata.bundles;
|
|
18085
|
+
if (Array.isArray(bundles)) {
|
|
18086
|
+
return bundles.map((b) => b && typeof b === "object" && typeof b.name === "string" ? b.name : null).filter((n) => n !== null);
|
|
18087
|
+
}
|
|
18088
|
+
if (bundles && typeof bundles === "object") return Object.keys(bundles);
|
|
18089
|
+
return [];
|
|
18090
|
+
}
|
|
18091
|
+
var HUB_AUTHZ_POINTER_PARAM, HUB_OPS_HUB_METADATA_PARAM;
|
|
18092
|
+
var init_seed_hub_catalog = __esm({
|
|
18093
|
+
"libs/mesh-cli/src/commands/local/seed-hub-catalog.ts"() {
|
|
18094
|
+
"use strict";
|
|
18095
|
+
init_seed();
|
|
18096
|
+
HUB_AUTHZ_POINTER_PARAM = `/mesh-platform/${LOCAL_TENANT}/${LOCAL_ENV}/apps/hub/stacks/local/authz`;
|
|
18097
|
+
HUB_OPS_HUB_METADATA_PARAM = `${HUB_AUTHZ_POINTER_PARAM}/ops-hub-metadata`;
|
|
17890
18098
|
}
|
|
17891
18099
|
});
|
|
17892
18100
|
|
|
@@ -18063,6 +18271,17 @@ Re-running start from here may recreate shared containers with this checkout's c
|
|
|
18063
18271
|
logInfo("Seeding Zitadel (Platform project, Mesh CLI app, Hub auth, test users)\u2026");
|
|
18064
18272
|
const zitadel = await seedZitadel(LOCAL_AWS_CONFIG);
|
|
18065
18273
|
hubAuth = zitadel.hubAuth;
|
|
18274
|
+
if (hubVersion) {
|
|
18275
|
+
const compiled = readHubCompiledAuthz(hubVersion);
|
|
18276
|
+
if (compiled) {
|
|
18277
|
+
const { bundles } = await publishHubAuthzCatalog(compiled, LOCAL_AWS_CONFIG);
|
|
18278
|
+
logSuccess(`Hub role catalog seeded: ${bundles.length} role(s) (${bundles.join(", ")})`);
|
|
18279
|
+
} else {
|
|
18280
|
+
logWarn(
|
|
18281
|
+
`Hub v${hubVersion} ships no compiled role catalog (api/dist/authz/compiled.json) \u2014 Users \u2192 Roles will be empty. Hub \u2265 2.1.0 publishes one.`
|
|
18282
|
+
);
|
|
18283
|
+
}
|
|
18284
|
+
}
|
|
18066
18285
|
try {
|
|
18067
18286
|
const reconciled = await reconcileRegistryFromZitadel();
|
|
18068
18287
|
if (reconciled.tenants.length > 0) {
|
|
@@ -18230,6 +18449,7 @@ var init_local = __esm({
|
|
|
18230
18449
|
init_auth_provision();
|
|
18231
18450
|
init_seed();
|
|
18232
18451
|
init_seed_zitadel();
|
|
18452
|
+
init_seed_hub_catalog();
|
|
18233
18453
|
WAIT_TIMEOUT_MS = 18e4;
|
|
18234
18454
|
WAIT_POLL_MS = 3e3;
|
|
18235
18455
|
}
|
|
@@ -19424,7 +19644,7 @@ var init_site = __esm({
|
|
|
19424
19644
|
});
|
|
19425
19645
|
|
|
19426
19646
|
// libs/mesh-cli/src/commands/stack.ts
|
|
19427
|
-
import { execFileSync as
|
|
19647
|
+
import { execFileSync as execFileSync28 } from "child_process";
|
|
19428
19648
|
import * as path42 from "path";
|
|
19429
19649
|
import * as fs35 from "fs";
|
|
19430
19650
|
import { parse as parseYaml5 } from "yaml";
|
|
@@ -19517,7 +19737,7 @@ function readBaseConfigFromYaml(appRoot, stack) {
|
|
|
19517
19737
|
}
|
|
19518
19738
|
function getGitHubUsername() {
|
|
19519
19739
|
try {
|
|
19520
|
-
const result =
|
|
19740
|
+
const result = execFileSync28("gh", ["api", "user", "--jq", ".login"], {
|
|
19521
19741
|
encoding: "utf-8",
|
|
19522
19742
|
stdio: ["pipe", "pipe", "pipe"]
|
|
19523
19743
|
});
|
|
@@ -19526,7 +19746,7 @@ function getGitHubUsername() {
|
|
|
19526
19746
|
} catch {
|
|
19527
19747
|
}
|
|
19528
19748
|
try {
|
|
19529
|
-
const result =
|
|
19749
|
+
const result = execFileSync28("git", ["config", "user.email"], {
|
|
19530
19750
|
encoding: "utf-8",
|
|
19531
19751
|
stdio: ["pipe", "pipe", "pipe"]
|
|
19532
19752
|
});
|
|
@@ -19612,7 +19832,7 @@ Specify which to base on: mesh stack init --from <stack>`
|
|
|
19612
19832
|
if (!opts.adopt) {
|
|
19613
19833
|
let existing = [];
|
|
19614
19834
|
try {
|
|
19615
|
-
const raw =
|
|
19835
|
+
const raw = execFileSync28("pulumi", ["stack", "ls", "--json"], {
|
|
19616
19836
|
cwd: appRoot,
|
|
19617
19837
|
encoding: "utf-8",
|
|
19618
19838
|
env: pulumiEnv,
|
|
@@ -19636,7 +19856,7 @@ Specify which to base on: mesh stack init --from <stack>`
|
|
|
19636
19856
|
logInfo(`Using KMS secrets provider: ${secretsProvider}`);
|
|
19637
19857
|
}
|
|
19638
19858
|
try {
|
|
19639
|
-
|
|
19859
|
+
execFileSync28("pulumi", initArgs, {
|
|
19640
19860
|
cwd: appRoot,
|
|
19641
19861
|
env: pulumiEnv,
|
|
19642
19862
|
stdio: "inherit"
|
|
@@ -19653,7 +19873,7 @@ Specify which to base on: mesh stack init --from <stack>`
|
|
|
19653
19873
|
}
|
|
19654
19874
|
}
|
|
19655
19875
|
try {
|
|
19656
|
-
|
|
19876
|
+
execFileSync28("pulumi", ["stack", "select", newStack], {
|
|
19657
19877
|
cwd: appRoot,
|
|
19658
19878
|
env: pulumiEnv,
|
|
19659
19879
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -19663,7 +19883,7 @@ Specify which to base on: mesh stack init --from <stack>`
|
|
|
19663
19883
|
if (!configExists) {
|
|
19664
19884
|
let baseConfig = {};
|
|
19665
19885
|
try {
|
|
19666
|
-
const raw =
|
|
19886
|
+
const raw = execFileSync28(
|
|
19667
19887
|
"pulumi",
|
|
19668
19888
|
["config", "--json", "--stack", baseStack],
|
|
19669
19889
|
{ cwd: appRoot, env: pulumiEnv, encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }
|
|
@@ -19681,19 +19901,19 @@ Specify which to base on: mesh stack init --from <stack>`
|
|
|
19681
19901
|
if (key === "mesh:deploy") continue;
|
|
19682
19902
|
try {
|
|
19683
19903
|
if (entry.objectValue !== void 0) {
|
|
19684
|
-
|
|
19904
|
+
execFileSync28(
|
|
19685
19905
|
"pulumi",
|
|
19686
19906
|
["config", "set", key, JSON.stringify(entry.objectValue)],
|
|
19687
19907
|
{ cwd: appRoot, env: pulumiEnv, stdio: ["pipe", "pipe", "pipe"] }
|
|
19688
19908
|
);
|
|
19689
19909
|
} else if (entry.value === "true" || entry.value === "false") {
|
|
19690
|
-
|
|
19910
|
+
execFileSync28(
|
|
19691
19911
|
"pulumi",
|
|
19692
19912
|
["config", "set", "--type", "bool", key, entry.value],
|
|
19693
19913
|
{ cwd: appRoot, env: pulumiEnv, stdio: ["pipe", "pipe", "pipe"] }
|
|
19694
19914
|
);
|
|
19695
19915
|
} else {
|
|
19696
|
-
|
|
19916
|
+
execFileSync28(
|
|
19697
19917
|
"pulumi",
|
|
19698
19918
|
["config", "set", key, entry.value],
|
|
19699
19919
|
{ cwd: appRoot, env: pulumiEnv, stdio: ["pipe", "pipe", "pipe"] }
|
|
@@ -19706,7 +19926,7 @@ Specify which to base on: mesh stack init --from <stack>`
|
|
|
19706
19926
|
const baseEnv = readConfigBlockKey(appRoot, baseStack, "mesh:coreEnv") ?? (baseTenant && baseStack.startsWith(`${baseTenant}-`) ? baseStack.slice(baseTenant.length + 1) : baseStack);
|
|
19707
19927
|
const setCfg = (args) => {
|
|
19708
19928
|
try {
|
|
19709
|
-
|
|
19929
|
+
execFileSync28("pulumi", ["config", "set", ...args], {
|
|
19710
19930
|
cwd: appRoot,
|
|
19711
19931
|
env: pulumiEnv,
|
|
19712
19932
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -19755,7 +19975,7 @@ Specify which to base on: mesh stack init --from <stack>`
|
|
|
19755
19975
|
`Configured Pulumi.${newStack}.yaml (personal platform env on core '${baseEnv}'${opts.parentZone ? `, DNS zone ${newStack.startsWith(`${baseTenant}-`) ? newStack.slice(baseTenant.length + 1) : newStack}.${opts.parentZone}` : ""})`
|
|
19756
19976
|
);
|
|
19757
19977
|
} else {
|
|
19758
|
-
|
|
19978
|
+
execFileSync28("pulumi", ["config", "set", "--type", "bool", "mesh:deploy", "false"], {
|
|
19759
19979
|
cwd: appRoot,
|
|
19760
19980
|
env: pulumiEnv,
|
|
19761
19981
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -19785,7 +20005,7 @@ Specify which to base on: mesh stack init --from <stack>`
|
|
|
19785
20005
|
const args = ["stack", "rm", name];
|
|
19786
20006
|
if (opts.yes) args.push("--yes");
|
|
19787
20007
|
try {
|
|
19788
|
-
|
|
20008
|
+
execFileSync28("pulumi", args, { cwd: appRoot, env: pulumiEnv, stdio: "inherit" });
|
|
19789
20009
|
logSuccess(`Removed stack ${name}`);
|
|
19790
20010
|
} catch (err) {
|
|
19791
20011
|
process.exit(err.status ?? 1);
|
|
@@ -19997,12 +20217,12 @@ var init_recover_conversation = __esm({
|
|
|
19997
20217
|
});
|
|
19998
20218
|
|
|
19999
20219
|
// libs/mesh-cli/src/utils/temporal-codec.ts
|
|
20000
|
-
import { execFileSync as
|
|
20220
|
+
import { execFileSync as execFileSync29 } from "child_process";
|
|
20001
20221
|
import { webcrypto as crypto4 } from "node:crypto";
|
|
20002
20222
|
function resolveTemporalEncodingKeyFromK8s(namespace) {
|
|
20003
20223
|
const secretName = `${namespace}-temporal-encoding-key`;
|
|
20004
20224
|
try {
|
|
20005
|
-
const b64 =
|
|
20225
|
+
const b64 = execFileSync29(
|
|
20006
20226
|
"kubectl",
|
|
20007
20227
|
[
|
|
20008
20228
|
"get",
|
|
@@ -23342,7 +23562,7 @@ var init_src4 = __esm({
|
|
|
23342
23562
|
import * as fs38 from "fs";
|
|
23343
23563
|
import * as path45 from "path";
|
|
23344
23564
|
import { createRequire as createRequire2 } from "module";
|
|
23345
|
-
import { execFileSync as
|
|
23565
|
+
import { execFileSync as execFileSync30 } from "child_process";
|
|
23346
23566
|
function resolveExtractorPath() {
|
|
23347
23567
|
try {
|
|
23348
23568
|
const require2 = createRequire2(import.meta.url);
|
|
@@ -23397,7 +23617,7 @@ for (const file of files) {
|
|
|
23397
23617
|
process.stdout.write(JSON.stringify(results));
|
|
23398
23618
|
`;
|
|
23399
23619
|
try {
|
|
23400
|
-
const result =
|
|
23620
|
+
const result = execFileSync30("npx", ["tsx", "--eval", script], {
|
|
23401
23621
|
encoding: "utf-8",
|
|
23402
23622
|
stdio: ["pipe", "pipe", "inherit"],
|
|
23403
23623
|
maxBuffer: 10 * 1024 * 1024
|
|
@@ -23439,7 +23659,7 @@ for (const file of files) {
|
|
|
23439
23659
|
process.stdout.write(JSON.stringify(results));
|
|
23440
23660
|
`;
|
|
23441
23661
|
try {
|
|
23442
|
-
const result =
|
|
23662
|
+
const result = execFileSync30("npx", ["tsx", "--eval", script], {
|
|
23443
23663
|
encoding: "utf-8",
|
|
23444
23664
|
stdio: ["pipe", "pipe", "inherit"],
|
|
23445
23665
|
maxBuffer: 10 * 1024 * 1024
|
|
@@ -23494,7 +23714,7 @@ for (const file of files) {
|
|
|
23494
23714
|
process.stdout.write(JSON.stringify(results));
|
|
23495
23715
|
`;
|
|
23496
23716
|
try {
|
|
23497
|
-
const result =
|
|
23717
|
+
const result = execFileSync30("npx", ["tsx", "--eval", script], {
|
|
23498
23718
|
encoding: "utf-8",
|
|
23499
23719
|
stdio: ["pipe", "pipe", "inherit"],
|
|
23500
23720
|
maxBuffer: 10 * 1024 * 1024
|