storebound/cli/apple/bundle.ts

31 lines
2.4 KiB
TypeScript

// Register the bundle id (Certificates, Identifiers & Profiles) through the API. Idempotent.
// storebound apple bundle [--name "My App"] [--dry]
// The App Store Connect app record itself can NOT be created through the API: do that in the web UI afterwards
// (Apps > + > New App, pick this bundle id), see the appstore-first-release skill.
import { consoleLink } from '../lib/console-links';
import type { Ctx } from '../lib/ctx';
import { need } from '../lib/ctx';
import { done, log } from '../lib/log';
import { createOnce } from '../lib/upsert';
import { ascClient } from './asc';
export async function run(ctx: Ctx): Promise<void> {
const { config, root } = ctx.loaded;
const bundleId = need(config.apple?.bundleId, 'apple.bundleId');
const c = await ascClient(root, bundleId, config.apple?.appId);
const found = (await c.asc('GET', `/v1/bundleIds?filter[identifier]=${encodeURIComponent(bundleId)}`)).data
.filter((b: { attributes: { identifier: string } }) => b.attributes.identifier === bundleId);
if (found.length) { log('apple', `bundle id ${bundleId} already registered (${found[0].attributes.platform})`); }
else if (ctx.args.has('dry')) { log('apple', `bundle id ${bundleId} missing (dry run, not registering)`); return; }
else {
// identifiers are unique per team: a 409 (or an unclear answer) is checked by a direct lookup, never re-sent blindly
const r = await createOnce({ what: `bundle id ${bundleId}`, tag: 'apple', unique: true,
find: async () => (await c.asc('GET', `/v1/bundleIds?filter[identifier]=${encodeURIComponent(bundleId)}`)).data?.find((b: { attributes: { identifier: string } }) => b.attributes.identifier === bundleId) ?? null,
create: async () => (await c.asc('POST', '/v1/bundleIds', { data: { type: 'bundleIds', attributes: { identifier: bundleId, name: ctx.args.str('name', config.app.name).replace(/[^A-Za-z0-9 ]/g, ' ').trim(), platform: 'IOS' } } })).data });
log('apple', `bundle id ${bundleId} ${r.created ? 'registered' : 'already registered'}`);
}
const apps = (await c.asc('GET', `/v1/apps?filter[bundleId]=${encodeURIComponent(bundleId)}`)).data;
if (apps.length) log('apple', `app record: ${apps[0].attributes.name} (Apple ID ${apps[0].id}); put it in apple.appId`);
else log('apple', `no app record yet: ${consoleLink('asc.new-app')} (UI only), then re-run \`apple status\``);
done('apple', 'bundle done');
}