@better-update/cli 0.47.0 → 0.47.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/dist/index.mjs CHANGED
@@ -35,7 +35,7 @@ var __require = /* #__PURE__ */ (() => createRequire(import.meta.url))();
35
35
 
36
36
  //#endregion
37
37
  //#region package.json
38
- var version = "0.47.0";
38
+ var version = "0.47.2";
39
39
 
40
40
  //#endregion
41
41
  //#region src/lib/interactive-mode.ts
@@ -3466,7 +3466,9 @@ const promptText = (message, options) => Effect.gen(function* () {
3466
3466
  return handleCancel(yield* Effect.promise(async () => text(compact({
3467
3467
  message,
3468
3468
  placeholder: options?.placeholder,
3469
- defaultValue: options?.defaultValue
3469
+ defaultValue: options?.defaultValue,
3470
+ initialValue: options?.initialValue,
3471
+ validate: options?.validate
3470
3472
  }))));
3471
3473
  });
3472
3474
  const promptConfirm = (message, options) => Effect.gen(function* () {
@@ -35031,12 +35033,12 @@ const APP_CREATE_HINTS = {
35031
35033
  };
35032
35034
  /** Best-effort: write the resolved id back to eas.json so the next run reuses it. */
35033
35035
  const persist$1 = (input, ascAppId) => setSubmitProfileAscAppId(input.projectRoot, input.profileName, ascAppId).pipe(Effect.flatMap((path) => printHuman(`Saved ascAppId to ${path} (submit profile "${input.profileName}") for reuse.`)), Effect.catchAll((error) => printHuman(`Note: could not write ascAppId to eas.json (${error.message}). Add it manually to reuse it.`)));
35034
- const createApp = (cookieCtx, name, input) => wrapConnect("apple-create-app", async () => AppleUtils.App.createAsync(cookieCtx, compact({
35036
+ const createApp = (cookieCtx, name, companyName, input) => wrapConnect("apple-create-app", async () => AppleUtils.App.createAsync(cookieCtx, compact({
35035
35037
  name,
35036
35038
  bundleId: input.bundleIdentifier,
35037
35039
  sku: input.sku ?? input.bundleIdentifier,
35038
35040
  primaryLocale: input.primaryLocale ?? DEFAULT_LOCALE,
35039
- companyName: input.companyName,
35041
+ companyName,
35040
35042
  platforms: [AppleUtils.Platform.IOS]
35041
35043
  }))).pipe(Effect.mapError((error) => {
35042
35044
  const hint = Object.entries(APP_CREATE_HINTS).find(([code]) => error.message.includes(code));
@@ -35045,6 +35047,36 @@ const createApp = (cookieCtx, name, input) => wrapConnect("apple-create-app", as
35045
35047
  message: `${error.message} — ${hint[1]}.`
35046
35048
  });
35047
35049
  }));
35050
+ /**
35051
+ * Best-effort App Store name default to pre-fill the prompt with. Prefers the
35052
+ * Expo config's `name` (app.json `expo.name`), then the passed-in fallback (the
35053
+ * better-update project name) so non-Expo projects — which have no `@expo/config`
35054
+ * — still get a sensible default. Returns `undefined` when neither is available.
35055
+ */
35056
+ const resolveDefaultAppName = (input) => readExpoConfig(input.projectRoot).pipe(Effect.map((config) => config.name?.trim() ? config.name.trim() : void 0), Effect.orElseSucceed(() => void 0), Effect.map((expoName) => {
35057
+ const fallback = input.defaultAppName?.trim();
35058
+ return expoName ?? (fallback || void 0);
35059
+ }));
35060
+ /** Reject a blank app name so the prompt re-asks instead of 500'ing `App.createAsync`. */
35061
+ const requireNonEmptyName = (value) => value?.trim() ? void 0 : "An app name is required.";
35062
+ /**
35063
+ * The App Store name to create the app under. A non-empty configured `appName`
35064
+ * wins; else prompt — pre-filled with the resolved default (Expo `expo.name` or
35065
+ * the better-update project name) and *required*, so an empty Enter re-asks
35066
+ * rather than reaching `App.createAsync` with a blank name (which Apple 500s).
35067
+ */
35068
+ const resolveAppName = (input) => Effect.gen(function* () {
35069
+ const configured = input.appName?.trim();
35070
+ if (configured) return configured;
35071
+ const defaultName = yield* resolveDefaultAppName(input);
35072
+ return (yield* promptText("App name (as shown on the App Store)", defaultName === void 0 ? {
35073
+ placeholder: input.bundleIdentifier,
35074
+ validate: requireNonEmptyName
35075
+ } : {
35076
+ initialValue: defaultName,
35077
+ validate: requireNonEmptyName
35078
+ })).trim();
35079
+ });
35048
35080
  const ensureAscAppForSubmit = (input) => Effect.gen(function* () {
35049
35081
  const ctx = buildTokenRequestContext(input.credentials);
35050
35082
  const existing = yield* wrapConnect("apple-find-app", async () => AppleUtils.App.findAsync(ctx, { bundleId: input.bundleIdentifier }));
@@ -35057,12 +35089,17 @@ const ensureAscAppForSubmit = (input) => Effect.gen(function* () {
35057
35089
  return null;
35058
35090
  }
35059
35091
  if (!(yield* promptConfirm(`No App Store Connect app exists for bundle id ${input.bundleIdentifier}. Create it now from your Apple ID?`, { initialValue: true }))) return null;
35060
- const name = input.appName ?? (yield* promptText("App name (as shown on the App Store)", { placeholder: input.bundleIdentifier }));
35092
+ const name = yield* resolveAppName(input);
35093
+ if (name.length === 0) {
35094
+ yield* printHuman(`No app name was provided, so the App Store Connect app can't be created. Re-run and enter a name, or set submit.${input.profileName}.ios.appName in eas.json.`);
35095
+ return null;
35096
+ }
35061
35097
  const auth = yield* AppleAuth;
35062
35098
  const session = yield* auth.ensureLoggedIn();
35063
35099
  const cookieCtx = auth.buildRequestContext(session);
35100
+ const companyName = input.companyName ?? toOptional(session.teamName);
35064
35101
  yield* printHuman("Creating the App Store Connect app via your Apple ID...");
35065
- const app = yield* createApp(cookieCtx, name, input);
35102
+ const app = yield* createApp(cookieCtx, name, companyName, input);
35066
35103
  yield* printHuman(`Created App Store Connect app "${name}" (${app.id}).`);
35067
35104
  yield* persist$1(input, app.id);
35068
35105
  return app.id;
@@ -35247,16 +35284,20 @@ const submitIosBranch = (params) => Effect.gen(function* () {
35247
35284
  return false;
35248
35285
  }
35249
35286
  let resolvedAscAppId = iosProfile?.ascAppId;
35250
- if (wantsConfig && resolvedAscAppId === void 0 && ascCredentials !== null) resolvedAscAppId = toOptional(yield* ensureAscAppForSubmit({
35251
- credentials: ascCredentials,
35252
- projectRoot: params.projectRoot,
35253
- profileName: params.profile,
35254
- bundleIdentifier: iosConfig.bundleIdentifier,
35255
- appName: iosProfile?.appName,
35256
- sku: iosProfile?.sku,
35257
- companyName: iosProfile?.companyName,
35258
- primaryLocale: iosProfile?.language
35259
- }));
35287
+ if (wantsConfig && resolvedAscAppId === void 0 && ascCredentials !== null) {
35288
+ const defaultAppName = yield* api.projects.get({ path: { id: params.projectId } }).pipe(Effect.map((project) => project.name), Effect.orElseSucceed(() => void 0));
35289
+ resolvedAscAppId = toOptional(yield* ensureAscAppForSubmit({
35290
+ credentials: ascCredentials,
35291
+ projectRoot: params.projectRoot,
35292
+ profileName: params.profile,
35293
+ bundleIdentifier: iosConfig.bundleIdentifier,
35294
+ appName: iosProfile?.appName,
35295
+ defaultAppName,
35296
+ sku: iosProfile?.sku,
35297
+ companyName: iosProfile?.companyName,
35298
+ primaryLocale: iosProfile?.language
35299
+ }));
35300
+ }
35260
35301
  yield* printHuman(auth.kind === "app-specific-password" ? "Running xcrun altool upload (Apple ID app-specific password)..." : "Running xcrun altool upload (ASC API key)...");
35261
35302
  yield* runIosSubmit({
35262
35303
  api,
@@ -35296,6 +35337,7 @@ const runFlow = (api, projectId, args) => Effect.gen(function* () {
35296
35337
  if (args.platform === "ios" && iosConfig !== void 0) {
35297
35338
  if (!(yield* submitIosBranch({
35298
35339
  api,
35340
+ projectId,
35299
35341
  submissionId: submission.id,
35300
35342
  projectRoot: args.projectRoot,
35301
35343
  profile: args.profile,