@mesh-tech/mesh-cli 0.33.0 → 0.34.1

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 CHANGED
@@ -92,8 +92,9 @@ It writes a tenant **platform** repo (the core + platform Pulumi layers on
92
92
  `@mesh-tech/infra-components`) that deploys with `mesh deploy` unmodified, asks
93
93
  for the per-install values, offers to create the Pulumi state bucket, and prints
94
94
  the deploy sequence — including the one manual step in the middle: **delegating
95
- the NS records** of the new public zone, without which the deploy stalls on its
96
- ACM certificate.
95
+ the NS records** of the new public zone. The deploy stops at the mesh-gateway
96
+ Ingress until ACM issues the wildcard certificate, which it does on its own once
97
+ that delegation resolves.
97
98
 
98
99
  The platform layer builds service images with Docker by default, so it needs a
99
100
  working Docker daemon; the core layer does not. On a machine without Docker (a
package/dist/bin/mesh.js CHANGED
@@ -1110,6 +1110,17 @@ var init_seed = __esm({
1110
1110
  }
1111
1111
  });
1112
1112
 
1113
+ // libs/mesh-cli/src/utils/aws-errors.ts
1114
+ function isAwsErrorCode(err, code) {
1115
+ const e = err;
1116
+ return e?.name === code || e?.__type === code || e?.Code === code || e?.code === code || typeof e?.message === "string" && e.message.includes(code);
1117
+ }
1118
+ var init_aws_errors = __esm({
1119
+ "libs/mesh-cli/src/utils/aws-errors.ts"() {
1120
+ "use strict";
1121
+ }
1122
+ });
1123
+
1113
1124
  // libs/mesh-cli/src/commands/local/helpers.ts
1114
1125
  import * as net from "net";
1115
1126
  import { execFileSync as execFileSync3 } from "child_process";
