@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.
- package/README.md +81 -0
- package/bin/fastnode.js +13 -0
- package/bin/fastnode.ts +5 -0
- package/dist/actions/index.cjs +7405 -0
- package/dist/actions/index.cjs.map +1 -0
- package/dist/actions/index.d.cts +15 -0
- package/dist/actions/index.d.ts +15 -0
- package/dist/actions/index.mjs +7377 -0
- package/dist/actions/index.mjs.map +1 -0
- package/dist/cert/index.cjs +219 -0
- package/dist/cert/index.cjs.map +1 -0
- package/dist/cert/index.d.cts +4 -0
- package/dist/cert/index.d.ts +4 -0
- package/dist/cert/index.mjs +191 -0
- package/dist/cert/index.mjs.map +1 -0
- package/dist/cert-BmJGtYtb.d.cts +27 -0
- package/dist/cert-owkOFNW8.d.ts +27 -0
- package/dist/cli/index.cjs +7998 -0
- package/dist/cli/index.cjs.map +1 -0
- package/dist/cli/index.d.cts +9 -0
- package/dist/cli/index.d.ts +9 -0
- package/dist/cli/index.mjs +7972 -0
- package/dist/cli/index.mjs.map +1 -0
- package/dist/client/index.cjs +2592 -0
- package/dist/client/index.cjs.map +1 -0
- package/dist/client/index.d.cts +2 -0
- package/dist/client/index.d.ts +2 -0
- package/dist/client/index.mjs +2582 -0
- package/dist/client/index.mjs.map +1 -0
- package/dist/context-CymLkfrS.d.cts +13 -0
- package/dist/context-CymLkfrS.d.ts +13 -0
- package/dist/core/index.cjs +281 -0
- package/dist/core/index.cjs.map +1 -0
- package/dist/core/index.d.cts +1 -0
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.mjs +254 -0
- package/dist/core/index.mjs.map +1 -0
- package/dist/deliver/index.cjs +328 -0
- package/dist/deliver/index.cjs.map +1 -0
- package/dist/deliver/index.d.cts +3 -0
- package/dist/deliver/index.d.ts +3 -0
- package/dist/deliver/index.mjs +322 -0
- package/dist/deliver/index.mjs.map +1 -0
- package/dist/enums-B609j2rb.d.cts +20 -0
- package/dist/enums-B609j2rb.d.ts +20 -0
- package/dist/frameit/index.cjs +247 -0
- package/dist/frameit/index.cjs.map +1 -0
- package/dist/frameit/index.d.cts +1 -0
- package/dist/frameit/index.d.ts +1 -0
- package/dist/frameit/index.mjs +242 -0
- package/dist/frameit/index.mjs.map +1 -0
- package/dist/gym/index.cjs +356 -0
- package/dist/gym/index.cjs.map +1 -0
- package/dist/gym/index.d.cts +2 -0
- package/dist/gym/index.d.ts +2 -0
- package/dist/gym/index.mjs +346 -0
- package/dist/gym/index.mjs.map +1 -0
- package/dist/index-1Vu2cRQ2.d.ts +99 -0
- package/dist/index-A5MimeQk.d.ts +72 -0
- package/dist/index-B0yhu_LZ.d.ts +76 -0
- package/dist/index-B9yXicrQ.d.ts +62 -0
- package/dist/index-BFdNOmPJ.d.cts +53 -0
- package/dist/index-BLubSlgK.d.cts +1513 -0
- package/dist/index-BN0ubxjZ.d.ts +70 -0
- package/dist/index-BQJIJlK7.d.cts +70 -0
- package/dist/index-BYonklf3.d.cts +84 -0
- package/dist/index-BYonklf3.d.ts +84 -0
- package/dist/index-BimqCmY8.d.cts +78 -0
- package/dist/index-BimqCmY8.d.ts +78 -0
- package/dist/index-BoU8qt8r.d.cts +59 -0
- package/dist/index-BoU8qt8r.d.ts +59 -0
- package/dist/index-C2yG3wXA.d.cts +95 -0
- package/dist/index-C2yG3wXA.d.ts +95 -0
- package/dist/index-CR3BFPIz.d.cts +77 -0
- package/dist/index-CR3BFPIz.d.ts +77 -0
- package/dist/index-CWNLnSOL.d.cts +99 -0
- package/dist/index-Cp6cjtd-.d.cts +65 -0
- package/dist/index-Cp6cjtd-.d.ts +65 -0
- package/dist/index-D1Izm7qt.d.ts +1513 -0
- package/dist/index-D5eihzwM.d.cts +76 -0
- package/dist/index-DImN9PWc.d.ts +155 -0
- package/dist/index-DfCUVJX1.d.cts +62 -0
- package/dist/index-DfirmFbC.d.ts +32 -0
- package/dist/index-DkvinY7_.d.ts +54 -0
- package/dist/index-DrUpRXRG.d.cts +155 -0
- package/dist/index-EcVvViW8.d.cts +72 -0
- package/dist/index-HRiaaX-Q.d.cts +54 -0
- package/dist/index-TfXqwuac.d.ts +53 -0
- package/dist/index-lt819Jgj.d.cts +32 -0
- package/dist/index.cjs +8464 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +23 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.mjs +8410 -0
- package/dist/index.mjs.map +1 -0
- package/dist/lane/index.cjs +7641 -0
- package/dist/lane/index.cjs.map +1 -0
- package/dist/lane/index.d.cts +51 -0
- package/dist/lane/index.d.ts +51 -0
- package/dist/lane/index.mjs +7603 -0
- package/dist/lane/index.mjs.map +1 -0
- package/dist/match/index.cjs +942 -0
- package/dist/match/index.cjs.map +1 -0
- package/dist/match/index.d.cts +5 -0
- package/dist/match/index.d.ts +5 -0
- package/dist/match/index.mjs +913 -0
- package/dist/match/index.mjs.map +1 -0
- package/dist/pem/index.cjs +195 -0
- package/dist/pem/index.cjs.map +1 -0
- package/dist/pem/index.d.cts +3 -0
- package/dist/pem/index.d.ts +3 -0
- package/dist/pem/index.mjs +170 -0
- package/dist/pem/index.mjs.map +1 -0
- package/dist/pilot/index.cjs +206 -0
- package/dist/pilot/index.cjs.map +1 -0
- package/dist/pilot/index.d.cts +3 -0
- package/dist/pilot/index.d.ts +3 -0
- package/dist/pilot/index.mjs +196 -0
- package/dist/pilot/index.mjs.map +1 -0
- package/dist/precheck/index.cjs +277 -0
- package/dist/precheck/index.cjs.map +1 -0
- package/dist/precheck/index.d.cts +3 -0
- package/dist/precheck/index.d.ts +3 -0
- package/dist/precheck/index.mjs +274 -0
- package/dist/precheck/index.mjs.map +1 -0
- package/dist/produce/index.cjs +200 -0
- package/dist/produce/index.cjs.map +1 -0
- package/dist/produce/index.d.cts +3 -0
- package/dist/produce/index.d.ts +3 -0
- package/dist/produce/index.mjs +191 -0
- package/dist/produce/index.mjs.map +1 -0
- package/dist/scan/index.cjs +187 -0
- package/dist/scan/index.cjs.map +1 -0
- package/dist/scan/index.d.cts +1 -0
- package/dist/scan/index.d.ts +1 -0
- package/dist/scan/index.mjs +183 -0
- package/dist/scan/index.mjs.map +1 -0
- package/dist/sigh/index.cjs +203 -0
- package/dist/sigh/index.cjs.map +1 -0
- package/dist/sigh/index.d.cts +3 -0
- package/dist/sigh/index.d.ts +3 -0
- package/dist/sigh/index.mjs +198 -0
- package/dist/sigh/index.mjs.map +1 -0
- package/dist/snapshot/index.cjs +448 -0
- package/dist/snapshot/index.cjs.map +1 -0
- package/dist/snapshot/index.d.cts +1 -0
- package/dist/snapshot/index.d.ts +1 -0
- package/dist/snapshot/index.mjs +438 -0
- package/dist/snapshot/index.mjs.map +1 -0
- package/dist/trainer/index.cjs +395 -0
- package/dist/trainer/index.cjs.map +1 -0
- package/dist/trainer/index.d.cts +1 -0
- package/dist/trainer/index.d.ts +1 -0
- package/dist/trainer/index.mjs +372 -0
- package/dist/trainer/index.mjs.map +1 -0
- package/dist/xcode/index.cjs +188 -0
- package/dist/xcode/index.cjs.map +1 -0
- package/dist/xcode/index.d.cts +1 -0
- package/dist/xcode/index.d.ts +1 -0
- package/dist/xcode/index.mjs +176 -0
- package/dist/xcode/index.mjs.map +1 -0
- package/package.json +223 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/xcode/platform.ts","../../src/scan/command.ts","../../src/scan/retry.ts","../../src/scan/index.ts"],"names":["join","mkdirSync","existsSync","spawn"],"mappings":"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","file":"index.cjs","sourcesContent":["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","export interface TestCommandOptions {\n scheme?: string;\n workspace?: string;\n project?: string;\n destination?: string;\n devices?: string[];\n testPlan?: string;\n onlyTesting?: string[];\n skipTesting?: string[];\n configuration?: string;\n derivedDataPath?: string;\n resultBundlePath?: string;\n codeCoverage?: boolean;\n xcargs?: string;\n clean?: boolean;\n // ── Parallel testing (Fastlane scan parity) ──────────────────────────────\n /** Enable `-parallel-testing-enabled YES`. */\n parallelTesting?: boolean;\n /** Sets `-parallel-testing-worker-count`. */\n concurrentWorkers?: number;\n /** Sets `-maximum-concurrent-test-simulator-destinations`. */\n maxConcurrentSimulators?: number;\n /** Explicitly disable concurrent destinations (`-disable-concurrent-destination-testing`). */\n disableConcurrentTesting?: boolean;\n // ── Sanitizers ───────────────────────────────────────────────────────────\n addressSanitizer?: boolean;\n threadSanitizer?: boolean;\n undefinedBehaviorSanitizer?: boolean;\n}\n\nexport function buildTestCommand(options: TestCommandOptions): string[] {\n const args: string[] = [];\n\n if (options.clean) args.push(\"clean\");\n args.push(\"test\");\n\n if (options.workspace) args.push(\"-workspace\", options.workspace);\n else if (options.project) args.push(\"-project\", options.project);\n\n if (options.scheme) args.push(\"-scheme\", options.scheme);\n\n // Destination\n if (options.destination) {\n args.push(\"-destination\", options.destination);\n } else if (options.devices && options.devices.length > 0) {\n for (const device of options.devices) {\n args.push(\"-destination\", `platform=iOS Simulator,name=${device}`);\n }\n }\n\n if (options.testPlan) args.push(\"-testPlan\", options.testPlan);\n if (options.configuration) args.push(\"-configuration\", options.configuration);\n if (options.derivedDataPath) args.push(\"-derivedDataPath\", options.derivedDataPath);\n if (options.resultBundlePath) args.push(\"-resultBundlePath\", options.resultBundlePath);\n\n if (options.codeCoverage) args.push(\"-enableCodeCoverage\", \"YES\");\n\n if (options.onlyTesting) {\n for (const test of options.onlyTesting) {\n args.push(\"-only-testing:\" + test);\n }\n }\n if (options.skipTesting) {\n for (const test of options.skipTesting) {\n args.push(\"-skip-testing:\" + test);\n }\n }\n\n // Parallel testing flags (xcodebuild native, not xcargs)\n if (options.parallelTesting !== undefined) {\n args.push(\"-parallel-testing-enabled\", options.parallelTesting ? \"YES\" : \"NO\");\n }\n if (options.concurrentWorkers !== undefined) {\n args.push(\"-parallel-testing-worker-count\", String(options.concurrentWorkers));\n }\n if (options.maxConcurrentSimulators !== undefined) {\n args.push(\n \"-maximum-concurrent-test-simulator-destinations\",\n String(options.maxConcurrentSimulators)\n );\n }\n if (options.disableConcurrentTesting) {\n args.push(\"-disable-concurrent-destination-testing\");\n }\n\n // Runtime sanitizers\n if (options.addressSanitizer !== undefined) {\n args.push(\"-enableAddressSanitizer\", options.addressSanitizer ? \"YES\" : \"NO\");\n }\n if (options.threadSanitizer !== undefined) {\n args.push(\"-enableThreadSanitizer\", options.threadSanitizer ? \"YES\" : \"NO\");\n }\n if (options.undefinedBehaviorSanitizer !== undefined) {\n args.push(\n \"-enableUndefinedBehaviorSanitizer\",\n options.undefinedBehaviorSanitizer ? \"YES\" : \"NO\"\n );\n }\n\n if (options.xcargs) args.push(...options.xcargs.split(/\\s+/));\n\n return args;\n}\n","export interface FailedTest {\n target: string;\n suite: string;\n testCase: string;\n onlyTestingArg: string;\n}\n\nexport function parseFailedTests(output: string): FailedTest[] {\n const results: FailedTest[] = [];\n // Strip ANSI color codes\n const clean = output.replace(/\\x1b\\[[0-9;]*m/g, \"\");\n\n // Look for \"Failing tests:\" section\n const failingMatch = clean.match(/Failing tests:\\s*\\n([\\s\\S]*?)(?:\\n\\n|\\n\\*\\*|$)/);\n if (!failingMatch) return results;\n\n const lines = failingMatch[1].split(\"\\n\");\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"*\")) continue;\n\n // Format: -[TestSuite testMethod] or TestTarget.TestSuite/testMethod\n const bracketMatch = trimmed.match(/-\\[(\\w+)\\s+(\\w+)\\]/);\n if (bracketMatch) {\n results.push({\n target: \"\",\n suite: bracketMatch[1],\n testCase: bracketMatch[2],\n onlyTestingArg: `${bracketMatch[1]}/${bracketMatch[2]}`,\n });\n continue;\n }\n\n const slashMatch = trimmed.match(/^(\\w+)\\.(\\w+)\\/(\\w+)$/);\n if (slashMatch) {\n results.push({\n target: slashMatch[1],\n suite: slashMatch[2],\n testCase: slashMatch[3],\n onlyTestingArg: `${slashMatch[1]}/${slashMatch[2]}/${slashMatch[3]}`,\n });\n }\n }\n\n return results;\n}\n","import { spawn } from \"node:child_process\";\nimport { join } from \"node:path\";\nimport { mkdirSync, existsSync } from \"node:fs\";\nimport { requireMacOS } from \"../xcode/platform.js\";\nimport { buildTestCommand } from \"./command.js\";\nimport { parseFailedTests } from \"./retry.js\";\n\nexport type { FailedTest } from \"./retry.js\";\nexport { buildTestCommand } from \"./command.js\";\nexport { parseFailedTests } from \"./retry.js\";\n\nexport interface ScanOptions {\n scheme?: string;\n workspace?: string;\n project?: string;\n devices?: string[];\n testPlan?: string;\n onlyTesting?: string[];\n skipTesting?: string[];\n configuration?: string;\n outputDirectory?: string;\n clean?: boolean;\n codeCoverage?: boolean;\n derivedDataPath?: string;\n resultBundlePath?: string;\n maxRetries?: number;\n xcargs?: string;\n onOutput?: (chunk: string) => void;\n}\n\nexport interface TestResult {\n success: boolean;\n totalTests: number;\n failures: number;\n skipped: number;\n retries: number;\n duration: number;\n reportPaths: string[];\n output: string;\n}\n\nexport async function runTests(options: ScanOptions): Promise<TestResult> {\n requireMacOS(\"scan\");\n\n const outputDir = options.outputDirectory ?? join(process.cwd(), \"test_output\");\n mkdirSync(outputDir, { recursive: true });\n\n const resultBundlePath = options.resultBundlePath ?? join(outputDir, \"result.xcresult\");\n const maxRetries = options.maxRetries ?? 0;\n let retryCount = 0;\n let lastOutput = \"\";\n let currentOnlyTesting = options.onlyTesting;\n\n const startTime = Date.now();\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n const args = buildTestCommand({\n ...options,\n resultBundlePath: attempt === 0 ? resultBundlePath : `${resultBundlePath}-retry-${attempt}`,\n onlyTesting: currentOnlyTesting,\n });\n\n const result = await runXcodebuild(args, options.onOutput);\n lastOutput = result.output;\n\n if (result.exitCode === 0) {\n // Tests passed\n break;\n }\n\n if (attempt < maxRetries) {\n // Parse failures for retry\n const failed = parseFailedTests(result.output);\n if (failed.length === 0) break; // No parseable failures\n\n currentOnlyTesting = failed.map((f) => f.onlyTestingArg);\n retryCount++;\n }\n }\n\n // Parse test counts from output\n const counts = parseTestCounts(lastOutput);\n const duration = (Date.now() - startTime) / 1000;\n\n return {\n success: counts.failures === 0,\n totalTests: counts.total,\n failures: counts.failures,\n skipped: counts.skipped,\n retries: retryCount,\n duration,\n reportPaths: existsSync(resultBundlePath) ? [resultBundlePath] : [],\n output: lastOutput,\n };\n}\n\nfunction runXcodebuild(\n args: string[],\n onOutput?: (chunk: string) => void\n): Promise<{ exitCode: number; output: string }> {\n return new Promise((resolve) => {\n const child = spawn(\"xcodebuild\", 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({ exitCode: code ?? 1, output }));\n });\n}\n\nfunction parseTestCounts(output: string): { total: number; failures: number; skipped: number } {\n // Match: \"Executed N tests, with M failures (X unexpected) in Y (Z) seconds\"\n const match = output.match(/Executed (\\d+) tests?, with (\\d+) failures?/);\n if (match) {\n return {\n total: parseInt(match[1], 10),\n failures: parseInt(match[2], 10),\n skipped: 0,\n };\n }\n return { total: 0, failures: 0, skipped: 0 };\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { F as FailedTest, S as ScanOptions, T as TestResult, b as buildTestCommand, p as parseFailedTests, r as runTests } from '../index-BimqCmY8.cjs';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { F as FailedTest, S as ScanOptions, T as TestResult, b as buildTestCommand, p as parseFailedTests, r as runTests } from '../index-BimqCmY8.js';
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { spawn } from 'child_process';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import { mkdirSync, existsSync } from 'fs';
|
|
4
|
+
|
|
5
|
+
// src/scan/index.ts
|
|
6
|
+
|
|
7
|
+
// src/xcode/platform.ts
|
|
8
|
+
function requireMacOS(feature) {
|
|
9
|
+
if (process.platform !== "darwin") {
|
|
10
|
+
throw new Error(
|
|
11
|
+
`${feature} requires macOS. This operation uses Xcode command-line tools which are not available on ${process.platform}.`
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// src/scan/command.ts
|
|
17
|
+
function buildTestCommand(options) {
|
|
18
|
+
const args = [];
|
|
19
|
+
if (options.clean) args.push("clean");
|
|
20
|
+
args.push("test");
|
|
21
|
+
if (options.workspace) args.push("-workspace", options.workspace);
|
|
22
|
+
else if (options.project) args.push("-project", options.project);
|
|
23
|
+
if (options.scheme) args.push("-scheme", options.scheme);
|
|
24
|
+
if (options.destination) {
|
|
25
|
+
args.push("-destination", options.destination);
|
|
26
|
+
} else if (options.devices && options.devices.length > 0) {
|
|
27
|
+
for (const device of options.devices) {
|
|
28
|
+
args.push("-destination", `platform=iOS Simulator,name=${device}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
if (options.testPlan) args.push("-testPlan", options.testPlan);
|
|
32
|
+
if (options.configuration) args.push("-configuration", options.configuration);
|
|
33
|
+
if (options.derivedDataPath) args.push("-derivedDataPath", options.derivedDataPath);
|
|
34
|
+
if (options.resultBundlePath) args.push("-resultBundlePath", options.resultBundlePath);
|
|
35
|
+
if (options.codeCoverage) args.push("-enableCodeCoverage", "YES");
|
|
36
|
+
if (options.onlyTesting) {
|
|
37
|
+
for (const test of options.onlyTesting) {
|
|
38
|
+
args.push("-only-testing:" + test);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
if (options.skipTesting) {
|
|
42
|
+
for (const test of options.skipTesting) {
|
|
43
|
+
args.push("-skip-testing:" + test);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if (options.parallelTesting !== void 0) {
|
|
47
|
+
args.push("-parallel-testing-enabled", options.parallelTesting ? "YES" : "NO");
|
|
48
|
+
}
|
|
49
|
+
if (options.concurrentWorkers !== void 0) {
|
|
50
|
+
args.push("-parallel-testing-worker-count", String(options.concurrentWorkers));
|
|
51
|
+
}
|
|
52
|
+
if (options.maxConcurrentSimulators !== void 0) {
|
|
53
|
+
args.push(
|
|
54
|
+
"-maximum-concurrent-test-simulator-destinations",
|
|
55
|
+
String(options.maxConcurrentSimulators)
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
if (options.disableConcurrentTesting) {
|
|
59
|
+
args.push("-disable-concurrent-destination-testing");
|
|
60
|
+
}
|
|
61
|
+
if (options.addressSanitizer !== void 0) {
|
|
62
|
+
args.push("-enableAddressSanitizer", options.addressSanitizer ? "YES" : "NO");
|
|
63
|
+
}
|
|
64
|
+
if (options.threadSanitizer !== void 0) {
|
|
65
|
+
args.push("-enableThreadSanitizer", options.threadSanitizer ? "YES" : "NO");
|
|
66
|
+
}
|
|
67
|
+
if (options.undefinedBehaviorSanitizer !== void 0) {
|
|
68
|
+
args.push(
|
|
69
|
+
"-enableUndefinedBehaviorSanitizer",
|
|
70
|
+
options.undefinedBehaviorSanitizer ? "YES" : "NO"
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
if (options.xcargs) args.push(...options.xcargs.split(/\s+/));
|
|
74
|
+
return args;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// src/scan/retry.ts
|
|
78
|
+
function parseFailedTests(output) {
|
|
79
|
+
const results = [];
|
|
80
|
+
const clean = output.replace(/\x1b\[[0-9;]*m/g, "");
|
|
81
|
+
const failingMatch = clean.match(/Failing tests:\s*\n([\s\S]*?)(?:\n\n|\n\*\*|$)/);
|
|
82
|
+
if (!failingMatch) return results;
|
|
83
|
+
const lines = failingMatch[1].split("\n");
|
|
84
|
+
for (const line of lines) {
|
|
85
|
+
const trimmed = line.trim();
|
|
86
|
+
if (!trimmed || trimmed.startsWith("*")) continue;
|
|
87
|
+
const bracketMatch = trimmed.match(/-\[(\w+)\s+(\w+)\]/);
|
|
88
|
+
if (bracketMatch) {
|
|
89
|
+
results.push({
|
|
90
|
+
target: "",
|
|
91
|
+
suite: bracketMatch[1],
|
|
92
|
+
testCase: bracketMatch[2],
|
|
93
|
+
onlyTestingArg: `${bracketMatch[1]}/${bracketMatch[2]}`
|
|
94
|
+
});
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
const slashMatch = trimmed.match(/^(\w+)\.(\w+)\/(\w+)$/);
|
|
98
|
+
if (slashMatch) {
|
|
99
|
+
results.push({
|
|
100
|
+
target: slashMatch[1],
|
|
101
|
+
suite: slashMatch[2],
|
|
102
|
+
testCase: slashMatch[3],
|
|
103
|
+
onlyTestingArg: `${slashMatch[1]}/${slashMatch[2]}/${slashMatch[3]}`
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return results;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// src/scan/index.ts
|
|
111
|
+
async function runTests(options) {
|
|
112
|
+
requireMacOS("scan");
|
|
113
|
+
const outputDir = options.outputDirectory ?? join(process.cwd(), "test_output");
|
|
114
|
+
mkdirSync(outputDir, { recursive: true });
|
|
115
|
+
const resultBundlePath = options.resultBundlePath ?? join(outputDir, "result.xcresult");
|
|
116
|
+
const maxRetries = options.maxRetries ?? 0;
|
|
117
|
+
let retryCount = 0;
|
|
118
|
+
let lastOutput = "";
|
|
119
|
+
let currentOnlyTesting = options.onlyTesting;
|
|
120
|
+
const startTime = Date.now();
|
|
121
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
122
|
+
const args = buildTestCommand({
|
|
123
|
+
...options,
|
|
124
|
+
resultBundlePath: attempt === 0 ? resultBundlePath : `${resultBundlePath}-retry-${attempt}`,
|
|
125
|
+
onlyTesting: currentOnlyTesting
|
|
126
|
+
});
|
|
127
|
+
const result = await runXcodebuild(args, options.onOutput);
|
|
128
|
+
lastOutput = result.output;
|
|
129
|
+
if (result.exitCode === 0) {
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
if (attempt < maxRetries) {
|
|
133
|
+
const failed = parseFailedTests(result.output);
|
|
134
|
+
if (failed.length === 0) break;
|
|
135
|
+
currentOnlyTesting = failed.map((f) => f.onlyTestingArg);
|
|
136
|
+
retryCount++;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
const counts = parseTestCounts(lastOutput);
|
|
140
|
+
const duration = (Date.now() - startTime) / 1e3;
|
|
141
|
+
return {
|
|
142
|
+
success: counts.failures === 0,
|
|
143
|
+
totalTests: counts.total,
|
|
144
|
+
failures: counts.failures,
|
|
145
|
+
skipped: counts.skipped,
|
|
146
|
+
retries: retryCount,
|
|
147
|
+
duration,
|
|
148
|
+
reportPaths: existsSync(resultBundlePath) ? [resultBundlePath] : [],
|
|
149
|
+
output: lastOutput
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
function runXcodebuild(args, onOutput) {
|
|
153
|
+
return new Promise((resolve) => {
|
|
154
|
+
const child = spawn("xcodebuild", args, { stdio: ["ignore", "pipe", "pipe"] });
|
|
155
|
+
let output = "";
|
|
156
|
+
child.stdout.on("data", (data) => {
|
|
157
|
+
const chunk = data.toString();
|
|
158
|
+
output += chunk;
|
|
159
|
+
onOutput?.(chunk);
|
|
160
|
+
});
|
|
161
|
+
child.stderr.on("data", (data) => {
|
|
162
|
+
const chunk = data.toString();
|
|
163
|
+
output += chunk;
|
|
164
|
+
onOutput?.(chunk);
|
|
165
|
+
});
|
|
166
|
+
child.on("close", (code) => resolve({ exitCode: code ?? 1, output }));
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
function parseTestCounts(output) {
|
|
170
|
+
const match = output.match(/Executed (\d+) tests?, with (\d+) failures?/);
|
|
171
|
+
if (match) {
|
|
172
|
+
return {
|
|
173
|
+
total: parseInt(match[1], 10),
|
|
174
|
+
failures: parseInt(match[2], 10),
|
|
175
|
+
skipped: 0
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
return { total: 0, failures: 0, skipped: 0 };
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export { buildTestCommand, parseFailedTests, runTests };
|
|
182
|
+
//# sourceMappingURL=index.mjs.map
|
|
183
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/xcode/platform.ts","../../src/scan/command.ts","../../src/scan/retry.ts","../../src/scan/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["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","export interface TestCommandOptions {\n scheme?: string;\n workspace?: string;\n project?: string;\n destination?: string;\n devices?: string[];\n testPlan?: string;\n onlyTesting?: string[];\n skipTesting?: string[];\n configuration?: string;\n derivedDataPath?: string;\n resultBundlePath?: string;\n codeCoverage?: boolean;\n xcargs?: string;\n clean?: boolean;\n // ── Parallel testing (Fastlane scan parity) ──────────────────────────────\n /** Enable `-parallel-testing-enabled YES`. */\n parallelTesting?: boolean;\n /** Sets `-parallel-testing-worker-count`. */\n concurrentWorkers?: number;\n /** Sets `-maximum-concurrent-test-simulator-destinations`. */\n maxConcurrentSimulators?: number;\n /** Explicitly disable concurrent destinations (`-disable-concurrent-destination-testing`). */\n disableConcurrentTesting?: boolean;\n // ── Sanitizers ───────────────────────────────────────────────────────────\n addressSanitizer?: boolean;\n threadSanitizer?: boolean;\n undefinedBehaviorSanitizer?: boolean;\n}\n\nexport function buildTestCommand(options: TestCommandOptions): string[] {\n const args: string[] = [];\n\n if (options.clean) args.push(\"clean\");\n args.push(\"test\");\n\n if (options.workspace) args.push(\"-workspace\", options.workspace);\n else if (options.project) args.push(\"-project\", options.project);\n\n if (options.scheme) args.push(\"-scheme\", options.scheme);\n\n // Destination\n if (options.destination) {\n args.push(\"-destination\", options.destination);\n } else if (options.devices && options.devices.length > 0) {\n for (const device of options.devices) {\n args.push(\"-destination\", `platform=iOS Simulator,name=${device}`);\n }\n }\n\n if (options.testPlan) args.push(\"-testPlan\", options.testPlan);\n if (options.configuration) args.push(\"-configuration\", options.configuration);\n if (options.derivedDataPath) args.push(\"-derivedDataPath\", options.derivedDataPath);\n if (options.resultBundlePath) args.push(\"-resultBundlePath\", options.resultBundlePath);\n\n if (options.codeCoverage) args.push(\"-enableCodeCoverage\", \"YES\");\n\n if (options.onlyTesting) {\n for (const test of options.onlyTesting) {\n args.push(\"-only-testing:\" + test);\n }\n }\n if (options.skipTesting) {\n for (const test of options.skipTesting) {\n args.push(\"-skip-testing:\" + test);\n }\n }\n\n // Parallel testing flags (xcodebuild native, not xcargs)\n if (options.parallelTesting !== undefined) {\n args.push(\"-parallel-testing-enabled\", options.parallelTesting ? \"YES\" : \"NO\");\n }\n if (options.concurrentWorkers !== undefined) {\n args.push(\"-parallel-testing-worker-count\", String(options.concurrentWorkers));\n }\n if (options.maxConcurrentSimulators !== undefined) {\n args.push(\n \"-maximum-concurrent-test-simulator-destinations\",\n String(options.maxConcurrentSimulators)\n );\n }\n if (options.disableConcurrentTesting) {\n args.push(\"-disable-concurrent-destination-testing\");\n }\n\n // Runtime sanitizers\n if (options.addressSanitizer !== undefined) {\n args.push(\"-enableAddressSanitizer\", options.addressSanitizer ? \"YES\" : \"NO\");\n }\n if (options.threadSanitizer !== undefined) {\n args.push(\"-enableThreadSanitizer\", options.threadSanitizer ? \"YES\" : \"NO\");\n }\n if (options.undefinedBehaviorSanitizer !== undefined) {\n args.push(\n \"-enableUndefinedBehaviorSanitizer\",\n options.undefinedBehaviorSanitizer ? \"YES\" : \"NO\"\n );\n }\n\n if (options.xcargs) args.push(...options.xcargs.split(/\\s+/));\n\n return args;\n}\n","export interface FailedTest {\n target: string;\n suite: string;\n testCase: string;\n onlyTestingArg: string;\n}\n\nexport function parseFailedTests(output: string): FailedTest[] {\n const results: FailedTest[] = [];\n // Strip ANSI color codes\n const clean = output.replace(/\\x1b\\[[0-9;]*m/g, \"\");\n\n // Look for \"Failing tests:\" section\n const failingMatch = clean.match(/Failing tests:\\s*\\n([\\s\\S]*?)(?:\\n\\n|\\n\\*\\*|$)/);\n if (!failingMatch) return results;\n\n const lines = failingMatch[1].split(\"\\n\");\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"*\")) continue;\n\n // Format: -[TestSuite testMethod] or TestTarget.TestSuite/testMethod\n const bracketMatch = trimmed.match(/-\\[(\\w+)\\s+(\\w+)\\]/);\n if (bracketMatch) {\n results.push({\n target: \"\",\n suite: bracketMatch[1],\n testCase: bracketMatch[2],\n onlyTestingArg: `${bracketMatch[1]}/${bracketMatch[2]}`,\n });\n continue;\n }\n\n const slashMatch = trimmed.match(/^(\\w+)\\.(\\w+)\\/(\\w+)$/);\n if (slashMatch) {\n results.push({\n target: slashMatch[1],\n suite: slashMatch[2],\n testCase: slashMatch[3],\n onlyTestingArg: `${slashMatch[1]}/${slashMatch[2]}/${slashMatch[3]}`,\n });\n }\n }\n\n return results;\n}\n","import { spawn } from \"node:child_process\";\nimport { join } from \"node:path\";\nimport { mkdirSync, existsSync } from \"node:fs\";\nimport { requireMacOS } from \"../xcode/platform.js\";\nimport { buildTestCommand } from \"./command.js\";\nimport { parseFailedTests } from \"./retry.js\";\n\nexport type { FailedTest } from \"./retry.js\";\nexport { buildTestCommand } from \"./command.js\";\nexport { parseFailedTests } from \"./retry.js\";\n\nexport interface ScanOptions {\n scheme?: string;\n workspace?: string;\n project?: string;\n devices?: string[];\n testPlan?: string;\n onlyTesting?: string[];\n skipTesting?: string[];\n configuration?: string;\n outputDirectory?: string;\n clean?: boolean;\n codeCoverage?: boolean;\n derivedDataPath?: string;\n resultBundlePath?: string;\n maxRetries?: number;\n xcargs?: string;\n onOutput?: (chunk: string) => void;\n}\n\nexport interface TestResult {\n success: boolean;\n totalTests: number;\n failures: number;\n skipped: number;\n retries: number;\n duration: number;\n reportPaths: string[];\n output: string;\n}\n\nexport async function runTests(options: ScanOptions): Promise<TestResult> {\n requireMacOS(\"scan\");\n\n const outputDir = options.outputDirectory ?? join(process.cwd(), \"test_output\");\n mkdirSync(outputDir, { recursive: true });\n\n const resultBundlePath = options.resultBundlePath ?? join(outputDir, \"result.xcresult\");\n const maxRetries = options.maxRetries ?? 0;\n let retryCount = 0;\n let lastOutput = \"\";\n let currentOnlyTesting = options.onlyTesting;\n\n const startTime = Date.now();\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n const args = buildTestCommand({\n ...options,\n resultBundlePath: attempt === 0 ? resultBundlePath : `${resultBundlePath}-retry-${attempt}`,\n onlyTesting: currentOnlyTesting,\n });\n\n const result = await runXcodebuild(args, options.onOutput);\n lastOutput = result.output;\n\n if (result.exitCode === 0) {\n // Tests passed\n break;\n }\n\n if (attempt < maxRetries) {\n // Parse failures for retry\n const failed = parseFailedTests(result.output);\n if (failed.length === 0) break; // No parseable failures\n\n currentOnlyTesting = failed.map((f) => f.onlyTestingArg);\n retryCount++;\n }\n }\n\n // Parse test counts from output\n const counts = parseTestCounts(lastOutput);\n const duration = (Date.now() - startTime) / 1000;\n\n return {\n success: counts.failures === 0,\n totalTests: counts.total,\n failures: counts.failures,\n skipped: counts.skipped,\n retries: retryCount,\n duration,\n reportPaths: existsSync(resultBundlePath) ? [resultBundlePath] : [],\n output: lastOutput,\n };\n}\n\nfunction runXcodebuild(\n args: string[],\n onOutput?: (chunk: string) => void\n): Promise<{ exitCode: number; output: string }> {\n return new Promise((resolve) => {\n const child = spawn(\"xcodebuild\", 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({ exitCode: code ?? 1, output }));\n });\n}\n\nfunction parseTestCounts(output: string): { total: number; failures: number; skipped: number } {\n // Match: \"Executed N tests, with M failures (X unexpected) in Y (Z) seconds\"\n const match = output.match(/Executed (\\d+) tests?, with (\\d+) failures?/);\n if (match) {\n return {\n total: parseInt(match[1], 10),\n failures: parseInt(match[2], 10),\n skipped: 0,\n };\n }\n return { total: 0, failures: 0, skipped: 0 };\n}\n"]}
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var promises = require('fs/promises');
|
|
4
|
+
var path = require('path');
|
|
5
|
+
var os = require('os');
|
|
6
|
+
|
|
7
|
+
// src/sigh/index.ts
|
|
8
|
+
function resolveProfileType(options) {
|
|
9
|
+
if (options.profileType) return options.profileType;
|
|
10
|
+
const platform = options.platform ?? "ios";
|
|
11
|
+
const isDev = options.development ?? false;
|
|
12
|
+
const isAdhoc = options.adhoc ?? false;
|
|
13
|
+
const isInHouse = options.inHouse ?? false;
|
|
14
|
+
switch (platform) {
|
|
15
|
+
case "macos":
|
|
16
|
+
if (isDev) return "MAC_APP_DEVELOPMENT";
|
|
17
|
+
if (isInHouse) return "MAC_APP_INHOUSE";
|
|
18
|
+
return "MAC_APP_STORE";
|
|
19
|
+
case "tvos":
|
|
20
|
+
if (isDev) return "TVOS_APP_DEVELOPMENT";
|
|
21
|
+
if (isAdhoc) return "TVOS_APP_ADHOC";
|
|
22
|
+
if (isInHouse) return "TVOS_APP_INHOUSE";
|
|
23
|
+
return "TVOS_APP_STORE";
|
|
24
|
+
case "catalyst":
|
|
25
|
+
if (isDev) return "MAC_CATALYST_APP_DEVELOPMENT";
|
|
26
|
+
if (isInHouse) return "MAC_CATALYST_APP_INHOUSE";
|
|
27
|
+
return "MAC_CATALYST_APP_STORE";
|
|
28
|
+
default:
|
|
29
|
+
if (isDev) return "IOS_APP_DEVELOPMENT";
|
|
30
|
+
if (isAdhoc) return "IOS_APP_ADHOC";
|
|
31
|
+
if (isInHouse) return "IOS_APP_INHOUSE";
|
|
32
|
+
return "IOS_APP_STORE";
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
function certificateTypesForProfile(profileType) {
|
|
36
|
+
switch (profileType) {
|
|
37
|
+
case "IOS_APP_DEVELOPMENT":
|
|
38
|
+
case "TVOS_APP_DEVELOPMENT":
|
|
39
|
+
case "MAC_CATALYST_APP_DEVELOPMENT":
|
|
40
|
+
return ["IOS_DEVELOPMENT"];
|
|
41
|
+
case "MAC_APP_DEVELOPMENT":
|
|
42
|
+
return ["MAC_APP_DEVELOPMENT"];
|
|
43
|
+
case "IOS_APP_STORE":
|
|
44
|
+
case "IOS_APP_ADHOC":
|
|
45
|
+
case "TVOS_APP_STORE":
|
|
46
|
+
case "TVOS_APP_ADHOC":
|
|
47
|
+
case "MAC_CATALYST_APP_STORE":
|
|
48
|
+
return ["IOS_DISTRIBUTION"];
|
|
49
|
+
case "IOS_APP_INHOUSE":
|
|
50
|
+
case "TVOS_APP_INHOUSE":
|
|
51
|
+
case "MAC_CATALYST_APP_INHOUSE":
|
|
52
|
+
return ["IOS_DISTRIBUTION"];
|
|
53
|
+
case "MAC_APP_STORE":
|
|
54
|
+
case "MAC_APP_INHOUSE":
|
|
55
|
+
return ["MAC_APP_DISTRIBUTION"];
|
|
56
|
+
case "MAC_APP_DIRECT":
|
|
57
|
+
return ["DEVELOPER_ID_APPLICATION"];
|
|
58
|
+
default:
|
|
59
|
+
return ["IOS_DISTRIBUTION"];
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function needsDevices(profileType) {
|
|
63
|
+
return profileType.includes("DEVELOPMENT") || profileType.includes("ADHOC");
|
|
64
|
+
}
|
|
65
|
+
function profileExtension(profileType) {
|
|
66
|
+
return profileType.startsWith("MAC_") && !profileType.includes("CATALYST") ? ".provisionprofile" : ".mobileprovision";
|
|
67
|
+
}
|
|
68
|
+
async function findMatchingProfile(options) {
|
|
69
|
+
const profileType = resolveProfileType(options);
|
|
70
|
+
const profiles = await options.client.profiles.list({
|
|
71
|
+
filter: { profileType },
|
|
72
|
+
include: "bundleId",
|
|
73
|
+
limit: 200
|
|
74
|
+
});
|
|
75
|
+
const now = /* @__PURE__ */ new Date();
|
|
76
|
+
for (const profile of profiles) {
|
|
77
|
+
const bundleIdRel = profile.relationships?.bundleId?.data;
|
|
78
|
+
if (bundleIdRel) {
|
|
79
|
+
const bundleId = await options.client.bundleIds.get(bundleIdRel.id);
|
|
80
|
+
if (bundleId.attributes.identifier !== options.bundleIdentifier) continue;
|
|
81
|
+
}
|
|
82
|
+
if (profile.attributes.profileState !== "ACTIVE") continue;
|
|
83
|
+
if (new Date(profile.attributes.expirationDate) <= now) continue;
|
|
84
|
+
if (options.profileName && profile.attributes.name !== options.profileName) {
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
return profile;
|
|
88
|
+
}
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
async function createProfile(options) {
|
|
92
|
+
const profileType = resolveProfileType(options);
|
|
93
|
+
if (options.force) {
|
|
94
|
+
const existing = await findMatchingProfile(options);
|
|
95
|
+
if (existing) {
|
|
96
|
+
await options.client.profiles.delete(existing.id);
|
|
97
|
+
}
|
|
98
|
+
} else {
|
|
99
|
+
const existing = await findMatchingProfile(options);
|
|
100
|
+
if (existing) {
|
|
101
|
+
return downloadAndReturn(options, existing);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
let bundleId = await options.client.bundleIds.find(options.bundleIdentifier);
|
|
105
|
+
if (!bundleId) {
|
|
106
|
+
throw new Error(
|
|
107
|
+
`Bundle ID '${options.bundleIdentifier}' not found. Register it first with produce.registerBundleId().`
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
const certTypes = certificateTypesForProfile(profileType);
|
|
111
|
+
let certificateIds = options.certificateIds;
|
|
112
|
+
if (!certificateIds || certificateIds.length === 0) {
|
|
113
|
+
const certs = await options.client.certificates.list({
|
|
114
|
+
filter: { certificateType: certTypes }
|
|
115
|
+
});
|
|
116
|
+
const now = /* @__PURE__ */ new Date();
|
|
117
|
+
const validCerts = certs.filter(
|
|
118
|
+
(c) => new Date(c.attributes.expirationDate) > now
|
|
119
|
+
);
|
|
120
|
+
if (validCerts.length === 0) {
|
|
121
|
+
throw new Error(
|
|
122
|
+
`No valid certificates found of type ${certTypes.join(", ")}. Create one first with cert.createCertificate().`
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
certificateIds = options.includeAllCertificates ? validCerts.map((c) => c.id) : [validCerts[0].id];
|
|
126
|
+
}
|
|
127
|
+
let deviceIds = options.deviceIds;
|
|
128
|
+
if (needsDevices(profileType) && (!deviceIds || deviceIds.length === 0)) {
|
|
129
|
+
const platform = options.platform === "macos" ? "MAC_OS" : options.platform === "tvos" ? "TVOS" : "IOS";
|
|
130
|
+
const devices = await options.client.devices.list({
|
|
131
|
+
filter: { platform, status: "ENABLED" }
|
|
132
|
+
});
|
|
133
|
+
deviceIds = devices.map((d) => d.id);
|
|
134
|
+
}
|
|
135
|
+
const profileName = options.profileName ?? `${profileType} ${options.bundleIdentifier} ${Date.now()}`;
|
|
136
|
+
const profile = await options.client.profiles.create({
|
|
137
|
+
name: profileName,
|
|
138
|
+
profileType,
|
|
139
|
+
bundleIdId: bundleId.id,
|
|
140
|
+
certificateIds,
|
|
141
|
+
deviceIds
|
|
142
|
+
});
|
|
143
|
+
return downloadAndReturn(options, profile);
|
|
144
|
+
}
|
|
145
|
+
async function downloadAndReturn(options, profile) {
|
|
146
|
+
const content = Buffer.from(profile.attributes.profileContent, "base64");
|
|
147
|
+
const profileType = resolveProfileType(options);
|
|
148
|
+
const ext = profileExtension(profileType);
|
|
149
|
+
const result = {
|
|
150
|
+
profile,
|
|
151
|
+
profileContent: content,
|
|
152
|
+
uuid: profile.attributes.uuid,
|
|
153
|
+
name: profile.attributes.name
|
|
154
|
+
};
|
|
155
|
+
if (options.outputDir) {
|
|
156
|
+
await promises.mkdir(options.outputDir, { recursive: true });
|
|
157
|
+
const filename = `${profileType}_${options.bundleIdentifier}${ext}`;
|
|
158
|
+
const filePath = path.join(options.outputDir, filename);
|
|
159
|
+
await promises.writeFile(filePath, content);
|
|
160
|
+
result.filePath = filePath;
|
|
161
|
+
}
|
|
162
|
+
if (!options.skipInstall && process.platform === "darwin") {
|
|
163
|
+
await installProfile(content, profile.attributes.uuid);
|
|
164
|
+
}
|
|
165
|
+
return result;
|
|
166
|
+
}
|
|
167
|
+
async function downloadProfile(client, id) {
|
|
168
|
+
const profile = await client.profiles.get(id);
|
|
169
|
+
return Buffer.from(profile.attributes.profileContent, "base64");
|
|
170
|
+
}
|
|
171
|
+
async function installProfile(profileContent, uuid) {
|
|
172
|
+
const legacyDir = path.join(
|
|
173
|
+
os.homedir(),
|
|
174
|
+
"Library",
|
|
175
|
+
"MobileDevice",
|
|
176
|
+
"Provisioning Profiles"
|
|
177
|
+
);
|
|
178
|
+
const xcode16Dir = path.join(
|
|
179
|
+
os.homedir(),
|
|
180
|
+
"Library",
|
|
181
|
+
"Developer",
|
|
182
|
+
"Xcode",
|
|
183
|
+
"UserData",
|
|
184
|
+
"Provisioning Profiles"
|
|
185
|
+
);
|
|
186
|
+
const filename = `${uuid}.mobileprovision`;
|
|
187
|
+
await promises.mkdir(legacyDir, { recursive: true });
|
|
188
|
+
const legacyPath = path.join(legacyDir, filename);
|
|
189
|
+
await promises.writeFile(legacyPath, profileContent);
|
|
190
|
+
try {
|
|
191
|
+
await promises.mkdir(xcode16Dir, { recursive: true });
|
|
192
|
+
await promises.writeFile(path.join(xcode16Dir, filename), profileContent);
|
|
193
|
+
} catch {
|
|
194
|
+
}
|
|
195
|
+
return legacyPath;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
exports.createProfile = createProfile;
|
|
199
|
+
exports.downloadProfile = downloadProfile;
|
|
200
|
+
exports.findMatchingProfile = findMatchingProfile;
|
|
201
|
+
exports.installProfile = installProfile;
|
|
202
|
+
//# sourceMappingURL=index.cjs.map
|
|
203
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/sigh/index.ts"],"names":["mkdir","join","writeFile","homedir"],"mappings":"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","file":"index.cjs","sourcesContent":["import { writeFile, mkdir, copyFile } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { homedir } from \"node:os\";\nimport type { AppStoreConnectClient } from \"../client/index.js\";\nimport type { Profile, ProfileType, CertificateType, Platform } from \"../types/index.js\";\n\nexport interface SighOptions {\n client: AppStoreConnectClient;\n bundleIdentifier: string;\n profileType?: ProfileType;\n profileName?: string;\n certificateIds?: string[];\n deviceIds?: string[];\n force?: boolean;\n outputDir?: string;\n platform?: \"ios\" | \"macos\" | \"tvos\" | \"catalyst\";\n development?: boolean;\n adhoc?: boolean;\n inHouse?: boolean;\n readonly?: boolean;\n skipInstall?: boolean;\n skipCertificateVerification?: boolean;\n includeAllCertificates?: boolean;\n}\n\nexport interface SighResult {\n profile: Profile;\n profileContent: Buffer;\n uuid: string;\n name: string;\n filePath?: string;\n}\n\nfunction resolveProfileType(options: SighOptions): ProfileType {\n if (options.profileType) return options.profileType;\n\n const platform = options.platform ?? \"ios\";\n const isDev = options.development ?? false;\n const isAdhoc = options.adhoc ?? false;\n const isInHouse = options.inHouse ?? false;\n\n switch (platform) {\n case \"macos\":\n if (isDev) return \"MAC_APP_DEVELOPMENT\";\n if (isInHouse) return \"MAC_APP_INHOUSE\";\n return \"MAC_APP_STORE\";\n case \"tvos\":\n if (isDev) return \"TVOS_APP_DEVELOPMENT\";\n if (isAdhoc) return \"TVOS_APP_ADHOC\";\n if (isInHouse) return \"TVOS_APP_INHOUSE\";\n return \"TVOS_APP_STORE\";\n case \"catalyst\":\n if (isDev) return \"MAC_CATALYST_APP_DEVELOPMENT\";\n if (isInHouse) return \"MAC_CATALYST_APP_INHOUSE\";\n return \"MAC_CATALYST_APP_STORE\";\n default:\n if (isDev) return \"IOS_APP_DEVELOPMENT\";\n if (isAdhoc) return \"IOS_APP_ADHOC\";\n if (isInHouse) return \"IOS_APP_INHOUSE\";\n return \"IOS_APP_STORE\";\n }\n}\n\nfunction certificateTypesForProfile(\n profileType: ProfileType\n): CertificateType[] {\n switch (profileType) {\n case \"IOS_APP_DEVELOPMENT\":\n case \"TVOS_APP_DEVELOPMENT\":\n case \"MAC_CATALYST_APP_DEVELOPMENT\":\n return [\"IOS_DEVELOPMENT\"];\n case \"MAC_APP_DEVELOPMENT\":\n return [\"MAC_APP_DEVELOPMENT\"];\n case \"IOS_APP_STORE\":\n case \"IOS_APP_ADHOC\":\n case \"TVOS_APP_STORE\":\n case \"TVOS_APP_ADHOC\":\n case \"MAC_CATALYST_APP_STORE\":\n return [\"IOS_DISTRIBUTION\"];\n case \"IOS_APP_INHOUSE\":\n case \"TVOS_APP_INHOUSE\":\n case \"MAC_CATALYST_APP_INHOUSE\":\n return [\"IOS_DISTRIBUTION\"];\n case \"MAC_APP_STORE\":\n case \"MAC_APP_INHOUSE\":\n return [\"MAC_APP_DISTRIBUTION\"];\n case \"MAC_APP_DIRECT\":\n return [\"DEVELOPER_ID_APPLICATION\"];\n default:\n return [\"IOS_DISTRIBUTION\"];\n }\n}\n\nfunction needsDevices(profileType: ProfileType): boolean {\n return (\n profileType.includes(\"DEVELOPMENT\") || profileType.includes(\"ADHOC\")\n );\n}\n\nfunction profileExtension(profileType: ProfileType): string {\n return profileType.startsWith(\"MAC_\") && !profileType.includes(\"CATALYST\")\n ? \".provisionprofile\"\n : \".mobileprovision\";\n}\n\nexport async function findMatchingProfile(\n options: Omit<SighOptions, \"force\">\n): Promise<Profile | null> {\n const profileType = resolveProfileType(options as SighOptions);\n const profiles = await options.client.profiles.list({\n filter: { profileType },\n include: \"bundleId\",\n limit: 200,\n });\n\n const now = new Date();\n for (const profile of profiles) {\n // Check bundle ID match\n const bundleIdRel = profile.relationships?.bundleId?.data;\n if (bundleIdRel) {\n const bundleId = await options.client.bundleIds.get(bundleIdRel.id);\n if (bundleId.attributes.identifier !== options.bundleIdentifier) continue;\n }\n\n // Check state and expiration\n if (profile.attributes.profileState !== \"ACTIVE\") continue;\n if (new Date(profile.attributes.expirationDate) <= now) continue;\n\n // Check name if specified\n if (\n options.profileName &&\n profile.attributes.name !== options.profileName\n ) {\n continue;\n }\n\n return profile;\n }\n\n return null;\n}\n\nexport async function createProfile(\n options: SighOptions\n): Promise<SighResult> {\n const profileType = resolveProfileType(options);\n\n // If force, delete existing first\n if (options.force) {\n const existing = await findMatchingProfile(options);\n if (existing) {\n await options.client.profiles.delete(existing.id);\n }\n } else {\n // Check for existing\n const existing = await findMatchingProfile(options);\n if (existing) {\n return downloadAndReturn(options, existing);\n }\n }\n\n // Find or verify bundle ID\n let bundleId = await options.client.bundleIds.find(options.bundleIdentifier);\n if (!bundleId) {\n throw new Error(\n `Bundle ID '${options.bundleIdentifier}' not found. Register it first with produce.registerBundleId().`\n );\n }\n\n // Get certificates\n const certTypes = certificateTypesForProfile(profileType);\n let certificateIds = options.certificateIds;\n if (!certificateIds || certificateIds.length === 0) {\n const certs = await options.client.certificates.list({\n filter: { certificateType: certTypes },\n });\n const now = new Date();\n const validCerts = certs.filter(\n (c) => new Date(c.attributes.expirationDate) > now\n );\n if (validCerts.length === 0) {\n throw new Error(\n `No valid certificates found of type ${certTypes.join(\", \")}. Create one first with cert.createCertificate().`\n );\n }\n certificateIds = options.includeAllCertificates\n ? validCerts.map((c) => c.id)\n : [validCerts[0].id];\n }\n\n // Get devices if needed\n let deviceIds = options.deviceIds;\n if (needsDevices(profileType) && (!deviceIds || deviceIds.length === 0)) {\n const platform: Platform =\n options.platform === \"macos\"\n ? \"MAC_OS\"\n : options.platform === \"tvos\"\n ? \"TVOS\"\n : \"IOS\";\n const devices = await options.client.devices.list({\n filter: { platform, status: \"ENABLED\" },\n });\n deviceIds = devices.map((d) => d.id);\n }\n\n // Generate profile name\n const profileName =\n options.profileName ??\n `${profileType} ${options.bundleIdentifier} ${Date.now()}`;\n\n // Create profile\n const profile = await options.client.profiles.create({\n name: profileName,\n profileType,\n bundleIdId: bundleId.id,\n certificateIds,\n deviceIds,\n });\n\n return downloadAndReturn(options, profile);\n}\n\nasync function downloadAndReturn(\n options: SighOptions,\n profile: Profile\n): Promise<SighResult> {\n const content = Buffer.from(profile.attributes.profileContent, \"base64\");\n const profileType = resolveProfileType(options);\n const ext = profileExtension(profileType);\n\n const result: SighResult = {\n profile,\n profileContent: content,\n uuid: profile.attributes.uuid,\n name: profile.attributes.name,\n };\n\n if (options.outputDir) {\n await mkdir(options.outputDir, { recursive: true });\n const filename = `${profileType}_${options.bundleIdentifier}${ext}`;\n const filePath = join(options.outputDir, filename);\n await writeFile(filePath, content);\n result.filePath = filePath;\n }\n\n // Install on macOS\n if (!options.skipInstall && process.platform === \"darwin\") {\n await installProfile(content, profile.attributes.uuid);\n }\n\n return result;\n}\n\nexport async function downloadProfile(\n client: AppStoreConnectClient,\n id: string\n): Promise<Buffer> {\n const profile = await client.profiles.get(id);\n return Buffer.from(profile.attributes.profileContent, \"base64\");\n}\n\n/**\n * Install a provisioning profile to both the legacy MobileDevice directory\n * (Xcode ≤ 15) and the new Xcode 16+ location. Xcode 16 moved the default\n * profiles directory to `~/Library/Developer/Xcode/UserData/Provisioning\n * Profiles/`; writing to both keeps old and new Xcodes happy without needing\n * to detect the installed Xcode version.\n *\n * Returns the legacy path as the primary install location.\n */\nexport async function installProfile(\n profileContent: Buffer,\n uuid: string\n): Promise<string> {\n const legacyDir = join(\n homedir(),\n \"Library\",\n \"MobileDevice\",\n \"Provisioning Profiles\"\n );\n const xcode16Dir = join(\n homedir(),\n \"Library\",\n \"Developer\",\n \"Xcode\",\n \"UserData\",\n \"Provisioning Profiles\"\n );\n const filename = `${uuid}.mobileprovision`;\n\n await mkdir(legacyDir, { recursive: true });\n const legacyPath = join(legacyDir, filename);\n await writeFile(legacyPath, profileContent);\n\n // Also install into the Xcode 16+ location. Non-fatal if it fails\n // (e.g. sandboxed environments).\n try {\n await mkdir(xcode16Dir, { recursive: true });\n await writeFile(join(xcode16Dir, filename), profileContent);\n } catch {\n // Ignore — legacy path install is the authoritative one.\n }\n\n return legacyPath;\n}\n"]}
|