@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/cli/index.cjs
CHANGED
|
@@ -209,8 +209,8 @@ async function revokeExpiredCertificates(options) {
|
|
|
209
209
|
return count;
|
|
210
210
|
}
|
|
211
211
|
async function importToKeychain(certData, keychainPath, keychainPassword) {
|
|
212
|
-
const { tmpdir:
|
|
213
|
-
const tempCertPath = path.join(
|
|
212
|
+
const { tmpdir: tmpdir8 } = await import('os');
|
|
213
|
+
const tempCertPath = path.join(tmpdir8(), `fastnode-cert-${Date.now()}.cer`);
|
|
214
214
|
await promises.writeFile(tempCertPath, certData);
|
|
215
215
|
try {
|
|
216
216
|
const args = [
|
|
@@ -1642,14 +1642,14 @@ var init_building = __esm({
|
|
|
1642
1642
|
name: "clean_build_artifacts",
|
|
1643
1643
|
description: "Remove build artifacts (IPA, dSYM, etc.)",
|
|
1644
1644
|
async run(params, ctx) {
|
|
1645
|
-
const { rm:
|
|
1645
|
+
const { rm: rm4 } = await import('fs/promises');
|
|
1646
1646
|
const paths = [
|
|
1647
1647
|
ctx.get("IPA_OUTPUT_PATH"),
|
|
1648
1648
|
ctx.get("PKG_OUTPUT_PATH"),
|
|
1649
1649
|
ctx.get("DSYM_OUTPUT_PATH")
|
|
1650
1650
|
].filter(Boolean);
|
|
1651
1651
|
for (const p of paths) {
|
|
1652
|
-
await
|
|
1652
|
+
await rm4(p, { force: true }).catch(() => {
|
|
1653
1653
|
});
|
|
1654
1654
|
}
|
|
1655
1655
|
return { cleaned: paths };
|
|
@@ -2296,23 +2296,13 @@ var init_request = __esm({
|
|
|
2296
2296
|
};
|
|
2297
2297
|
}
|
|
2298
2298
|
});
|
|
2299
|
-
|
|
2300
|
-
// src/pilot/index.ts
|
|
2301
|
-
var pilot_exports = {};
|
|
2302
|
-
__export(pilot_exports, {
|
|
2303
|
-
distributeToGroups: () => distributeToGroups,
|
|
2304
|
-
expireBuild: () => expireBuild,
|
|
2305
|
-
setChangelog: () => setChangelog,
|
|
2306
|
-
uploadToTestFlight: () => uploadToTestFlight,
|
|
2307
|
-
waitForProcessing: () => waitForProcessing
|
|
2308
|
-
});
|
|
2309
|
-
async function uploadToTestFlight(options) {
|
|
2299
|
+
async function uploadWithAltool(options) {
|
|
2310
2300
|
if (!fs.existsSync(options.ipaPath)) {
|
|
2311
2301
|
throw new Error(`File not found: ${options.ipaPath}`);
|
|
2312
2302
|
}
|
|
2313
2303
|
const platform = options.platform ?? "ios";
|
|
2314
2304
|
const timeout = options.timeout ?? 18e5;
|
|
2315
|
-
const keyDir = await promises.mkdtemp(path.join(os.tmpdir(), "fastnode-
|
|
2305
|
+
const keyDir = await promises.mkdtemp(path.join(os.tmpdir(), "fastnode-altool-"));
|
|
2316
2306
|
const keyPath = path.join(keyDir, `AuthKey_${options.apiKeyId}.p8`);
|
|
2317
2307
|
await promises.writeFile(keyPath, options.apiPrivateKey);
|
|
2318
2308
|
return new Promise((resolve4) => {
|
|
@@ -2336,24 +2326,228 @@ async function uploadToTestFlight(options) {
|
|
|
2336
2326
|
const timer = setTimeout(() => {
|
|
2337
2327
|
child.kill("SIGTERM");
|
|
2338
2328
|
}, timeout);
|
|
2339
|
-
|
|
2329
|
+
const onData = (data) => {
|
|
2340
2330
|
const chunk = data.toString();
|
|
2341
2331
|
output += chunk;
|
|
2342
2332
|
options.onOutput?.(chunk);
|
|
2333
|
+
};
|
|
2334
|
+
child.stdout.on("data", onData);
|
|
2335
|
+
child.stderr.on("data", onData);
|
|
2336
|
+
child.on("close", async (code) => {
|
|
2337
|
+
clearTimeout(timer);
|
|
2338
|
+
await promises.unlink(keyPath).catch(() => {
|
|
2339
|
+
});
|
|
2340
|
+
await promises.rm(keyDir, { recursive: true, force: true }).catch(() => {
|
|
2341
|
+
});
|
|
2342
|
+
resolve4({ success: code === 0, output, backend: "altool" });
|
|
2343
2343
|
});
|
|
2344
|
-
|
|
2344
|
+
});
|
|
2345
|
+
}
|
|
2346
|
+
var init_upload_altool = __esm({
|
|
2347
|
+
"src/pilot/upload-altool.ts"() {
|
|
2348
|
+
}
|
|
2349
|
+
});
|
|
2350
|
+
async function resolveTransporter() {
|
|
2351
|
+
const override = process.env.ITMSTRANSPORTER_BIN;
|
|
2352
|
+
if (override) {
|
|
2353
|
+
if (!fs.existsSync(override)) {
|
|
2354
|
+
throw new Error(
|
|
2355
|
+
`ITMSTRANSPORTER_BIN is set to "${override}" but that path does not exist.`
|
|
2356
|
+
);
|
|
2357
|
+
}
|
|
2358
|
+
return override;
|
|
2359
|
+
}
|
|
2360
|
+
const candidates = process.platform === "darwin" ? [
|
|
2361
|
+
// Xcode 15+: Transporter.app bundled with Xcode
|
|
2362
|
+
"/Applications/Xcode.app/Contents/SharedFrameworks/ContentDeliveryServices.framework/Versions/A/itms/bin/iTMSTransporter",
|
|
2363
|
+
// Standalone Transporter.app from the Mac App Store
|
|
2364
|
+
"/Applications/Transporter.app/Contents/itms/bin/iTMSTransporter"
|
|
2365
|
+
] : [
|
|
2366
|
+
"/usr/local/itms/bin/iTMSTransporter",
|
|
2367
|
+
"/opt/itms/bin/iTMSTransporter",
|
|
2368
|
+
"/usr/local/bin/iTMSTransporter"
|
|
2369
|
+
];
|
|
2370
|
+
for (const path of candidates) {
|
|
2371
|
+
if (fs.existsSync(path)) return path;
|
|
2372
|
+
}
|
|
2373
|
+
throw new Error(
|
|
2374
|
+
[
|
|
2375
|
+
"iTMSTransporter not found.",
|
|
2376
|
+
"",
|
|
2377
|
+
"Install options:",
|
|
2378
|
+
process.platform === "darwin" ? " - Install Xcode (includes Transporter)" : " - Download Apple's standalone iTMSTransporter package for Linux",
|
|
2379
|
+
" - Or set ITMSTRANSPORTER_BIN to the absolute path of the binary",
|
|
2380
|
+
"",
|
|
2381
|
+
`Searched: ${candidates.join(", ")}`
|
|
2382
|
+
].join("\n")
|
|
2383
|
+
);
|
|
2384
|
+
}
|
|
2385
|
+
async function verifyJava() {
|
|
2386
|
+
return new Promise((resolve4, reject) => {
|
|
2387
|
+
const child = child_process.spawn("java", ["-version"], { stdio: ["ignore", "pipe", "pipe"] });
|
|
2388
|
+
let stderr = "";
|
|
2389
|
+
child.stderr.on("data", (d) => {
|
|
2390
|
+
stderr += d.toString();
|
|
2391
|
+
});
|
|
2392
|
+
child.on("error", (err) => {
|
|
2393
|
+
reject(
|
|
2394
|
+
new Error(
|
|
2395
|
+
`java not found on PATH (${err.message}). Install Java 17 LTS and ensure it is on PATH.`
|
|
2396
|
+
)
|
|
2397
|
+
);
|
|
2398
|
+
});
|
|
2399
|
+
child.on("close", (code) => {
|
|
2400
|
+
if (code !== 0) {
|
|
2401
|
+
reject(new Error(`java -version exited ${code}: ${stderr}`));
|
|
2402
|
+
return;
|
|
2403
|
+
}
|
|
2404
|
+
const match = stderr.match(/version "([^"]+)"/);
|
|
2405
|
+
resolve4({ version: match?.[1] ?? "unknown" });
|
|
2406
|
+
});
|
|
2407
|
+
});
|
|
2408
|
+
}
|
|
2409
|
+
var init_transporter_install = __esm({
|
|
2410
|
+
"src/pilot/transporter-install.ts"() {
|
|
2411
|
+
}
|
|
2412
|
+
});
|
|
2413
|
+
async function uploadWithTransporter(options) {
|
|
2414
|
+
if (!fs.existsSync(options.ipaPath)) {
|
|
2415
|
+
throw new Error(`File not found: ${options.ipaPath}`);
|
|
2416
|
+
}
|
|
2417
|
+
await verifyJava();
|
|
2418
|
+
const transporterBin = await resolveTransporter();
|
|
2419
|
+
const platform = options.platform ?? "ios";
|
|
2420
|
+
const timeout = options.timeout ?? 18e5;
|
|
2421
|
+
const keyDir = await promises.mkdtemp(path.join(os.tmpdir(), "fastnode-itms-"));
|
|
2422
|
+
const keyPath = path.join(keyDir, `AuthKey_${options.apiKeyId}.p8`);
|
|
2423
|
+
await promises.writeFile(keyPath, options.apiPrivateKey);
|
|
2424
|
+
return new Promise((resolve4) => {
|
|
2425
|
+
const args = [
|
|
2426
|
+
"-m",
|
|
2427
|
+
"upload",
|
|
2428
|
+
"-assetFile",
|
|
2429
|
+
options.ipaPath,
|
|
2430
|
+
"-apiKey",
|
|
2431
|
+
options.apiKeyId,
|
|
2432
|
+
"-apiIssuer",
|
|
2433
|
+
options.apiIssuerId,
|
|
2434
|
+
// WONoPause prevents the JVM from waiting on stdin in non-TTY
|
|
2435
|
+
// environments (CI, LaunchAgent) where it would hang forever.
|
|
2436
|
+
"-WONoPause",
|
|
2437
|
+
"true"
|
|
2438
|
+
];
|
|
2439
|
+
if (platform !== "ios") {
|
|
2440
|
+
args.push("-bundleType", platform);
|
|
2441
|
+
}
|
|
2442
|
+
const child = child_process.spawn(transporterBin, args, {
|
|
2443
|
+
env: {
|
|
2444
|
+
...process.env,
|
|
2445
|
+
API_PRIVATE_KEYS_DIR: keyDir
|
|
2446
|
+
},
|
|
2447
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
2448
|
+
});
|
|
2449
|
+
let output = "";
|
|
2450
|
+
const timer = setTimeout(() => {
|
|
2451
|
+
child.kill("SIGTERM");
|
|
2452
|
+
}, timeout);
|
|
2453
|
+
const onData = (data) => {
|
|
2345
2454
|
const chunk = data.toString();
|
|
2346
2455
|
output += chunk;
|
|
2347
2456
|
options.onOutput?.(chunk);
|
|
2348
|
-
}
|
|
2457
|
+
};
|
|
2458
|
+
child.stdout.on("data", onData);
|
|
2459
|
+
child.stderr.on("data", onData);
|
|
2349
2460
|
child.on("close", async (code) => {
|
|
2350
2461
|
clearTimeout(timer);
|
|
2351
|
-
await promises.
|
|
2462
|
+
await promises.rm(keyDir, { recursive: true, force: true }).catch(() => {
|
|
2463
|
+
});
|
|
2464
|
+
resolve4({ success: code === 0, output, backend: "transporter" });
|
|
2465
|
+
});
|
|
2466
|
+
child.on("error", async (err) => {
|
|
2467
|
+
clearTimeout(timer);
|
|
2468
|
+
await promises.rm(keyDir, { recursive: true, force: true }).catch(() => {
|
|
2469
|
+
});
|
|
2470
|
+
resolve4({
|
|
2471
|
+
success: false,
|
|
2472
|
+
output: output + `
|
|
2473
|
+
Process error: ${err.message}`,
|
|
2474
|
+
backend: "transporter"
|
|
2352
2475
|
});
|
|
2353
|
-
resolve4({ success: code === 0, output });
|
|
2354
2476
|
});
|
|
2355
2477
|
});
|
|
2356
2478
|
}
|
|
2479
|
+
var init_upload_transporter = __esm({
|
|
2480
|
+
"src/pilot/upload-transporter.ts"() {
|
|
2481
|
+
init_transporter_install();
|
|
2482
|
+
}
|
|
2483
|
+
});
|
|
2484
|
+
|
|
2485
|
+
// src/pilot/classify.ts
|
|
2486
|
+
function classifyUploadError(output) {
|
|
2487
|
+
for (const { pattern, kind } of RULES) {
|
|
2488
|
+
if (pattern.test(output)) return kind;
|
|
2489
|
+
}
|
|
2490
|
+
return null;
|
|
2491
|
+
}
|
|
2492
|
+
function isTransientUploadError(output) {
|
|
2493
|
+
return classifyUploadError(output) !== null;
|
|
2494
|
+
}
|
|
2495
|
+
var RULES;
|
|
2496
|
+
var init_classify = __esm({
|
|
2497
|
+
"src/pilot/classify.ts"() {
|
|
2498
|
+
RULES = [
|
|
2499
|
+
// Apple's finalize-upload call returning 5xx — the most common transient
|
|
2500
|
+
// failure we see in practice. Example:
|
|
2501
|
+
// "CHANGE UPLOAD STATE TO COMPLETE (UPLOADING ASSET DESCRIPTION):
|
|
2502
|
+
// received status code 500; internal server error."
|
|
2503
|
+
{ pattern: /CHANGE UPLOAD STATE TO COMPLETE/i, kind: "finalize_failed" },
|
|
2504
|
+
// Generic 5xx from ASC backend services
|
|
2505
|
+
{ pattern: /status code 5\d\d/i, kind: "apple_5xx" },
|
|
2506
|
+
{ pattern: /internal server error/i, kind: "apple_5xx" },
|
|
2507
|
+
{ pattern: /Service Unavailable/i, kind: "apple_5xx" },
|
|
2508
|
+
{ pattern: /Bad Gateway/i, kind: "apple_5xx" },
|
|
2509
|
+
// Network-level interruptions during the upload body transfer
|
|
2510
|
+
{ pattern: /Connection reset/i, kind: "connection_reset" },
|
|
2511
|
+
{ pattern: /SocketException/i, kind: "connection_reset" },
|
|
2512
|
+
{ pattern: /Broken pipe/i, kind: "connection_reset" },
|
|
2513
|
+
// Timeouts — distinct from resets because the other side may have
|
|
2514
|
+
// actually processed the request, so dedupe logic may matter.
|
|
2515
|
+
{ pattern: /Read timed out/i, kind: "network_timeout" },
|
|
2516
|
+
{ pattern: /SocketTimeoutException/i, kind: "network_timeout" },
|
|
2517
|
+
{ pattern: /Operation timed out/i, kind: "network_timeout" },
|
|
2518
|
+
// JVM-internal errors from iTMSTransporter (OOM, thread interruption, etc.)
|
|
2519
|
+
{ pattern: /java\.lang\.OutOfMemoryError/i, kind: "transporter_jvm_error" },
|
|
2520
|
+
{ pattern: /EOFException/i, kind: "transporter_jvm_error" }
|
|
2521
|
+
];
|
|
2522
|
+
}
|
|
2523
|
+
});
|
|
2524
|
+
|
|
2525
|
+
// src/pilot/index.ts
|
|
2526
|
+
var pilot_exports = {};
|
|
2527
|
+
__export(pilot_exports, {
|
|
2528
|
+
classifyUploadError: () => classifyUploadError,
|
|
2529
|
+
distributeToGroups: () => distributeToGroups,
|
|
2530
|
+
expireBuild: () => expireBuild,
|
|
2531
|
+
isTransientUploadError: () => isTransientUploadError,
|
|
2532
|
+
resolveTransporter: () => resolveTransporter,
|
|
2533
|
+
setChangelog: () => setChangelog,
|
|
2534
|
+
uploadToTestFlight: () => uploadToTestFlight,
|
|
2535
|
+
uploadWithAltool: () => uploadWithAltool,
|
|
2536
|
+
uploadWithTransporter: () => uploadWithTransporter,
|
|
2537
|
+
verifyJava: () => verifyJava,
|
|
2538
|
+
waitForProcessing: () => waitForProcessing
|
|
2539
|
+
});
|
|
2540
|
+
async function uploadToTestFlight(options) {
|
|
2541
|
+
const backend = selectBackend(options.backend ?? "auto");
|
|
2542
|
+
if (backend === "altool") {
|
|
2543
|
+
return uploadWithAltool(options);
|
|
2544
|
+
}
|
|
2545
|
+
return uploadWithTransporter(options);
|
|
2546
|
+
}
|
|
2547
|
+
function selectBackend(pref) {
|
|
2548
|
+
if (pref !== "auto") return pref;
|
|
2549
|
+
return process.platform === "darwin" ? "altool" : "transporter";
|
|
2550
|
+
}
|
|
2357
2551
|
async function waitForProcessing(client, params) {
|
|
2358
2552
|
const timeout = params.timeout ?? 18e5;
|
|
2359
2553
|
const pollInterval = params.pollInterval ?? 3e4;
|
|
@@ -2474,6 +2668,12 @@ function sleep2(ms) {
|
|
|
2474
2668
|
var init_pilot = __esm({
|
|
2475
2669
|
"src/pilot/index.ts"() {
|
|
2476
2670
|
init_request();
|
|
2671
|
+
init_upload_altool();
|
|
2672
|
+
init_upload_transporter();
|
|
2673
|
+
init_upload_altool();
|
|
2674
|
+
init_upload_transporter();
|
|
2675
|
+
init_classify();
|
|
2676
|
+
init_transporter_install();
|
|
2477
2677
|
}
|
|
2478
2678
|
});
|
|
2479
2679
|
async function loadMetadata(metadataPath) {
|
|
@@ -2561,9 +2761,9 @@ var init_metadata = __esm({
|
|
|
2561
2761
|
// src/xcode/upload.ts
|
|
2562
2762
|
var upload_exports = {};
|
|
2563
2763
|
__export(upload_exports, {
|
|
2564
|
-
uploadWithAltool: () =>
|
|
2764
|
+
uploadWithAltool: () => uploadWithAltool2
|
|
2565
2765
|
});
|
|
2566
|
-
async function
|
|
2766
|
+
async function uploadWithAltool2(options) {
|
|
2567
2767
|
requireMacOS("altool upload");
|
|
2568
2768
|
let keyDir;
|
|
2569
2769
|
if (options.apiPrivateKey && !options.apiKeyPath) {
|
|
@@ -2672,8 +2872,8 @@ async function uploadToAppStore(options) {
|
|
|
2672
2872
|
if (!options.skipBinaryUpload) {
|
|
2673
2873
|
const binaryPath = options.ipaPath ?? options.pkgPath;
|
|
2674
2874
|
if (binaryPath && options.apiKeyId && options.apiIssuerId) {
|
|
2675
|
-
const { uploadWithAltool:
|
|
2676
|
-
await
|
|
2875
|
+
const { uploadWithAltool: uploadWithAltool3 } = await Promise.resolve().then(() => (init_upload(), upload_exports));
|
|
2876
|
+
await uploadWithAltool3({
|
|
2677
2877
|
filePath: binaryPath,
|
|
2678
2878
|
apiKeyId: options.apiKeyId,
|
|
2679
2879
|
apiIssuerId: options.apiIssuerId,
|
|
@@ -3459,8 +3659,8 @@ async function captureScreenshots(options) {
|
|
|
3459
3659
|
const outputDir = options.outputDirectory ?? path.join(process.cwd(), "screenshots");
|
|
3460
3660
|
const retries = options.numberOfRetries ?? 1;
|
|
3461
3661
|
if (options.clearPreviousScreenshots && fs.existsSync(outputDir)) {
|
|
3462
|
-
const { rm:
|
|
3463
|
-
await
|
|
3662
|
+
const { rm: rm4 } = await import('fs/promises');
|
|
3663
|
+
await rm4(outputDir, { recursive: true, force: true });
|
|
3464
3664
|
}
|
|
3465
3665
|
fs.mkdirSync(outputDir, { recursive: true });
|
|
3466
3666
|
const screenshots = {};
|