@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/actions/index.cjs
CHANGED
|
@@ -178,8 +178,8 @@ async function revokeExpiredCertificates(options) {
|
|
|
178
178
|
return count;
|
|
179
179
|
}
|
|
180
180
|
async function importToKeychain(certData, keychainPath, keychainPassword) {
|
|
181
|
-
const { tmpdir:
|
|
182
|
-
const tempCertPath = path.join(
|
|
181
|
+
const { tmpdir: tmpdir8 } = await import('os');
|
|
182
|
+
const tempCertPath = path.join(tmpdir8(), `fastnode-cert-${Date.now()}.cer`);
|
|
183
183
|
await promises.writeFile(tempCertPath, certData);
|
|
184
184
|
try {
|
|
185
185
|
const args = [
|
|
@@ -1611,14 +1611,14 @@ var init_building = __esm({
|
|
|
1611
1611
|
name: "clean_build_artifacts",
|
|
1612
1612
|
description: "Remove build artifacts (IPA, dSYM, etc.)",
|
|
1613
1613
|
async run(params, ctx) {
|
|
1614
|
-
const { rm:
|
|
1614
|
+
const { rm: rm4 } = await import('fs/promises');
|
|
1615
1615
|
const paths = [
|
|
1616
1616
|
ctx.get("IPA_OUTPUT_PATH"),
|
|
1617
1617
|
ctx.get("PKG_OUTPUT_PATH"),
|
|
1618
1618
|
ctx.get("DSYM_OUTPUT_PATH")
|
|
1619
1619
|
].filter(Boolean);
|
|
1620
1620
|
for (const p of paths) {
|
|
1621
|
-
await
|
|
1621
|
+
await rm4(p, { force: true }).catch(() => {
|
|
1622
1622
|
});
|
|
1623
1623
|
}
|
|
1624
1624
|
return { cleaned: paths };
|
|
@@ -2265,23 +2265,13 @@ var init_request = __esm({
|
|
|
2265
2265
|
};
|
|
2266
2266
|
}
|
|
2267
2267
|
});
|
|
2268
|
-
|
|
2269
|
-
// src/pilot/index.ts
|
|
2270
|
-
var pilot_exports = {};
|
|
2271
|
-
__export(pilot_exports, {
|
|
2272
|
-
distributeToGroups: () => distributeToGroups,
|
|
2273
|
-
expireBuild: () => expireBuild,
|
|
2274
|
-
setChangelog: () => setChangelog,
|
|
2275
|
-
uploadToTestFlight: () => uploadToTestFlight,
|
|
2276
|
-
waitForProcessing: () => waitForProcessing
|
|
2277
|
-
});
|
|
2278
|
-
async function uploadToTestFlight(options) {
|
|
2268
|
+
async function uploadWithAltool(options) {
|
|
2279
2269
|
if (!fs.existsSync(options.ipaPath)) {
|
|
2280
2270
|
throw new Error(`File not found: ${options.ipaPath}`);
|
|
2281
2271
|
}
|
|
2282
2272
|
const platform = options.platform ?? "ios";
|
|
2283
2273
|
const timeout = options.timeout ?? 18e5;
|
|
2284
|
-
const keyDir = await promises.mkdtemp(path.join(os.tmpdir(), "fastnode-
|
|
2274
|
+
const keyDir = await promises.mkdtemp(path.join(os.tmpdir(), "fastnode-altool-"));
|
|
2285
2275
|
const keyPath = path.join(keyDir, `AuthKey_${options.apiKeyId}.p8`);
|
|
2286
2276
|
await promises.writeFile(keyPath, options.apiPrivateKey);
|
|
2287
2277
|
return new Promise((resolve3) => {
|
|
@@ -2305,24 +2295,228 @@ async function uploadToTestFlight(options) {
|
|
|
2305
2295
|
const timer = setTimeout(() => {
|
|
2306
2296
|
child.kill("SIGTERM");
|
|
2307
2297
|
}, timeout);
|
|
2308
|
-
|
|
2298
|
+
const onData = (data) => {
|
|
2309
2299
|
const chunk = data.toString();
|
|
2310
2300
|
output += chunk;
|
|
2311
2301
|
options.onOutput?.(chunk);
|
|
2302
|
+
};
|
|
2303
|
+
child.stdout.on("data", onData);
|
|
2304
|
+
child.stderr.on("data", onData);
|
|
2305
|
+
child.on("close", async (code) => {
|
|
2306
|
+
clearTimeout(timer);
|
|
2307
|
+
await promises.unlink(keyPath).catch(() => {
|
|
2308
|
+
});
|
|
2309
|
+
await promises.rm(keyDir, { recursive: true, force: true }).catch(() => {
|
|
2310
|
+
});
|
|
2311
|
+
resolve3({ success: code === 0, output, backend: "altool" });
|
|
2312
2312
|
});
|
|
2313
|
-
|
|
2313
|
+
});
|
|
2314
|
+
}
|
|
2315
|
+
var init_upload_altool = __esm({
|
|
2316
|
+
"src/pilot/upload-altool.ts"() {
|
|
2317
|
+
}
|
|
2318
|
+
});
|
|
2319
|
+
async function resolveTransporter() {
|
|
2320
|
+
const override = process.env.ITMSTRANSPORTER_BIN;
|
|
2321
|
+
if (override) {
|
|
2322
|
+
if (!fs.existsSync(override)) {
|
|
2323
|
+
throw new Error(
|
|
2324
|
+
`ITMSTRANSPORTER_BIN is set to "${override}" but that path does not exist.`
|
|
2325
|
+
);
|
|
2326
|
+
}
|
|
2327
|
+
return override;
|
|
2328
|
+
}
|
|
2329
|
+
const candidates = process.platform === "darwin" ? [
|
|
2330
|
+
// Xcode 15+: Transporter.app bundled with Xcode
|
|
2331
|
+
"/Applications/Xcode.app/Contents/SharedFrameworks/ContentDeliveryServices.framework/Versions/A/itms/bin/iTMSTransporter",
|
|
2332
|
+
// Standalone Transporter.app from the Mac App Store
|
|
2333
|
+
"/Applications/Transporter.app/Contents/itms/bin/iTMSTransporter"
|
|
2334
|
+
] : [
|
|
2335
|
+
"/usr/local/itms/bin/iTMSTransporter",
|
|
2336
|
+
"/opt/itms/bin/iTMSTransporter",
|
|
2337
|
+
"/usr/local/bin/iTMSTransporter"
|
|
2338
|
+
];
|
|
2339
|
+
for (const path of candidates) {
|
|
2340
|
+
if (fs.existsSync(path)) return path;
|
|
2341
|
+
}
|
|
2342
|
+
throw new Error(
|
|
2343
|
+
[
|
|
2344
|
+
"iTMSTransporter not found.",
|
|
2345
|
+
"",
|
|
2346
|
+
"Install options:",
|
|
2347
|
+
process.platform === "darwin" ? " - Install Xcode (includes Transporter)" : " - Download Apple's standalone iTMSTransporter package for Linux",
|
|
2348
|
+
" - Or set ITMSTRANSPORTER_BIN to the absolute path of the binary",
|
|
2349
|
+
"",
|
|
2350
|
+
`Searched: ${candidates.join(", ")}`
|
|
2351
|
+
].join("\n")
|
|
2352
|
+
);
|
|
2353
|
+
}
|
|
2354
|
+
async function verifyJava() {
|
|
2355
|
+
return new Promise((resolve3, reject) => {
|
|
2356
|
+
const child = child_process.spawn("java", ["-version"], { stdio: ["ignore", "pipe", "pipe"] });
|
|
2357
|
+
let stderr = "";
|
|
2358
|
+
child.stderr.on("data", (d) => {
|
|
2359
|
+
stderr += d.toString();
|
|
2360
|
+
});
|
|
2361
|
+
child.on("error", (err) => {
|
|
2362
|
+
reject(
|
|
2363
|
+
new Error(
|
|
2364
|
+
`java not found on PATH (${err.message}). Install Java 17 LTS and ensure it is on PATH.`
|
|
2365
|
+
)
|
|
2366
|
+
);
|
|
2367
|
+
});
|
|
2368
|
+
child.on("close", (code) => {
|
|
2369
|
+
if (code !== 0) {
|
|
2370
|
+
reject(new Error(`java -version exited ${code}: ${stderr}`));
|
|
2371
|
+
return;
|
|
2372
|
+
}
|
|
2373
|
+
const match = stderr.match(/version "([^"]+)"/);
|
|
2374
|
+
resolve3({ version: match?.[1] ?? "unknown" });
|
|
2375
|
+
});
|
|
2376
|
+
});
|
|
2377
|
+
}
|
|
2378
|
+
var init_transporter_install = __esm({
|
|
2379
|
+
"src/pilot/transporter-install.ts"() {
|
|
2380
|
+
}
|
|
2381
|
+
});
|
|
2382
|
+
async function uploadWithTransporter(options) {
|
|
2383
|
+
if (!fs.existsSync(options.ipaPath)) {
|
|
2384
|
+
throw new Error(`File not found: ${options.ipaPath}`);
|
|
2385
|
+
}
|
|
2386
|
+
await verifyJava();
|
|
2387
|
+
const transporterBin = await resolveTransporter();
|
|
2388
|
+
const platform = options.platform ?? "ios";
|
|
2389
|
+
const timeout = options.timeout ?? 18e5;
|
|
2390
|
+
const keyDir = await promises.mkdtemp(path.join(os.tmpdir(), "fastnode-itms-"));
|
|
2391
|
+
const keyPath = path.join(keyDir, `AuthKey_${options.apiKeyId}.p8`);
|
|
2392
|
+
await promises.writeFile(keyPath, options.apiPrivateKey);
|
|
2393
|
+
return new Promise((resolve3) => {
|
|
2394
|
+
const args = [
|
|
2395
|
+
"-m",
|
|
2396
|
+
"upload",
|
|
2397
|
+
"-assetFile",
|
|
2398
|
+
options.ipaPath,
|
|
2399
|
+
"-apiKey",
|
|
2400
|
+
options.apiKeyId,
|
|
2401
|
+
"-apiIssuer",
|
|
2402
|
+
options.apiIssuerId,
|
|
2403
|
+
// WONoPause prevents the JVM from waiting on stdin in non-TTY
|
|
2404
|
+
// environments (CI, LaunchAgent) where it would hang forever.
|
|
2405
|
+
"-WONoPause",
|
|
2406
|
+
"true"
|
|
2407
|
+
];
|
|
2408
|
+
if (platform !== "ios") {
|
|
2409
|
+
args.push("-bundleType", platform);
|
|
2410
|
+
}
|
|
2411
|
+
const child = child_process.spawn(transporterBin, args, {
|
|
2412
|
+
env: {
|
|
2413
|
+
...process.env,
|
|
2414
|
+
API_PRIVATE_KEYS_DIR: keyDir
|
|
2415
|
+
},
|
|
2416
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
2417
|
+
});
|
|
2418
|
+
let output = "";
|
|
2419
|
+
const timer = setTimeout(() => {
|
|
2420
|
+
child.kill("SIGTERM");
|
|
2421
|
+
}, timeout);
|
|
2422
|
+
const onData = (data) => {
|
|
2314
2423
|
const chunk = data.toString();
|
|
2315
2424
|
output += chunk;
|
|
2316
2425
|
options.onOutput?.(chunk);
|
|
2317
|
-
}
|
|
2426
|
+
};
|
|
2427
|
+
child.stdout.on("data", onData);
|
|
2428
|
+
child.stderr.on("data", onData);
|
|
2318
2429
|
child.on("close", async (code) => {
|
|
2319
2430
|
clearTimeout(timer);
|
|
2320
|
-
await promises.
|
|
2431
|
+
await promises.rm(keyDir, { recursive: true, force: true }).catch(() => {
|
|
2432
|
+
});
|
|
2433
|
+
resolve3({ success: code === 0, output, backend: "transporter" });
|
|
2434
|
+
});
|
|
2435
|
+
child.on("error", async (err) => {
|
|
2436
|
+
clearTimeout(timer);
|
|
2437
|
+
await promises.rm(keyDir, { recursive: true, force: true }).catch(() => {
|
|
2438
|
+
});
|
|
2439
|
+
resolve3({
|
|
2440
|
+
success: false,
|
|
2441
|
+
output: output + `
|
|
2442
|
+
Process error: ${err.message}`,
|
|
2443
|
+
backend: "transporter"
|
|
2321
2444
|
});
|
|
2322
|
-
resolve3({ success: code === 0, output });
|
|
2323
2445
|
});
|
|
2324
2446
|
});
|
|
2325
2447
|
}
|
|
2448
|
+
var init_upload_transporter = __esm({
|
|
2449
|
+
"src/pilot/upload-transporter.ts"() {
|
|
2450
|
+
init_transporter_install();
|
|
2451
|
+
}
|
|
2452
|
+
});
|
|
2453
|
+
|
|
2454
|
+
// src/pilot/classify.ts
|
|
2455
|
+
function classifyUploadError(output) {
|
|
2456
|
+
for (const { pattern, kind } of RULES) {
|
|
2457
|
+
if (pattern.test(output)) return kind;
|
|
2458
|
+
}
|
|
2459
|
+
return null;
|
|
2460
|
+
}
|
|
2461
|
+
function isTransientUploadError(output) {
|
|
2462
|
+
return classifyUploadError(output) !== null;
|
|
2463
|
+
}
|
|
2464
|
+
var RULES;
|
|
2465
|
+
var init_classify = __esm({
|
|
2466
|
+
"src/pilot/classify.ts"() {
|
|
2467
|
+
RULES = [
|
|
2468
|
+
// Apple's finalize-upload call returning 5xx — the most common transient
|
|
2469
|
+
// failure we see in practice. Example:
|
|
2470
|
+
// "CHANGE UPLOAD STATE TO COMPLETE (UPLOADING ASSET DESCRIPTION):
|
|
2471
|
+
// received status code 500; internal server error."
|
|
2472
|
+
{ pattern: /CHANGE UPLOAD STATE TO COMPLETE/i, kind: "finalize_failed" },
|
|
2473
|
+
// Generic 5xx from ASC backend services
|
|
2474
|
+
{ pattern: /status code 5\d\d/i, kind: "apple_5xx" },
|
|
2475
|
+
{ pattern: /internal server error/i, kind: "apple_5xx" },
|
|
2476
|
+
{ pattern: /Service Unavailable/i, kind: "apple_5xx" },
|
|
2477
|
+
{ pattern: /Bad Gateway/i, kind: "apple_5xx" },
|
|
2478
|
+
// Network-level interruptions during the upload body transfer
|
|
2479
|
+
{ pattern: /Connection reset/i, kind: "connection_reset" },
|
|
2480
|
+
{ pattern: /SocketException/i, kind: "connection_reset" },
|
|
2481
|
+
{ pattern: /Broken pipe/i, kind: "connection_reset" },
|
|
2482
|
+
// Timeouts — distinct from resets because the other side may have
|
|
2483
|
+
// actually processed the request, so dedupe logic may matter.
|
|
2484
|
+
{ pattern: /Read timed out/i, kind: "network_timeout" },
|
|
2485
|
+
{ pattern: /SocketTimeoutException/i, kind: "network_timeout" },
|
|
2486
|
+
{ pattern: /Operation timed out/i, kind: "network_timeout" },
|
|
2487
|
+
// JVM-internal errors from iTMSTransporter (OOM, thread interruption, etc.)
|
|
2488
|
+
{ pattern: /java\.lang\.OutOfMemoryError/i, kind: "transporter_jvm_error" },
|
|
2489
|
+
{ pattern: /EOFException/i, kind: "transporter_jvm_error" }
|
|
2490
|
+
];
|
|
2491
|
+
}
|
|
2492
|
+
});
|
|
2493
|
+
|
|
2494
|
+
// src/pilot/index.ts
|
|
2495
|
+
var pilot_exports = {};
|
|
2496
|
+
__export(pilot_exports, {
|
|
2497
|
+
classifyUploadError: () => classifyUploadError,
|
|
2498
|
+
distributeToGroups: () => distributeToGroups,
|
|
2499
|
+
expireBuild: () => expireBuild,
|
|
2500
|
+
isTransientUploadError: () => isTransientUploadError,
|
|
2501
|
+
resolveTransporter: () => resolveTransporter,
|
|
2502
|
+
setChangelog: () => setChangelog,
|
|
2503
|
+
uploadToTestFlight: () => uploadToTestFlight,
|
|
2504
|
+
uploadWithAltool: () => uploadWithAltool,
|
|
2505
|
+
uploadWithTransporter: () => uploadWithTransporter,
|
|
2506
|
+
verifyJava: () => verifyJava,
|
|
2507
|
+
waitForProcessing: () => waitForProcessing
|
|
2508
|
+
});
|
|
2509
|
+
async function uploadToTestFlight(options) {
|
|
2510
|
+
const backend = selectBackend(options.backend ?? "auto");
|
|
2511
|
+
if (backend === "altool") {
|
|
2512
|
+
return uploadWithAltool(options);
|
|
2513
|
+
}
|
|
2514
|
+
return uploadWithTransporter(options);
|
|
2515
|
+
}
|
|
2516
|
+
function selectBackend(pref) {
|
|
2517
|
+
if (pref !== "auto") return pref;
|
|
2518
|
+
return process.platform === "darwin" ? "altool" : "transporter";
|
|
2519
|
+
}
|
|
2326
2520
|
async function waitForProcessing(client, params) {
|
|
2327
2521
|
const timeout = params.timeout ?? 18e5;
|
|
2328
2522
|
const pollInterval = params.pollInterval ?? 3e4;
|
|
@@ -2443,6 +2637,12 @@ function sleep2(ms) {
|
|
|
2443
2637
|
var init_pilot = __esm({
|
|
2444
2638
|
"src/pilot/index.ts"() {
|
|
2445
2639
|
init_request();
|
|
2640
|
+
init_upload_altool();
|
|
2641
|
+
init_upload_transporter();
|
|
2642
|
+
init_upload_altool();
|
|
2643
|
+
init_upload_transporter();
|
|
2644
|
+
init_classify();
|
|
2645
|
+
init_transporter_install();
|
|
2446
2646
|
}
|
|
2447
2647
|
});
|
|
2448
2648
|
async function loadMetadata(metadataPath) {
|
|
@@ -2530,9 +2730,9 @@ var init_metadata = __esm({
|
|
|
2530
2730
|
// src/xcode/upload.ts
|
|
2531
2731
|
var upload_exports = {};
|
|
2532
2732
|
__export(upload_exports, {
|
|
2533
|
-
uploadWithAltool: () =>
|
|
2733
|
+
uploadWithAltool: () => uploadWithAltool2
|
|
2534
2734
|
});
|
|
2535
|
-
async function
|
|
2735
|
+
async function uploadWithAltool2(options) {
|
|
2536
2736
|
requireMacOS("altool upload");
|
|
2537
2737
|
let keyDir;
|
|
2538
2738
|
if (options.apiPrivateKey && !options.apiKeyPath) {
|
|
@@ -2641,8 +2841,8 @@ async function uploadToAppStore(options) {
|
|
|
2641
2841
|
if (!options.skipBinaryUpload) {
|
|
2642
2842
|
const binaryPath = options.ipaPath ?? options.pkgPath;
|
|
2643
2843
|
if (binaryPath && options.apiKeyId && options.apiIssuerId) {
|
|
2644
|
-
const { uploadWithAltool:
|
|
2645
|
-
await
|
|
2844
|
+
const { uploadWithAltool: uploadWithAltool3 } = await Promise.resolve().then(() => (init_upload(), upload_exports));
|
|
2845
|
+
await uploadWithAltool3({
|
|
2646
2846
|
filePath: binaryPath,
|
|
2647
2847
|
apiKeyId: options.apiKeyId,
|
|
2648
2848
|
apiIssuerId: options.apiIssuerId,
|
|
@@ -3428,8 +3628,8 @@ async function captureScreenshots(options) {
|
|
|
3428
3628
|
const outputDir = options.outputDirectory ?? path.join(process.cwd(), "screenshots");
|
|
3429
3629
|
const retries = options.numberOfRetries ?? 1;
|
|
3430
3630
|
if (options.clearPreviousScreenshots && fs.existsSync(outputDir)) {
|
|
3431
|
-
const { rm:
|
|
3432
|
-
await
|
|
3631
|
+
const { rm: rm4 } = await import('fs/promises');
|
|
3632
|
+
await rm4(outputDir, { recursive: true, force: true });
|
|
3433
3633
|
}
|
|
3434
3634
|
fs.mkdirSync(outputDir, { recursive: true });
|
|
3435
3635
|
const screenshots = {};
|