@sitepong/fastnode 0.2.0 → 0.2.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.
Files changed (63) hide show
  1. package/dist/actions/index.cjs +27 -6
  2. package/dist/actions/index.cjs.map +1 -1
  3. package/dist/actions/index.mjs +27 -6
  4. package/dist/actions/index.mjs.map +1 -1
  5. package/dist/cert/index.d.cts +3 -3
  6. package/dist/cert/index.d.ts +3 -3
  7. package/dist/{cert-DtYDJBjG.d.ts → cert-e5GAgAPb.d.ts} +1 -1
  8. package/dist/{cert-6m1R8UeW.d.cts → cert-uLLdb5a7.d.cts} +1 -1
  9. package/dist/cli/index.cjs +27 -6
  10. package/dist/cli/index.cjs.map +1 -1
  11. package/dist/cli/index.d.cts +1 -1
  12. package/dist/cli/index.d.ts +1 -1
  13. package/dist/cli/index.mjs +27 -6
  14. package/dist/cli/index.mjs.map +1 -1
  15. package/dist/client/index.cjs +27 -6
  16. package/dist/client/index.cjs.map +1 -1
  17. package/dist/client/index.d.cts +1 -1
  18. package/dist/client/index.d.ts +1 -1
  19. package/dist/client/index.mjs +27 -6
  20. package/dist/client/index.mjs.map +1 -1
  21. package/dist/deliver/index.d.cts +2 -2
  22. package/dist/deliver/index.d.ts +2 -2
  23. package/dist/{index-Ce-WMV7c.d.cts → index-BN0iWhuw.d.cts} +1 -1
  24. package/dist/{index-CQKpbHZt.d.ts → index-BNP7Bpu5.d.ts} +1 -1
  25. package/dist/{index-CsFIp7OO.d.ts → index-BbY_H_f6.d.ts} +1 -1
  26. package/dist/{index-AD8QXY1T.d.cts → index-BgHagzj1.d.cts} +1 -1
  27. package/dist/{index-KCB2q1-8.d.cts → index-BjkOUQcQ.d.cts} +1 -1
  28. package/dist/{index-D2z7RiAM.d.ts → index-BwwpAlk2.d.ts} +5 -0
  29. package/dist/{index-Kq3rbG0u.d.ts → index-C2YLoFVl.d.ts} +1 -1
  30. package/dist/{index-CojSGJ7m.d.ts → index-CEldrbyz.d.ts} +1 -1
  31. package/dist/{index-CMH_GpN9.d.cts → index-CdfgEZwh.d.cts} +5 -0
  32. package/dist/{index-BW8wQUGC.d.cts → index-Clyf4-lu.d.cts} +1 -1
  33. package/dist/{index-CCs5irG7.d.cts → index-CtydPNxA.d.cts} +1 -1
  34. package/dist/{index-CQd4bo3G.d.cts → index-DHxi-QPC.d.cts} +3 -3
  35. package/dist/{index-DZaPkUnC.d.ts → index-Di4Ic0EE.d.ts} +3 -3
  36. package/dist/{index-BWK-T2-S.d.cts → index-DrCOh0Vh.d.cts} +1 -1
  37. package/dist/{index-BpiEBPVd.d.ts → index-EKU_G1G5.d.ts} +1 -1
  38. package/dist/{index-CdYdwxpQ.d.cts → index-XsMsVc3O.d.cts} +1 -1
  39. package/dist/{index-CLsvyTkh.d.ts → index-jeI44Q5G.d.ts} +1 -1
  40. package/dist/{index-D82CmjMP.d.ts → index-mddpvrRX.d.ts} +1 -1
  41. package/dist/index.cjs +148 -9
  42. package/dist/index.cjs.map +1 -1
  43. package/dist/index.d.cts +40 -13
  44. package/dist/index.d.ts +40 -13
  45. package/dist/index.mjs +148 -9
  46. package/dist/index.mjs.map +1 -1
  47. package/dist/lane/index.cjs +27 -6
  48. package/dist/lane/index.cjs.map +1 -1
  49. package/dist/lane/index.mjs +27 -6
  50. package/dist/lane/index.mjs.map +1 -1
  51. package/dist/match/index.d.cts +4 -4
  52. package/dist/match/index.d.ts +4 -4
  53. package/dist/pem/index.d.cts +2 -2
  54. package/dist/pem/index.d.ts +2 -2
  55. package/dist/pilot/index.d.cts +2 -2
  56. package/dist/pilot/index.d.ts +2 -2
  57. package/dist/precheck/index.d.cts +2 -2
  58. package/dist/precheck/index.d.ts +2 -2
  59. package/dist/produce/index.d.cts +2 -2
  60. package/dist/produce/index.d.ts +2 -2
  61. package/dist/sigh/index.d.cts +2 -2
  62. package/dist/sigh/index.d.ts +2 -2
  63. package/package.json +1 -1
