@better-update/cli 0.33.2 → 0.34.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/dist/index.mjs CHANGED
@@ -34,7 +34,7 @@ var __require = /* @__PURE__ */ createRequire(import.meta.url);
34
34
 
35
35
  //#endregion
36
36
  //#region package.json
37
- var version = "0.33.2";
37
+ var version = "0.34.0";
38
38
 
39
39
  //#endregion
40
40
  //#region src/lib/interactive-mode.ts
@@ -355,7 +355,15 @@ var OrgVault = class extends Schema.Class("OrgVault")({
355
355
  organizationId: Id,
356
356
  vaultVersion: VaultVersion,
357
357
  createdAt: DateTimeString,
358
- updatedAt: DateTimeString
358
+ updatedAt: DateTimeString,
359
+ /**
360
+ * A recipient was dropped out-of-band (member removed/downgraded); the live key
361
+ * is considered compromised and must be rotated. While true, credential-download
362
+ * paths fail closed (409). `rotate` clears it.
363
+ */
364
+ rotationPending: Schema.Boolean,
365
+ rotationPendingSince: Schema.NullOr(DateTimeString),
366
+ rotationPendingReason: Schema.NullOr(Schema.String)
359
367
  }) {};
360
368
  /**
361
369
  * One wrap of the org vault key to a recipient's public key — an `age` blob the
@@ -1045,7 +1053,7 @@ const projectIdParam$5 = HttpApiSchema.param("projectId", Schema.String);
1045
1053
  var BuildCredentialsGroup = class extends HttpApiGroup.make("buildCredentials").add(HttpApiEndpoint.post("resolve")`/api/projects/${projectIdParam$5}/build-credentials/resolve`.setPayload(ResolveBuildCredentialsBody).addSuccess(ResolveBuildCredentialsResult).annotateContext(OpenApi.annotations({
1046
1054
  title: "Resolve build credentials",
1047
1055
  description: "Return decrypted signing assets for a project build. Regenerates the iOS provisioning profile via Apple ASC when the registered device roster has changed since the profile was last generated."
1048
- }))).addError(NotFound).addError(BadRequest).addError(Forbidden).annotateContext(OpenApi.annotations({
1056
+ }))).addError(NotFound).addError(BadRequest).addError(Forbidden).addError(Conflict).annotateContext(OpenApi.annotations({
1049
1057
  title: "Build Credentials",
1050
1058
  description: "Materialize signing assets needed by a CLI build run"
1051
1059
  })) {};
@@ -22279,12 +22287,14 @@ const exportDecryptedEnvVars = (api, projectId, environment) => Effect.gen(funct
22279
22287
  });
22280
22288
  /**
22281
22289
  * Pull + decrypt environment variables flattened into a key/value map for
22282
- * injection into a build/subprocess.
22290
+ * injection into a build/subprocess. Reports which variables were loaded (names
22291
+ * only — values stay secret) so users can see what the server contributed.
22283
22292
  */
22284
22293
  const pullEnvVars = (api, { projectId, environment }) => Effect.gen(function* () {
22285
22294
  const validated = coerceEnvironment(environment);
22286
22295
  if (!validated) return yield* new EnvExportError({ message: `Invalid environment "${environment}": must be lowercase letters, digits, and hyphens, starting with a letter.` });
22287
22296
  const items = yield* exportDecryptedEnvVars(api, projectId, validated);
22297
+ yield* printHuman(items.length === 0 ? `No environment variables found for the "${validated}" environment.` : `Environment variables loaded from the "${validated}" environment: ${items.map((item) => item.key).join(", ")}`);
22288
22298
  return Object.fromEntries(items.map((item) => [item.key, item.value]));
22289
22299
  });
22290
22300
  /**
@@ -22552,13 +22562,14 @@ const inferPlatforms = (config) => {
22552
22562
  };
22553
22563
  /**
22554
22564
  * Resolve a build platform from an explicit flag, or fall back to the Expo
22555
- * config (`expo.platforms` or the presence of `ios`/`android` sections). Prompts
22556
- * when the config declares both platforms; fails when ambiguous and prompts are
22557
- * disallowed.
22565
+ * config (`expo.platforms` or the presence of `ios`/`android` sections). The
22566
+ * config is loaded lazily so an explicit `--platform` skips evaluating
22567
+ * `app.config.js`/`.ts` entirely. Prompts when the config declares both
22568
+ * platforms; fails when ambiguous and prompts are disallowed.
22558
22569
  */
