@tamagui/native-ci 1.139.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 +320 -0
- package/action.yml +98 -0
- package/actions/fingerprint/action.yml +110 -0
- package/actions/test-detox-android/action.yml +70 -0
- package/actions/test-detox-ios/action.yml +66 -0
- package/dist/cache.js +71 -0
- package/dist/cache.js.map +6 -0
- package/dist/cache.mjs +73 -0
- package/dist/cache.mjs.map +1 -0
- package/dist/cli.js +275 -0
- package/dist/cli.js.map +6 -0
- package/dist/cli.mjs +306 -0
- package/dist/cli.mjs.map +1 -0
- package/dist/constants.js +12 -0
- package/dist/constants.js.map +6 -0
- package/dist/constants.mjs +10 -0
- package/dist/constants.mjs.map +1 -0
- package/dist/deps.js +44 -0
- package/dist/deps.js.map +6 -0
- package/dist/deps.mjs +53 -0
- package/dist/deps.mjs.map +1 -0
- package/dist/detox.js +49 -0
- package/dist/detox.js.map +6 -0
- package/dist/detox.mjs +55 -0
- package/dist/detox.mjs.map +1 -0
- package/dist/fingerprint.js +43 -0
- package/dist/fingerprint.js.map +6 -0
- package/dist/fingerprint.mjs +40 -0
- package/dist/fingerprint.mjs.map +1 -0
- package/dist/index.js +90 -0
- package/dist/index.js.map +6 -0
- package/dist/index.mjs +11 -0
- package/dist/index.mjs.map +1 -0
- package/dist/metro.js +79 -0
- package/dist/metro.js.map +6 -0
- package/dist/metro.mjs +75 -0
- package/dist/metro.mjs.map +1 -0
- package/dist/runner.js +73 -0
- package/dist/runner.js.map +6 -0
- package/dist/runner.mjs +73 -0
- package/dist/runner.mjs.map +1 -0
- package/package.json +50 -0
- package/src/android.ts +103 -0
- package/src/cache.ts +144 -0
- package/src/cli.ts +513 -0
- package/src/constants.ts +30 -0
- package/src/deps.ts +109 -0
- package/src/detox.ts +102 -0
- package/src/fingerprint.ts +77 -0
- package/src/index.ts +86 -0
- package/src/ios.ts +38 -0
- package/src/metro.ts +157 -0
- package/src/run-detox-android.ts +49 -0
- package/src/run-detox-ios.ts +40 -0
- package/src/runner.ts +123 -0
- package/types/android.d.ts +32 -0
- package/types/android.d.ts.map +1 -0
- package/types/cache.d.ts +41 -0
- package/types/cache.d.ts.map +1 -0
- package/types/cli.d.ts +11 -0
- package/types/cli.d.ts.map +1 -0
- package/types/constants.d.ts +18 -0
- package/types/constants.d.ts.map +1 -0
- package/types/deps.d.ts +32 -0
- package/types/deps.d.ts.map +1 -0
- package/types/detox.d.ts +39 -0
- package/types/detox.d.ts.map +1 -0
- package/types/fingerprint.d.ts +21 -0
- package/types/fingerprint.d.ts.map +1 -0
- package/types/index.d.ts +16 -0
- package/types/index.d.ts.map +1 -0
- package/types/ios.d.ts +18 -0
- package/types/ios.d.ts.map +1 -0
- package/types/metro.d.ts +51 -0
- package/types/metro.d.ts.map +1 -0
- package/types/run-detox-android.d.ts +15 -0
- package/types/run-detox-android.d.ts.map +1 -0
- package/types/run-detox-ios.d.ts +14 -0
- package/types/run-detox-ios.d.ts.map +1 -0
- package/types/runner.d.ts +35 -0
- package/types/runner.d.ts.map +1 -0
package/dist/cache.js
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { DEFAULT_KV_TTL_SECONDS } from "./constants";
|
|
4
|
+
function createCacheKey(options) {
|
|
5
|
+
const { platform, fingerprint, prefix = "native-build" } = options;
|
|
6
|
+
return `${prefix}-${platform}-${fingerprint}`;
|
|
7
|
+
}
|
|
8
|
+
async function saveFingerprintToKV(kv, key, fingerprint, ttlSeconds = DEFAULT_KV_TTL_SECONDS) {
|
|
9
|
+
try {
|
|
10
|
+
const response = await fetch(`${kv.url}/SETEX/${key}/${ttlSeconds}/${fingerprint}`, {
|
|
11
|
+
method: "POST",
|
|
12
|
+
headers: {
|
|
13
|
+
Authorization: `Bearer ${kv.token}`
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
if (!response.ok)
|
|
17
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
18
|
+
} catch (error) {
|
|
19
|
+
throw error instanceof TypeError ? new Error(`Network error connecting to KV store: ${error.message}`) : new Error(`Failed to save fingerprint to KV: ${error.message}`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
async function getFingerprintFromKV(kv, key) {
|
|
23
|
+
try {
|
|
24
|
+
const response = await fetch(`${kv.url}/get/${key}`, {
|
|
25
|
+
headers: {
|
|
26
|
+
Authorization: `Bearer ${kv.token}`
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
if (!response.ok)
|
|
30
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
31
|
+
const data = await response.json();
|
|
32
|
+
return data.result === "null" ? null : data.result;
|
|
33
|
+
} catch (error) {
|
|
34
|
+
throw error instanceof TypeError ? new Error(`Network error connecting to KV store: ${error.message}`) : new Error(`Failed to get fingerprint from KV: ${error.message}`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
async function extendKVTTL(kv, key, ttlSeconds = DEFAULT_KV_TTL_SECONDS) {
|
|
38
|
+
try {
|
|
39
|
+
await fetch(`${kv.url}/EXPIRE/${key}/${ttlSeconds}`, {
|
|
40
|
+
method: "POST",
|
|
41
|
+
headers: {
|
|
42
|
+
Authorization: `Bearer ${kv.token}`
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
} catch (error) {
|
|
46
|
+
console.warn(`Failed to extend KV TTL: ${error.message}`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function saveCache(filePath, data, options = {}) {
|
|
50
|
+
const { cacheDir } = options, cachePath = cacheDir ? join(process.cwd(), cacheDir, filePath) : join(process.cwd(), filePath);
|
|
51
|
+
mkdirSync(dirname(cachePath), { recursive: !0 }), writeFileSync(cachePath, JSON.stringify(data, null, 2));
|
|
52
|
+
}
|
|
53
|
+
function loadCache(filePath, options = {}) {
|
|
54
|
+
const { cacheDir } = options, cachePath = cacheDir ? join(process.cwd(), cacheDir, filePath) : join(process.cwd(), filePath);
|
|
55
|
+
if (!existsSync(cachePath))
|
|
56
|
+
return null;
|
|
57
|
+
try {
|
|
58
|
+
return JSON.parse(readFileSync(cachePath, "utf-8"));
|
|
59
|
+
} catch {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
export {
|
|
64
|
+
createCacheKey,
|
|
65
|
+
extendKVTTL,
|
|
66
|
+
getFingerprintFromKV,
|
|
67
|
+
loadCache,
|
|
68
|
+
saveCache,
|
|
69
|
+
saveFingerprintToKV
|
|
70
|
+
};
|
|
71
|
+
//# sourceMappingURL=cache.js.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/cache.ts"],
|
|
4
|
+
"mappings": "AAAA,SAAS,YAAY,cAAc,eAAe,iBAAiB;AACnE,SAAS,SAAS,YAAY;AAC9B,SAAS,8BAA6C;AAgB/C,SAAS,eAAe,SAA+B;AAC5D,QAAM,EAAE,UAAU,aAAa,SAAS,eAAe,IAAI;AAC3D,SAAO,GAAG,MAAM,IAAI,QAAQ,IAAI,WAAW;AAC7C;AAMA,eAAsB,oBACpB,IACA,KACA,aACA,aAAa,wBACE;AACf,MAAI;AACF,UAAM,WAAW,MAAM,MAAM,GAAG,GAAG,GAAG,UAAU,GAAG,IAAI,UAAU,IAAI,WAAW,IAAI;AAAA,MAClF,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,eAAe,UAAU,GAAG,KAAK;AAAA,MACnC;AAAA,IACF,CAAC;AAED,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI,MAAM,QAAQ,SAAS,MAAM,KAAK,SAAS,UAAU,EAAE;AAAA,EAErE,SAAS,OAAO;AACd,UAAI,iBAAiB,YACb,IAAI,MAAM,yCAA0C,MAAgB,OAAO,EAAE,IAE/E,IAAI,MAAM,qCAAsC,MAAgB,OAAO,EAAE;AAAA,EACjF;AACF;AAKA,eAAsB,qBACpB,IACA,KACwB;AACxB,MAAI;AACF,UAAM,WAAW,MAAM,MAAM,GAAG,GAAG,GAAG,QAAQ,GAAG,IAAI;AAAA,MACnD,SAAS;AAAA,QACP,eAAe,UAAU,GAAG,KAAK;AAAA,MACnC;AAAA,IACF,CAAC;AAED,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI,MAAM,QAAQ,SAAS,MAAM,KAAK,SAAS,UAAU,EAAE;AAGnE,UAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,WAAO,KAAK,WAAW,SAAS,OAAO,KAAK;AAAA,EAC9C,SAAS,OAAO;AACd,UAAI,iBAAiB,YACb,IAAI,MAAM,yCAA0C,MAAgB,OAAO,EAAE,IAE/E,IAAI,MAAM,sCAAuC,MAAgB,OAAO,EAAE;AAAA,EAClF;AACF;AAKA,eAAsB,YACpB,IACA,KACA,aAAa,wBACE;AACf,MAAI;AACF,UAAM,MAAM,GAAG,GAAG,GAAG,WAAW,GAAG,IAAI,UAAU,IAAI;AAAA,MACnD,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,eAAe,UAAU,GAAG,KAAK;AAAA,MACnC;AAAA,IACF,CAAC;AAAA,EACH,SAAS,OAAO;AAEd,YAAQ,KAAK,4BAA6B,MAAgB,OAAO,EAAE;AAAA,EACrE;AACF;AAYO,SAAS,UACd,UACA,MACA,UAA6B,CAAC,GACxB;AACN,QAAM,EAAE,SAAS,IAAI,SACf,YAAY,WAAW,KAAK,QAAQ,IAAI,GAAG,UAAU,QAAQ,IAAI,KAAK,QAAQ,IAAI,GAAG,QAAQ;AAEnG,YAAU,QAAQ,SAAS,GAAG,EAAE,WAAW,GAAK,CAAC,GACjD,cAAc,WAAW,KAAK,UAAU,MAAM,MAAM,CAAC,CAAC;AACxD;AAMO,SAAS,UACd,UACA,UAA6B,CAAC,GACpB;AACV,QAAM,EAAE,SAAS,IAAI,SACf,YAAY,WAAW,KAAK,QAAQ,IAAI,GAAG,UAAU,QAAQ,IAAI,KAAK,QAAQ,IAAI,GAAG,QAAQ;AAEnG,MAAI,CAAC,WAAW,SAAS;AACvB,WAAO;AAGT,MAAI;AACF,WAAO,KAAK,MAAM,aAAa,WAAW,OAAO,CAAC;AAAA,EACpD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;",
|
|
5
|
+
"names": []
|
|
6
|
+
}
|
package/dist/cache.mjs
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { DEFAULT_KV_TTL_SECONDS } from "./constants.mjs";
|
|
4
|
+
function createCacheKey(options) {
|
|
5
|
+
const {
|
|
6
|
+
platform,
|
|
7
|
+
fingerprint,
|
|
8
|
+
prefix = "native-build"
|
|
9
|
+
} = options;
|
|
10
|
+
return `${prefix}-${platform}-${fingerprint}`;
|
|
11
|
+
}
|
|
12
|
+
async function saveFingerprintToKV(kv, key, fingerprint, ttlSeconds = DEFAULT_KV_TTL_SECONDS) {
|
|
13
|
+
try {
|
|
14
|
+
const response = await fetch(`${kv.url}/SETEX/${key}/${ttlSeconds}/${fingerprint}`, {
|
|
15
|
+
method: "POST",
|
|
16
|
+
headers: {
|
|
17
|
+
Authorization: `Bearer ${kv.token}`
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
if (!response.ok) throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
21
|
+
} catch (error) {
|
|
22
|
+
throw error instanceof TypeError ? new Error(`Network error connecting to KV store: ${error.message}`) : new Error(`Failed to save fingerprint to KV: ${error.message}`);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
async function getFingerprintFromKV(kv, key) {
|
|
26
|
+
try {
|
|
27
|
+
const response = await fetch(`${kv.url}/get/${key}`, {
|
|
28
|
+
headers: {
|
|
29
|
+
Authorization: `Bearer ${kv.token}`
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
if (!response.ok) throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
33
|
+
const data = await response.json();
|
|
34
|
+
return data.result === "null" ? null : data.result;
|
|
35
|
+
} catch (error) {
|
|
36
|
+
throw error instanceof TypeError ? new Error(`Network error connecting to KV store: ${error.message}`) : new Error(`Failed to get fingerprint from KV: ${error.message}`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
async function extendKVTTL(kv, key, ttlSeconds = DEFAULT_KV_TTL_SECONDS) {
|
|
40
|
+
try {
|
|
41
|
+
await fetch(`${kv.url}/EXPIRE/${key}/${ttlSeconds}`, {
|
|
42
|
+
method: "POST",
|
|
43
|
+
headers: {
|
|
44
|
+
Authorization: `Bearer ${kv.token}`
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
} catch (error) {
|
|
48
|
+
console.warn(`Failed to extend KV TTL: ${error.message}`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function saveCache(filePath, data, options = {}) {
|
|
52
|
+
const {
|
|
53
|
+
cacheDir
|
|
54
|
+
} = options,
|
|
55
|
+
cachePath = cacheDir ? join(process.cwd(), cacheDir, filePath) : join(process.cwd(), filePath);
|
|
56
|
+
mkdirSync(dirname(cachePath), {
|
|
57
|
+
recursive: !0
|
|
58
|
+
}), writeFileSync(cachePath, JSON.stringify(data, null, 2));
|
|
59
|
+
}
|
|
60
|
+
function loadCache(filePath, options = {}) {
|
|
61
|
+
const {
|
|
62
|
+
cacheDir
|
|
63
|
+
} = options,
|
|
64
|
+
cachePath = cacheDir ? join(process.cwd(), cacheDir, filePath) : join(process.cwd(), filePath);
|
|
65
|
+
if (!existsSync(cachePath)) return null;
|
|
66
|
+
try {
|
|
67
|
+
return JSON.parse(readFileSync(cachePath, "utf-8"));
|
|
68
|
+
} catch {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
export { createCacheKey, extendKVTTL, getFingerprintFromKV, loadCache, saveCache, saveFingerprintToKV };
|
|
73
|
+
//# sourceMappingURL=cache.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["existsSync","readFileSync","writeFileSync","mkdirSync","dirname","join","DEFAULT_KV_TTL_SECONDS","createCacheKey","options","platform","fingerprint","prefix","saveFingerprintToKV","kv","key","ttlSeconds","response","fetch","url","method","headers","Authorization","token","ok","Error","status","statusText","error","TypeError","message","getFingerprintFromKV","data","json","result","extendKVTTL","console","warn","saveCache","filePath","cacheDir","cachePath","process","cwd","recursive","JSON","stringify","loadCache","parse"],"sources":["../src/cache.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { generateFingerprint, generatePreFingerprintHash } from "./fingerprint";
|
|
3
|
+
import { createCacheKey, saveFingerprintToKV, getFingerprintFromKV, saveCache, loadCache } from "./cache";
|
|
4
|
+
import { setGitHubOutput, isGitHubActions, isCI } from "./runner";
|
|
5
|
+
import { ensureIosDeps, ensureAndroidDeps, ensureMaestro, printDepsStatus } from "./deps";
|
|
6
|
+
import { withMetro } from "./metro";
|
|
7
|
+
import { runDetoxTests } from "./detox";
|
|
8
|
+
import { ensureIOSFolder } from "./ios";
|
|
9
|
+
import { setupAndroidDevice, ensureAndroidFolder } from "./android";
|
|
10
|
+
const HELP = `
|
|
11
|
+
native-ci - Native CI/CD helpers for Expo apps
|
|
12
|
+
|
|
13
|
+
COMMANDS:
|
|
14
|
+
|
|
15
|
+
Test Commands:
|
|
16
|
+
test ios [options] Run iOS Detox tests
|
|
17
|
+
test android [options] Run Android Detox tests
|
|
18
|
+
test maestro [flow] Run Maestro tests
|
|
19
|
+
test all Run all tests (iOS + Android)
|
|
20
|
+
|
|
21
|
+
Dependency Commands:
|
|
22
|
+
deps Show dependency status
|
|
23
|
+
deps install Install missing dependencies
|
|
24
|
+
deps install-ios Install iOS dependencies (macOS only)
|
|
25
|
+
deps install-android Install Android dependencies
|
|
26
|
+
deps install-maestro Install Maestro
|
|
27
|
+
|
|
28
|
+
Fingerprint Commands:
|
|
29
|
+
fingerprint <platform> Generate native build fingerprint
|
|
30
|
+
fingerprint-test Test fingerprint caching locally
|
|
31
|
+
pre-hash <files...> Generate quick pre-fingerprint hash
|
|
32
|
+
cache-key <platform> <fp> Generate cache key from fingerprint
|
|
33
|
+
|
|
34
|
+
KV Store Commands:
|
|
35
|
+
kv-get <key> Get value from KV store
|
|
36
|
+
kv-set <key> <value> Set value in KV store
|
|
37
|
+
|
|
38
|
+
OPTIONS:
|
|
39
|
+
--project-root <path> Project root directory (default: cwd)
|
|
40
|
+
--config <name> Detox configuration name
|
|
41
|
+
--record-logs <mode> Record logs: none, failing, all (default: all)
|
|
42
|
+
--retries <n> Number of retries for flaky tests (default: 0)
|
|
43
|
+
--headless Run in headless mode (Android only)
|
|
44
|
+
--prefix <prefix> Cache key prefix (default: native-build)
|
|
45
|
+
--github-output Output results for GitHub Actions
|
|
46
|
+
--json Output as JSON
|
|
47
|
+
--help Show this help message
|
|
48
|
+
|
|
49
|
+
ENVIRONMENT:
|
|
50
|
+
KV_STORE_REDIS_REST_URL Redis REST API URL for fingerprint caching
|
|
51
|
+
KV_STORE_REDIS_REST_TOKEN Redis REST API token
|
|
52
|
+
|
|
53
|
+
EXAMPLES:
|
|
54
|
+
native-ci test ios
|
|
55
|
+
native-ci test android --headless
|
|
56
|
+
native-ci test maestro
|
|
57
|
+
native-ci deps
|
|
58
|
+
native-ci deps install
|
|
59
|
+
native-ci fingerprint ios
|
|
60
|
+
native-ci fingerprint-test
|
|
61
|
+
`;
|
|
62
|
+
function parseArgs(argv) {
|
|
63
|
+
const args2 = [], options2 = {
|
|
64
|
+
projectRoot: process.cwd(),
|
|
65
|
+
config: "",
|
|
66
|
+
recordLogs: "all",
|
|
67
|
+
retries: 0,
|
|
68
|
+
headless: !1,
|
|
69
|
+
prefix: "native-build",
|
|
70
|
+
githubOutput: !1,
|
|
71
|
+
json: !1,
|
|
72
|
+
help: !1
|
|
73
|
+
};
|
|
74
|
+
let i = 0;
|
|
75
|
+
for (; i < argv.length; ) {
|
|
76
|
+
const arg = argv[i];
|
|
77
|
+
if (arg === "--project-root" && argv[i + 1])
|
|
78
|
+
options2.projectRoot = argv[++i];
|
|
79
|
+
else if (arg === "--config" && argv[i + 1])
|
|
80
|
+
options2.config = argv[++i];
|
|
81
|
+
else if (arg === "--record-logs" && argv[i + 1])
|
|
82
|
+
options2.recordLogs = argv[++i];
|
|
83
|
+
else if (arg === "--retries" && argv[i + 1]) {
|
|
84
|
+
const val = Number.parseInt(argv[++i], 10);
|
|
85
|
+
!Number.isNaN(val) && val >= 0 && (options2.retries = val);
|
|
86
|
+
} else arg === "--prefix" && argv[i + 1] ? options2.prefix = argv[++i] : arg === "--github-output" ? options2.githubOutput = !0 : arg === "--json" ? options2.json = !0 : arg === "--help" || arg === "-h" ? options2.help = !0 : arg.startsWith("-") || args2.push(arg);
|
|
87
|
+
i++;
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
command: args2[0] || "",
|
|
91
|
+
subcommand: args2[1] || "",
|
|
92
|
+
args: args2.slice(2),
|
|
93
|
+
options: options2
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
function validatePlatform(value) {
|
|
97
|
+
return value !== "ios" && value !== "android" && (console.error('Error: platform must be "ios" or "android"'), process.exit(1)), value;
|
|
98
|
+
}
|
|
99
|
+
function getKVCredentials() {
|
|
100
|
+
const url = process.env.KV_STORE_REDIS_REST_URL, token = process.env.KV_STORE_REDIS_REST_TOKEN;
|
|
101
|
+
return (!url || !token) && (console.error("Error: KV_STORE_REDIS_REST_URL and KV_STORE_REDIS_REST_TOKEN required"), process.exit(1)), { url, token };
|
|
102
|
+
}
|
|
103
|
+
const { command, subcommand, args, options } = parseArgs(process.argv.slice(2));
|
|
104
|
+
(options.help || !command) && (console.info(HELP), process.exit(options.help ? 0 : 1));
|
|
105
|
+
try {
|
|
106
|
+
switch (command) {
|
|
107
|
+
// ========================================
|
|
108
|
+
// Test Commands
|
|
109
|
+
// ========================================
|
|
110
|
+
case "test": {
|
|
111
|
+
isCI() && !process.env.NATIVE_CI_FORCE_RUN && (console.info("Skipping native tests in CI (handled by separate workflow)"), console.info("Set NATIVE_CI_FORCE_RUN=1 to force run"), process.exit(0));
|
|
112
|
+
const platform = subcommand || "ios";
|
|
113
|
+
if (platform === "ios") {
|
|
114
|
+
await ensureIosDeps();
|
|
115
|
+
const config = options.config || "ios.sim.debug";
|
|
116
|
+
console.info("=== iOS Detox Test Runner ==="), console.info(`Config: ${config}`), console.info(`Project root: ${options.projectRoot}`), process.chdir(options.projectRoot), await ensureIOSFolder();
|
|
117
|
+
const exitCode = await withMetro("ios", async () => runDetoxTests({
|
|
118
|
+
config,
|
|
119
|
+
projectRoot: options.projectRoot,
|
|
120
|
+
recordLogs: options.recordLogs,
|
|
121
|
+
retries: options.retries
|
|
122
|
+
}));
|
|
123
|
+
process.exit(exitCode);
|
|
124
|
+
} else if (platform === "android") {
|
|
125
|
+
await ensureAndroidDeps();
|
|
126
|
+
const config = options.config || "android.emu.debug";
|
|
127
|
+
console.info("=== Android Detox Test Runner ==="), console.info(`Config: ${config}`), console.info(`Project root: ${options.projectRoot}`), console.info(`Headless: ${options.headless}`), process.chdir(options.projectRoot), await ensureAndroidFolder(), await setupAndroidDevice();
|
|
128
|
+
const exitCode = await withMetro("android", async () => runDetoxTests({
|
|
129
|
+
config,
|
|
130
|
+
projectRoot: options.projectRoot,
|
|
131
|
+
recordLogs: options.recordLogs,
|
|
132
|
+
retries: options.retries,
|
|
133
|
+
headless: options.headless
|
|
134
|
+
}));
|
|
135
|
+
process.exit(exitCode);
|
|
136
|
+
} else if (platform === "maestro") {
|
|
137
|
+
await ensureMaestro();
|
|
138
|
+
const flow = args[0] || "";
|
|
139
|
+
console.info("=== Maestro Test Runner ==="), console.info(`Flow: ${flow || "all"}`), console.info(`Project root: ${options.projectRoot}`), process.chdir(options.projectRoot);
|
|
140
|
+
const exitCode = await withMetro("ios", async () => {
|
|
141
|
+
const { $ } = await import("bun"), flowArg = flow ? `./flows/${flow}` : "./flows";
|
|
142
|
+
return (await $`maestro test ${flowArg} --exclude-tags=util --no-ansi`.nothrow()).exitCode;
|
|
143
|
+
});
|
|
144
|
+
process.exit(exitCode);
|
|
145
|
+
} else if (platform === "all") {
|
|
146
|
+
console.info(`=== Running All Native Tests ===
|
|
147
|
+
`), await ensureIosDeps(), console.info(`
|
|
148
|
+
--- iOS Tests ---
|
|
149
|
+
`), process.chdir(options.projectRoot), await ensureIOSFolder();
|
|
150
|
+
let iosExit = 0;
|
|
151
|
+
try {
|
|
152
|
+
iosExit = await withMetro("ios", async () => runDetoxTests({
|
|
153
|
+
config: options.config || "ios.sim.debug",
|
|
154
|
+
projectRoot: options.projectRoot,
|
|
155
|
+
recordLogs: options.recordLogs,
|
|
156
|
+
retries: options.retries
|
|
157
|
+
}));
|
|
158
|
+
} catch (err) {
|
|
159
|
+
console.error("iOS tests failed:", err), iosExit = 1;
|
|
160
|
+
}
|
|
161
|
+
await ensureAndroidDeps(), console.info(`
|
|
162
|
+
--- Android Tests ---
|
|
163
|
+
`), await ensureAndroidFolder(), await setupAndroidDevice();
|
|
164
|
+
let androidExit = 0;
|
|
165
|
+
try {
|
|
166
|
+
androidExit = await withMetro("android", async () => runDetoxTests({
|
|
167
|
+
config: options.config || "android.emu.debug",
|
|
168
|
+
projectRoot: options.projectRoot,
|
|
169
|
+
recordLogs: options.recordLogs,
|
|
170
|
+
retries: options.retries,
|
|
171
|
+
headless: options.headless
|
|
172
|
+
}));
|
|
173
|
+
} catch (err) {
|
|
174
|
+
console.error("Android tests failed:", err), androidExit = 1;
|
|
175
|
+
}
|
|
176
|
+
const success = iosExit === 0 && androidExit === 0;
|
|
177
|
+
console.info(`
|
|
178
|
+
=== Test Results ===`), console.info(`iOS: ${iosExit === 0 ? "PASSED" : "FAILED"}`), console.info(`Android: ${androidExit === 0 ? "PASSED" : "FAILED"}`), process.exit(success ? 0 : 1);
|
|
179
|
+
} else
|
|
180
|
+
console.error(`Unknown test platform: ${platform}`), console.info("Usage: native-ci test [ios|android|maestro|all]"), process.exit(1);
|
|
181
|
+
break;
|
|
182
|
+
}
|
|
183
|
+
// ========================================
|
|
184
|
+
// Dependency Commands
|
|
185
|
+
// ========================================
|
|
186
|
+
case "deps": {
|
|
187
|
+
!subcommand || subcommand === "status" ? printDepsStatus() : subcommand === "install" ? (console.info(`Installing all dependencies...
|
|
188
|
+
`), await ensureIosDeps(), await ensureMaestro(), console.info(`
|
|
189
|
+
All dependencies installed!`)) : subcommand === "install-ios" ? await ensureIosDeps() : subcommand === "install-android" ? await ensureAndroidDeps() : subcommand === "install-maestro" ? await ensureMaestro() : (console.error(`Unknown deps subcommand: ${subcommand}`), process.exit(1));
|
|
190
|
+
break;
|
|
191
|
+
}
|
|
192
|
+
// ========================================
|
|
193
|
+
// Fingerprint Commands
|
|
194
|
+
// ========================================
|
|
195
|
+
case "fingerprint": {
|
|
196
|
+
const platform = validatePlatform(subcommand), result = await generateFingerprint({
|
|
197
|
+
platform,
|
|
198
|
+
projectRoot: options.projectRoot
|
|
199
|
+
});
|
|
200
|
+
(options.githubOutput || isGitHubActions()) && (setGitHubOutput("fingerprint", result.hash), setGitHubOutput(
|
|
201
|
+
"cache-key",
|
|
202
|
+
createCacheKey({
|
|
203
|
+
platform,
|
|
204
|
+
fingerprint: result.hash,
|
|
205
|
+
prefix: options.prefix
|
|
206
|
+
})
|
|
207
|
+
)), options.json ? console.info(JSON.stringify(result, null, 2)) : console.info(result.hash);
|
|
208
|
+
break;
|
|
209
|
+
}
|
|
210
|
+
case "fingerprint-test": {
|
|
211
|
+
const CACHE_FILE = ".fingerprint-cache.json";
|
|
212
|
+
console.info(`Generating fingerprints...
|
|
213
|
+
`);
|
|
214
|
+
const iosResult = await generateFingerprint({ platform: "ios", projectRoot: options.projectRoot }), androidResult = await generateFingerprint({ platform: "android", projectRoot: options.projectRoot }), iosFingerprint = iosResult.hash, androidFingerprint = androidResult.hash;
|
|
215
|
+
console.info("Current fingerprints:"), console.info(` iOS: ${iosFingerprint}`), console.info(` Android: ${androidFingerprint}`), console.info("");
|
|
216
|
+
const cache = loadCache(CACHE_FILE);
|
|
217
|
+
if (cache?.ios && cache?.android) {
|
|
218
|
+
console.info("Previous fingerprints (from cache):"), console.info(` iOS: ${cache.ios}`), console.info(` Android: ${cache.android}`), console.info("");
|
|
219
|
+
const iosChanged = cache.ios !== iosFingerprint, androidChanged = cache.android !== androidFingerprint;
|
|
220
|
+
iosChanged || androidChanged ? (console.info("Fingerprints changed!"), iosChanged && console.info(" - iOS fingerprint changed (would trigger iOS rebuild)"), androidChanged && console.info(" - Android fingerprint changed (would trigger Android rebuild)")) : console.info("Fingerprints match - no rebuild needed");
|
|
221
|
+
} else
|
|
222
|
+
console.info("No previous fingerprints cached.");
|
|
223
|
+
saveCache(CACHE_FILE, { ios: iosFingerprint, android: androidFingerprint, timestamp: (/* @__PURE__ */ new Date()).toISOString() }), console.info(`
|
|
224
|
+
Saved fingerprints to ${CACHE_FILE}`), console.info(`
|
|
225
|
+
To test cache invalidation:
|
|
226
|
+
1. Add a native dependency: yarn add react-native-mmkv
|
|
227
|
+
2. Run this script again: native-ci fingerprint-test
|
|
228
|
+
3. Fingerprints should change!
|
|
229
|
+
4. Remove the dependency: yarn remove react-native-mmkv
|
|
230
|
+
5. Run this script again - fingerprints should match original
|
|
231
|
+
`);
|
|
232
|
+
break;
|
|
233
|
+
}
|
|
234
|
+
case "pre-hash": {
|
|
235
|
+
const files = [subcommand, ...args].filter(Boolean);
|
|
236
|
+
files.length === 0 && (console.error("Error: at least one file required"), process.exit(1));
|
|
237
|
+
const hash = generatePreFingerprintHash(files, options.projectRoot);
|
|
238
|
+
(options.githubOutput || isGitHubActions()) && setGitHubOutput("pre-fingerprint-hash", hash), options.json ? console.info(JSON.stringify({ hash, files }, null, 2)) : console.info(hash);
|
|
239
|
+
break;
|
|
240
|
+
}
|
|
241
|
+
case "cache-key": {
|
|
242
|
+
const platform = validatePlatform(subcommand), fingerprint = args[0];
|
|
243
|
+
fingerprint || (console.error("Error: fingerprint is required"), process.exit(1));
|
|
244
|
+
const cacheKey = createCacheKey({
|
|
245
|
+
platform,
|
|
246
|
+
fingerprint,
|
|
247
|
+
prefix: options.prefix
|
|
248
|
+
});
|
|
249
|
+
(options.githubOutput || isGitHubActions()) && setGitHubOutput("cache-key", cacheKey), console.info(cacheKey);
|
|
250
|
+
break;
|
|
251
|
+
}
|
|
252
|
+
// ========================================
|
|
253
|
+
// KV Store Commands
|
|
254
|
+
// ========================================
|
|
255
|
+
case "kv-get": {
|
|
256
|
+
const key = subcommand;
|
|
257
|
+
key || (console.error("Error: key is required"), process.exit(1));
|
|
258
|
+
const kv = getKVCredentials(), value = await getFingerprintFromKV(kv, key);
|
|
259
|
+
(options.githubOutput || isGitHubActions()) && (setGitHubOutput("value", value || ""), setGitHubOutput("found", value ? "true" : "false")), value ? console.info(value) : process.exit(1);
|
|
260
|
+
break;
|
|
261
|
+
}
|
|
262
|
+
case "kv-set": {
|
|
263
|
+
const key = subcommand, value = args[0];
|
|
264
|
+
(!key || !value) && (console.error("Error: key and value are required"), process.exit(1));
|
|
265
|
+
const kv = getKVCredentials();
|
|
266
|
+
await saveFingerprintToKV(kv, key, value), console.info("OK");
|
|
267
|
+
break;
|
|
268
|
+
}
|
|
269
|
+
default:
|
|
270
|
+
console.error(`Unknown command: ${command}`), console.info(HELP), process.exit(1);
|
|
271
|
+
}
|
|
272
|
+
} catch (error) {
|
|
273
|
+
console.error("Error:", error.message), process.exit(1);
|
|
274
|
+
}
|
|
275
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/cli.ts"],
|
|
4
|
+
"mappings": ";AAUA,SAAS,qBAAqB,kCAAkC;AAChE,SAAS,gBAAgB,qBAAqB,sBAAsB,WAAW,iBAAiB;AAChG,SAAS,iBAAiB,iBAAiB,YAAY;AACvD,SAAoB,eAAe,mBAAmB,eAAe,uBAAuB;AAC5F,SAAS,iBAAiB;AAC1B,SAAyB,qBAAqB;AAC9C,SAAS,uBAAuB;AAChC,SAAS,oBAAoB,2BAA2B;AAGxD,MAAM,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAsEb,SAAS,UAAU,MAA4B;AAC7C,QAAMA,QAAiB,CAAC,GAClBC,WAAU;AAAA,IACd,aAAa,QAAQ,IAAI;AAAA,IACzB,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,SAAS;AAAA,IACT,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,cAAc;AAAA,IACd,MAAM;AAAA,IACN,MAAM;AAAA,EACR;AAEA,MAAI,IAAI;AACR,SAAO,IAAI,KAAK,UAAQ;AACtB,UAAM,MAAM,KAAK,CAAC;AAElB,QAAI,QAAQ,oBAAoB,KAAK,IAAI,CAAC;AACxC,MAAAA,SAAQ,cAAc,KAAK,EAAE,CAAC;AAAA,aACrB,QAAQ,cAAc,KAAK,IAAI,CAAC;AACzC,MAAAA,SAAQ,SAAS,KAAK,EAAE,CAAC;AAAA,aAChB,QAAQ,mBAAmB,KAAK,IAAI,CAAC;AAC9C,MAAAA,SAAQ,aAAa,KAAK,EAAE,CAAC;AAAA,aACpB,QAAQ,eAAe,KAAK,IAAI,CAAC,GAAG;AAC7C,YAAM,MAAM,OAAO,SAAS,KAAK,EAAE,CAAC,GAAG,EAAE;AACzC,MAAI,CAAC,OAAO,MAAM,GAAG,KAAK,OAAO,MAC/BA,SAAQ,UAAU;AAAA,IAEtB,MAAO,CAAI,QAAQ,cAAc,KAAK,IAAI,CAAC,IACzCA,SAAQ,SAAS,KAAK,EAAE,CAAC,IAChB,QAAQ,oBACjBA,SAAQ,eAAe,KACd,QAAQ,WACjBA,SAAQ,OAAO,KACN,QAAQ,YAAY,QAAQ,OACrCA,SAAQ,OAAO,KACL,IAAI,WAAW,GAAG,KAC5BD,MAAK,KAAK,GAAG;AAGf;AAAA,EACF;AAEA,SAAO;AAAA,IACL,SAASA,MAAK,CAAC,KAAK;AAAA,IACpB,YAAYA,MAAK,CAAC,KAAK;AAAA,IACvB,MAAMA,MAAK,MAAM,CAAC;AAAA,IAClB,SAAAC;AAAA,EACF;AACF;AAEA,SAAS,iBAAiB,OAAyB;AACjD,SAAI,UAAU,SAAS,UAAU,cAC/B,QAAQ,MAAM,4CAA4C,GAC1D,QAAQ,KAAK,CAAC,IAET;AACT;AAEA,SAAS,mBAAmD;AAC1D,QAAM,MAAM,QAAQ,IAAI,yBAClB,QAAQ,QAAQ,IAAI;AAE1B,UAAI,CAAC,OAAO,CAAC,WACX,QAAQ,MAAM,uEAAuE,GACrF,QAAQ,KAAK,CAAC,IAGT,EAAE,KAAK,MAAM;AACtB;AAGA,MAAM,EAAE,SAAS,YAAY,MAAM,QAAQ,IAAI,UAAU,QAAQ,KAAK,MAAM,CAAC,CAAC;AAAA,CAE1E,QAAQ,QAAQ,CAAC,aACnB,QAAQ,KAAK,IAAI,GACjB,QAAQ,KAAK,QAAQ,OAAO,IAAI,CAAC;AAGnC,IAAI;AACF,UAAQ,SAAS;AAAA;AAAA;AAAA;AAAA,IAIf,KAAK,QAAQ;AAEX,MAAI,KAAK,KAAK,CAAC,QAAQ,IAAI,wBACzB,QAAQ,KAAK,4DAA4D,GACzE,QAAQ,KAAK,wCAAwC,GACrD,QAAQ,KAAK,CAAC;AAGhB,YAAM,WAAW,cAAc;AAE/B,UAAI,aAAa,OAAO;AAEtB,cAAM,cAAc;AAEpB,cAAM,SAAS,QAAQ,UAAU;AACjC,gBAAQ,KAAK,+BAA+B,GAC5C,QAAQ,KAAK,WAAW,MAAM,EAAE,GAChC,QAAQ,KAAK,iBAAiB,QAAQ,WAAW,EAAE,GAEnD,QAAQ,MAAM,QAAQ,WAAW,GACjC,MAAM,gBAAgB;AAEtB,cAAM,WAAW,MAAM,UAAU,OAAO,YAC/B,cAAc;AAAA,UACnB;AAAA,UACA,aAAa,QAAQ;AAAA,UACrB,YAAY,QAAQ;AAAA,UACpB,SAAS,QAAQ;AAAA,QACnB,CAAC,CACF;AACD,gBAAQ,KAAK,QAAQ;AAAA,MACvB,WAAW,aAAa,WAAW;AAEjC,cAAM,kBAAkB;AAExB,cAAM,SAAS,QAAQ,UAAU;AACjC,gBAAQ,KAAK,mCAAmC,GAChD,QAAQ,KAAK,WAAW,MAAM,EAAE,GAChC,QAAQ,KAAK,iBAAiB,QAAQ,WAAW,EAAE,GACnD,QAAQ,KAAK,aAAa,QAAQ,QAAQ,EAAE,GAE5C,QAAQ,MAAM,QAAQ,WAAW,GACjC,MAAM,oBAAoB,GAG1B,MAAM,mBAAmB;AAEzB,cAAM,WAAW,MAAM,UAAU,WAAW,YACnC,cAAc;AAAA,UACnB;AAAA,UACA,aAAa,QAAQ;AAAA,UACrB,YAAY,QAAQ;AAAA,UACpB,SAAS,QAAQ;AAAA,UACjB,UAAU,QAAQ;AAAA,QACpB,CAAC,CACF;AACD,gBAAQ,KAAK,QAAQ;AAAA,MACvB,WAAW,aAAa,WAAW;AAEjC,cAAM,cAAc;AAEpB,cAAM,OAAO,KAAK,CAAC,KAAK;AACxB,gBAAQ,KAAK,6BAA6B,GAC1C,QAAQ,KAAK,SAAS,QAAQ,KAAK,EAAE,GACrC,QAAQ,KAAK,iBAAiB,QAAQ,WAAW,EAAE,GAEnD,QAAQ,MAAM,QAAQ,WAAW;AAGjC,cAAM,WAAW,MAAM,UAAU,OAAO,YAAY;AAClD,gBAAM,EAAE,EAAE,IAAI,MAAM,OAAO,KAAK,GAE1B,UAAU,OAAO,WAAW,IAAI,KAAK;AAE3C,kBADe,MAAM,iBAAiB,OAAO,iCAAiC,QAAQ,GACxE;AAAA,QAChB,CAAC;AACD,gBAAQ,KAAK,QAAQ;AAAA,MACvB,WAAW,aAAa,OAAO;AAC7B,gBAAQ,KAAK;AAAA,CAAoC,GAGjD,MAAM,cAAc,GACpB,QAAQ,KAAK;AAAA;AAAA,CAAuB,GACpC,QAAQ,MAAM,QAAQ,WAAW,GACjC,MAAM,gBAAgB;AAEtB,YAAI,UAAU;AACd,YAAI;AACF,oBAAU,MAAM,UAAU,OAAO,YACxB,cAAc;AAAA,YACnB,QAAQ,QAAQ,UAAU;AAAA,YAC1B,aAAa,QAAQ;AAAA,YACrB,YAAY,QAAQ;AAAA,YACpB,SAAS,QAAQ;AAAA,UACnB,CAAC,CACF;AAAA,QACH,SAAS,KAAK;AACZ,kBAAQ,MAAM,qBAAqB,GAAG,GACtC,UAAU;AAAA,QACZ;AAGA,cAAM,kBAAkB,GACxB,QAAQ,KAAK;AAAA;AAAA,CAA2B,GACxC,MAAM,oBAAoB,GAC1B,MAAM,mBAAmB;AAEzB,YAAI,cAAc;AAClB,YAAI;AACF,wBAAc,MAAM,UAAU,WAAW,YAChC,cAAc;AAAA,YACnB,QAAQ,QAAQ,UAAU;AAAA,YAC1B,aAAa,QAAQ;AAAA,YACrB,YAAY,QAAQ;AAAA,YACpB,SAAS,QAAQ;AAAA,YACjB,UAAU,QAAQ;AAAA,UACpB,CAAC,CACF;AAAA,QACH,SAAS,KAAK;AACZ,kBAAQ,MAAM,yBAAyB,GAAG,GAC1C,cAAc;AAAA,QAChB;AAEA,cAAM,UAAU,YAAY,KAAK,gBAAgB;AACjD,gBAAQ,KAAK;AAAA,qBAAwB,GACrC,QAAQ,KAAK,QAAQ,YAAY,IAAI,WAAW,QAAQ,EAAE,GAC1D,QAAQ,KAAK,YAAY,gBAAgB,IAAI,WAAW,QAAQ,EAAE,GAClE,QAAQ,KAAK,UAAU,IAAI,CAAC;AAAA,MAC9B;AACE,gBAAQ,MAAM,0BAA0B,QAAQ,EAAE,GAClD,QAAQ,KAAK,iDAAiD,GAC9D,QAAQ,KAAK,CAAC;AAEhB;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKA,KAAK,QAAQ;AACX,MAAI,CAAC,cAAc,eAAe,WAChC,gBAAgB,IACP,eAAe,aACxB,QAAQ,KAAK;AAAA,CAAkC,GAC/C,MAAM,cAAc,GACpB,MAAM,cAAc,GACpB,QAAQ,KAAK;AAAA,4BAA+B,KACnC,eAAe,gBACxB,MAAM,cAAc,IACX,eAAe,oBACxB,MAAM,kBAAkB,IACf,eAAe,oBACxB,MAAM,cAAc,KAEpB,QAAQ,MAAM,4BAA4B,UAAU,EAAE,GACtD,QAAQ,KAAK,CAAC;AAEhB;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKA,KAAK,eAAe;AAClB,YAAM,WAAW,iBAAiB,UAAU,GAEtC,SAAS,MAAM,oBAAoB;AAAA,QACvC;AAAA,QACA,aAAa,QAAQ;AAAA,MACvB,CAAC;AAED,OAAI,QAAQ,gBAAgB,gBAAgB,OAC1C,gBAAgB,eAAe,OAAO,IAAI,GAC1C;AAAA,QACE;AAAA,QACA,eAAe;AAAA,UACb;AAAA,UACA,aAAa,OAAO;AAAA,UACpB,QAAQ,QAAQ;AAAA,QAClB,CAAC;AAAA,MACH,IAGE,QAAQ,OACV,QAAQ,KAAK,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC,IAE5C,QAAQ,KAAK,OAAO,IAAI;AAE1B;AAAA,IACF;AAAA,IAEA,KAAK,oBAAoB;AACvB,YAAM,aAAa;AAEnB,cAAQ,KAAK;AAAA,CAA8B;AAE3C,YAAM,YAAY,MAAM,oBAAoB,EAAE,UAAU,OAAO,aAAa,QAAQ,YAAY,CAAC,GAC3F,gBAAgB,MAAM,oBAAoB,EAAE,UAAU,WAAW,aAAa,QAAQ,YAAY,CAAC,GAEnG,iBAAiB,UAAU,MAC3B,qBAAqB,cAAc;AAEzC,cAAQ,KAAK,uBAAuB,GACpC,QAAQ,KAAK,cAAc,cAAc,EAAE,GAC3C,QAAQ,KAAK,cAAc,kBAAkB,EAAE,GAC/C,QAAQ,KAAK,EAAE;AAEf,YAAM,QAAQ,UAAU,UAAU;AAElC,UAAI,OAAO,OAAO,OAAO,SAAS;AAChC,gBAAQ,KAAK,qCAAqC,GAClD,QAAQ,KAAK,cAAc,MAAM,GAAG,EAAE,GACtC,QAAQ,KAAK,cAAc,MAAM,OAAO,EAAE,GAC1C,QAAQ,KAAK,EAAE;AAEf,cAAM,aAAa,MAAM,QAAQ,gBAC3B,iBAAiB,MAAM,YAAY;AAEzC,QAAI,cAAc,kBAChB,QAAQ,KAAK,uBAAuB,GAChC,cAAY,QAAQ,KAAK,0DAA0D,GACnF,kBAAgB,QAAQ,KAAK,kEAAkE,KAEnG,QAAQ,KAAK,wCAAwC;AAAA,MAEzD;AACE,gBAAQ,KAAK,kCAAkC;AAIjD,gBAAU,YAAY,EAAE,KAAK,gBAAgB,SAAS,oBAAoB,YAAW,oBAAI,KAAK,GAAE,YAAY,EAAE,CAAC,GAC/G,QAAQ,KAAK;AAAA,wBAA2B,UAAU,EAAE,GAEpD,QAAQ,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAOlB;AACK;AAAA,IACF;AAAA,IAEA,KAAK,YAAY;AACf,YAAM,QAAQ,CAAC,YAAY,GAAG,IAAI,EAAE,OAAO,OAAO;AAClD,MAAI,MAAM,WAAW,MACnB,QAAQ,MAAM,mCAAmC,GACjD,QAAQ,KAAK,CAAC;AAGhB,YAAM,OAAO,2BAA2B,OAAO,QAAQ,WAAW;AAElE,OAAI,QAAQ,gBAAgB,gBAAgB,MAC1C,gBAAgB,wBAAwB,IAAI,GAG1C,QAAQ,OACV,QAAQ,KAAK,KAAK,UAAU,EAAE,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,IAErD,QAAQ,KAAK,IAAI;AAEnB;AAAA,IACF;AAAA,IAEA,KAAK,aAAa;AAChB,YAAM,WAAW,iBAAiB,UAAU,GACtC,cAAc,KAAK,CAAC;AAE1B,MAAK,gBACH,QAAQ,MAAM,gCAAgC,GAC9C,QAAQ,KAAK,CAAC;AAGhB,YAAM,WAAW,eAAe;AAAA,QAC9B;AAAA,QACA;AAAA,QACA,QAAQ,QAAQ;AAAA,MAClB,CAAC;AAED,OAAI,QAAQ,gBAAgB,gBAAgB,MAC1C,gBAAgB,aAAa,QAAQ,GAGvC,QAAQ,KAAK,QAAQ;AACrB;AAAA,IACF;AAAA;AAAA;AAAA;AAAA,IAKA,KAAK,UAAU;AACb,YAAM,MAAM;AACZ,MAAK,QACH,QAAQ,MAAM,wBAAwB,GACtC,QAAQ,KAAK,CAAC;AAGhB,YAAM,KAAK,iBAAiB,GACtB,QAAQ,MAAM,qBAAqB,IAAI,GAAG;AAEhD,OAAI,QAAQ,gBAAgB,gBAAgB,OAC1C,gBAAgB,SAAS,SAAS,EAAE,GACpC,gBAAgB,SAAS,QAAQ,SAAS,OAAO,IAG/C,QACF,QAAQ,KAAK,KAAK,IAElB,QAAQ,KAAK,CAAC;AAEhB;AAAA,IACF;AAAA,IAEA,KAAK,UAAU;AACb,YAAM,MAAM,YACN,QAAQ,KAAK,CAAC;AAEpB,OAAI,CAAC,OAAO,CAAC,WACX,QAAQ,MAAM,mCAAmC,GACjD,QAAQ,KAAK,CAAC;AAGhB,YAAM,KAAK,iBAAiB;AAC5B,YAAM,oBAAoB,IAAI,KAAK,KAAK,GACxC,QAAQ,KAAK,IAAI;AACjB;AAAA,IACF;AAAA,IAEA;AACE,cAAQ,MAAM,oBAAoB,OAAO,EAAE,GAC3C,QAAQ,KAAK,IAAI,GACjB,QAAQ,KAAK,CAAC;AAAA,EAClB;AACF,SAAS,OAAO;AACd,UAAQ,MAAM,UAAW,MAAgB,OAAO,GAChD,QAAQ,KAAK,CAAC;AAChB;",
|
|
5
|
+
"names": ["args", "options"]
|
|
6
|
+
}
|