@@ -1,3 +1,3 @@
1
- import '../index-CMH_GpN9.cjs';
1
+ import '../index-CdfgEZwh.cjs';
2
2
  import '../enums-B609j2rb.cjs';
3
- export { D as DeliverOptions, a as DeliverResult, L as LocalizedMetadata, M as MetadataSet, l as loadMetadata, s as submitForReview, b as uploadMetadata, c as uploadScreenshots, u as uploadToAppStore } from '../index-CdYdwxpQ.cjs';
3
+ export { D as DeliverOptions, a as DeliverResult, L as LocalizedMetadata, M as MetadataSet, l as loadMetadata, s as submitForReview, b as uploadMetadata, c as uploadScreenshots, u as uploadToAppStore } from '../index-XsMsVc3O.cjs';
@@ -1,3 +1,3 @@
1
- import '../index-D2z7RiAM.js';
1
+ import '../index-BwwpAlk2.js';
2
2
  import '../enums-B609j2rb.js';
3
- export { D as DeliverOptions, a as DeliverResult, L as LocalizedMetadata, M as MetadataSet, l as loadMetadata, s as submitForReview, b as uploadMetadata, c as uploadScreenshots, u as uploadToAppStore } from '../index-CsFIp7OO.js';
3
+ export { D as DeliverOptions, a as DeliverResult, L as LocalizedMetadata, M as MetadataSet, l as loadMetadata, s as submitForReview, b as uploadMetadata, c as uploadScreenshots, u as uploadToAppStore } from '../index-BbY_H_f6.js';
@@ -1,4 +1,4 @@
1
- import { a as AppStoreConnectClient, P as Profile } from './index-CMH_GpN9.cjs';
1
+ import { a as AppStoreConnectClient, P as Profile } from './index-CdfgEZwh.cjs';
2
2
  import { P as ProfileType } from './enums-B609j2rb.cjs';
3
3
 