22559
- const detectPlatform = (explicit, config) => Effect.gen(function* () {
22570
+ const detectPlatform = (explicit, loadConfig) => Effect.gen(function* () {
22560
22571
  if (explicit !== void 0) return explicit;
22561
- const candidates = inferPlatforms(config);
22572
+ const candidates = inferPlatforms(yield* loadConfig);
22562
22573
  if (candidates.length === 0) return yield* new BuildProfileError({ message: "Cannot infer build platform. Add an `ios` or `android` section to your Expo config, or pass --platform." });
22563
22574
  if (candidates.length === 1) {
22564
22575
  const [only] = candidates;
@@ -23680,11 +23691,6 @@ const runBuildWorkflow = (options) => Effect.scoped(Effect.gen(function* () {
23680
23691
  const projectId = yield* readProjectId;
23681
23692
  const profile = yield* readBuildProfile(userCwd, yield* resolveProfileName(userCwd, options.profileName));
23682
23693
  if (profile.developmentClient === true) yield* warnIfDevClientMissing(userCwd);
23683
- const platform = isExpo ? yield* detectPlatform(options.platform, yield* readExpoConfig(userCwd)) : yield* detectPlatformGeneric(options.platform, {
23684
- profile,
23685
- hasAndroidDir: yield* dirExists(userCwd, "android"),
23686
- hasIosDir: yield* dirExists(userCwd, "ios")
23687
- });
23688
23694
  const envVars = {
23689
23695
  ...yield* pullEnvVars(api, {
23690
23696
  projectId,
@@ -23692,6 +23698,11 @@ const runBuildWorkflow = (options) => Effect.scoped(Effect.gen(function* () {
23692
23698
  }),
23693
23699
  ...profile.env
23694
23700
  };
23701
+ const platform = isExpo ? yield* detectPlatform(options.platform, readExpoConfig(userCwd, envVars)) : yield* detectPlatformGeneric(options.platform, {
23702
+ profile,
23703
+ hasAndroidDir: yield* dirExists(userCwd, "android"),
23704
+ hasIosDir: yield* dirExists(userCwd, "ios")
23705
+ });
23695
23706
  const { appMeta, runtimeVersion } = isExpo ? yield* resolveExpoBuildMeta({
23696
23707
  userCwd,
23697
23708
  platform,
@@ -26842,9 +26853,14 @@ const listCommand$6 = defineCommand({
26842
26853
  },
26843
26854
  run: async () => runEffect(Effect.gen(function* () {
26844
26855
  const api = yield* apiClient;
26845
- const [{ recipients, vaultVersion }, { items }] = yield* Effect.all([api.orgVault.listWraps(), api.userEncryptionKeys.list()]);
26856
+ const [{ recipients, vaultVersion }, { items }, vault] = yield* Effect.all([
26857
+ api.orgVault.listWraps(),
26858
+ api.userEncryptionKeys.list(),
26859
+ api.orgVault.get()
26860
+ ]);
26846
26861
  const byId = new Map(items.map((key) => [key.id, key]));
26847
26862
  yield* printHuman(`Vault version ${vaultVersion}`);
26863
+ if (vault.rotationPending) yield* printHuman(`⚠ Rotation pending — a recipient was removed (${vault.rotationPendingReason ?? "vault access revoked"}). Credential downloads are blocked until you run \`credentials access rotate\`.`);
26848
26864
  yield* printHumanList([
26849
26865
  "Key ID",
26850
26866
  "Kind",
@@ -26861,6 +26877,7 @@ const listCommand$6 = defineCommand({
26861
26877
  }), "No recipients hold the vault key yet.");
26862
26878
  return {
26863
26879
  vaultVersion,
26880
+ rotationPending: vault.rotationPending,
26864
26881
  recipients: recipients.map((recipient) => toRecipientView(recipient.userEncryptionKeyId, byId.get(recipient.userEncryptionKeyId)))
26865
26882
  };
26866
26883
  }), { json: "value" })