@better-update/cli 0.33.1 → 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 +39 -17
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
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.
|
|
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
|
})) {};
|
|
@@ -19985,7 +19993,6 @@ const DISTRIBUTION_TO_CERTIFICATE_TYPE = {
|
|
|
19985
19993
|
DEVELOPMENT: AppleUtils.CertificateType.IOS_DEVELOPMENT
|
|
19986
19994
|
};
|
|
19987
19995
|
var AppleIdGenerateFailedError = class extends Data.TaggedError("AppleIdGenerateFailedError") {};
|
|
19988
|
-
var ApnsKeyLimitError = class extends Data.TaggedError("ApnsKeyLimitError") {};
|
|
19989
19996
|
const CERT_LIMIT_PATTERN = /already have a current.*certificate|pending certificate request/iu;
|
|
19990
19997
|
const messageOf = (cause) => cause instanceof Error ? cause.message : String(cause);
|
|
19991
19998
|
const wrap = (step, run) => Effect.tryPromise({
|
|
@@ -20130,8 +20137,12 @@ const generateAndUploadProvisioningProfileViaAppleId = (api, input) => Effect.ge
|
|
|
20130
20137
|
developerPortalIdentifier: created.developerPortalIdentifier
|
|
20131
20138
|
};
|
|
20132
20139
|
});
|
|
20140
|
+
|
|
20141
|
+
//#endregion
|
|
20142
|
+
//#region src/lib/credentials-generator-apns.ts
|
|
20133
20143
|
const APNS_SERVICE_ID = "U27F4V844T";
|
|
20134
20144
|
const APNS_KEY_LIMIT_PATTERN = /maximum allowed number of .*keys/iu;
|
|
20145
|
+
var ApnsKeyLimitError = class extends Data.TaggedError("ApnsKeyLimitError") {};
|
|
20135
20146
|
const wrapKeyCreate = (run) => Effect.tryPromise({
|
|
20136
20147
|
try: run,
|
|
20137
20148
|
catch: (cause) => {
|
|
@@ -20169,7 +20180,8 @@ const generateAndUploadApnsKeyViaAppleId = (api, input) => Effect.gen(function*
|
|
|
20169
20180
|
});
|
|
20170
20181
|
return yield* api.applePushKeys.upload({ payload: {
|
|
20171
20182
|
...toUploadEnvelope(envelope),
|
|
20172
|
-
...metadata
|
|
20183
|
+
...metadata,
|
|
20184
|
+
...compact({ appleTeamName: toOptional(input.appleTeamName) })
|
|
20173
20185
|
} });
|
|
20174
20186
|
}).pipe(Effect.catchAll((cause) => Effect.gen(function* () {
|
|
20175
20187
|
const rescuePath = yield* writeRescueP8(key.id, p8Pem).pipe(Effect.catchAll(() => Effect.succeed(null)));
|
|
@@ -20308,6 +20320,7 @@ const createApnsKeyViaAppleId = (api, name) => Effect.gen(function* () {
|
|
|
20308
20320
|
const generate = generateAndUploadApnsKeyViaAppleId(api, {
|
|
20309
20321
|
context: ctx,
|
|
20310
20322
|
appleTeamIdentifier: session.teamId,
|
|
20323
|
+
appleTeamName: session.teamName,
|
|
20311
20324
|
name
|
|
20312
20325
|
});
|
|
20313
20326
|
return yield* generate.pipe(Effect.catchTag("ApnsKeyLimitError", () => apnsKeyLimitRecover(ctx).pipe(Effect.flatMap(() => generate))));
|
|
@@ -22274,12 +22287,14 @@ const exportDecryptedEnvVars = (api, projectId, environment) => Effect.gen(funct
|
|
|
22274
22287
|
});
|
|
22275
22288
|
/**
|
|
22276
22289
|
* Pull + decrypt environment variables flattened into a key/value map for
|
|
22277
|
-
* 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.
|
|
22278
22292
|
*/
|
|
22279
22293
|
const pullEnvVars = (api, { projectId, environment }) => Effect.gen(function* () {
|
|
22280
22294
|
const validated = coerceEnvironment(environment);
|
|
22281
22295
|
if (!validated) return yield* new EnvExportError({ message: `Invalid environment "${environment}": must be lowercase letters, digits, and hyphens, starting with a letter.` });
|
|
22282
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(", ")}`);
|
|
22283
22298
|
return Object.fromEntries(items.map((item) => [item.key, item.value]));
|
|
22284
22299
|
});
|
|
22285
22300
|
/**
|
|
@@ -22547,13 +22562,14 @@ const inferPlatforms = (config) => {
|
|
|
22547
22562
|
};
|
|
22548
22563
|
/**
|
|
22549
22564
|
* Resolve a build platform from an explicit flag, or fall back to the Expo
|
|
22550
|
-
* config (`expo.platforms` or the presence of `ios`/`android` sections).
|
|
22551
|
-
*
|
|
22552
|
-
*
|
|
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.
|
|
22553
22569
|
*/
|
|
22554
|
-
const detectPlatform = (explicit,
|
|
22570
|
+
const detectPlatform = (explicit, loadConfig) => Effect.gen(function* () {
|
|
22555
22571
|
if (explicit !== void 0) return explicit;
|
|
22556
|
-
const candidates = inferPlatforms(
|
|
22572
|
+
const candidates = inferPlatforms(yield* loadConfig);
|
|
22557
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." });
|
|
22558
22574
|
if (candidates.length === 1) {
|
|
22559
22575
|
const [only] = candidates;
|
|
@@ -23675,11 +23691,6 @@ const runBuildWorkflow = (options) => Effect.scoped(Effect.gen(function* () {
|
|
|
23675
23691
|
const projectId = yield* readProjectId;
|
|
23676
23692
|
const profile = yield* readBuildProfile(userCwd, yield* resolveProfileName(userCwd, options.profileName));
|
|
23677
23693
|
if (profile.developmentClient === true) yield* warnIfDevClientMissing(userCwd);
|
|
23678
|
-
const platform = isExpo ? yield* detectPlatform(options.platform, yield* readExpoConfig(userCwd)) : yield* detectPlatformGeneric(options.platform, {
|
|
23679
|
-
profile,
|
|
23680
|
-
hasAndroidDir: yield* dirExists(userCwd, "android"),
|
|
23681
|
-
hasIosDir: yield* dirExists(userCwd, "ios")
|
|
23682
|
-
});
|
|
23683
23694
|
const envVars = {
|
|
23684
23695
|
...yield* pullEnvVars(api, {
|
|
23685
23696
|
projectId,
|
|
@@ -23687,6 +23698,11 @@ const runBuildWorkflow = (options) => Effect.scoped(Effect.gen(function* () {
|
|
|
23687
23698
|
}),
|
|
23688
23699
|
...profile.env
|
|
23689
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
|
+
});
|
|
23690
23706
|
const { appMeta, runtimeVersion } = isExpo ? yield* resolveExpoBuildMeta({
|
|
23691
23707
|
userCwd,
|
|
23692
23708
|
platform,
|
|
@@ -26837,9 +26853,14 @@ const listCommand$6 = defineCommand({
|
|
|
26837
26853
|
},
|
|
26838
26854
|
run: async () => runEffect(Effect.gen(function* () {
|
|
26839
26855
|
const api = yield* apiClient;
|
|
26840
|
-
const [{ recipients, vaultVersion }, { items }] = yield* Effect.all([
|
|
26856
|
+
const [{ recipients, vaultVersion }, { items }, vault] = yield* Effect.all([
|
|
26857
|
+
api.orgVault.listWraps(),
|
|
26858
|
+
api.userEncryptionKeys.list(),
|
|
26859
|
+
api.orgVault.get()
|
|
26860
|
+
]);
|
|
26841
26861
|
const byId = new Map(items.map((key) => [key.id, key]));
|
|
26842
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\`.`);
|
|
26843
26864
|
yield* printHumanList([
|
|
26844
26865
|
"Key ID",
|
|
26845
26866
|
"Kind",
|
|
@@ -26856,6 +26877,7 @@ const listCommand$6 = defineCommand({
|
|
|
26856
26877
|
}), "No recipients hold the vault key yet.");
|
|
26857
26878
|
return {
|
|
26858
26879
|
vaultVersion,
|
|
26880
|
+
rotationPending: vault.rotationPending,
|
|
26859
26881
|
recipients: recipients.map((recipient) => toRecipientView(recipient.userEncryptionKeyId, byId.get(recipient.userEncryptionKeyId)))
|
|
26860
26882
|
};
|
|
26861
26883
|
}), { json: "value" })
|