@sitepong/fastnode 0.1.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.
Files changed (162) hide show
  1. package/README.md +81 -0
  2. package/bin/fastnode.js +13 -0
  3. package/bin/fastnode.ts +5 -0
  4. package/dist/actions/index.cjs +7405 -0
  5. package/dist/actions/index.cjs.map +1 -0
  6. package/dist/actions/index.d.cts +15 -0
  7. package/dist/actions/index.d.ts +15 -0
  8. package/dist/actions/index.mjs +7377 -0
  9. package/dist/actions/index.mjs.map +1 -0
  10. package/dist/cert/index.cjs +219 -0
  11. package/dist/cert/index.cjs.map +1 -0
  12. package/dist/cert/index.d.cts +4 -0
  13. package/dist/cert/index.d.ts +4 -0
  14. package/dist/cert/index.mjs +191 -0
  15. package/dist/cert/index.mjs.map +1 -0
  16. package/dist/cert-BmJGtYtb.d.cts +27 -0
  17. package/dist/cert-owkOFNW8.d.ts +27 -0
  18. package/dist/cli/index.cjs +7998 -0
  19. package/dist/cli/index.cjs.map +1 -0
  20. package/dist/cli/index.d.cts +9 -0
  21. package/dist/cli/index.d.ts +9 -0
  22. package/dist/cli/index.mjs +7972 -0
  23. package/dist/cli/index.mjs.map +1 -0
  24. package/dist/client/index.cjs +2592 -0
  25. package/dist/client/index.cjs.map +1 -0
  26. package/dist/client/index.d.cts +2 -0
  27. package/dist/client/index.d.ts +2 -0
  28. package/dist/client/index.mjs +2582 -0
  29. package/dist/client/index.mjs.map +1 -0
  30. package/dist/context-CymLkfrS.d.cts +13 -0
  31. package/dist/context-CymLkfrS.d.ts +13 -0
  32. package/dist/core/index.cjs +281 -0
  33. package/dist/core/index.cjs.map +1 -0
  34. package/dist/core/index.d.cts +1 -0
  35. package/dist/core/index.d.ts +1 -0
  36. package/dist/core/index.mjs +254 -0
  37. package/dist/core/index.mjs.map +1 -0
  38. package/dist/deliver/index.cjs +328 -0
  39. package/dist/deliver/index.cjs.map +1 -0
  40. package/dist/deliver/index.d.cts +3 -0
  41. package/dist/deliver/index.d.ts +3 -0
  42. package/dist/deliver/index.mjs +322 -0
  43. package/dist/deliver/index.mjs.map +1 -0
  44. package/dist/enums-B609j2rb.d.cts +20 -0
  45. package/dist/enums-B609j2rb.d.ts +20 -0
  46. package/dist/frameit/index.cjs +247 -0
  47. package/dist/frameit/index.cjs.map +1 -0
  48. package/dist/frameit/index.d.cts +1 -0
  49. package/dist/frameit/index.d.ts +1 -0
  50. package/dist/frameit/index.mjs +242 -0
  51. package/dist/frameit/index.mjs.map +1 -0
  52. package/dist/gym/index.cjs +356 -0
  53. package/dist/gym/index.cjs.map +1 -0
  54. package/dist/gym/index.d.cts +2 -0
  55. package/dist/gym/index.d.ts +2 -0
  56. package/dist/gym/index.mjs +346 -0
  57. package/dist/gym/index.mjs.map +1 -0
  58. package/dist/index-1Vu2cRQ2.d.ts +99 -0
  59. package/dist/index-A5MimeQk.d.ts +72 -0
  60. package/dist/index-B0yhu_LZ.d.ts +76 -0
  61. package/dist/index-B9yXicrQ.d.ts +62 -0
  62. package/dist/index-BFdNOmPJ.d.cts +53 -0
  63. package/dist/index-BLubSlgK.d.cts +1513 -0
  64. package/dist/index-BN0ubxjZ.d.ts +70 -0
  65. package/dist/index-BQJIJlK7.d.cts +70 -0
  66. package/dist/index-BYonklf3.d.cts +84 -0
  67. package/dist/index-BYonklf3.d.ts +84 -0
  68. package/dist/index-BimqCmY8.d.cts +78 -0
  69. package/dist/index-BimqCmY8.d.ts +78 -0
  70. package/dist/index-BoU8qt8r.d.cts +59 -0
  71. package/dist/index-BoU8qt8r.d.ts +59 -0
  72. package/dist/index-C2yG3wXA.d.cts +95 -0
  73. package/dist/index-C2yG3wXA.d.ts +95 -0
  74. package/dist/index-CR3BFPIz.d.cts +77 -0
  75. package/dist/index-CR3BFPIz.d.ts +77 -0
  76. package/dist/index-CWNLnSOL.d.cts +99 -0
  77. package/dist/index-Cp6cjtd-.d.cts +65 -0
  78. package/dist/index-Cp6cjtd-.d.ts +65 -0
  79. package/dist/index-D1Izm7qt.d.ts +1513 -0
  80. package/dist/index-D5eihzwM.d.cts +76 -0
  81. package/dist/index-DImN9PWc.d.ts +155 -0
  82. package/dist/index-DfCUVJX1.d.cts +62 -0
  83. package/dist/index-DfirmFbC.d.ts +32 -0
  84. package/dist/index-DkvinY7_.d.ts +54 -0
  85. package/dist/index-DrUpRXRG.d.cts +155 -0
  86. package/dist/index-EcVvViW8.d.cts +72 -0
  87. package/dist/index-HRiaaX-Q.d.cts +54 -0
  88. package/dist/index-TfXqwuac.d.ts +53 -0
  89. package/dist/index-lt819Jgj.d.cts +32 -0
  90. package/dist/index.cjs +8464 -0
  91. package/dist/index.cjs.map +1 -0
  92. package/dist/index.d.cts +23 -0
  93. package/dist/index.d.ts +23 -0
  94. package/dist/index.mjs +8410 -0
  95. package/dist/index.mjs.map +1 -0
  96. package/dist/lane/index.cjs +7641 -0
  97. package/dist/lane/index.cjs.map +1 -0
  98. package/dist/lane/index.d.cts +51 -0
  99. package/dist/lane/index.d.ts +51 -0
  100. package/dist/lane/index.mjs +7603 -0
  101. package/dist/lane/index.mjs.map +1 -0
  102. package/dist/match/index.cjs +942 -0
  103. package/dist/match/index.cjs.map +1 -0
  104. package/dist/match/index.d.cts +5 -0
  105. package/dist/match/index.d.ts +5 -0
  106. package/dist/match/index.mjs +913 -0
  107. package/dist/match/index.mjs.map +1 -0
  108. package/dist/pem/index.cjs +195 -0
  109. package/dist/pem/index.cjs.map +1 -0
  110. package/dist/pem/index.d.cts +3 -0
  111. package/dist/pem/index.d.ts +3 -0
  112. package/dist/pem/index.mjs +170 -0
  113. package/dist/pem/index.mjs.map +1 -0
  114. package/dist/pilot/index.cjs +206 -0
  115. package/dist/pilot/index.cjs.map +1 -0
  116. package/dist/pilot/index.d.cts +3 -0
  117. package/dist/pilot/index.d.ts +3 -0
  118. package/dist/pilot/index.mjs +196 -0
  119. package/dist/pilot/index.mjs.map +1 -0
  120. package/dist/precheck/index.cjs +277 -0
  121. package/dist/precheck/index.cjs.map +1 -0
  122. package/dist/precheck/index.d.cts +3 -0
  123. package/dist/precheck/index.d.ts +3 -0
  124. package/dist/precheck/index.mjs +274 -0
  125. package/dist/precheck/index.mjs.map +1 -0
  126. package/dist/produce/index.cjs +200 -0
  127. package/dist/produce/index.cjs.map +1 -0
  128. package/dist/produce/index.d.cts +3 -0
  129. package/dist/produce/index.d.ts +3 -0
  130. package/dist/produce/index.mjs +191 -0
  131. package/dist/produce/index.mjs.map +1 -0
  132. package/dist/scan/index.cjs +187 -0
  133. package/dist/scan/index.cjs.map +1 -0
  134. package/dist/scan/index.d.cts +1 -0
  135. package/dist/scan/index.d.ts +1 -0
  136. package/dist/scan/index.mjs +183 -0
  137. package/dist/scan/index.mjs.map +1 -0
  138. package/dist/sigh/index.cjs +203 -0
  139. package/dist/sigh/index.cjs.map +1 -0
  140. package/dist/sigh/index.d.cts +3 -0
  141. package/dist/sigh/index.d.ts +3 -0
  142. package/dist/sigh/index.mjs +198 -0
  143. package/dist/sigh/index.mjs.map +1 -0
  144. package/dist/snapshot/index.cjs +448 -0
  145. package/dist/snapshot/index.cjs.map +1 -0
  146. package/dist/snapshot/index.d.cts +1 -0
  147. package/dist/snapshot/index.d.ts +1 -0
  148. package/dist/snapshot/index.mjs +438 -0
  149. package/dist/snapshot/index.mjs.map +1 -0
  150. package/dist/trainer/index.cjs +395 -0
  151. package/dist/trainer/index.cjs.map +1 -0
  152. package/dist/trainer/index.d.cts +1 -0
  153. package/dist/trainer/index.d.ts +1 -0
  154. package/dist/trainer/index.mjs +372 -0
  155. package/dist/trainer/index.mjs.map +1 -0
  156. package/dist/xcode/index.cjs +188 -0
  157. package/dist/xcode/index.cjs.map +1 -0
  158. package/dist/xcode/index.d.cts +1 -0
  159. package/dist/xcode/index.d.ts +1 -0
  160. package/dist/xcode/index.mjs +176 -0
  161. package/dist/xcode/index.mjs.map +1 -0
  162. package/package.json +223 -0
