@sitepong/fastnode 0.1.0 → 0.1.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/actions/index.cjs +227 -27
- package/dist/actions/index.cjs.map +1 -1
- package/dist/actions/index.mjs +227 -27
- package/dist/actions/index.mjs.map +1 -1
- package/dist/cli/index.cjs +227 -27
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.mjs +227 -27
- package/dist/cli/index.mjs.map +1 -1
- package/dist/index-D6zjGlPL.d.cts +158 -0
- package/dist/index-DHw08dUc.d.ts +158 -0
- package/dist/index.cjs +228 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +228 -28
- package/dist/index.mjs.map +1 -1
- package/dist/lane/index.cjs +227 -27
- package/dist/lane/index.cjs.map +1 -1
- package/dist/lane/index.mjs +227 -27
- package/dist/lane/index.mjs.map +1 -1
- package/dist/pilot/index.cjs +190 -12
- package/dist/pilot/index.cjs.map +1 -1
- package/dist/pilot/index.d.cts +1 -1
- package/dist/pilot/index.d.ts +1 -1
- package/dist/pilot/index.mjs +186 -14
- package/dist/pilot/index.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/index-DkvinY7_.d.ts +0 -54
- package/dist/index-HRiaaX-Q.d.cts +0 -54
package/dist/lane/index.mjs
CHANGED
|
@@ -153,8 +153,8 @@ async function revokeExpiredCertificates(options) {
|
|
|
153
153
|
return count;
|
|
154
154
|
}
|
|
155
155
|
async function importToKeychain(certData, keychainPath, keychainPassword) {
|
|
156
|
-
const { tmpdir:
|
|
157
|
-
const tempCertPath = join(
|
|
156
|
+
const { tmpdir: tmpdir8 } = await import('os');
|
|
157
|
+
const tempCertPath = join(tmpdir8(), `fastnode-cert-${Date.now()}.cer`);
|
|
158
158
|
await writeFile(tempCertPath, certData);
|
|
159
159
|
try {
|
|
160
160
|
const args = [
|
|
@@ -1586,14 +1586,14 @@ var init_building = __esm({
|
|
|
1586
1586
|
name: "clean_build_artifacts",
|
|
1587
1587
|
description: "Remove build artifacts (IPA, dSYM, etc.)",
|
|
1588
1588
|
async run(params, ctx) {
|
|
1589
|
-
const { rm:
|
|
1589
|
+
const { rm: rm4 } = await import('fs/promises');
|
|
1590
1590
|
const paths = [
|
|
1591
1591
|
ctx.get("IPA_OUTPUT_PATH"),
|
|
1592
1592
|
ctx.get("PKG_OUTPUT_PATH"),
|
|
1593
1593
|
ctx.get("DSYM_OUTPUT_PATH")
|
|
1594
1594
|
].filter(Boolean);
|
|
1595
1595
|
for (const p of paths) {
|
|
1596
|
-
await
|
|
1596
|
+
await rm4(p, { force: true }).catch(() => {
|
|
1597
1597
|
});
|
|
1598
1598
|
}
|
|
1599
1599
|
return { cleaned: paths };
|
|
@@ -2240,23 +2240,13 @@ var init_request = __esm({
|
|
|
2240
2240
|
};
|
|
2241
2241
|
}
|
|
2242
2242
|
});
|
|
2243
|
-
|
|
2244
|
-
// src/pilot/index.ts
|
|
2245
|
-
var pilot_exports = {};
|
|
2246
|
-
__export(pilot_exports, {
|
|
2247
|
-
distributeToGroups: () => distributeToGroups,
|
|
2248
|
-
expireBuild: () => expireBuild,
|
|
2249
|
-
setChangelog: () => setChangelog,
|
|
2250
|
-
uploadToTestFlight: () => uploadToTestFlight,
|
|
2251
|
-
waitForProcessing: () => waitForProcessing
|
|
2252
|
-
});
|
|
2253
|
-
async function uploadToTestFlight(options) {
|
|
2243
|
+
async function uploadWithAltool(options) {
|
|
2254
2244
|
if (!existsSync(options.ipaPath)) {
|
|
2255
2245
|
throw new Error(`File not found: ${options.ipaPath}`);
|
|
2256
2246
|
}
|
|
2257
2247
|
const platform = options.platform ?? "ios";
|
|
2258
2248
|
const timeout = options.timeout ?? 18e5;
|
|
2259
|
-
const keyDir = await mkdtemp(join(tmpdir(), "fastnode-
|
|
2249
|
+
const keyDir = await mkdtemp(join(tmpdir(), "fastnode-altool-"));
|
|
2260
2250
|
const keyPath = join(keyDir, `AuthKey_${options.apiKeyId}.p8`);
|
|
2261
2251
|
await writeFile(keyPath, options.apiPrivateKey);
|
|
2262
2252
|
return new Promise((resolve4) => {
|
|
@@ -2280,24 +2270,228 @@ async function uploadToTestFlight(options) {
|
|
|
2280
2270
|
const timer = setTimeout(() => {
|
|
2281
2271
|
child.kill("SIGTERM");
|
|
2282
2272
|
}, timeout);
|
|
2283
|
-
|
|
2273
|
+
const onData = (data) => {
|
|
2284
2274
|
const chunk = data.toString();
|
|
2285
2275
|
output += chunk;
|
|
2286
2276
|
options.onOutput?.(chunk);
|
|
2277
|
+
};
|
|
2278
|
+
child.stdout.on("data", onData);
|
|
2279
|
+
child.stderr.on("data", onData);
|
|
2280
|
+
child.on("close", async (code) => {
|
|
2281
|
+
clearTimeout(timer);
|
|
2282
|
+
await unlink(keyPath).catch(() => {
|
|
2283
|
+
});
|
|
2284
|
+
await rm(keyDir, { recursive: true, force: true }).catch(() => {
|
|
2285
|
+
});
|
|
2286
|
+
resolve4({ success: code === 0, output, backend: "altool" });
|
|
2287
2287
|
});
|
|
2288
|
-
|
|
2288
|
+
});
|
|
2289
|
+
}
|
|
2290
|
+
var init_upload_altool = __esm({
|
|
2291
|
+
"src/pilot/upload-altool.ts"() {
|
|
2292
|
+
}
|
|
2293
|
+
});
|
|
2294
|
+
async function resolveTransporter() {
|
|
2295
|
+
const override = process.env.ITMSTRANSPORTER_BIN;
|
|
2296
|
+
if (override) {
|
|
2297
|
+
if (!existsSync(override)) {
|
|
2298
|
+
throw new Error(
|
|
2299
|
+
`ITMSTRANSPORTER_BIN is set to "${override}" but that path does not exist.`
|
|
2300
|
+
);
|
|
2301
|
+
}
|
|
2302
|
+
return override;
|
|
2303
|
+
}
|
|
2304
|
+
const candidates = process.platform === "darwin" ? [
|
|
2305
|
+
// Xcode 15+: Transporter.app bundled with Xcode
|
|
2306
|
+
"/Applications/Xcode.app/Contents/SharedFrameworks/ContentDeliveryServices.framework/Versions/A/itms/bin/iTMSTransporter",
|
|
2307
|
+
// Standalone Transporter.app from the Mac App Store
|
|
2308
|
+
"/Applications/Transporter.app/Contents/itms/bin/iTMSTransporter"
|
|
2309
|
+
] : [
|
|
2310
|
+
"/usr/local/itms/bin/iTMSTransporter",
|
|
2311
|
+
"/opt/itms/bin/iTMSTransporter",
|
|
2312
|
+
"/usr/local/bin/iTMSTransporter"
|
|
2313
|
+
];
|
|
2314
|
+
for (const path of candidates) {
|
|
2315
|
+
if (existsSync(path)) return path;
|
|
2316
|
+
}
|
|
2317
|
+
throw new Error(
|
|
2318
|
+
[
|
|
2319
|
+
"iTMSTransporter not found.",
|
|
2320
|
+
"",
|
|
2321
|
+
"Install options:",
|
|
2322
|
+
process.platform === "darwin" ? " - Install Xcode (includes Transporter)" : " - Download Apple's standalone iTMSTransporter package for Linux",
|
|
2323
|
+
" - Or set ITMSTRANSPORTER_BIN to the absolute path of the binary",
|
|
2324
|
+
"",
|
|
2325
|
+
`Searched: ${candidates.join(", ")}`
|
|
2326
|
+
].join("\n")
|
|
2327
|
+
);
|
|
2328
|
+
}
|
|
2329
|
+
async function verifyJava() {
|
|
2330
|
+
return new Promise((resolve4, reject) => {
|
|
2331
|
+
const child = spawn("java", ["-version"], { stdio: ["ignore", "pipe", "pipe"] });
|
|
2332
|
+
let stderr = "";
|
|
2333
|
+
child.stderr.on("data", (d) => {
|
|
2334
|
+
stderr += d.toString();
|
|
2335
|
+
});
|
|
2336
|
+
child.on("error", (err) => {
|
|
2337
|
+
reject(
|
|
2338
|
+
new Error(
|
|
2339
|
+
`java not found on PATH (${err.message}). Install Java 17 LTS and ensure it is on PATH.`
|
|
2340
|
+
)
|
|
2341
|
+
);
|
|
2342
|
+
});
|
|
2343
|
+
child.on("close", (code) => {
|
|
2344
|
+
if (code !== 0) {
|
|
2345
|
+
reject(new Error(`java -version exited ${code}: ${stderr}`));
|
|
2346
|
+
return;
|
|
2347
|
+
}
|
|
2348
|
+
const match = stderr.match(/version "([^"]+)"/);
|
|
2349
|
+
resolve4({ version: match?.[1] ?? "unknown" });
|
|
2350
|
+
});
|
|
2351
|
+
});
|
|
2352
|
+
}
|
|
2353
|
+
var init_transporter_install = __esm({
|
|
2354
|
+
"src/pilot/transporter-install.ts"() {
|
|
2355
|
+
}
|
|
2356
|
+
});
|
|
2357
|
+
async function uploadWithTransporter(options) {
|
|
2358
|
+
if (!existsSync(options.ipaPath)) {
|
|
2359
|
+
throw new Error(`File not found: ${options.ipaPath}`);
|
|
2360
|
+
}
|
|
2361
|
+
await verifyJava();
|
|
2362
|
+
const transporterBin = await resolveTransporter();
|
|
2363
|
+
const platform = options.platform ?? "ios";
|
|
2364
|
+
const timeout = options.timeout ?? 18e5;
|
|
2365
|
+
const keyDir = await mkdtemp(join(tmpdir(), "fastnode-itms-"));
|
|
2366
|
+
const keyPath = join(keyDir, `AuthKey_${options.apiKeyId}.p8`);
|
|
2367
|
+
await writeFile(keyPath, options.apiPrivateKey);
|
|
2368
|
+
return new Promise((resolve4) => {
|
|
2369
|
+
const args = [
|
|
2370
|
+
"-m",
|
|
2371
|
+
"upload",
|
|
2372
|
+
"-assetFile",
|
|
2373
|
+
options.ipaPath,
|
|
2374
|
+
"-apiKey",
|
|
2375
|
+
options.apiKeyId,
|
|
2376
|
+
"-apiIssuer",
|
|
2377
|
+
options.apiIssuerId,
|
|
2378
|
+
// WONoPause prevents the JVM from waiting on stdin in non-TTY
|
|
2379
|
+
// environments (CI, LaunchAgent) where it would hang forever.
|
|
2380
|
+
"-WONoPause",
|
|
2381
|
+
"true"
|
|
2382
|
+
];
|
|
2383
|
+
if (platform !== "ios") {
|
|
2384
|
+
args.push("-bundleType", platform);
|
|
2385
|
+
}
|
|
2386
|
+
const child = spawn(transporterBin, args, {
|
|
2387
|
+
env: {
|
|
2388
|
+
...process.env,
|
|
2389
|
+
API_PRIVATE_KEYS_DIR: keyDir
|
|
2390
|
+
},
|
|
2391
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
2392
|
+
});
|
|
2393
|
+
let output = "";
|
|
2394
|
+
const timer = setTimeout(() => {
|
|
2395
|
+
child.kill("SIGTERM");
|
|
2396
|
+
}, timeout);
|
|
2397
|
+
const onData = (data) => {
|
|
2289
2398
|
const chunk = data.toString();
|
|
2290
2399
|
output += chunk;
|
|
2291
2400
|
options.onOutput?.(chunk);
|
|
2292
|
-
}
|
|
2401
|
+
};
|
|
2402
|
+
child.stdout.on("data", onData);
|
|
2403
|
+
child.stderr.on("data", onData);
|
|
2293
2404
|
child.on("close", async (code) => {
|
|
2294
2405
|
clearTimeout(timer);
|
|
2295
|
-
await
|
|
2406
|
+
await rm(keyDir, { recursive: true, force: true }).catch(() => {
|
|
2407
|
+
});
|
|
2408
|
+
resolve4({ success: code === 0, output, backend: "transporter" });
|
|
2409
|
+
});
|
|
2410
|
+
child.on("error", async (err) => {
|
|
2411
|
+
clearTimeout(timer);
|
|
2412
|
+
await rm(keyDir, { recursive: true, force: true }).catch(() => {
|
|
2413
|
+
});
|
|
2414
|
+
resolve4({
|
|
2415
|
+
success: false,
|
|
2416
|
+
output: output + `
|
|
2417
|
+
Process error: ${err.message}`,
|
|
2418
|
+
backend: "transporter"
|
|
2296
2419
|
});
|
|
2297
|
-
resolve4({ success: code === 0, output });
|
|
2298
2420
|
});
|
|
2299
2421
|
});
|
|
2300
2422
|
}
|
|
2423
|
+
var init_upload_transporter = __esm({
|
|
2424
|
+
"src/pilot/upload-transporter.ts"() {
|
|
2425
|
+
init_transporter_install();
|
|
2426
|
+
}
|
|
2427
|
+
});
|
|
2428
|
+
|
|
2429
|
+
// src/pilot/classify.ts
|
|
2430
|
+
function classifyUploadError(output) {
|
|
2431
|
+
for (const { pattern, kind } of RULES) {
|
|
2432
|
+
if (pattern.test(output)) return kind;
|
|
2433
|
+
}
|
|
2434
|
+
return null;
|
|
2435
|
+
}
|
|
2436
|
+
function isTransientUploadError(output) {
|
|
2437
|
+
return classifyUploadError(output) !== null;
|
|
2438
|
+
}
|
|
2439
|
+
var RULES;
|
|
2440
|
+
var init_classify = __esm({
|
|
2441
|
+
"src/pilot/classify.ts"() {
|
|
2442
|
+
RULES = [
|
|
2443
|
+
// Apple's finalize-upload call returning 5xx — the most common transient
|
|
2444
|
+
// failure we see in practice. Example:
|
|
2445
|
+
// "CHANGE UPLOAD STATE TO COMPLETE (UPLOADING ASSET DESCRIPTION):
|
|
2446
|
+
// received status code 500; internal server error."
|
|
2447
|
+
{ pattern: /CHANGE UPLOAD STATE TO COMPLETE/i, kind: "finalize_failed" },
|
|
2448
|
+
// Generic 5xx from ASC backend services
|
|
2449
|
+
{ pattern: /status code 5\d\d/i, kind: "apple_5xx" },
|
|
2450
|
+
{ pattern: /internal server error/i, kind: "apple_5xx" },
|
|
2451
|
+
{ pattern: /Service Unavailable/i, kind: "apple_5xx" },
|
|
2452
|
+
{ pattern: /Bad Gateway/i, kind: "apple_5xx" },
|
|
2453
|
+
// Network-level interruptions during the upload body transfer
|
|
2454
|
+
{ pattern: /Connection reset/i, kind: "connection_reset" },
|
|
2455
|
+
{ pattern: /SocketException/i, kind: "connection_reset" },
|
|
2456
|
+
{ pattern: /Broken pipe/i, kind: "connection_reset" },
|
|
2457
|
+
// Timeouts — distinct from resets because the other side may have
|
|
2458
|
+
// actually processed the request, so dedupe logic may matter.
|
|
2459
|
+
{ pattern: /Read timed out/i, kind: "network_timeout" },
|
|
2460
|
+
{ pattern: /SocketTimeoutException/i, kind: "network_timeout" },
|
|
2461
|
+
{ pattern: /Operation timed out/i, kind: "network_timeout" },
|
|
2462
|
+
// JVM-internal errors from iTMSTransporter (OOM, thread interruption, etc.)
|
|
2463
|
+
{ pattern: /java\.lang\.OutOfMemoryError/i, kind: "transporter_jvm_error" },
|
|
2464
|
+
{ pattern: /EOFException/i, kind: "transporter_jvm_error" }
|
|
2465
|
+
];
|
|
2466
|
+
}
|
|
2467
|
+
});
|
|
2468
|
+
|
|
2469
|
+
// src/pilot/index.ts
|
|
2470
|
+
var pilot_exports = {};
|
|
2471
|
+
__export(pilot_exports, {
|
|
2472
|
+
classifyUploadError: () => classifyUploadError,
|
|
2473
|
+
distributeToGroups: () => distributeToGroups,
|
|
2474
|
+
expireBuild: () => expireBuild,
|
|
2475
|
+
isTransientUploadError: () => isTransientUploadError,
|
|
2476
|
+
resolveTransporter: () => resolveTransporter,
|
|
2477
|
+
setChangelog: () => setChangelog,
|
|
2478
|
+
uploadToTestFlight: () => uploadToTestFlight,
|
|
2479
|
+
uploadWithAltool: () => uploadWithAltool,
|
|
2480
|
+
uploadWithTransporter: () => uploadWithTransporter,
|
|
2481
|
+
verifyJava: () => verifyJava,
|
|
2482
|
+
waitForProcessing: () => waitForProcessing
|
|
2483
|
+
});
|
|
2484
|
+
async function uploadToTestFlight(options) {
|
|
2485
|
+
const backend = selectBackend(options.backend ?? "auto");
|
|
2486
|
+
if (backend === "altool") {
|
|
2487
|
+
return uploadWithAltool(options);
|
|
2488
|
+
}
|
|
2489
|
+
return uploadWithTransporter(options);
|
|
2490
|
+
}
|
|
2491
|
+
function selectBackend(pref) {
|
|
2492
|
+
if (pref !== "auto") return pref;
|
|
2493
|
+
return process.platform === "darwin" ? "altool" : "transporter";
|
|
2494
|
+
}
|
|
2301
2495
|
async function waitForProcessing(client, params) {
|
|
2302
2496
|
const timeout = params.timeout ?? 18e5;
|
|
2303
2497
|
const pollInterval = params.pollInterval ?? 3e4;
|
|
@@ -2418,6 +2612,12 @@ function sleep2(ms) {
|
|
|
2418
2612
|
var init_pilot = __esm({
|
|
2419
2613
|
"src/pilot/index.ts"() {
|
|
2420
2614
|
init_request();
|
|
2615
|
+
init_upload_altool();
|
|
2616
|
+
init_upload_transporter();
|
|
2617
|
+
init_upload_altool();
|
|
2618
|
+
init_upload_transporter();
|
|
2619
|
+
init_classify();
|
|
2620
|
+
init_transporter_install();
|
|
2421
2621
|
}
|
|
2422
2622
|
});
|
|
2423
2623
|
async function loadMetadata(metadataPath) {
|
|
@@ -2505,9 +2705,9 @@ var init_metadata = __esm({
|
|
|
2505
2705
|
// src/xcode/upload.ts
|
|
2506
2706
|
var upload_exports = {};
|
|
2507
2707
|
__export(upload_exports, {
|
|
2508
|
-
uploadWithAltool: () =>
|
|
2708
|
+
uploadWithAltool: () => uploadWithAltool2
|
|
2509
2709
|
});
|
|
2510
|
-
async function
|
|
2710
|
+
async function uploadWithAltool2(options) {
|
|
2511
2711
|
requireMacOS("altool upload");
|
|
2512
2712
|
let keyDir;
|
|
2513
2713
|
if (options.apiPrivateKey && !options.apiKeyPath) {
|
|
@@ -2616,8 +2816,8 @@ async function uploadToAppStore(options) {
|
|
|
2616
2816
|
if (!options.skipBinaryUpload) {
|
|
2617
2817
|
const binaryPath = options.ipaPath ?? options.pkgPath;
|
|
2618
2818
|
if (binaryPath && options.apiKeyId && options.apiIssuerId) {
|
|
2619
|
-
const { uploadWithAltool:
|
|
2620
|
-
await
|
|
2819
|
+
const { uploadWithAltool: uploadWithAltool3 } = await Promise.resolve().then(() => (init_upload(), upload_exports));
|
|
2820
|
+
await uploadWithAltool3({
|
|
2621
2821
|
filePath: binaryPath,
|
|
2622
2822
|
apiKeyId: options.apiKeyId,
|
|
2623
2823
|
apiIssuerId: options.apiIssuerId,
|
|
@@ -3403,8 +3603,8 @@ async function captureScreenshots(options) {
|
|
|
3403
3603
|
const outputDir = options.outputDirectory ?? join(process.cwd(), "screenshots");
|
|
3404
3604
|
const retries = options.numberOfRetries ?? 1;
|
|
3405
3605
|
if (options.clearPreviousScreenshots && existsSync(outputDir)) {
|
|
3406
|
-
const { rm:
|
|
3407
|
-
await
|
|
3606
|
+
const { rm: rm4 } = await import('fs/promises');
|
|
3607
|
+
await rm4(outputDir, { recursive: true, force: true });
|
|
3408
3608
|
}
|
|
3409
3609
|
mkdirSync(outputDir, { recursive: true });
|
|
3410
3610
|
const screenshots = {};
|