4
4
  interface SighOptions {
@@ -1,4 +1,4 @@
1
- import { C as CertOptions, a as CertResult, c as createCertificate, d as downloadCertificate, f as findValidCertificates, r as revokeCertificate, b as revokeExpiredCertificates } from './cert-DtYDJBjG.js';
1
+ import { C as CertOptions, a as CertResult, c as createCertificate, d as downloadCertificate, f as findValidCertificates, r as revokeCertificate, b as revokeExpiredCertificates } from './cert-e5GAgAPb.js';
2
2
 
3
3
  /**
4
4
  * Generate EC P-256 CSR — used by App Store Connect API (JWT auth).
@@ -1,4 +1,4 @@
1
- import { a as AppStoreConnectClient } from './index-D2z7RiAM.js';
1
+ import { a as AppStoreConnectClient } from './index-BwwpAlk2.js';
2
2
  import { b as Platform, R as ReleaseType } from './enums-B609j2rb.js';
3
3
 
4
4
  interface LocalizedMetadata {
@@ -1,4 +1,4 @@
1
- import { a as AppStoreConnectClient, k as Build } from './index-CMH_GpN9.cjs';
1
+ import { a as AppStoreConnectClient, k as Build } from './index-CdfgEZwh.cjs';
2
2
 
3
3
  /**
4
4
  * Shared types for the pilot module's upload backends.
@@ -1,4 +1,4 @@
1
- import { a as AppStoreConnectClient, q as CapabilitySettingInput, B as BundleId, p as BundleIdCapability, j as App } from './index-CMH_GpN9.cjs';
1
+ import { a as AppStoreConnectClient, q as CapabilitySettingInput, B as BundleId, p as BundleIdCapability, j as App } from './index-CdfgEZwh.cjs';
2
2
  import { B as BundleIdPlatform, d as CapabilityType } from './enums-B609j2rb.cjs';
3
3
 
4
4
  interface ProduceOptions {
@@ -1571,6 +1571,11 @@ declare class PortalClient {
1571
1571
  * The exact body comes from @expo/apple-utils v2.1.21 — both fields
1572
1572
  * are produced by separate functions (`d` for the map, `h` for the
1573
1573
  * array) and merged into the create payload.
1574
+ *
1575
+ * Apple also rejects duplicate key names ("Another key with same
1576
+ * name exists") — we dedupe by listing existing keys first and
1577
+ * appending " (N)" until we find a free slot, mirroring the
1578
+ * provisioning profile dedup.
1574
1579
  */
1575
1580
  createApnsAuthKey(rawName: string): Promise<{
1576
1581
  keyId: string;
@@ -1,4 +1,4 @@
1
- import { a as AppStoreConnectClient } from './index-D2z7RiAM.js';
1
+ import { a as AppStoreConnectClient } from './index-BwwpAlk2.js';
2
2
  import { C as CertificateType } from './enums-B609j2rb.js';
3
3
 
4
4
  type PushCertKind = "development" | "production" | "website" | "voip" | "passbook";
@@ -1,4 +1,4 @@
1
- import { a as AppStoreConnectClient, P as Profile } from './index-D2z7RiAM.js';
1
+ import { a as AppStoreConnectClient, P as Profile } from './index-BwwpAlk2.js';
2
2
  import { P as ProfileType } from './enums-B609j2rb.js';
3
3
 
4
4
  interface SighOptions {
@@ -1571,6 +1571,11 @@ declare class PortalClient {
1571
1571
  * The exact body comes from @expo/apple-utils v2.1.21 — both fields
1572
1572
  * are produced by separate functions (`d` for the map, `h` for the
1573
1573
  * array) and merged into the create payload.
1574
+ *
1575
+ * Apple also rejects duplicate key names ("Another key with same
1576
+ * name exists") — we dedupe by listing existing keys first and
1577
+ * appending " (N)" until we find a free slot, mirroring the
1578
+ * provisioning profile dedup.
1574
1579
  */
1575
1580
  createApnsAuthKey(rawName: string): Promise<{
1576
1581
  keyId: string;
@@ -1,4 +1,4 @@
1
- import { a as AppStoreConnectClient } from './index-CMH_GpN9.cjs';
1
+ import { a as AppStoreConnectClient } from './index-CdfgEZwh.cjs';
2
2
 
3
3
  interface RuleResult {
4
4
  passed: boolean;
@@ -1,4 +1,4 @@
1
- import { C as CertOptions, a as CertResult, c as createCertificate, d as downloadCertificate, f as findValidCertificates, r as revokeCertificate, b as revokeExpiredCertificates } from './cert-6m1R8UeW.cjs';
1
+ import { C as CertOptions, a as CertResult, c as createCertificate, d as downloadCertificate, f as findValidCertificates, r as revokeCertificate, b as revokeExpiredCertificates } from './cert-uLLdb5a7.cjs';
2
2
 
3
3
  /**
4
4
  * Generate EC P-256 CSR — used by App Store Connect API (JWT auth).
@@ -1,6 +1,6 @@
1
- import { a as AppStoreConnectClient } from './index-CMH_GpN9.cjs';
2
- import { a as CertResult } from './cert-6m1R8UeW.cjs';
3
- import { S as SighResult } from './index-Ce-WMV7c.cjs';
1
+ import { a as AppStoreConnectClient } from './index-CdfgEZwh.cjs';
2
+ import { a as CertResult } from './cert-uLLdb5a7.cjs';
3
+ import { S as SighResult } from './index-BN0iWhuw.cjs';
4
4
 
5
5
  type StorageMode = "git" | "s3" | "local";
6
6
 
@@ -1,6 +1,6 @@
1
- import { a as AppStoreConnectClient } from './index-D2z7RiAM.js';
2
- import { a as CertResult } from './cert-DtYDJBjG.js';
3
- import { S as SighResult } from './index-CojSGJ7m.js';
1
+ import { a as AppStoreConnectClient } from './index-BwwpAlk2.js';
2
+ import { a as CertResult } from './cert-e5GAgAPb.js';
3
+ import { S as SighResult } from './index-CEldrbyz.js';
4
4
 
5
5
  type StorageMode = "git" | "s3" | "local";
6
6
 
@@ -1,4 +1,4 @@
1
- import { a as AppStoreConnectClient } from './index-CMH_GpN9.cjs';
1
+ import { a as AppStoreConnectClient } from './index-CdfgEZwh.cjs';
2
2
  import { C as CertificateType } from './enums-B609j2rb.cjs';
3
3
 
4
4
  type PushCertKind = "development" | "production" | "website" | "voip" | "passbook";
@@ -1,4 +1,4 @@
1
- import { a as AppStoreConnectClient, q as CapabilitySettingInput, B as BundleId, p as BundleIdCapability, j as App } from './index-D2z7RiAM.js';
1
+ import { a as AppStoreConnectClient, q as CapabilitySettingInput, B as BundleId, p as BundleIdCapability, j as App } from './index-BwwpAlk2.js';
2
2
  import { B as BundleIdPlatform, d as CapabilityType } from './enums-B609j2rb.js';
3
3
 
4
4
  interface ProduceOptions {
@@ -1,4 +1,4 @@
1
- import { a as AppStoreConnectClient } from './index-CMH_GpN9.cjs';
1
+ import { a as AppStoreConnectClient } from './index-CdfgEZwh.cjs';
2
2
  import { b as Platform, R as ReleaseType } from './enums-B609j2rb.cjs';
3
3
 
4
4
  interface LocalizedMetadata {
@@ -1,4 +1,4 @@
1
- import { a as AppStoreConnectClient } from './index-D2z7RiAM.js';
1
+ import { a as AppStoreConnectClient } from './index-BwwpAlk2.js';
2
2
 
3
3
  interface RuleResult {
4
4
  passed: boolean;
@@ -1,4 +1,4 @@
1
- import { a as AppStoreConnectClient, k as Build } from './index-D2z7RiAM.js';
1
+ import { a as AppStoreConnectClient, k as Build } from './index-BwwpAlk2.js';
2
2
 
3
3
  /**
4
4
  * Shared types for the pilot module's upload backends.
package/dist/index.cjs CHANGED
@@ -2502,6 +2502,12 @@ var init_xcode_metrics = __esm({
2502
2502
  });
2503
2503
 
2504
2504
  // src/client/portal.ts
2505
+ function pickUniqueKeyName(base, taken) {
2506
+ if (!taken.has(base)) return base;
2507
+ let n = 1;
2508
+ while (taken.has(`${base} - ${n}`)) n++;
2509
+ return `${base} - ${n}`;
2510
+ }
2505
2511
  var PORTAL_BASE, PortalClient;
2506
2512
  var init_portal = __esm({
2507
2513
  "src/client/portal.ts"() {
@@ -2620,12 +2626,17 @@ var init_portal = __esm({
2620
2626
  * + period and collapse whitespace.
2621
2627
  */
2622
2628
  async createApiKey(rawName, serviceConfigurations = {}) {
2623
- const name = rawName.replace(/[^A-Za-z0-9 _\-.]/g, " ").replace(/\s+/g, " ").trim().slice(0, 50);
2624
- if (!name) throw new Error("createApiKey: name is empty after sanitization");
2629
+ const baseName = rawName.replace(/[^A-Za-z0-9 _\-.]/g, " ").replace(/\s+/g, " ").trim().slice(0, 45);
2630
+ if (!baseName) throw new Error("createApiKey: name is empty after sanitization");
2631
+ let existingNames = /* @__PURE__ */ new Set();
2625
2632
  try {
2626
- await this.listApiKeys();
2633
+ const list = await this.listApiKeys();
2634
+ existingNames = new Set(
2635
+ (list.keys ?? []).map((k) => String(k.keyName ?? "").trim())
2636
+ );
2627
2637
  } catch {
2628
2638
  }
2639
+ const name = pickUniqueKeyName(baseName, existingNames);
2629
2640
  const body = {
2630
2641
  teamId: this.teamId,
2631
2642
  name,
@@ -2680,14 +2691,24 @@ var init_portal = __esm({
2680
2691
  * The exact body comes from @expo/apple-utils v2.1.21 — both fields
2681
2692
  * are produced by separate functions (`d` for the map, `h` for the
2682
2693
  * array) and merged into the create payload.
2694
+ *
2695
+ * Apple also rejects duplicate key names ("Another key with same
2696
+ * name exists") — we dedupe by listing existing keys first and
2697
+ * appending " (N)" until we find a free slot, mirroring the
2698
+ * provisioning profile dedup.
2683
2699
  */
2684
2700
  async createApnsAuthKey(rawName) {
2685
- const name = rawName.replace(/[^A-Za-z0-9 _\-.]/g, " ").replace(/\s+/g, " ").trim().slice(0, 50);
2686
- if (!name) throw new Error("createApnsAuthKey: name is empty after sanitization");
2701
+ const baseName = rawName.replace(/[^A-Za-z0-9 _\-.]/g, " ").replace(/\s+/g, " ").trim().slice(0, 45);
2702
+ if (!baseName) throw new Error("createApnsAuthKey: name is empty after sanitization");
2703
+ let existingNames = /* @__PURE__ */ new Set();
2687
2704
  try {
2688
- await this.listApiKeys();
2705
+ const list = await this.listApiKeys();
2706
+ existingNames = new Set(
2707
+ (list.keys ?? []).map((k) => String(k.keyName ?? "").trim())
2708
+ );
2689
2709
  } catch {
2690
2710
  }
2711
+ const name = pickUniqueKeyName(baseName, existingNames);
2691
2712
  const body = {
2692
2713
  teamId: this.teamId,
2693
2714
  name,
@@ -9003,6 +9024,8 @@ init_iris();
9003
9024
  init_client();
9004
9025
  init_csr();
9005
9026
  var DIST_CERT_TYPE = PortalClient.CERT_TYPES.IOS_DISTRIBUTION;
9027
+ var PUSH_PROD_TYPE = PortalClient.CERT_TYPES.IOS_PRODUCTION_PUSH;
9028
+ var PUSH_DEV_TYPE = PortalClient.CERT_TYPES.IOS_DEVELOPMENT_PUSH;
9006
9029
  function randomPassword(length = 32) {
9007
9030
  const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
9008
9031
  const bytes = crypto.randomBytes(length);
@@ -9049,11 +9072,12 @@ async function oneClickListTeams(session) {
9049
9072
  async function oneClickInventory(session, teamId) {
9050
9073
  const portal = new PortalClient(session, teamId);
9051
9074
  await portal.init();
9052
- const [appIds, allCerts, profiles, pushCerts] = await Promise.all([
9075
+ const [appIds, allCerts, profiles, pushCerts, apiKeys] = await Promise.all([
9053
9076
  portal.listAppIds(),
9054
9077
  portal.listCertificates([DIST_CERT_TYPE]),
9055
9078
  portal.listProfiles(),
9056
- portal.listPushCertificates()
9079
+ portal.listPushCertificates(),
9080
+ portal.listApiKeys().catch(() => ({ keys: [] }))
9057
9081
  ]);
9058
9082
  const distributionCerts = (allCerts ?? []).map((c) => ({
9059
9083
  certificateId: c.certificateId,
@@ -9062,6 +9086,15 @@ async function oneClickInventory(session, teamId) {
9062
9086
  expirationDate: c.expirationDateString,
9063
9087
  ownerName: c.ownerName
9064
9088
  }));
9089
+ const apnsAuthKeys = (apiKeys.keys ?? []).filter(
9090
+ (k) => (k.services ?? []).some(
9091
+ (s) => s.id === PortalClient.APNS_SERVICE_ID || /apns/i.test(s.name ?? "")
9092
+ )
9093
+ ).map((k) => ({
9094
+ keyId: k.keyId,
9095
+ keyName: k.keyName,
9096
+ dateCreated: k.dateCreated
9097
+ }));
9065
9098
  return {
9066
9099
  team: { id: teamId },
9067
9100
  bundleIds: (appIds ?? []).map((a) => ({
@@ -9071,6 +9104,8 @@ async function oneClickInventory(session, teamId) {
9071
9104
  })),
9072
9105
  distributionCerts,
9073
9106
  distCertCapacity: { used: distributionCerts.length, max: 3 },
9107
+ apnsAuthKeys,
9108
+ apnsKeyCapacity: { used: apnsAuthKeys.length, max: 2 },
9074
9109
  pushCerts: (pushCerts ?? []).map((c) => ({
9075
9110
  certificateId: c.certificateId,
9076
9111
  name: c.name ?? "Push",
@@ -9108,15 +9143,52 @@ async function createDistCert(portal) {
9108
9143
  }
9109
9144
  return { certificateId: cert.certificateId, privateKeyPem: privateKey, certContent };
9110
9145
  }
9146
+ async function createPushCert(portal, appIdId, type) {
9147
+ const { csr, privateKey } = generateRSACSR();
9148
+ const cert = await portal.createCertificate({ type, csrContent: csr, appIdId });
9149
+ let certContent;
9150
+ if (cert.certificateContent) {
9151
+ certContent = Buffer.from(cert.certificateContent, "base64");
9152
+ } else {
9153
+ certContent = await portal.downloadCertificate(cert.certificateId, type);
9154
+ }
9155
+ return { certificateId: cert.certificateId, privateKeyPem: privateKey, certContent };
9156
+ }
9157
+ function findExistingPushCertForBundle(pushCerts, appIdId, bundleIdentifier, kind) {
9158
+ for (const c of pushCerts) {
9159
+ const appMatches = c.appId?.appIdId === appIdId || c.appId?.identifier === bundleIdentifier;
9160
+ if (!appMatches) continue;
9161
+ const ts = (c.typeString ?? "").toLowerCase();
9162
+ const name = (c.name ?? "").toLowerCase();
9163
+ const looksLikePush = ts.includes("push") || ts.includes("apns") || name.includes("apple push services");
9164
+ if (!looksLikePush) continue;
9165
+ const isProduction = ts.includes("production");
9166
+ const isSandbox = ts.includes("development") || ts.includes("sandbox");
9167
+ const isUnified = !isProduction && !isSandbox;
9168
+ if (!isUnified) {
9169
+ if (kind === "production" && !isProduction) continue;
9170
+ if (kind === "sandbox" && !isSandbox) continue;
9171
+ }
9172
+ return {
9173
+ certificateId: c.certificateId,
9174
+ name: c.name ?? "Apple Push Services",
9175
+ expirationDate: c.expirationDateString
9176
+ };
9177
+ }
9178
+ return null;
9179
+ }
9111
9180
  async function oneClickSetup(input) {
9112
9181
  const opts = {
9113
9182
  generateDistributionCert: input.options?.generateDistributionCert ?? true,
9114
9183
  generateStoreProfile: input.options?.generateStoreProfile ?? true,
9115
9184
  generateAscApiKey: input.options?.generateAscApiKey ?? true,
9116
9185
  generateApnsAuthKey: input.options?.generateApnsAuthKey ?? true,
9186
+ generatePushProductionCert: input.options?.generatePushProductionCert ?? false,
9187
+ generatePushSandboxCert: input.options?.generatePushSandboxCert ?? false,
9117
9188
  enableSignInWithApple: input.options?.enableSignInWithApple ?? true,
9118
9189
  enablePushNotifications: input.options?.enablePushNotifications ?? true,
9119
- revokeCertIds: input.options?.revokeCertIds ?? []
9190
+ revokeCertIds: input.options?.revokeCertIds ?? [],
9191
+ revokeApnsKeyIds: input.options?.revokeApnsKeyIds ?? []
9120
9192
  };
9121
9193
  const onProgress = input.onProgress ?? (() => {
9122
9194
  });
@@ -9187,6 +9259,11 @@ async function oneClickSetup(input) {
9187
9259
  created.provisioningProfileId = profile.id;
9188
9260
  const profileMeta = extractProfileMetadata(profile.content);
9189
9261
  if (profileMeta.uuid) created.profileUuid = profileMeta.uuid;
9262
+ for (const keyId of opts.revokeApnsKeyIds) {
9263
+ await step(`revoke_apns:${keyId}`, `Revoke APNs auth key ${keyId}`, async () => {
9264
+ await portal.revokeApiKey(keyId);
9265
+ });
9266
+ }
9190
9267
  if (opts.generateApnsAuthKey) {
9191
9268
  await step("apns_auth_key", "APNs Authentication Key (.p8)", async () => {
9192
9269
  try {
@@ -9204,6 +9281,68 @@ async function oneClickSetup(input) {
9204
9281
  }
9205
9282
  });
9206
9283
  }
9284
+ let pushCertCache = null;
9285
+ const loadPushCerts = async () => {
9286
+ if (pushCertCache == null) {
9287
+ pushCertCache = await portal.listPushCertificates();
9288
+ }
9289
+ return pushCertCache;
9290
+ };
9291
+ async function provisionLegacyPushCert(stepId, label, kind, pushType, certType, friendlyName) {
9292
+ await step(stepId, label, async () => {
9293
+ try {
9294
+ const existing = findExistingPushCertForBundle(
9295
+ await loadPushCerts(),
9296
+ appIdId,
9297
+ input.bundleIdentifier,
9298
+ kind
9299
+ );
9300
+ if (existing) {
9301
+ warnings.push(
9302
+ `${label} already exists for ${input.bundleIdentifier} ("${existing.name}"` + (existing.expirationDate ? `, expires ${existing.expirationDate}` : "") + `). Skipped \u2014 Apple caps these at 1 per bundle per environment and we can't recover the existing private key. Revoke it manually in Apple Developer Portal and re-run if you need a sitepong-managed copy.`
9303
+ );
9304
+ return;
9305
+ }
9306
+ const c = await createPushCert(portal, appIdId, pushType);
9307
+ const pushPassword = randomPassword();
9308
+ const p12 = bundleP12({
9309
+ certificate: c.certContent,
9310
+ privateKeyPem: c.privateKeyPem,
9311
+ password: pushPassword,
9312
+ friendlyName
9313
+ });
9314
+ additionalCerts.push({
9315
+ cert_type: certType,
9316
+ cert_base64: p12.toString("base64"),
9317
+ cert_password: pushPassword
9318
+ });
9319
+ } catch (err) {
9320
+ warnings.push(
9321
+ `${label} could not be created: ${err.message}. You can upload an existing .p12 manually from the credentials list.`
9322
+ );
9323
+ }
9324
+ });
9325
+ }
9326
+ if (opts.generatePushProductionCert) {
9327
+ await provisionLegacyPushCert(
9328
+ "push_prod_cert",
9329
+ "APS Production push certificate (.p12)",
9330
+ "production",
9331
+ PUSH_PROD_TYPE,
9332
+ "aps_production",
9333
+ `${input.appName} APNs Production`
9334
+ );
9335
+ }
9336
+ if (opts.generatePushSandboxCert) {
9337
+ await provisionLegacyPushCert(
9338
+ "push_sandbox_cert",
9339
+ "APS Sandbox push certificate (.p12)",
9340
+ "sandbox",
9341
+ PUSH_DEV_TYPE,
9342
+ "aps_sandbox",
9343
+ `${input.appName} APNs Sandbox`
9344
+ );
9345
+ }
9207
9346
  let ascKeyId = "";
9208
9347
  let ascIssuerId = "";
9209
9348
  let ascP8Base64 = "";