@@ -0,0 +1,281 @@
1
+ 'use strict';
2
+
3
+ var child_process = require('child_process');
4
+ var util = require('util');
5
+ var promises = require('fs/promises');
6
+ var path = require('path');
7
+ var os = require('os');
8
+ var plist = require('plist');
9
+
10
+ function _interopNamespace(e) {
11
+ if (e && e.__esModule) return e;
12
+ var n = Object.create(null);
13
+ if (e) {
14
+ Object.keys(e).forEach(function (k) {
15
+ if (k !== 'default') {
16
+ var d = Object.getOwnPropertyDescriptor(e, k);
17
+ Object.defineProperty(n, k, d.get ? d : {
18
+ enumerable: true,
19
+ get: function () { return e[k]; }
20
+ });
21
+ }
22
+ });
23
+ }
24
+ n.default = e;
25
+ return Object.freeze(n);
26
+ }
27
+
28
+ var plist__namespace = /*#__PURE__*/_interopNamespace(plist);
29
+
30
+ // src/core/config.ts
31
+ function resolveConfig(_overrides) {
32
+ return {
33
+ keyId: process.env.APP_STORE_CONNECT_API_KEY_KEY_ID,
34
+ issuerId: process.env.APP_STORE_CONNECT_API_KEY_ISSUER_ID,
35
+ privateKeyPath: process.env.APP_STORE_CONNECT_API_KEY_KEY_FILEPATH,
36
+ teamId: process.env.FASTLANE_TEAM_ID,
37
+ bundleIdentifier: process.env.FASTLANE_APP_IDENTIFIER,
38
+ platform: process.env.FASTLANE_PLATFORM_NAME,
39
+ ..._overrides
40
+ };
41
+ }
42
+
43
+ // src/xcode/platform.ts
44
+ function requireMacOS(feature) {
45
+ if (process.platform !== "darwin") {
46
+ throw new Error(
47
+ `${feature} requires macOS. This operation uses Xcode command-line tools which are not available on ${process.platform}.`
48
+ );
49
+ }
50
+ }
51
+
52
+ // src/core/transporter.ts
53
+ var ItunesTransporter = class {
54
+ async upload(options) {
55
+ requireMacOS("iTunes Transporter");
56
+ const args = ["altool", "--upload-app", "-f", options.packagePath, "-t", "ios"];
57
+ if (options.apiKeyId) args.push("--apiKey", options.apiKeyId);
58
+ if (options.apiIssuerId) args.push("--apiIssuer", options.apiIssuerId);
59
+ return this.run(args, options.onOutput);
60
+ }
61
+ async verify(options) {
62
+ requireMacOS("iTunes Transporter");
63
+ const args = ["altool", "--validate-app", "-f", options.packagePath, "-t", "ios"];
64
+ if (options.apiKeyId) args.push("--apiKey", options.apiKeyId);
65
+ if (options.apiIssuerId) args.push("--apiIssuer", options.apiIssuerId);
66
+ return this.run(args);
67
+ }
68
+ run(args, onOutput) {
69
+ return new Promise((resolve) => {
70
+ const child = child_process.spawn("xcrun", args, { stdio: ["ignore", "pipe", "pipe"] });
71
+ let output = "";
72
+ child.stdout.on("data", (data) => {
73
+ const chunk = data.toString();
74
+ output += chunk;
75
+ onOutput?.(chunk);
76
+ });
77
+ child.stderr.on("data", (data) => {
78
+ const chunk = data.toString();
79
+ output += chunk;
80
+ onOutput?.(chunk);
81
+ });
82
+ child.on("close", (code) => resolve({ success: code === 0, output }));
83
+ });
84
+ }
85
+ };
86
+ var execFileAsync = util.promisify(child_process.execFile);
87
+ async function analyzeIpa(ipaPath) {
88
+ const tmpDir = await promises.mkdtemp(path.join(os.tmpdir(), "fastnode-ipa-"));
89
+ try {
90
+ await execFileAsync("unzip", ["-o", ipaPath, "Payload/**/Info.plist", "-d", tmpDir]);
91
+ const { stdout } = await execFileAsync("find", [
92
+ tmpDir,
93
+ "-name",
94
+ "Info.plist",
95
+ "-path",
96
+ "*/Payload/*"
97
+ ]);
98
+ const allPlistPaths = stdout.trim().split("\n").filter((p) => p.length > 0);
99
+ if (allPlistPaths.length === 0) {
100
+ throw new Error("Info.plist not found in IPA");
101
+ }
102
+ const candidates = [...allPlistPaths].sort(
103
+ (a, b) => a.length - b.length
104
+ );
105
+ let plistPath = null;
106
+ let parsed = null;
107
+ for (const candidate of candidates) {
108
+ try {
109
+ await execFileAsync("plutil", ["-convert", "xml1", candidate]);
110
+ } catch {
111
+ }
112
+ const content = await promises.readFile(candidate, "utf-8");
113
+ const data = plist__namespace.parse(content);
114
+ if (data.WKWatchKitApp === true) continue;
115
+ plistPath = candidate;
116
+ parsed = data;
117
+ break;
118
+ }
119
+ if (!parsed) {
120
+ plistPath = candidates[0];
121
+ const content = await promises.readFile(plistPath, "utf-8");
122
+ parsed = plist__namespace.parse(content);
123
+ }
124
+ return {
125
+ bundleIdentifier: parsed.CFBundleIdentifier ?? "",
126
+ bundleVersion: String(parsed.CFBundleVersion ?? ""),
127
+ bundleShortVersion: parsed.CFBundleShortVersionString ?? "",
128
+ appName: parsed.CFBundleName ?? parsed.CFBundleDisplayName ?? "",
129
+ minimumOSVersion: parsed.MinimumOSVersion ?? ""
130
+ };
131
+ } finally {
132
+ await promises.rm(tmpDir, { recursive: true, force: true });
133
+ }
134
+ }
135
+ var execFileAsync2 = util.promisify(child_process.execFile);
136
+ async function parseProvisioningProfile(data) {
137
+ const tempPath = path.join(os.tmpdir(), `fastnode-profile-${Date.now()}.mobileprovision`);
138
+ await promises.writeFile(tempPath, data);
139
+ try {
140
+ const { stdout } = await execFileAsync2("security", ["cms", "-D", "-i", tempPath]);
141
+ const parsed = plist__namespace.parse(stdout);
142
+ return {
143
+ uuid: parsed.UUID ?? "",
144
+ name: parsed.Name ?? "",
145
+ appIdName: parsed.AppIDName ?? "",
146
+ teamIdentifier: parsed.TeamIdentifier ?? [],
147
+ teamName: parsed.TeamName ?? "",
148
+ creationDate: new Date(parsed.CreationDate ?? 0),
149
+ expirationDate: new Date(parsed.ExpirationDate ?? 0),
150
+ certificates: (parsed.DeveloperCertificates ?? []).map(
151
+ (c) => Buffer.from(c, "base64")
152
+ ),
153
+ provisionedDevices: parsed.ProvisionedDevices ?? [],
154
+ entitlements: parsed.Entitlements ?? {}
155
+ };
156
+ } finally {
157
+ await promises.unlink(tempPath).catch(() => {
158
+ });
159
+ }
160
+ }
161
+ var execFileAsync3 = util.promisify(child_process.execFile);
162
+ var SimulatorManager = class {
163
+ async list() {
164
+ requireMacOS("simulator");
165
+ const { stdout } = await execFileAsync3("xcrun", ["simctl", "list", "devices", "-j"]);
166
+ const data = JSON.parse(stdout);
167
+ const simulators = [];
168
+ for (const [runtime, devices] of Object.entries(data.devices ?? {})) {
169
+ for (const device of devices) {
170
+ if (device.isAvailable) {
171
+ simulators.push({
172
+ udid: device.udid,
173
+ name: device.name,
174
+ deviceType: device.deviceTypeIdentifier ?? "",
175
+ runtime,
176
+ state: device.state === "Booted" ? "Booted" : "Shutdown"
177
+ });
178
+ }
179
+ }
180
+ }
181
+ return simulators;
182
+ }
183
+ async boot(udid) {
184
+ requireMacOS("simulator");
185
+ try {
186
+ await execFileAsync3("xcrun", ["simctl", "boot", udid]);
187
+ } catch (err) {
188
+ const msg = err instanceof Error ? err.message : "";
189
+ if (!msg.includes("current state: Booted")) throw err;
190
+ }
191
+ }
192
+ async shutdown(udid) {
193
+ requireMacOS("simulator");
194
+ try {
195
+ await execFileAsync3("xcrun", ["simctl", "shutdown", udid]);
196
+ } catch {
197
+ }
198
+ }
199
+ async reset(udid) {
200
+ requireMacOS("simulator");
201
+ await this.shutdown(udid);
202
+ await execFileAsync3("xcrun", ["simctl", "erase", udid]);
203
+ }
204
+ async install(udid, appPath) {
205
+ requireMacOS("simulator");
206
+ await execFileAsync3("xcrun", ["simctl", "install", udid, appPath]);
207
+ }
208
+ async findBestMatch(deviceName, runtime) {
209
+ const all = await this.list();
210
+ const matching = all.filter(
211
+ (s) => s.name.toLowerCase().includes(deviceName.toLowerCase()) && (!runtime || s.runtime.includes(runtime))
212
+ );
213
+ if (matching.length === 0) return null;
214
+ matching.sort((a, b) => b.runtime.localeCompare(a.runtime));
215
+ return matching[0];
216
+ }
217
+ };
218
+ var execFileAsync4 = util.promisify(child_process.execFile);
219
+ var CredentialManager = class {
220
+ serviceName;
221
+ constructor(serviceName = "fastnode") {
222
+ this.serviceName = serviceName;
223
+ }
224
+ async get(service, account) {
225
+ const envKey = `${service.toUpperCase()}_${account.toUpperCase()}`.replace(/[^A-Z0-9]/g, "_");
226
+ if (process.env[envKey]) return process.env[envKey];
227
+ if (process.platform === "darwin") {
228
+ try {
229
+ const { stdout } = await execFileAsync4("security", [
230
+ "find-generic-password",
231
+ "-s",
232
+ service,
233
+ "-a",
234
+ account,
235
+ "-w"
236
+ ]);
237
+ return stdout.trim();
238
+ } catch {
239
+ return null;
240
+ }
241
+ }
242
+ return null;
243
+ }
244
+ async set(service, account, password) {
245
+ if (process.platform === "darwin") {
246
+ await execFileAsync4("security", [
247
+ "add-generic-password",
248
+ "-U",
249
+ "-s",
250
+ service,
251
+ "-a",
252
+ account,
253
+ "-w",
254
+ password
255
+ ]);
256
+ }
257
+ }
258
+ async delete(service, account) {
259
+ if (process.platform === "darwin") {
260
+ try {
261
+ await execFileAsync4("security", [
262
+ "delete-generic-password",
263
+ "-s",
264
+ service,
265
+ "-a",
266
+ account
267
+ ]);
268
+ } catch {
269
+ }
270
+ }
271
+ }
272
+ };
273
+
274
+ exports.CredentialManager = CredentialManager;
275
+ exports.ItunesTransporter = ItunesTransporter;
276
+ exports.SimulatorManager = SimulatorManager;
277
+ exports.analyzeIpa = analyzeIpa;
278
+ exports.parseProvisioningProfile = parseProvisioningProfile;
279
+ exports.resolveConfig = resolveConfig;
280
+ //# sourceMappingURL=index.cjs.map
281
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/core/config.ts","../../src/xcode/platform.ts","../../src/core/transporter.ts","../../src/core/ipa-analyzer.ts","../../src/core/provisioning-profile.ts","../../src/core/simulator.ts","../../src/core/credentials.ts"],"names":["spawn","promisify","execFile","mkdtemp","join","tmpdir","readFile","plist","rm","execFileAsync","writeFile","plist2","unlink"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AASO,SAAS,cAAc,UAAA,EAAsD;AAClF,EAAA,OAAO;AAAA,IACL,KAAA,EAAO,QAAQ,GAAA,CAAI,gCAAA;AAAA,IACnB,QAAA,EAAU,QAAQ,GAAA,CAAI,mCAAA;AAAA,IACtB,cAAA,EAAgB,QAAQ,GAAA,CAAI,sCAAA;AAAA,IAC5B,MAAA,EAAQ,QAAQ,GAAA,CAAI,gBAAA;AAAA,IACpB,gBAAA,EAAkB,QAAQ,GAAA,CAAI,uBAAA;AAAA,IAC9B,QAAA,EAAU,QAAQ,GAAA,CAAI,sBAAA;AAAA,IACtB,GAAG;AAAA,GACL;AACF;;;ACnBO,SAAS,aAAa,OAAA,EAAuB;AAClD,EAAA,IAAI,OAAA,CAAQ,aAAa,QAAA,EAAU;AACjC,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,EAAG,OAAO,CAAA,yFAAA,EACoB,OAAA,CAAQ,QAAQ,CAAA,CAAA;AAAA,KAChD;AAAA,EACF;AACF;;;ACJO,IAAM,oBAAN,MAAwB;AAAA,EAC7B,MAAM,OAAO,OAAA,EAKqC;AAChD,IAAA,YAAA,CAAa,oBAAoB,CAAA;AAEjC,IAAA,MAAM,IAAA,GAAO,CAAC,QAAA,EAAU,cAAA,EAAgB,MAAM,OAAA,CAAQ,WAAA,EAAa,MAAM,KAAK,CAAA;AAC9E,IAAA,IAAI,QAAQ,QAAA,EAAU,IAAA,CAAK,IAAA,CAAK,UAAA,EAAY,QAAQ,QAAQ,CAAA;AAC5D,IAAA,IAAI,QAAQ,WAAA,EAAa,IAAA,CAAK,IAAA,CAAK,aAAA,EAAe,QAAQ,WAAW,CAAA;AAErE,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,EAAM,OAAA,CAAQ,QAAQ,CAAA;AAAA,EACxC;AAAA,EAEA,MAAM,OAAO,OAAA,EAIqC;AAChD,IAAA,YAAA,CAAa,oBAAoB,CAAA;AAEjC,IAAA,MAAM,IAAA,GAAO,CAAC,QAAA,EAAU,gBAAA,EAAkB,MAAM,OAAA,CAAQ,WAAA,EAAa,MAAM,KAAK,CAAA;AAChF,IAAA,IAAI,QAAQ,QAAA,EAAU,IAAA,CAAK,IAAA,CAAK,UAAA,EAAY,QAAQ,QAAQ,CAAA;AAC5D,IAAA,IAAI,QAAQ,WAAA,EAAa,IAAA,CAAK,IAAA,CAAK,aAAA,EAAe,QAAQ,WAAW,CAAA;AAErE,IAAA,OAAO,IAAA,CAAK,IAAI,IAAI,CAAA;AAAA,EACtB;AAAA,EAEQ,GAAA,CAAI,MAAgB,QAAA,EAAmF;AAC7G,IAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,KAAY;AAC9B,MAAA,MAAM,KAAA,GAAQA,mBAAA,CAAM,OAAA,EAAS,IAAA,EAAM,EAAE,KAAA,EAAO,CAAC,QAAA,EAAU,MAAA,EAAQ,MAAM,CAAA,EAAG,CAAA;AACxE,MAAA,IAAI,MAAA,GAAS,EAAA;AAEb,MAAA,KAAA,CAAM,MAAA,CAAO,EAAA,CAAG,MAAA,EAAQ,CAAC,IAAA,KAAiB;AACxC,QAAA,MAAM,KAAA,GAAQ,KAAK,QAAA,EAAS;AAC5B,QAAA,MAAA,IAAU,KAAA;AACV,QAAA,QAAA,GAAW,KAAK,CAAA;AAAA,MAClB,CAAC,CAAA;AACD,MAAA,KAAA,CAAM,MAAA,CAAO,EAAA,CAAG,MAAA,EAAQ,CAAC,IAAA,KAAiB;AACxC,QAAA,MAAM,KAAA,GAAQ,KAAK,QAAA,EAAS;AAC5B,QAAA,MAAA,IAAU,KAAA;AACV,QAAA,QAAA,GAAW,KAAK,CAAA;AAAA,MAClB,CAAC,CAAA;AACD,MAAA,KAAA,CAAM,EAAA,CAAG,OAAA,EAAS,CAAC,IAAA,KAAS,OAAA,CAAQ,EAAE,OAAA,EAAS,IAAA,KAAS,CAAA,EAAG,MAAA,EAAQ,CAAC,CAAA;AAAA,IACtE,CAAC,CAAA;AAAA,EACH;AACF;AC5CA,IAAM,aAAA,GAAgBC,eAAUC,sBAAQ,CAAA;AAUxC,eAAsB,WAAW,OAAA,EAAmC;AAClE,EAAA,MAAM,SAAS,MAAMC,gBAAA,CAAQC,UAAKC,SAAA,EAAO,EAAG,eAAe,CAAC,CAAA;AAE5D,EAAA,IAAI;AAIF,IAAA,MAAM,aAAA,CAAc,SAAS,CAAC,IAAA,EAAM,SAAS,uBAAA,EAAyB,IAAA,EAAM,MAAM,CAAC,CAAA;AAEnF,IAAA,MAAM,EAAE,MAAA,EAAO,GAAI,MAAM,cAAc,MAAA,EAAQ;AAAA,MAC7C,MAAA;AAAA,MACA,OAAA;AAAA,MACA,YAAA;AAAA,MACA,OAAA;AAAA,MACA;AAAA,KACD,CAAA;AACD,IAAA,MAAM,aAAA,GAAgB,MAAA,CACnB,IAAA,EAAK,CACL,KAAA,CAAM,IAAI,CAAA,CACV,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,MAAA,GAAS,CAAC,CAAA;AAC7B,IAAA,IAAI,aAAA,CAAc,WAAW,CAAA,EAAG;AAC9B,MAAA,MAAM,IAAI,MAAM,6BAA6B,CAAA;AAAA,IAC/C;AAMA,IAAA,MAAM,UAAA,GAAa,CAAC,GAAG,aAAa,CAAA,CAAE,IAAA;AAAA,MACpC,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,SAAS,CAAA,CAAE;AAAA,KACzB;AAEA,IAAA,IAAI,SAAA,GAA2B,IAAA;AAC/B,IAAA,IAAI,MAAA,GAAqC,IAAA;AAEzC,IAAA,KAAA,MAAW,aAAa,UAAA,EAAY;AAClC,MAAA,IAAI;AACF,QAAA,MAAM,cAAc,QAAA,EAAU,CAAC,UAAA,EAAY,MAAA,EAAQ,SAAS,CAAC,CAAA;AAAA,MAC/D,CAAA,CAAA,MAAQ;AAAA,MAER;AACA,MAAA,MAAM,OAAA,GAAU,MAAMC,iBAAA,CAAS,SAAA,EAAW,OAAO,CAAA;AACjD,MAAA,MAAM,IAAA,GAAaC,uBAAM,OAAO,CAAA;AAChC,MAAA,IAAI,IAAA,CAAK,kBAAkB,IAAA,EAAM;AACjC,MAAA,SAAA,GAAY,SAAA;AACZ,MAAA,MAAA,GAAS,IAAA;AACT,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,CAAC,MAAA,EAAQ;AAEX,MAAA,SAAA,GAAY,WAAW,CAAC,CAAA;AACxB,MAAA,MAAM,OAAA,GAAU,MAAMD,iBAAA,CAAS,SAAA,EAAW,OAAO,CAAA;AACjD,MAAA,MAAA,GAAeC,uBAAM,OAAO,CAAA;AAAA,IAC9B;AAEA,IAAA,OAAO;AAAA,MACL,gBAAA,EAAkB,OAAO,kBAAA,IAAsB,EAAA;AAAA,MAC/C,aAAA,EAAe,MAAA,CAAO,MAAA,CAAO,eAAA,IAAmB,EAAE,CAAA;AAAA,MAClD,kBAAA,EAAoB,OAAO,0BAAA,IAA8B,EAAA;AAAA,MACzD,OAAA,EAAS,MAAA,CAAO,YAAA,IAAgB,MAAA,CAAO,mBAAA,IAAuB,EAAA;AAAA,MAC9D,gBAAA,EAAkB,OAAO,gBAAA,IAAoB;AAAA,KAC/C;AAAA,EACF,CAAA,SAAE;AACA,IAAA,MAAMC,YAAG,MAAA,EAAQ,EAAE,WAAW,IAAA,EAAM,KAAA,EAAO,MAAM,CAAA;AAAA,EACnD;AACF;AC5EA,IAAMC,cAAAA,GAAgBR,eAAUC,sBAAQ,CAAA;AAexC,eAAsB,yBACpB,IAAA,EACkC;AAElC,EAAA,MAAM,QAAA,GAAWE,UAAKC,SAAAA,EAAO,EAAG,oBAAoB,IAAA,CAAK,GAAA,EAAK,CAAA,gBAAA,CAAkB,CAAA;AAChF,EAAA,MAAMK,kBAAA,CAAU,UAAU,IAAI,CAAA;AAE9B,EAAA,IAAI;AAEF,IAAA,MAAM,EAAE,MAAA,EAAO,GAAI,MAAMD,cAAAA,CAAc,UAAA,EAAY,CAAC,KAAA,EAAO,IAAA,EAAM,IAAA,EAAM,QAAQ,CAAC,CAAA;AAEhF,IAAA,MAAM,MAAA,GAAeE,uBAAM,MAAM,CAAA;AAEjC,IAAA,OAAO;AAAA,MACL,IAAA,EAAM,OAAO,IAAA,IAAQ,EAAA;AAAA,MACrB,IAAA,EAAM,OAAO,IAAA,IAAQ,EAAA;AAAA,MACrB,SAAA,EAAW,OAAO,SAAA,IAAa,EAAA;AAAA,MAC/B,cAAA,EAAgB,MAAA,CAAO,cAAA,IAAkB,EAAC;AAAA,MAC1C,QAAA,EAAU,OAAO,QAAA,IAAY,EAAA;AAAA,MAC7B,YAAA,EAAc,IAAI,IAAA,CAAK,MAAA,CAAO,gBAAgB,CAAC,CAAA;AAAA,MAC/C,cAAA,EAAgB,IAAI,IAAA,CAAK,MAAA,CAAO,kBAAkB,CAAC,CAAA;AAAA,MACnD,YAAA,EAAA,CAAe,MAAA,CAAO,qBAAA,IAAyB,EAAC,EAAG,GAAA;AAAA,QAAI,CAAC,CAAA,KACtD,MAAA,CAAO,IAAA,CAAK,GAAG,QAAQ;AAAA,OACzB;AAAA,MACA,kBAAA,EAAoB,MAAA,CAAO,kBAAA,IAAsB,EAAC;AAAA,MAClD,YAAA,EAAc,MAAA,CAAO,YAAA,IAAgB;AAAC,KACxC;AAAA,EACF,CAAA,SAAE;AACA,IAAA,MAAMC,eAAA,CAAO,QAAQ,CAAA,CAAE,KAAA,CAAM,MAAM;AAAA,IAAC,CAAC,CAAA;AAAA,EACvC;AACF;AChDA,IAAMH,cAAAA,GAAgBR,eAAUC,sBAAQ,CAAA;AAUjC,IAAM,mBAAN,MAAuB;AAAA,EAC5B,MAAM,IAAA,GAA6B;AACjC,IAAA,YAAA,CAAa,WAAW,CAAA;AACxB,IAAA,MAAM,EAAE,MAAA,EAAO,GAAI,MAAMO,cAAAA,CAAc,OAAA,EAAS,CAAC,QAAA,EAAU,MAAA,EAAQ,SAAA,EAAW,IAAI,CAAC,CAAA;AACnF,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,MAAM,CAAA;AAC9B,IAAA,MAAM,aAA0B,EAAC;AAEjC,IAAA,KAAA,MAAW,CAAC,OAAA,EAAS,OAAO,CAAA,IAAK,MAAA,CAAO,QAAQ,IAAA,CAAK,OAAA,IAAW,EAAE,CAAA,EAAG;AACnE,MAAA,KAAA,MAAW,UAAU,OAAA,EAAkB;AACrC,QAAA,IAAI,OAAO,WAAA,EAAa;AACtB,UAAA,UAAA,CAAW,IAAA,CAAK;AAAA,YACd,MAAM,MAAA,CAAO,IAAA;AAAA,YACb,MAAM,MAAA,CAAO,IAAA;AAAA,YACb,UAAA,EAAY,OAAO,oBAAA,IAAwB,EAAA;AAAA,YAC3C,OAAA;AAAA,YACA,KAAA,EAAO,MAAA,CAAO,KAAA,KAAU,QAAA,GAAW,QAAA,GAAW;AAAA,WAC/C,CAAA;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAEA,IAAA,OAAO,UAAA;AAAA,EACT;AAAA,EAEA,MAAM,KAAK,IAAA,EAA6B;AACtC,IAAA,YAAA,CAAa,WAAW,CAAA;AACxB,IAAA,IAAI;AACF,MAAA,MAAMA,eAAc,OAAA,EAAS,CAAC,QAAA,EAAU,MAAA,EAAQ,IAAI,CAAC,CAAA;AAAA,IACvD,SAAS,GAAA,EAAc;AACrB,MAAA,MAAM,GAAA,GAAM,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,EAAA;AACjD,MAAA,IAAI,CAAC,GAAA,CAAI,QAAA,CAAS,uBAAuB,GAAG,MAAM,GAAA;AAAA,IACpD;AAAA,EACF;AAAA,EAEA,MAAM,SAAS,IAAA,EAA6B;AAC1C,IAAA,YAAA,CAAa,WAAW,CAAA;AACxB,IAAA,IAAI;AACF,MAAA,MAAMA,eAAc,OAAA,EAAS,CAAC,QAAA,EAAU,UAAA,EAAY,IAAI,CAAC,CAAA;AAAA,IAC3D,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AAAA,EAEA,MAAM,MAAM,IAAA,EAA6B;AACvC,IAAA,YAAA,CAAa,WAAW,CAAA;AACxB,IAAA,MAAM,IAAA,CAAK,SAAS,IAAI,CAAA;AACxB,IAAA,MAAMA,eAAc,OAAA,EAAS,CAAC,QAAA,EAAU,OAAA,EAAS,IAAI,CAAC,CAAA;AAAA,EACxD;AAAA,EAEA,MAAM,OAAA,CAAQ,IAAA,EAAc,OAAA,EAAgC;AAC1D,IAAA,YAAA,CAAa,WAAW,CAAA;AACxB,IAAA,MAAMA,eAAc,OAAA,EAAS,CAAC,UAAU,SAAA,EAAW,IAAA,EAAM,OAAO,CAAC,CAAA;AAAA,EACnE;AAAA,EAEA,MAAM,aAAA,CAAc,UAAA,EAAoB,OAAA,EAA6C;AACnF,IAAA,MAAM,GAAA,GAAM,MAAM,IAAA,CAAK,IAAA,EAAK;AAC5B,IAAA,MAAM,WAAW,GAAA,CAAI,MAAA;AAAA,MAAO,CAAC,CAAA,KAC3B,CAAA,CAAE,IAAA,CAAK,WAAA,GAAc,QAAA,CAAS,UAAA,CAAW,WAAA,EAAa,MACrD,CAAC,OAAA,IAAW,CAAA,CAAE,OAAA,CAAQ,SAAS,OAAO,CAAA;AAAA,KACzC;AAEA,IAAA,IAAI,QAAA,CAAS,MAAA,KAAW,CAAA,EAAG,OAAO,IAAA;AAElC,IAAA,QAAA,CAAS,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,EAAE,OAAA,CAAQ,aAAA,CAAc,CAAA,CAAE,OAAO,CAAC,CAAA;AAC1D,IAAA,OAAO,SAAS,CAAC,CAAA;AAAA,EACnB;AACF;AC7EA,IAAMA,cAAAA,GAAgBR,eAAUC,sBAAQ,CAAA;AAEjC,IAAM,oBAAN,MAAwB;AAAA,EACrB,WAAA;AAAA,EAER,WAAA,CAAY,cAAc,UAAA,EAAY;AACpC,IAAA,IAAA,CAAK,WAAA,GAAc,WAAA;AAAA,EACrB;AAAA,EAEA,MAAM,GAAA,CAAI,OAAA,EAAiB,OAAA,EAAyC;AAElE,IAAA,MAAM,MAAA,GAAS,CAAA,EAAG,OAAA,CAAQ,WAAA,EAAa,CAAA,CAAA,EAAI,OAAA,CAAQ,WAAA,EAAa,CAAA,CAAA,CAAG,OAAA,CAAQ,YAAA,EAAc,GAAG,CAAA;AAC5F,IAAA,IAAI,QAAQ,GAAA,CAAI,MAAM,GAAG,OAAO,OAAA,CAAQ,IAAI,MAAM,CAAA;AAGlD,IAAA,IAAI,OAAA,CAAQ,aAAa,QAAA,EAAU;AACjC,MAAA,IAAI;AACF,QAAA,MAAM,EAAE,MAAA,EAAO,GAAI,MAAMO,eAAc,UAAA,EAAY;AAAA,UACjD,uBAAA;AAAA,UACA,IAAA;AAAA,UAAM,OAAA;AAAA,UACN,IAAA;AAAA,UAAM,OAAA;AAAA,UACN;AAAA,SACD,CAAA;AACD,QAAA,OAAO,OAAO,IAAA,EAAK;AAAA,MACrB,CAAA,CAAA,MAAQ;AACN,QAAA,OAAO,IAAA;AAAA,MACT;AAAA,IACF;AAEA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,MAAM,GAAA,CAAI,OAAA,EAAiB,OAAA,EAAiB,QAAA,EAAiC;AAC3E,IAAA,IAAI,OAAA,CAAQ,aAAa,QAAA,EAAU;AACjC,MAAA,MAAMA,eAAc,UAAA,EAAY;AAAA,QAC9B,sBAAA;AAAA,QACA,IAAA;AAAA,QACA,IAAA;AAAA,QAAM,OAAA;AAAA,QACN,IAAA;AAAA,QAAM,OAAA;AAAA,QACN,IAAA;AAAA,QAAM;AAAA,OACP,CAAA;AAAA,IACH;AAAA,EACF;AAAA,EAEA,MAAM,MAAA,CAAO,OAAA,EAAiB,OAAA,EAAgC;AAC5D,IAAA,IAAI,OAAA,CAAQ,aAAa,QAAA,EAAU;AACjC,MAAA,IAAI;AACF,QAAA,MAAMA,eAAc,UAAA,EAAY;AAAA,UAC9B,yBAAA;AAAA,UACA,IAAA;AAAA,UAAM,OAAA;AAAA,UACN,IAAA;AAAA,UAAM;AAAA,SACP,CAAA;AAAA,MACH,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AACF","file":"index.cjs","sourcesContent":["export interface FastnodeConfig {\n keyId?: string;\n issuerId?: string;\n privateKeyPath?: string;\n teamId?: string;\n bundleIdentifier?: string;\n platform?: string;\n}\n\nexport function resolveConfig(_overrides?: Partial<FastnodeConfig>): FastnodeConfig {\n return {\n keyId: process.env.APP_STORE_CONNECT_API_KEY_KEY_ID,\n issuerId: process.env.APP_STORE_CONNECT_API_KEY_ISSUER_ID,\n privateKeyPath: process.env.APP_STORE_CONNECT_API_KEY_KEY_FILEPATH,\n teamId: process.env.FASTLANE_TEAM_ID,\n bundleIdentifier: process.env.FASTLANE_APP_IDENTIFIER,\n platform: process.env.FASTLANE_PLATFORM_NAME,\n ..._overrides,\n };\n}\n","export function requireMacOS(feature: string): void {\n if (process.platform !== \"darwin\") {\n throw new Error(\n `${feature} requires macOS. This operation uses Xcode command-line tools ` +\n `which are not available on ${process.platform}.`\n );\n }\n}\n\nexport function isMacOS(): boolean {\n return process.platform === \"darwin\";\n}\n","import { spawn } from \"node:child_process\";\nimport { requireMacOS } from \"../xcode/platform.js\";\n\nexport class ItunesTransporter {\n async upload(options: {\n packagePath: string;\n apiKeyId?: string;\n apiIssuerId?: string;\n onOutput?: (chunk: string) => void;\n }): Promise<{ success: boolean; output: string }> {\n requireMacOS(\"iTunes Transporter\");\n\n const args = [\"altool\", \"--upload-app\", \"-f\", options.packagePath, \"-t\", \"ios\"];\n if (options.apiKeyId) args.push(\"--apiKey\", options.apiKeyId);\n if (options.apiIssuerId) args.push(\"--apiIssuer\", options.apiIssuerId);\n\n return this.run(args, options.onOutput);\n }\n\n async verify(options: {\n packagePath: string;\n apiKeyId?: string;\n apiIssuerId?: string;\n }): Promise<{ success: boolean; output: string }> {\n requireMacOS(\"iTunes Transporter\");\n\n const args = [\"altool\", \"--validate-app\", \"-f\", options.packagePath, \"-t\", \"ios\"];\n if (options.apiKeyId) args.push(\"--apiKey\", options.apiKeyId);\n if (options.apiIssuerId) args.push(\"--apiIssuer\", options.apiIssuerId);\n\n return this.run(args);\n }\n\n private run(args: string[], onOutput?: (chunk: string) => void): Promise<{ success: boolean; output: string }> {\n return new Promise((resolve) => {\n const child = spawn(\"xcrun\", args, { stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n let output = \"\";\n\n child.stdout.on(\"data\", (data: Buffer) => {\n const chunk = data.toString();\n output += chunk;\n onOutput?.(chunk);\n });\n child.stderr.on(\"data\", (data: Buffer) => {\n const chunk = data.toString();\n output += chunk;\n onOutput?.(chunk);\n });\n child.on(\"close\", (code) => resolve({ success: code === 0, output }));\n });\n }\n}\n","import { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { mkdtemp, readFile, rm } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { tmpdir } from \"node:os\";\nimport * as plist from \"plist\";\n\nconst execFileAsync = promisify(execFile);\n\nexport interface IpaInfo {\n bundleIdentifier: string;\n bundleVersion: string;\n bundleShortVersion: string;\n appName: string;\n minimumOSVersion: string;\n}\n\nexport async function analyzeIpa(ipaPath: string): Promise<IpaInfo> {\n const tmpDir = await mkdtemp(join(tmpdir(), \"fastnode-ipa-\"));\n\n try {\n // Unzip every Info.plist under Payload/. Modern IPAs ship the main app\n // alongside WatchKit apps, app extensions, intents, widgets, and more —\n // we need enough to identify the main one and skip the rest.\n await execFileAsync(\"unzip\", [\"-o\", ipaPath, \"Payload/**/Info.plist\", \"-d\", tmpDir]);\n\n const { stdout } = await execFileAsync(\"find\", [\n tmpDir,\n \"-name\",\n \"Info.plist\",\n \"-path\",\n \"*/Payload/*\",\n ]);\n const allPlistPaths = stdout\n .trim()\n .split(\"\\n\")\n .filter((p) => p.length > 0);\n if (allPlistPaths.length === 0) {\n throw new Error(\"Info.plist not found in IPA\");\n }\n\n // Pick the main app's Info.plist. Fastlane's approach is to prefer the\n // plist with the shortest path (main app lives at the top of Payload/,\n // extensions/watch apps live nested underneath). We also skip any plist\n // whose `WKWatchKitApp=true` to positively exclude WatchKit embeds.\n const candidates = [...allPlistPaths].sort(\n (a, b) => a.length - b.length\n );\n\n let plistPath: string | null = null;\n let parsed: Record<string, any> | null = null;\n\n for (const candidate of candidates) {\n try {\n await execFileAsync(\"plutil\", [\"-convert\", \"xml1\", candidate]);\n } catch {\n // May already be XML\n }\n const content = await readFile(candidate, \"utf-8\");\n const data = plist.parse(content) as Record<string, any>;\n if (data.WKWatchKitApp === true) continue; // skip WatchKit embed\n plistPath = candidate;\n parsed = data;\n break;\n }\n\n if (!parsed) {\n // Every candidate was a WatchKit embed — fall back to the shortest path.\n plistPath = candidates[0];\n const content = await readFile(plistPath, \"utf-8\");\n parsed = plist.parse(content) as Record<string, any>;\n }\n\n return {\n bundleIdentifier: parsed.CFBundleIdentifier ?? \"\",\n bundleVersion: String(parsed.CFBundleVersion ?? \"\"),\n bundleShortVersion: parsed.CFBundleShortVersionString ?? \"\",\n appName: parsed.CFBundleName ?? parsed.CFBundleDisplayName ?? \"\",\n minimumOSVersion: parsed.MinimumOSVersion ?? \"\",\n };\n } finally {\n await rm(tmpDir, { recursive: true, force: true });\n }\n}\n","import { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { writeFile, unlink } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { tmpdir } from \"node:os\";\nimport * as plist from \"plist\";\n\nconst execFileAsync = promisify(execFile);\n\nexport interface ProvisioningProfileInfo {\n uuid: string;\n name: string;\n appIdName: string;\n teamIdentifier: string[];\n teamName: string;\n creationDate: Date;\n expirationDate: Date;\n certificates: Buffer[];\n provisionedDevices: string[];\n entitlements: Record<string, unknown>;\n}\n\nexport async function parseProvisioningProfile(\n data: Buffer\n): Promise<ProvisioningProfileInfo> {\n // Write to temp file\n const tempPath = join(tmpdir(), `fastnode-profile-${Date.now()}.mobileprovision`);\n await writeFile(tempPath, data);\n\n try {\n // Extract the plist from the CMS/PKCS#7 envelope\n const { stdout } = await execFileAsync(\"security\", [\"cms\", \"-D\", \"-i\", tempPath]);\n\n const parsed = plist.parse(stdout) as Record<string, any>;\n\n return {\n uuid: parsed.UUID ?? \"\",\n name: parsed.Name ?? \"\",\n appIdName: parsed.AppIDName ?? \"\",\n teamIdentifier: parsed.TeamIdentifier ?? [],\n teamName: parsed.TeamName ?? \"\",\n creationDate: new Date(parsed.CreationDate ?? 0),\n expirationDate: new Date(parsed.ExpirationDate ?? 0),\n certificates: (parsed.DeveloperCertificates ?? []).map((c: any) =>\n Buffer.from(c, \"base64\")\n ),\n provisionedDevices: parsed.ProvisionedDevices ?? [],\n entitlements: parsed.Entitlements ?? {},\n };\n } finally {\n await unlink(tempPath).catch(() => {});\n }\n}\n","import { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { requireMacOS } from \"../xcode/platform.js\";\n\nconst execFileAsync = promisify(execFile);\n\nexport interface Simulator {\n udid: string;\n name: string;\n deviceType: string;\n runtime: string;\n state: \"Booted\" | \"Shutdown\";\n}\n\nexport class SimulatorManager {\n async list(): Promise<Simulator[]> {\n requireMacOS(\"simulator\");\n const { stdout } = await execFileAsync(\"xcrun\", [\"simctl\", \"list\", \"devices\", \"-j\"]);\n const data = JSON.parse(stdout);\n const simulators: Simulator[] = [];\n\n for (const [runtime, devices] of Object.entries(data.devices ?? {})) {\n for (const device of devices as any[]) {\n if (device.isAvailable) {\n simulators.push({\n udid: device.udid,\n name: device.name,\n deviceType: device.deviceTypeIdentifier ?? \"\",\n runtime,\n state: device.state === \"Booted\" ? \"Booted\" : \"Shutdown\",\n });\n }\n }\n }\n\n return simulators;\n }\n\n async boot(udid: string): Promise<void> {\n requireMacOS(\"simulator\");\n try {\n await execFileAsync(\"xcrun\", [\"simctl\", \"boot\", udid]);\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : \"\";\n if (!msg.includes(\"current state: Booted\")) throw err;\n }\n }\n\n async shutdown(udid: string): Promise<void> {\n requireMacOS(\"simulator\");\n try {\n await execFileAsync(\"xcrun\", [\"simctl\", \"shutdown\", udid]);\n } catch {\n // May already be shut down\n }\n }\n\n async reset(udid: string): Promise<void> {\n requireMacOS(\"simulator\");\n await this.shutdown(udid);\n await execFileAsync(\"xcrun\", [\"simctl\", \"erase\", udid]);\n }\n\n async install(udid: string, appPath: string): Promise<void> {\n requireMacOS(\"simulator\");\n await execFileAsync(\"xcrun\", [\"simctl\", \"install\", udid, appPath]);\n }\n\n async findBestMatch(deviceName: string, runtime?: string): Promise<Simulator | null> {\n const all = await this.list();\n const matching = all.filter((s) =>\n s.name.toLowerCase().includes(deviceName.toLowerCase()) &&\n (!runtime || s.runtime.includes(runtime))\n );\n\n if (matching.length === 0) return null;\n // Prefer latest runtime\n matching.sort((a, b) => b.runtime.localeCompare(a.runtime));\n return matching[0];\n }\n}\n","import { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\n\nconst execFileAsync = promisify(execFile);\n\nexport class CredentialManager {\n private serviceName: string;\n\n constructor(serviceName = \"fastnode\") {\n this.serviceName = serviceName;\n }\n\n async get(service: string, account: string): Promise<string | null> {\n // Check env vars first\n const envKey = `${service.toUpperCase()}_${account.toUpperCase()}`.replace(/[^A-Z0-9]/g, \"_\");\n if (process.env[envKey]) return process.env[envKey]!;\n\n // Try macOS keychain\n if (process.platform === \"darwin\") {\n try {\n const { stdout } = await execFileAsync(\"security\", [\n \"find-generic-password\",\n \"-s\", service,\n \"-a\", account,\n \"-w\",\n ]);\n return stdout.trim();\n } catch {\n return null;\n }\n }\n\n return null;\n }\n\n async set(service: string, account: string, password: string): Promise<void> {\n if (process.platform === \"darwin\") {\n await execFileAsync(\"security\", [\n \"add-generic-password\",\n \"-U\",\n \"-s\", service,\n \"-a\", account,\n \"-w\", password,\n ]);\n }\n }\n\n async delete(service: string, account: string): Promise<void> {\n if (process.platform === \"darwin\") {\n try {\n await execFileAsync(\"security\", [\n \"delete-generic-password\",\n \"-s\", service,\n \"-a\", account,\n ]);\n } catch {\n // May not exist\n }\n }\n }\n}\n"]}
@@ -0,0 +1 @@
1
+ export { C as CredentialManager, F as FastnodeConfig, b as IpaInfo, I as ItunesTransporter, P as ProvisioningProfileInfo, S as SimulatorManager, a as analyzeIpa, p as parseProvisioningProfile, r as resolveConfig } from '../index-C2yG3wXA.cjs';
@@ -0,0 +1 @@
1
+ export { C as CredentialManager, F as FastnodeConfig, b as IpaInfo, I as ItunesTransporter, P as ProvisioningProfileInfo, S as SimulatorManager, a as analyzeIpa, p as parseProvisioningProfile, r as resolveConfig } from '../index-C2yG3wXA.js';
@@ -0,0 +1,254 @@
1
+ import { execFile, spawn } from 'child_process';
2
+ import { promisify } from 'util';
3
+ import { mkdtemp, readFile, rm, writeFile, unlink } from 'fs/promises';
4
+ import { join } from 'path';
5
+ import { tmpdir } from 'os';
6
+ import * as plist from 'plist';
7
+
8
+ // src/core/config.ts
9
+ function resolveConfig(_overrides) {
10
+ return {
11
+ keyId: process.env.APP_STORE_CONNECT_API_KEY_KEY_ID,
12
+ issuerId: process.env.APP_STORE_CONNECT_API_KEY_ISSUER_ID,
13
+ privateKeyPath: process.env.APP_STORE_CONNECT_API_KEY_KEY_FILEPATH,
14
+ teamId: process.env.FASTLANE_TEAM_ID,
15
+ bundleIdentifier: process.env.FASTLANE_APP_IDENTIFIER,
16
+ platform: process.env.FASTLANE_PLATFORM_NAME,
17
+ ..._overrides
18
+ };
19
+ }
20
+
21
+ // src/xcode/platform.ts
22
+ function requireMacOS(feature) {
23
+ if (process.platform !== "darwin") {
24
+ throw new Error(
25
+ `${feature} requires macOS. This operation uses Xcode command-line tools which are not available on ${process.platform}.`
26
+ );
27
+ }
28
+ }
29
+
30
+ // src/core/transporter.ts
31
+ var ItunesTransporter = class {
32
+ async upload(options) {
33
+ requireMacOS("iTunes Transporter");
34
+ const args = ["altool", "--upload-app", "-f", options.packagePath, "-t", "ios"];
35
+ if (options.apiKeyId) args.push("--apiKey", options.apiKeyId);
36
+ if (options.apiIssuerId) args.push("--apiIssuer", options.apiIssuerId);
37
+ return this.run(args, options.onOutput);
38
+ }
39
+ async verify(options) {
40
+ requireMacOS("iTunes Transporter");
41
+ const args = ["altool", "--validate-app", "-f", options.packagePath, "-t", "ios"];
42
+ if (options.apiKeyId) args.push("--apiKey", options.apiKeyId);
43
+ if (options.apiIssuerId) args.push("--apiIssuer", options.apiIssuerId);
44
+ return this.run(args);
45
+ }
46
+ run(args, onOutput) {
47
+ return new Promise((resolve) => {
48
+ const child = spawn("xcrun", args, { stdio: ["ignore", "pipe", "pipe"] });
49
+ let output = "";
50
+ child.stdout.on("data", (data) => {
51
+ const chunk = data.toString();
52
+ output += chunk;
53
+ onOutput?.(chunk);
54
+ });
55
+ child.stderr.on("data", (data) => {
56
+ const chunk = data.toString();
57
+ output += chunk;
58
+ onOutput?.(chunk);
59
+ });
60
+ child.on("close", (code) => resolve({ success: code === 0, output }));
61
+ });
62
+ }
63
+ };
64
+ var execFileAsync = promisify(execFile);
65
+ async function analyzeIpa(ipaPath) {
66
+ const tmpDir = await mkdtemp(join(tmpdir(), "fastnode-ipa-"));
67
+ try {
68
+ await execFileAsync("unzip", ["-o", ipaPath, "Payload/**/Info.plist", "-d", tmpDir]);
69
+ const { stdout } = await execFileAsync("find", [
70
+ tmpDir,
71
+ "-name",
72
+ "Info.plist",
73
+ "-path",
74
+ "*/Payload/*"
75
+ ]);
76
+ const allPlistPaths = stdout.trim().split("\n").filter((p) => p.length > 0);
77
+ if (allPlistPaths.length === 0) {
78
+ throw new Error("Info.plist not found in IPA");
79
+ }
80
+ const candidates = [...allPlistPaths].sort(
81
+ (a, b) => a.length - b.length
82
+ );
83
+ let plistPath = null;
84
+ let parsed = null;
85
+ for (const candidate of candidates) {
86
+ try {
87
+ await execFileAsync("plutil", ["-convert", "xml1", candidate]);
88
+ } catch {
89
+ }
90
+ const content = await readFile(candidate, "utf-8");
91
+ const data = plist.parse(content);
92
+ if (data.WKWatchKitApp === true) continue;
93
+ plistPath = candidate;
94
+ parsed = data;
95
+ break;
96
+ }
97
+ if (!parsed) {
98
+ plistPath = candidates[0];
99
+ const content = await readFile(plistPath, "utf-8");
100
+ parsed = plist.parse(content);
101
+ }
102
+ return {
103
+ bundleIdentifier: parsed.CFBundleIdentifier ?? "",
104
+ bundleVersion: String(parsed.CFBundleVersion ?? ""),
105
+ bundleShortVersion: parsed.CFBundleShortVersionString ?? "",
106
+ appName: parsed.CFBundleName ?? parsed.CFBundleDisplayName ?? "",
107
+ minimumOSVersion: parsed.MinimumOSVersion ?? ""
108
+ };
109
+ } finally {
110
+ await rm(tmpDir, { recursive: true, force: true });
111
+ }
112
+ }
113
+ var execFileAsync2 = promisify(execFile);
114
+ async function parseProvisioningProfile(data) {
115
+ const tempPath = join(tmpdir(), `fastnode-profile-${Date.now()}.mobileprovision`);
116
+ await writeFile(tempPath, data);
117
+ try {
118
+ const { stdout } = await execFileAsync2("security", ["cms", "-D", "-i", tempPath]);
119
+ const parsed = plist.parse(stdout);
120
+ return {
121
+ uuid: parsed.UUID ?? "",
122
+ name: parsed.Name ?? "",
123
+ appIdName: parsed.AppIDName ?? "",
124
+ teamIdentifier: parsed.TeamIdentifier ?? [],
125
+ teamName: parsed.TeamName ?? "",
126
+ creationDate: new Date(parsed.CreationDate ?? 0),
127
+ expirationDate: new Date(parsed.ExpirationDate ?? 0),
128
+ certificates: (parsed.DeveloperCertificates ?? []).map(
129
+ (c) => Buffer.from(c, "base64")
130
+ ),
131
+ provisionedDevices: parsed.ProvisionedDevices ?? [],
132
+ entitlements: parsed.Entitlements ?? {}
133
+ };
134
+ } finally {
135
+ await unlink(tempPath).catch(() => {
136
+ });
137
+ }
138
+ }
139
+ var execFileAsync3 = promisify(execFile);
140
+ var SimulatorManager = class {
141
+ async list() {
142
+ requireMacOS("simulator");
143
+ const { stdout } = await execFileAsync3("xcrun", ["simctl", "list", "devices", "-j"]);
144
+ const data = JSON.parse(stdout);
145
+ const simulators = [];
146
+ for (const [runtime, devices] of Object.entries(data.devices ?? {})) {
147
+ for (const device of devices) {
148
+ if (device.isAvailable) {
149
+ simulators.push({
150
+ udid: device.udid,
151
+ name: device.name,
152
+ deviceType: device.deviceTypeIdentifier ?? "",
153
+ runtime,
154
+ state: device.state === "Booted" ? "Booted" : "Shutdown"
155
+ });
156
+ }
157
+ }
158
+ }
159
+ return simulators;
160
+ }
161
+ async boot(udid) {
162
+ requireMacOS("simulator");
163
+ try {
164
+ await execFileAsync3("xcrun", ["simctl", "boot", udid]);
165
+ } catch (err) {
166
+ const msg = err instanceof Error ? err.message : "";
167
+ if (!msg.includes("current state: Booted")) throw err;
168
+ }
169
+ }
170
+ async shutdown(udid) {
171
+ requireMacOS("simulator");
172
+ try {
173
+ await execFileAsync3("xcrun", ["simctl", "shutdown", udid]);
174
+ } catch {
175
+ }
176
+ }
177
+ async reset(udid) {
178
+ requireMacOS("simulator");
179
+ await this.shutdown(udid);
180
+ await execFileAsync3("xcrun", ["simctl", "erase", udid]);
181
+ }
182
+ async install(udid, appPath) {
183
+ requireMacOS("simulator");
184
+ await execFileAsync3("xcrun", ["simctl", "install", udid, appPath]);
185
+ }
186
+ async findBestMatch(deviceName, runtime) {
187
+ const all = await this.list();
188
+ const matching = all.filter(
189
+ (s) => s.name.toLowerCase().includes(deviceName.toLowerCase()) && (!runtime || s.runtime.includes(runtime))
190
+ );
191
+ if (matching.length === 0) return null;
192
+ matching.sort((a, b) => b.runtime.localeCompare(a.runtime));
193
+ return matching[0];
194
+ }
195
+ };
196
+ var execFileAsync4 = promisify(execFile);
197
+ var CredentialManager = class {
198
+ serviceName;
199
+ constructor(serviceName = "fastnode") {
200
+ this.serviceName = serviceName;
201
+ }
202
+ async get(service, account) {
203
+ const envKey = `${service.toUpperCase()}_${account.toUpperCase()}`.replace(/[^A-Z0-9]/g, "_");
204
+ if (process.env[envKey]) return process.env[envKey];
205
+ if (process.platform === "darwin") {
206
+ try {
207
+ const { stdout } = await execFileAsync4("security", [
208
+ "find-generic-password",
209
+ "-s",
210
+ service,
211
+ "-a",
212
+ account,
213
+ "-w"
214
+ ]);
215
+ return stdout.trim();
216
+ } catch {
217
+ return null;
218
+ }
219
+ }
220
+ return null;
221
+ }
222
+ async set(service, account, password) {
223
+ if (process.platform === "darwin") {
224
+ await execFileAsync4("security", [
225
+ "add-generic-password",
226
+ "-U",
227
+ "-s",
228
+ service,
229
+ "-a",
230
+ account,
231
+ "-w",
232
+ password
233
+ ]);
234
+ }
235
+ }
236
+ async delete(service, account) {
237
+ if (process.platform === "darwin") {
238
+ try {
239
+ await execFileAsync4("security", [
240
+ "delete-generic-password",
241
+ "-s",
242
+ service,
243
+ "-a",
244
+ account
245
+ ]);
246
+ } catch {
247
+ }
248
+ }
249
+ }
250
+ };
251
+
252
+ export { CredentialManager, ItunesTransporter, SimulatorManager, analyzeIpa, parseProvisioningProfile, resolveConfig };
253
+ //# sourceMappingURL=index.mjs.map
254
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/core/config.ts","../../src/xcode/platform.ts","../../src/core/transporter.ts","../../src/core/ipa-analyzer.ts","../../src/core/provisioning-profile.ts","../../src/core/simulator.ts","../../src/core/credentials.ts"],"names":["execFileAsync","promisify","execFile","join","tmpdir","plist2"],"mappings":"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","file":"index.mjs","sourcesContent":["export interface FastnodeConfig {\n keyId?: string;\n issuerId?: string;\n privateKeyPath?: string;\n teamId?: string;\n bundleIdentifier?: string;\n platform?: string;\n}\n\nexport function resolveConfig(_overrides?: Partial<FastnodeConfig>): FastnodeConfig {\n return {\n keyId: process.env.APP_STORE_CONNECT_API_KEY_KEY_ID,\n issuerId: process.env.APP_STORE_CONNECT_API_KEY_ISSUER_ID,\n privateKeyPath: process.env.APP_STORE_CONNECT_API_KEY_KEY_FILEPATH,\n teamId: process.env.FASTLANE_TEAM_ID,\n bundleIdentifier: process.env.FASTLANE_APP_IDENTIFIER,\n platform: process.env.FASTLANE_PLATFORM_NAME,\n ..._overrides,\n };\n}\n","export function requireMacOS(feature: string): void {\n if (process.platform !== \"darwin\") {\n throw new Error(\n `${feature} requires macOS. This operation uses Xcode command-line tools ` +\n `which are not available on ${process.platform}.`\n );\n }\n}\n\nexport function isMacOS(): boolean {\n return process.platform === \"darwin\";\n}\n","import { spawn } from \"node:child_process\";\nimport { requireMacOS } from \"../xcode/platform.js\";\n\nexport class ItunesTransporter {\n async upload(options: {\n packagePath: string;\n apiKeyId?: string;\n apiIssuerId?: string;\n onOutput?: (chunk: string) => void;\n }): Promise<{ success: boolean; output: string }> {\n requireMacOS(\"iTunes Transporter\");\n\n const args = [\"altool\", \"--upload-app\", \"-f\", options.packagePath, \"-t\", \"ios\"];\n if (options.apiKeyId) args.push(\"--apiKey\", options.apiKeyId);\n if (options.apiIssuerId) args.push(\"--apiIssuer\", options.apiIssuerId);\n\n return this.run(args, options.onOutput);\n }\n\n async verify(options: {\n packagePath: string;\n apiKeyId?: string;\n apiIssuerId?: string;\n }): Promise<{ success: boolean; output: string }> {\n requireMacOS(\"iTunes Transporter\");\n\n const args = [\"altool\", \"--validate-app\", \"-f\", options.packagePath, \"-t\", \"ios\"];\n if (options.apiKeyId) args.push(\"--apiKey\", options.apiKeyId);\n if (options.apiIssuerId) args.push(\"--apiIssuer\", options.apiIssuerId);\n\n return this.run(args);\n }\n\n private run(args: string[], onOutput?: (chunk: string) => void): Promise<{ success: boolean; output: string }> {\n return new Promise((resolve) => {\n const child = spawn(\"xcrun\", args, { stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n let output = \"\";\n\n child.stdout.on(\"data\", (data: Buffer) => {\n const chunk = data.toString();\n output += chunk;\n onOutput?.(chunk);\n });\n child.stderr.on(\"data\", (data: Buffer) => {\n const chunk = data.toString();\n output += chunk;\n onOutput?.(chunk);\n });\n child.on(\"close\", (code) => resolve({ success: code === 0, output }));\n });\n }\n}\n","import { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { mkdtemp, readFile, rm } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { tmpdir } from \"node:os\";\nimport * as plist from \"plist\";\n\nconst execFileAsync = promisify(execFile);\n\nexport interface IpaInfo {\n bundleIdentifier: string;\n bundleVersion: string;\n bundleShortVersion: string;\n appName: string;\n minimumOSVersion: string;\n}\n\nexport async function analyzeIpa(ipaPath: string): Promise<IpaInfo> {\n const tmpDir = await mkdtemp(join(tmpdir(), \"fastnode-ipa-\"));\n\n try {\n // Unzip every Info.plist under Payload/. Modern IPAs ship the main app\n // alongside WatchKit apps, app extensions, intents, widgets, and more —\n // we need enough to identify the main one and skip the rest.\n await execFileAsync(\"unzip\", [\"-o\", ipaPath, \"Payload/**/Info.plist\", \"-d\", tmpDir]);\n\n const { stdout } = await execFileAsync(\"find\", [\n tmpDir,\n \"-name\",\n \"Info.plist\",\n \"-path\",\n \"*/Payload/*\",\n ]);\n const allPlistPaths = stdout\n .trim()\n .split(\"\\n\")\n .filter((p) => p.length > 0);\n if (allPlistPaths.length === 0) {\n throw new Error(\"Info.plist not found in IPA\");\n }\n\n // Pick the main app's Info.plist. Fastlane's approach is to prefer the\n // plist with the shortest path (main app lives at the top of Payload/,\n // extensions/watch apps live nested underneath). We also skip any plist\n // whose `WKWatchKitApp=true` to positively exclude WatchKit embeds.\n const candidates = [...allPlistPaths].sort(\n (a, b) => a.length - b.length\n );\n\n let plistPath: string | null = null;\n let parsed: Record<string, any> | null = null;\n\n for (const candidate of candidates) {\n try {\n await execFileAsync(\"plutil\", [\"-convert\", \"xml1\", candidate]);\n } catch {\n // May already be XML\n }\n const content = await readFile(candidate, \"utf-8\");\n const data = plist.parse(content) as Record<string, any>;\n if (data.WKWatchKitApp === true) continue; // skip WatchKit embed\n plistPath = candidate;\n parsed = data;\n break;\n }\n\n if (!parsed) {\n // Every candidate was a WatchKit embed — fall back to the shortest path.\n plistPath = candidates[0];\n const content = await readFile(plistPath, \"utf-8\");\n parsed = plist.parse(content) as Record<string, any>;\n }\n\n return {\n bundleIdentifier: parsed.CFBundleIdentifier ?? \"\",\n bundleVersion: String(parsed.CFBundleVersion ?? \"\"),\n bundleShortVersion: parsed.CFBundleShortVersionString ?? \"\",\n appName: parsed.CFBundleName ?? parsed.CFBundleDisplayName ?? \"\",\n minimumOSVersion: parsed.MinimumOSVersion ?? \"\",\n };\n } finally {\n await rm(tmpDir, { recursive: true, force: true });\n }\n}\n","import { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { writeFile, unlink } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { tmpdir } from \"node:os\";\nimport * as plist from \"plist\";\n\nconst execFileAsync = promisify(execFile);\n\nexport interface ProvisioningProfileInfo {\n uuid: string;\n name: string;\n appIdName: string;\n teamIdentifier: string[];\n teamName: string;\n creationDate: Date;\n expirationDate: Date;\n certificates: Buffer[];\n provisionedDevices: string[];\n entitlements: Record<string, unknown>;\n}\n\nexport async function parseProvisioningProfile(\n data: Buffer\n): Promise<ProvisioningProfileInfo> {\n // Write to temp file\n const tempPath = join(tmpdir(), `fastnode-profile-${Date.now()}.mobileprovision`);\n await writeFile(tempPath, data);\n\n try {\n // Extract the plist from the CMS/PKCS#7 envelope\n const { stdout } = await execFileAsync(\"security\", [\"cms\", \"-D\", \"-i\", tempPath]);\n\n const parsed = plist.parse(stdout) as Record<string, any>;\n\n return {\n uuid: parsed.UUID ?? \"\",\n name: parsed.Name ?? \"\",\n appIdName: parsed.AppIDName ?? \"\",\n teamIdentifier: parsed.TeamIdentifier ?? [],\n teamName: parsed.TeamName ?? \"\",\n creationDate: new Date(parsed.CreationDate ?? 0),\n expirationDate: new Date(parsed.ExpirationDate ?? 0),\n certificates: (parsed.DeveloperCertificates ?? []).map((c: any) =>\n Buffer.from(c, \"base64\")\n ),\n provisionedDevices: parsed.ProvisionedDevices ?? [],\n entitlements: parsed.Entitlements ?? {},\n };\n } finally {\n await unlink(tempPath).catch(() => {});\n }\n}\n","import { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport { requireMacOS } from \"../xcode/platform.js\";\n\nconst execFileAsync = promisify(execFile);\n\nexport interface Simulator {\n udid: string;\n name: string;\n deviceType: string;\n runtime: string;\n state: \"Booted\" | \"Shutdown\";\n}\n\nexport class SimulatorManager {\n async list(): Promise<Simulator[]> {\n requireMacOS(\"simulator\");\n const { stdout } = await execFileAsync(\"xcrun\", [\"simctl\", \"list\", \"devices\", \"-j\"]);\n const data = JSON.parse(stdout);\n const simulators: Simulator[] = [];\n\n for (const [runtime, devices] of Object.entries(data.devices ?? {})) {\n for (const device of devices as any[]) {\n if (device.isAvailable) {\n simulators.push({\n udid: device.udid,\n name: device.name,\n deviceType: device.deviceTypeIdentifier ?? \"\",\n runtime,\n state: device.state === \"Booted\" ? \"Booted\" : \"Shutdown\",\n });\n }\n }\n }\n\n return simulators;\n }\n\n async boot(udid: string): Promise<void> {\n requireMacOS(\"simulator\");\n try {\n await execFileAsync(\"xcrun\", [\"simctl\", \"boot\", udid]);\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : \"\";\n if (!msg.includes(\"current state: Booted\")) throw err;\n }\n }\n\n async shutdown(udid: string): Promise<void> {\n requireMacOS(\"simulator\");\n try {\n await execFileAsync(\"xcrun\", [\"simctl\", \"shutdown\", udid]);\n } catch {\n // May already be shut down\n }\n }\n\n async reset(udid: string): Promise<void> {\n requireMacOS(\"simulator\");\n await this.shutdown(udid);\n await execFileAsync(\"xcrun\", [\"simctl\", \"erase\", udid]);\n }\n\n async install(udid: string, appPath: string): Promise<void> {\n requireMacOS(\"simulator\");\n await execFileAsync(\"xcrun\", [\"simctl\", \"install\", udid, appPath]);\n }\n\n async findBestMatch(deviceName: string, runtime?: string): Promise<Simulator | null> {\n const all = await this.list();\n const matching = all.filter((s) =>\n s.name.toLowerCase().includes(deviceName.toLowerCase()) &&\n (!runtime || s.runtime.includes(runtime))\n );\n\n if (matching.length === 0) return null;\n // Prefer latest runtime\n matching.sort((a, b) => b.runtime.localeCompare(a.runtime));\n return matching[0];\n }\n}\n","import { execFile } from \"node:child_process\";\nimport { promisify } from \"node:util\";\n\nconst execFileAsync = promisify(execFile);\n\nexport class CredentialManager {\n private serviceName: string;\n\n constructor(serviceName = \"fastnode\") {\n this.serviceName = serviceName;\n }\n\n async get(service: string, account: string): Promise<string | null> {\n // Check env vars first\n const envKey = `${service.toUpperCase()}_${account.toUpperCase()}`.replace(/[^A-Z0-9]/g, \"_\");\n if (process.env[envKey]) return process.env[envKey]!;\n\n // Try macOS keychain\n if (process.platform === \"darwin\") {\n try {\n const { stdout } = await execFileAsync(\"security\", [\n \"find-generic-password\",\n \"-s\", service,\n \"-a\", account,\n \"-w\",\n ]);\n return stdout.trim();\n } catch {\n return null;\n }\n }\n\n return null;\n }\n\n async set(service: string, account: string, password: string): Promise<void> {\n if (process.platform === \"darwin\") {\n await execFileAsync(\"security\", [\n \"add-generic-password\",\n \"-U\",\n \"-s\", service,\n \"-a\", account,\n \"-w\", password,\n ]);\n }\n }\n\n async delete(service: string, account: string): Promise<void> {\n if (process.platform === \"darwin\") {\n try {\n await execFileAsync(\"security\", [\n \"delete-generic-password\",\n \"-s\", service,\n \"-a\", account,\n ]);\n } catch {\n // May not exist\n }\n }\n }\n}\n"]}