@@ -1120,7 +1131,7 @@ async function upsertLocalSecret(secretId, value, client) {
1120
1131
  try {
1121
1132
  await sm.send(new CreateSecretCommand4({ Name: secretId, SecretString: secretString }));
1122
1133
  } catch (err) {
1123
- if (err?.name === "ResourceExistsException") {
1134
+ if (isAwsErrorCode(err, "ResourceExistsException")) {
1124
1135
  await sm.send(new PutSecretValueCommand4({ SecretId: secretId, SecretString: secretString }));
1125
1136
  } else {
1126
1137
  throw err;
@@ -1202,6 +1213,7 @@ var init_helpers = __esm({
1202
1213
  "libs/mesh-cli/src/commands/local/helpers.ts"() {
1203
1214
  "use strict";
1204
1215
  init_seed();
1216
+ init_aws_errors();
1205
1217
  defaultPortConflictIo = {
1206
1218
  dockerPs: () => {
1207
1219
  try {
@@ -10442,7 +10454,9 @@ function registerDevCommand(program2) {
10442
10454
  { remediation: { command: `docker compose -f ${decl.compose} up # debug it directly` } }
10443
10455
  );
10444
10456
  }
10445
- logWarn(`External '${name}' credential seeding failed: ${err instanceof Error ? err.message : err}`);
10457
+ logWarn(
10458
+ `External '${name}' credential seeding failed: ${err instanceof Error ? err.message : err} \u2014 the app will resolve whatever was seeded previously, which may point at a stale port.`
10459
+ );
10446
10460
  }
10447
10461
  }
10448
10462
  if (dockerRunner) {
@@ -17521,7 +17535,7 @@ function validateDomain(value) {
17521
17535
  return "a public domain you control, e.g. q2poc.pub";
17522
17536
  }
17523
17537
  if (/(^|\.)(example\.(com|org|net)|invalid|localhost|test)$/.test(domain)) {
17524
- return `${domain} is a placeholder \u2014 the deploy stalls on an ACM certificate for a zone nobody can delegate. Use a domain you control.`;
17538
+ return `${domain} is a placeholder \u2014 its ACM certificate can never validate, because nobody can delegate that zone to you. Use a domain you control.`;
17525
17539
  }
17526
17540
  return true;
17527
17541
  }
@@ -17633,7 +17647,7 @@ function renderPlatformNextSteps(setup, opts = {}) {
17633
17647
  `aws sso login --profile ${setup.profile} # if this profile is SSO`,
17634
17648
  exportCredentialsCommand(setup.profile),
17635
17649
  `cd core && mesh deploy up # the VPC, EKS, RDS and the public zone ${setup.env}.${setup.domain}`,
17636
- `# \u2192 then delegate the NS records of ${setup.env}.${setup.domain} from ${setup.domain}; the deploy waits on the ACM certificate until you do`,
17650
+ `# \u2192 then delegate the NS records of ${setup.env}.${setup.domain} from ${setup.domain} at your registrar; the deploy stops at the mesh-gateway Ingress until ACM issues the certificate, then continues`,
17637
17651
  "cd ../platform && mesh deploy up # Temporal, Zitadel, the Hub (needs Docker \u2014 it builds service images)",
17638
17652
  `mesh login ${setup.tenant}.${setup.env} # your platform sign-in, once it is up`,
17639
17653
  "",
@@ -17675,7 +17689,7 @@ var init_platform_setup = __esm({
17675
17689
  region: "us-east-2",
17676
17690
  profile: "default"
17677
17691
  };
17678
- DOMAIN_REQUIRED_MESSAGE = "--domain is required: the core stack creates the public Route 53 zone <env>.<domain>, and a placeholder domain scaffolds a zone that can never validate (the deploy stalls on the ACM certificate).";
17692
+ DOMAIN_REQUIRED_MESSAGE = "--domain is required: the core stack creates the public Route 53 zone <env>.<domain>, and a placeholder domain scaffolds a zone whose certificate can never validate, so ingress never serves HTTPS.";
17679
17693
  realStateBucketDeps = {
17680
17694
  headBucket(setup) {
17681
17695
  try {
@@ -19182,7 +19196,7 @@ function registerInitCommands(program2) {
19182
19196
  ).option("--tenant <name>", "app tenant this repo belongs to (prompted when omitted on a TTY)").option("--local", "local only \u2014 mesh start / mesh dev, no deployed platform (the default)").option("--platform <env>", "a deployed platform's environment; signs in to `<tenant>.<env>`").option(
19183
19197
  "--new-platform [env]",
19184
19198
  `nothing deployed yet \u2014 scaffold a tenant platform repo for \`<tenant>.<env>\` (default env: ${PLATFORM_SETUP_DEFAULTS.env}) and print its deploy sequence`
19185
- ).option("--region <region>", `--new-platform: AWS region (default: ${PLATFORM_SETUP_DEFAULTS.region})`).option("--domain <domain>", "--new-platform: base public domain you control; the core stack creates the zone {env}.{domain}. No default \u2014 a placeholder scaffolds a zone that can never validate").option("--state-bucket <bucket>", "--new-platform: Pulumi state S3 bucket (default: {tenant}-mesh-platform-pulumi-state)").option("--create-state-bucket", "--new-platform: create the state bucket (versioned) if it does not exist").option("--no-create-state-bucket", "--new-platform: never create the state bucket; print the aws command instead").option("--dir <path>", "--new-platform: where to scaffold the platform repo (default: ./{tenant}-mesh-platform)").option("--device", "device-code sign-in for the registry and platform steps (headless / SSH)").option("--profile <aws-profile>", "AWS profile this machine uses: read the registry without the broker (deployers only), and the profile a --new-platform stack config references").option("--skip-repo", "do not bootstrap, check or record anything in the current repo", false).option("--yes", "accept every default and never prompt", false).option("--json", "one JSON document on stdout ({tenant, mode, steps, next}); human output on stderr", false).action(
19199
+ ).option("--region <region>", `--new-platform: AWS region (default: ${PLATFORM_SETUP_DEFAULTS.region})`).option("--domain <domain>", "--new-platform: base public domain you control; the core stack creates the zone {env}.{domain} and stops at the mesh-gateway Ingress until you delegate its NS records. No default \u2014 a placeholder scaffolds a zone that can never validate").option("--state-bucket <bucket>", "--new-platform: Pulumi state S3 bucket (default: {tenant}-mesh-platform-pulumi-state)").option("--create-state-bucket", "--new-platform: create the state bucket (versioned) if it does not exist").option("--no-create-state-bucket", "--new-platform: never create the state bucket; print the aws command instead").option("--dir <path>", "--new-platform: where to scaffold the platform repo (default: ./{tenant}-mesh-platform)").option("--device", "device-code sign-in for the registry and platform steps (headless / SSH)").option("--profile <aws-profile>", "AWS profile this machine uses: read the registry without the broker (deployers only), and the profile a --new-platform stack config references").option("--skip-repo", "do not bootstrap, check or record anything in the current repo", false).option("--yes", "accept every default and never prompt", false).option("--json", "one JSON document on stdout ({tenant, mode, steps, next}); human output on stderr", false).action(
19186
19200
  async (opts) => {
19187
19201
  const { runInitWizard: runInitWizard2 } = await Promise.resolve().then(() => (init_wizard(), wizard_exports));
19188
19202
  const code = await runInitWizard2(opts);
@@ -19193,7 +19207,7 @@ function registerInitCommands(program2) {
19193
19207
  "Scaffold a tenant PLATFORM repo (core + platform Pulumi layers on @mesh-tech/infra-components) that deploys with `mesh deploy` unmodified \u2014 the proven mesh-sandbox shape, annotated. On a terminal it ASKS for the values that differ per install (env, region, domain, state bucket, AWS profile), each pre-filled with its default; every answer is also a flag."
19194
19208
  ).option("--env <env>", `environment the first stack targets (default: ${PLATFORM_SETUP_DEFAULTS.env})`).option("--region <region>", `AWS region (default: ${PLATFORM_SETUP_DEFAULTS.region})`).option(
19195
19209
  "--domain <domain>",
19196
- "base public domain you control \u2014 the core stack creates the Route 53 zone {env}.{domain} and waits on its NS delegation. Required: it has no default, because a placeholder scaffolds a zone that can never validate"
19210
+ "base public domain you control \u2014 the core stack creates the Route 53 zone {env}.{domain}, whose NS records you then delegate at your registrar; the deploy stops at the mesh-gateway Ingress until that lets ACM issue the certificate. Required: it has no default, because a placeholder scaffolds a zone nobody can delegate to you"
19197
19211
  ).option("--profile <profile>", `AWS profile the stack config references (default: ${PLATFORM_SETUP_DEFAULTS.profile})`).option("--state-bucket <bucket>", "Pulumi state S3 bucket (default: {tenant}-mesh-platform-pulumi-state)").option("--create-state-bucket", "create the state bucket (versioned) if it does not exist \u2014 prompted on a terminal").option("--no-create-state-bucket", "never create the state bucket; print the aws command instead").option("--dir <path>", "target directory (default: ./{tenant}-mesh-platform)").option("--yes", "accept every default and never prompt", false).action(
19198
19212
  async (tenant, opts) => {
19199
19213
  if (!/^[a-z][a-z0-9-]*$/.test(tenant)) {
@@ -20676,8 +20690,7 @@ Usage: mesh secrets set external/<name>`);
20676
20690
  console.error("");
20677
20691
  }
20678
20692
  function isResourceNotFound(err) {
20679
- const e = err;
20680
- return e?.name === "ResourceNotFoundException" || e?.__type === "ResourceNotFoundException" || e?.Code === "ResourceNotFoundException" || e?.code === "ResourceNotFoundException" || typeof e?.message === "string" && e.message.includes("ResourceNotFoundException");
20693
+ return isAwsErrorCode(err, "ResourceNotFoundException");
20681
20694
  }
20682
20695
  function deepMerge(target, source) {
20683
20696
  const result = { ...target };
@@ -20813,6 +20826,7 @@ var init_set = __esm({
20813
20826
  init_context2();
20814
20827
  init_pulumi();
20815
20828
  init_aws_auth();
20829
+ init_aws_errors();
20816
20830
  }
20817
20831
  });
20818
20832
 
@@ -21041,16 +21055,12 @@ function extractNonSecretFields2(fields, values) {
21041
21055
  }
21042
21056
  return result;
21043
21057
  }
21044
- function isResourceNotFound2(err) {
21045
- const e = err;
21046
- return e?.name === "ResourceNotFoundException" || e?.__type === "ResourceNotFoundException" || e?.Code === "ResourceNotFoundException" || e?.code === "ResourceNotFoundException" || typeof e?.message === "string" && e.message.includes("ResourceNotFoundException");
21047
- }
21048
21058
  async function readSecret(client, secretId) {
21049
21059
  try {
21050
21060
  const res = await client.send(new GetSecretValueCommand8({ SecretId: secretId }));
21051
21061
  return res.SecretString ? JSON.parse(res.SecretString) : null;
21052
21062
  } catch (err) {
21053
- if (isResourceNotFound2(err)) return null;
21063
+ if (isAwsErrorCode(err, "ResourceNotFoundException")) return null;
21054
21064
  throw err;
21055
21065
  }
21056
21066
  }
@@ -21059,7 +21069,7 @@ async function writeSecret2(client, secretId, values, description) {
21059
21069
  try {
21060
21070
  await client.send(new PutSecretValueCommand3({ SecretId: secretId, SecretString: secretString }));
21061
21071
  } catch (err) {
21062
- if (isResourceNotFound2(err)) {
21072
+ if (isAwsErrorCode(err, "ResourceNotFoundException")) {
21063
21073
  await client.send(new CreateSecretCommand3({
21064
21074
  Name: secretId,
21065
21075
  Description: description,
@@ -21076,7 +21086,7 @@ async function secretExists(client, secretId) {
21076
21086
  await client.send(new GetSecretValueCommand8({ SecretId: secretId }));
21077
21087
  return true;
21078
21088
  } catch (err) {
21079
- if (isResourceNotFound2(err)) return false;
21089
+ if (isAwsErrorCode(err, "ResourceNotFoundException")) return false;
21080
21090
  throw err;
21081
21091
  }
21082
21092
  }
@@ -21191,6 +21201,7 @@ var init_migrate_config = __esm({
21191
21201
  "use strict";
21192
21202
  init_log();
21193
21203
  init_context2();
21204
+ init_aws_errors();
21194
21205
  }
21195
21206
  });
21196
21207