vxrn 2.8.1 → 2.9.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.
Files changed (52) hide show
  1. package/dist/exports/clean.mjs +128 -19
  2. package/dist/exports/clean.mjs.map +1 -1
  3. package/dist/exports/clean.native.js +147 -21
  4. package/dist/exports/clean.native.js.map +1 -1
  5. package/dist/exports/prebuild.mjs +2 -1
  6. package/dist/exports/prebuild.mjs.map +1 -1
  7. package/dist/exports/prebuild.native.js +2 -1
  8. package/dist/exports/prebuild.native.js.map +1 -1
  9. package/dist/exports/prebuildWithoutExpo.mjs +196 -7
  10. package/dist/exports/prebuildWithoutExpo.mjs.map +1 -1
  11. package/dist/exports/prebuildWithoutExpo.native.js +280 -42
  12. package/dist/exports/prebuildWithoutExpo.native.js.map +1 -1
  13. package/dist/plugins/reactNativeDevServer.mjs +1 -1
  14. package/dist/plugins/reactNativeDevServer.mjs.map +1 -1
  15. package/dist/plugins/reactNativeDevServer.native.js +1 -1
  16. package/dist/plugins/reactNativeDevServer.native.js.map +1 -1
  17. package/dist/user-interface/index.mjs +31 -24
  18. package/dist/user-interface/index.mjs.map +1 -1
  19. package/dist/user-interface/index.native.js +32 -25
  20. package/dist/user-interface/index.native.js.map +1 -1
  21. package/dist/utils/createNativeDevEngine.mjs +111 -14
  22. package/dist/utils/createNativeDevEngine.mjs.map +1 -1
  23. package/dist/utils/createNativeDevEngine.native.js +143 -14
  24. package/dist/utils/createNativeDevEngine.native.js.map +1 -1
  25. package/dist/utils/scanDepsToOptimize.mjs +10 -6
  26. package/dist/utils/scanDepsToOptimize.mjs.map +1 -1
  27. package/dist/utils/scanDepsToOptimize.native.js +12 -6
  28. package/dist/utils/scanDepsToOptimize.native.js.map +1 -1
  29. package/expo-plugin.cjs +71 -8
  30. package/package.json +13 -13
  31. package/src/exports/clean.test.ts +502 -5
  32. package/src/exports/clean.ts +176 -19
  33. package/src/exports/expoPlugin.test.mjs +44 -1
  34. package/src/exports/prebuild.ts +6 -0
  35. package/src/exports/prebuildWithoutExpo.test.ts +134 -2
  36. package/src/exports/prebuildWithoutExpo.ts +235 -10
  37. package/src/plugins/reactNativeDevServer.ts +1 -1
  38. package/src/user-interface/index.ts +50 -42
  39. package/src/utils/createNativeDevEngine.test.ts +480 -1
  40. package/src/utils/createNativeDevEngine.ts +220 -17
  41. package/src/utils/imageSizePatch.test.ts +3 -3
  42. package/src/utils/scanDepsToOptimize.test.ts +35 -2
  43. package/src/utils/scanDepsToOptimize.ts +25 -8
  44. package/types/exports/clean.d.ts.map +1 -1
  45. package/types/exports/prebuild.d.ts +2 -1
  46. package/types/exports/prebuild.d.ts.map +1 -1
  47. package/types/exports/prebuildWithoutExpo.d.ts.map +1 -1
  48. package/types/user-interface/index.d.ts.map +1 -1
  49. package/types/utils/createNativeDevEngine.d.ts +1 -1
  50. package/types/utils/createNativeDevEngine.d.ts.map +1 -1
  51. package/types/utils/scanDepsToOptimize.d.ts +25 -0
  52. package/types/utils/scanDepsToOptimize.d.ts.map +1 -1
@@ -1,4 +1,5 @@
1
- import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
1
+ import { mkdir, readFile, rm, stat, writeFile } from "node:fs/promises";
2
+ import { createServer } from "node:net";
2
3
  import { dirname, join } from "node:path";
3
4
  import { fillOptions } from "../config/getOptionsFilled.mjs";
4
5
  import { getSSRExternalsCachePath } from "../plugins/autoDepOptimizePlugin.mjs";
@@ -12,38 +13,146 @@ function getErrorCode(err) {
12
13
  return err.code;
13
14
  }
14
15
  }
15
- async function withCacheCleanLock(cacheDir, action) {
16
- const lockPath = join(dirname(cacheDir), ".vxrn-clean.lock");
17
- const startedAt = Date.now();
18
- await mkdir(dirname(lockPath), { recursive: true });
16
+ function getCleanLockTimeoutMs() {
17
+ const override = Number.parseInt(process.env.VXRN_CLEAN_LOCK_TIMEOUT_MS ?? "", 10);
18
+ if (Number.isSafeInteger(override) && override > 0) {
19
+ return override;
20
+ }
21
+ return CLEAN_LOCK_TIMEOUT_MS;
22
+ }
23
+ const CLEAN_LOCK_PORT_BASE = 24e3;
24
+ const CLEAN_LOCK_PORT_COUNT = 1e3;
25
+ async function getCacheCleanLockPort(lockDir) {
26
+ const info = await stat(lockDir);
27
+ let hash = 2166136261;
28
+ const identity = `${info.dev}:${info.ino}`;
29
+ for (let index = 0; index < identity.length; index++) {
30
+ hash ^= identity.charCodeAt(index);
31
+ hash = Math.imul(hash, 16777619);
32
+ }
33
+ return CLEAN_LOCK_PORT_BASE + (hash >>> 0) % CLEAN_LOCK_PORT_COUNT;
34
+ }
35
+ function isLockOwnerAlive(pid) {
36
+ try {
37
+ process.kill(pid, 0);
38
+ return true;
39
+ } catch (err) {
40
+ return getErrorCode(err) !== "ESRCH";
41
+ }
42
+ }
43
+ function parseLockOwnerPid(content) {
44
+ const trimmed = content.trim();
45
+ if (!/^\d+$/.test(trimmed)) {
46
+ return void 0;
47
+ }
48
+ const pid = Number.parseInt(trimmed, 10);
49
+ if (!Number.isSafeInteger(pid) || pid <= 0) {
50
+ return void 0;
51
+ }
52
+ return pid;
53
+ }
54
+ async function joinLegacyLock(lockPath, startedAt, timeoutMs) {
19
55
  while (true) {
20
56
  try {
21
57
  await writeFile(lockPath, `${process.pid}
22
58
  `, { flag: "wx" });
23
- break;
59
+ return true;
24
60
  } catch (err) {
25
61
  if (getErrorCode(err) !== "EEXIST") {
26
62
  throw err;
27
63
  }
28
- if (Date.now() - startedAt >= CLEAN_LOCK_TIMEOUT_MS) {
29
- let owner = "unknown process";
30
- try {
31
- owner = `process ${(await readFile(lockPath, "utf8")).trim()}`;
32
- } catch (readErr) {
33
- if (getErrorCode(readErr) === "ENOENT") {
34
- continue;
35
- }
36
- throw readErr;
37
- }
38
- throw new Error(`Timed out waiting for VXRN cache cleanup lock held by ${owner}`);
64
+ }
65
+ let content;
66
+ try {
67
+ content = await readFile(lockPath, "utf8");
68
+ } catch (err) {
69
+ if (getErrorCode(err) === "ENOENT") {
70
+ continue;
39
71
  }
40
- await new Promise((resolve) => setTimeout(resolve, CLEAN_LOCK_WAIT_MS));
72
+ throw err;
73
+ }
74
+ const pid = parseLockOwnerPid(content);
75
+ if (pid !== void 0 && !isLockOwnerAlive(pid)) {
76
+ return false;
77
+ }
78
+ if (Date.now() - startedAt >= timeoutMs) {
79
+ const owner = pid === void 0 ? "unknown process" : `process ${pid}`;
80
+ throw new Error(`Timed out waiting for VXRN cache cleanup lock held by ${owner}`);
81
+ }
82
+ await new Promise((resolve) => setTimeout(resolve, CLEAN_LOCK_WAIT_MS));
83
+ }
84
+ }
85
+ function tryListen(server, port) {
86
+ return new Promise((resolve) => {
87
+ server.once("error", (err) => resolve(err));
88
+ server.once("listening", () => resolve(void 0));
89
+ server.listen({
90
+ port,
91
+ host: "127.0.0.1",
92
+ exclusive: true
93
+ });
94
+ });
95
+ }
96
+ async function acquirePortLock(port, startedAt, timeoutMs) {
97
+ while (true) {
98
+ const server = createServer((socket) => {
99
+ socket.on("error", () => {});
100
+ socket.destroy();
101
+ });
102
+ const err = await tryListen(server, port);
103
+ if (!err) {
104
+ return async () => {
105
+ await new Promise((resolve) => {
106
+ server.close(() => resolve());
107
+ });
108
+ };
109
+ }
110
+ if (getErrorCode(err) !== "EADDRINUSE") {
111
+ throw err;
41
112
  }
113
+ if (Date.now() - startedAt >= timeoutMs) {
114
+ throw new Error(`Timed out waiting for VXRN cache cleanup lock (127.0.0.1:${port})`);
115
+ }
116
+ await new Promise((resolve) => setTimeout(resolve, CLEAN_LOCK_WAIT_MS));
117
+ }
118
+ }
119
+ async function removeOwnLegacyLock(lockPath) {
120
+ try {
121
+ if (await readFile(lockPath, "utf8") === `${process.pid}
122
+ `) {
123
+ await rm(lockPath, { force: true });
124
+ }
125
+ } catch (err) {
126
+ if (getErrorCode(err) !== "ENOENT") {
127
+ throw err;
128
+ }
129
+ }
130
+ }
131
+ async function withCacheCleanLock(cacheDir, action) {
132
+ const lockDir = dirname(cacheDir);
133
+ const lockPath = join(lockDir, ".vxrn-clean.lock");
134
+ const startedAt = Date.now();
135
+ const timeoutMs = getCleanLockTimeoutMs();
136
+ await mkdir(lockDir, { recursive: true });
137
+ const created = await joinLegacyLock(lockPath, startedAt, timeoutMs);
138
+ let releasePort;
139
+ try {
140
+ releasePort = await acquirePortLock(await getCacheCleanLockPort(lockDir), startedAt, timeoutMs);
141
+ } catch (err) {
142
+ if (created) {
143
+ try {
144
+ await removeOwnLegacyLock(lockPath);
145
+ } catch {}
146
+ }
147
+ throw err;
42
148
  }
43
149
  try {
44
150
  return await action();
45
151
  } finally {
46
- await rm(lockPath, { force: true });
152
+ await releasePort();
153
+ if (created) {
154
+ await removeOwnLegacyLock(lockPath);
155
+ }
47
156
  }
48
157
  }
49
158
  async function removeCachePaths(root, only) {
@@ -1 +1 @@
1
- {"version":3,"file":"clean.js","names":[],"sources":["exports/clean.js"],"sourcesContent":["import { mkdir, readFile, rm, writeFile } from \"node:fs/promises\";\nimport { dirname, join } from \"node:path\";\nimport { fillOptions } from \"../config/getOptionsFilled\";\nimport { getSSRExternalsCachePath } from \"../plugins/autoDepOptimizePlugin\";\nimport { getCacheDir } from \"../utils/getCacheDir\";\nimport { readState, writeState } from \"../utils/state\";\nconst CLEAN_LOCK_WAIT_MS = 25;\nconst CLEAN_LOCK_TIMEOUT_MS = 6e4;\nfunction getErrorCode(err) {\n if (err instanceof Error && \"code\" in err && typeof err.code === \"string\") {\n return err.code;\n }\n}\nasync function withCacheCleanLock(cacheDir, action) {\n const lockPath = join(dirname(cacheDir), \".vxrn-clean.lock\");\n const startedAt = Date.now();\n await mkdir(dirname(lockPath), { recursive: true });\n while (true) {\n try {\n await writeFile(lockPath, `${process.pid}\n`, { flag: \"wx\" });\n break;\n } catch (err) {\n if (getErrorCode(err) !== \"EEXIST\") {\n throw err;\n }\n if (Date.now() - startedAt >= CLEAN_LOCK_TIMEOUT_MS) {\n let owner = \"unknown process\";\n try {\n owner = `process ${(await readFile(lockPath, \"utf8\")).trim()}`;\n } catch (readErr) {\n if (getErrorCode(readErr) === \"ENOENT\") {\n continue;\n }\n throw readErr;\n }\n throw new Error(`Timed out waiting for VXRN cache cleanup lock held by ${owner}`);\n }\n await new Promise((resolve) => setTimeout(resolve, CLEAN_LOCK_WAIT_MS));\n }\n }\n try {\n return await action();\n } finally {\n await rm(lockPath, { force: true });\n }\n}\nasync function removeCachePaths(root, only) {\n const removeVxrnCache = process.env.VXRN_DONT_CLEAN_SELF ? rm(getSSRExternalsCachePath(root)).catch(throwIfNotMissingError) : rm(getCacheDir(root), {\n recursive: true,\n force: true\n }).catch(throwIfNotMissingError);\n console.info(`[vxrn] cleaning`);\n await Promise.all([\n rm(join(root, \"node_modules\", \".vite\"), {\n recursive: true,\n force: true\n }).catch(throwIfNotMissingError),\n removeVxrnCache,\n only === \"vite\" ? null : rm(join(root, \"dist\"), {\n recursive: true,\n force: true\n }).catch(throwIfNotMissingError)\n ]);\n}\nasync function prepareCacheForVersion({\n root,\n cacheDir,\n versionHash,\n forceClean = false\n}) {\n return withCacheCleanLock(cacheDir, async () => {\n const state = await readState(cacheDir);\n const versionChanged = !!state.versionHash && state.versionHash !== versionHash;\n const shouldClean = forceClean || versionChanged;\n if (shouldClean) {\n await removeCachePaths(root, \"vite\");\n }\n if (shouldClean || state.versionHash !== versionHash) {\n await writeState(cacheDir, { versionHash });\n }\n return shouldClean;\n });\n}\nconst clean = async (rest, only) => {\n const options = await fillOptions(rest);\n await withCacheCleanLock(options.cacheDir, () => removeCachePaths(options.root, only));\n};\nfunction throwIfNotMissingError(err) {\n if (getErrorCode(err) !== \"ENOENT\") {\n throw err;\n }\n}\nexport {\n clean,\n prepareCacheForVersion\n};\n//# sourceMappingURL=clean.js.map\n"],"mappings":";;;;;;;;AAMA,MAAM,qBAAqB;AAC3B,MAAM,wBAAwB;AAC9B,SAAS,aAAa,KAAK;CACzB,IAAI,eAAe,SAAS,UAAU,OAAO,OAAO,IAAI,SAAS,UAAU;EACzE,OAAO,IAAI;CACb;AACF;AACA,eAAe,mBAAmB,UAAU,QAAQ;CAClD,MAAM,WAAW,KAAK,QAAQ,QAAQ,GAAG,kBAAkB;CAC3D,MAAM,YAAY,KAAK,IAAI;CAC3B,MAAM,MAAM,QAAQ,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;CAClD,OAAO,MAAM;EACX,IAAI;GACF,MAAM,UAAU,UAAU,GAAG,QAAQ,IAAI;GAC5C,EAAE,MAAM,KAAK,CAAC;GACX;EACF,SAAS,KAAK;GACZ,IAAI,aAAa,GAAG,MAAM,UAAU;IAClC,MAAM;GACR;GACA,IAAI,KAAK,IAAI,IAAI,aAAa,uBAAuB;IACnD,IAAI,QAAQ;IACZ,IAAI;KACF,QAAQ,YAAY,MAAM,SAAS,UAAU,MAAM,EAAC,CAAE,KAAK;IAC7D,SAAS,SAAS;KAChB,IAAI,aAAa,OAAO,MAAM,UAAU;MACtC;KACF;KACA,MAAM;IACR;IACA,MAAM,IAAI,MAAM,yDAAyD,OAAO;GAClF;GACA,MAAM,IAAI,SAAS,YAAY,WAAW,SAAS,kBAAkB,CAAC;EACxE;CACF;CACA,IAAI;EACF,OAAO,MAAM,OAAO;CACtB,UAAU;EACR,MAAM,GAAG,UAAU,EAAE,OAAO,KAAK,CAAC;CACpC;AACF;AACA,eAAe,iBAAiB,MAAM,MAAM;CAC1C,MAAM,kBAAkB,QAAQ,IAAI,uBAAuB,GAAG,yBAAyB,IAAI,CAAC,CAAC,CAAC,MAAM,sBAAsB,IAAI,GAAG,YAAY,IAAI,GAAG;EAClJ,WAAW;EACX,OAAO;CACT,CAAC,CAAC,CAAC,MAAM,sBAAsB;CAC/B,QAAQ,KAAK,iBAAiB;CAC9B,MAAM,QAAQ,IAAI;EAChB,GAAG,KAAK,MAAM,gBAAgB,OAAO,GAAG;GACtC,WAAW;GACX,OAAO;EACT,CAAC,CAAC,CAAC,MAAM,sBAAsB;EAC/B;EACA,SAAS,SAAS,OAAO,GAAG,KAAK,MAAM,MAAM,GAAG;GAC9C,WAAW;GACX,OAAO;EACT,CAAC,CAAC,CAAC,MAAM,sBAAsB;CACjC,CAAC;AACH;AACA,eAAe,uBAAuB,EACpC,MACA,UACA,aACA,aAAa,SACZ;CACD,OAAO,mBAAmB,UAAU,YAAY;EAC9C,MAAM,QAAQ,MAAM,UAAU,QAAQ;EACtC,MAAM,iBAAiB,CAAC,CAAC,MAAM,eAAe,MAAM,gBAAgB;EACpE,MAAM,cAAc,cAAc;EAClC,IAAI,aAAa;GACf,MAAM,iBAAiB,MAAM,MAAM;EACrC;EACA,IAAI,eAAe,MAAM,gBAAgB,aAAa;GACpD,MAAM,WAAW,UAAU,EAAE,YAAY,CAAC;EAC5C;EACA,OAAO;CACT,CAAC;AACH;AACA,MAAM,QAAQ,OAAO,MAAM,SAAS;CAClC,MAAM,UAAU,MAAM,YAAY,IAAI;CACtC,MAAM,mBAAmB,QAAQ,gBAAgB,iBAAiB,QAAQ,MAAM,IAAI,CAAC;AACvF;AACA,SAAS,uBAAuB,KAAK;CACnC,IAAI,aAAa,GAAG,MAAM,UAAU;EAClC,MAAM;CACR;AACF"}
1
+ {"version":3,"file":"clean.js","names":[],"sources":["exports/clean.js"],"sourcesContent":["import { mkdir, readFile, rm, stat, writeFile } from \"node:fs/promises\";\nimport { createServer } from \"node:net\";\nimport { dirname, join } from \"node:path\";\nimport { fillOptions } from \"../config/getOptionsFilled\";\nimport { getSSRExternalsCachePath } from \"../plugins/autoDepOptimizePlugin\";\nimport { getCacheDir } from \"../utils/getCacheDir\";\nimport { readState, writeState } from \"../utils/state\";\nconst CLEAN_LOCK_WAIT_MS = 25;\nconst CLEAN_LOCK_TIMEOUT_MS = 6e4;\nfunction getErrorCode(err) {\n if (err instanceof Error && \"code\" in err && typeof err.code === \"string\") {\n return err.code;\n }\n}\nfunction getCleanLockTimeoutMs() {\n const override = Number.parseInt(process.env.VXRN_CLEAN_LOCK_TIMEOUT_MS ?? \"\", 10);\n if (Number.isSafeInteger(override) && override > 0) {\n return override;\n }\n return CLEAN_LOCK_TIMEOUT_MS;\n}\nconst CLEAN_LOCK_PORT_BASE = 24e3;\nconst CLEAN_LOCK_PORT_COUNT = 1e3;\nasync function getCacheCleanLockPort(lockDir) {\n const info = await stat(lockDir);\n let hash = 2166136261;\n const identity = `${info.dev}:${info.ino}`;\n for (let index = 0; index < identity.length; index++) {\n hash ^= identity.charCodeAt(index);\n hash = Math.imul(hash, 16777619);\n }\n return CLEAN_LOCK_PORT_BASE + (hash >>> 0) % CLEAN_LOCK_PORT_COUNT;\n}\nfunction isLockOwnerAlive(pid) {\n try {\n process.kill(pid, 0);\n return true;\n } catch (err) {\n return getErrorCode(err) !== \"ESRCH\";\n }\n}\nfunction parseLockOwnerPid(content) {\n const trimmed = content.trim();\n if (!/^\\d+$/.test(trimmed)) {\n return void 0;\n }\n const pid = Number.parseInt(trimmed, 10);\n if (!Number.isSafeInteger(pid) || pid <= 0) {\n return void 0;\n }\n return pid;\n}\nasync function joinLegacyLock(lockPath, startedAt, timeoutMs) {\n while (true) {\n try {\n await writeFile(lockPath, `${process.pid}\n`, { flag: \"wx\" });\n return true;\n } catch (err) {\n if (getErrorCode(err) !== \"EEXIST\") {\n throw err;\n }\n }\n let content;\n try {\n content = await readFile(lockPath, \"utf8\");\n } catch (err) {\n if (getErrorCode(err) === \"ENOENT\") {\n continue;\n }\n throw err;\n }\n const pid = parseLockOwnerPid(content);\n if (pid !== void 0 && !isLockOwnerAlive(pid)) {\n return false;\n }\n if (Date.now() - startedAt >= timeoutMs) {\n const owner = pid === void 0 ? \"unknown process\" : `process ${pid}`;\n throw new Error(`Timed out waiting for VXRN cache cleanup lock held by ${owner}`);\n }\n await new Promise((resolve) => setTimeout(resolve, CLEAN_LOCK_WAIT_MS));\n }\n}\nfunction tryListen(server, port) {\n return new Promise((resolve) => {\n server.once(\"error\", (err) => resolve(err));\n server.once(\"listening\", () => resolve(void 0));\n server.listen({ port, host: \"127.0.0.1\", exclusive: true });\n });\n}\nasync function acquirePortLock(port, startedAt, timeoutMs) {\n while (true) {\n const server = createServer((socket) => {\n socket.on(\"error\", () => {\n });\n socket.destroy();\n });\n const err = await tryListen(server, port);\n if (!err) {\n return async () => {\n await new Promise((resolve) => {\n server.close(() => resolve());\n });\n };\n }\n if (getErrorCode(err) !== \"EADDRINUSE\") {\n throw err;\n }\n if (Date.now() - startedAt >= timeoutMs) {\n throw new Error(`Timed out waiting for VXRN cache cleanup lock (127.0.0.1:${port})`);\n }\n await new Promise((resolve) => setTimeout(resolve, CLEAN_LOCK_WAIT_MS));\n }\n}\nasync function removeOwnLegacyLock(lockPath) {\n try {\n if (await readFile(lockPath, \"utf8\") === `${process.pid}\n`) {\n await rm(lockPath, { force: true });\n }\n } catch (err) {\n if (getErrorCode(err) !== \"ENOENT\") {\n throw err;\n }\n }\n}\nasync function withCacheCleanLock(cacheDir, action) {\n const lockDir = dirname(cacheDir);\n const lockPath = join(lockDir, \".vxrn-clean.lock\");\n const startedAt = Date.now();\n const timeoutMs = getCleanLockTimeoutMs();\n await mkdir(lockDir, { recursive: true });\n const created = await joinLegacyLock(lockPath, startedAt, timeoutMs);\n let releasePort;\n try {\n releasePort = await acquirePortLock(await getCacheCleanLockPort(lockDir), startedAt, timeoutMs);\n } catch (err) {\n if (created) {\n try {\n await removeOwnLegacyLock(lockPath);\n } catch {\n }\n }\n throw err;\n }\n try {\n return await action();\n } finally {\n await releasePort();\n if (created) {\n await removeOwnLegacyLock(lockPath);\n }\n }\n}\nasync function removeCachePaths(root, only) {\n const removeVxrnCache = process.env.VXRN_DONT_CLEAN_SELF ? rm(getSSRExternalsCachePath(root)).catch(throwIfNotMissingError) : rm(getCacheDir(root), {\n recursive: true,\n force: true\n }).catch(throwIfNotMissingError);\n console.info(`[vxrn] cleaning`);\n await Promise.all([\n rm(join(root, \"node_modules\", \".vite\"), {\n recursive: true,\n force: true\n }).catch(throwIfNotMissingError),\n removeVxrnCache,\n only === \"vite\" ? null : rm(join(root, \"dist\"), {\n recursive: true,\n force: true\n }).catch(throwIfNotMissingError)\n ]);\n}\nasync function prepareCacheForVersion({\n root,\n cacheDir,\n versionHash,\n forceClean = false\n}) {\n return withCacheCleanLock(cacheDir, async () => {\n const state = await readState(cacheDir);\n const versionChanged = !!state.versionHash && state.versionHash !== versionHash;\n const shouldClean = forceClean || versionChanged;\n if (shouldClean) {\n await removeCachePaths(root, \"vite\");\n }\n if (shouldClean || state.versionHash !== versionHash) {\n await writeState(cacheDir, { versionHash });\n }\n return shouldClean;\n });\n}\nconst clean = async (rest, only) => {\n const options = await fillOptions(rest);\n await withCacheCleanLock(options.cacheDir, () => removeCachePaths(options.root, only));\n};\nfunction throwIfNotMissingError(err) {\n if (getErrorCode(err) !== \"ENOENT\") {\n throw err;\n }\n}\nexport {\n clean,\n prepareCacheForVersion\n};\n//# sourceMappingURL=clean.js.map\n"],"mappings":"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"}
@@ -1,10 +1,15 @@
1
- import { mkdir, readFile, rm, writeFile } from "fs/promises";
1
+ import { mkdir, readFile, rm, stat, writeFile } from "fs/promises";
2
+ import { createServer } from "net";
2
3
  import { dirname, join } from "path";
3
4
  import { fillOptions } from "../config/getOptionsFilled.native.js";
4
5
  import { getSSRExternalsCachePath } from "../plugins/autoDepOptimizePlugin.native.js";
5
6
  import { getCacheDir } from "../utils/getCacheDir.native.js";
6
7
  import { readState, writeState } from "../utils/state.native.js";
7
8
 
9
+ function _type_of(obj) {
10
+ "@swc/helpers - typeof";
11
+ return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
12
+ }
8
13
  var CLEAN_LOCK_WAIT_MS = 25;
9
14
  var CLEAN_LOCK_TIMEOUT_MS = 6e4;
10
15
  function getErrorCode(err) {
@@ -12,40 +17,161 @@ function getErrorCode(err) {
12
17
  return err.code;
13
18
  }
14
19
  }
15
- async function withCacheCleanLock(cacheDir, action) {
16
- var lockPath = join(dirname(cacheDir), ".vxrn-clean.lock");
17
- var startedAt = Date.now();
18
- await mkdir(dirname(lockPath), { recursive: true });
20
+ function getCleanLockTimeoutMs() {
21
+ var _process_env_VXRN_CLEAN_LOCK_TIMEOUT_MS;
22
+ var override = Number.parseInt((_process_env_VXRN_CLEAN_LOCK_TIMEOUT_MS = process.env.VXRN_CLEAN_LOCK_TIMEOUT_MS) !== null && _process_env_VXRN_CLEAN_LOCK_TIMEOUT_MS !== void 0 ? _process_env_VXRN_CLEAN_LOCK_TIMEOUT_MS : "", 10);
23
+ if (Number.isSafeInteger(override) && override > 0) {
24
+ return override;
25
+ }
26
+ return CLEAN_LOCK_TIMEOUT_MS;
27
+ }
28
+ var CLEAN_LOCK_PORT_BASE = 24e3;
29
+ var CLEAN_LOCK_PORT_COUNT = 1e3;
30
+ async function getCacheCleanLockPort(lockDir) {
31
+ var info = await stat(lockDir);
32
+ var hash = 2166136261;
33
+ var identity = `${info.dev}:${info.ino}`;
34
+ for (var index = 0; index < identity.length; index++) {
35
+ hash ^= identity.charCodeAt(index);
36
+ hash = Math.imul(hash, 16777619);
37
+ }
38
+ return CLEAN_LOCK_PORT_BASE + (hash >>> 0) % CLEAN_LOCK_PORT_COUNT;
39
+ }
40
+ function isLockOwnerAlive(pid) {
41
+ try {
42
+ process.kill(pid, 0);
43
+ return true;
44
+ } catch (err) {
45
+ return getErrorCode(err) !== "ESRCH";
46
+ }
47
+ }
48
+ function parseLockOwnerPid(content) {
49
+ var trimmed = content.trim();
50
+ if (!/^\d+$/.test(trimmed)) {
51
+ return void 0;
52
+ }
53
+ var pid = Number.parseInt(trimmed, 10);
54
+ if (!Number.isSafeInteger(pid) || pid <= 0) {
55
+ return void 0;
56
+ }
57
+ return pid;
58
+ }
59
+ async function joinLegacyLock(lockPath, startedAt, timeoutMs) {
19
60
  while (true) {
20
61
  try {
21
62
  await writeFile(lockPath, `${process.pid}
22
63
  `, { flag: "wx" });
23
- break;
64
+ return true;
24
65
  } catch (err) {
25
66
  if (getErrorCode(err) !== "EEXIST") {
26
67
  throw err;
27
68
  }
28
- if (Date.now() - startedAt >= CLEAN_LOCK_TIMEOUT_MS) {
29
- var owner = "unknown process";
30
- try {
31
- owner = `process ${(await readFile(lockPath, "utf8")).trim()}`;
32
- } catch (readErr) {
33
- if (getErrorCode(readErr) === "ENOENT") {
34
- continue;
35
- }
36
- throw readErr;
37
- }
38
- throw new Error(`Timed out waiting for VXRN cache cleanup lock held by ${owner}`);
69
+ }
70
+ var content = void 0;
71
+ try {
72
+ content = await readFile(lockPath, "utf8");
73
+ } catch (err) {
74
+ if (getErrorCode(err) === "ENOENT") {
75
+ continue;
39
76
  }
40
- await new Promise(function(resolve) {
41
- return setTimeout(resolve, CLEAN_LOCK_WAIT_MS);
42
- });
77
+ throw err;
78
+ }
79
+ var pid = parseLockOwnerPid(content);
80
+ if (pid !== void 0 && !isLockOwnerAlive(pid)) {
81
+ return false;
82
+ }
83
+ if (Date.now() - startedAt >= timeoutMs) {
84
+ var owner = pid === void 0 ? "unknown process" : `process ${pid}`;
85
+ throw new Error(`Timed out waiting for VXRN cache cleanup lock held by ${owner}`);
43
86
  }
87
+ await new Promise(function(resolve) {
88
+ return setTimeout(resolve, CLEAN_LOCK_WAIT_MS);
89
+ });
90
+ }
91
+ }
92
+ function tryListen(server, port) {
93
+ return new Promise(function(resolve) {
94
+ server.once("error", function(err) {
95
+ return resolve(err);
96
+ });
97
+ server.once("listening", function() {
98
+ return resolve(void 0);
99
+ });
100
+ server.listen({
101
+ port,
102
+ host: "127.0.0.1",
103
+ exclusive: true
104
+ });
105
+ });
106
+ }
107
+ async function acquirePortLock(port, startedAt, timeoutMs) {
108
+ var _loop = async function() {
109
+ var server = createServer(function(socket) {
110
+ socket.on("error", function() {});
111
+ socket.destroy();
112
+ });
113
+ var err = await tryListen(server, port);
114
+ if (!err) {
115
+ return { v: async function() {
116
+ await new Promise(function(resolve) {
117
+ server.close(function() {
118
+ return resolve();
119
+ });
120
+ });
121
+ } };
122
+ }
123
+ if (getErrorCode(err) !== "EADDRINUSE") {
124
+ throw err;
125
+ }
126
+ if (Date.now() - startedAt >= timeoutMs) {
127
+ throw new Error(`Timed out waiting for VXRN cache cleanup lock (127.0.0.1:${port})`);
128
+ }
129
+ await new Promise(function(resolve) {
130
+ return setTimeout(resolve, CLEAN_LOCK_WAIT_MS);
131
+ });
132
+ };
133
+ while (true) {
134
+ var _ret = await _loop();
135
+ if (_type_of(_ret) === "object") return _ret.v;
136
+ }
137
+ }
138
+ async function removeOwnLegacyLock(lockPath) {
139
+ try {
140
+ if (await readFile(lockPath, "utf8") === `${process.pid}
141
+ `) {
142
+ await rm(lockPath, { force: true });
143
+ }
144
+ } catch (err) {
145
+ if (getErrorCode(err) !== "ENOENT") {
146
+ throw err;
147
+ }
148
+ }
149
+ }
150
+ async function withCacheCleanLock(cacheDir, action) {
151
+ var lockDir = dirname(cacheDir);
152
+ var lockPath = join(lockDir, ".vxrn-clean.lock");
153
+ var startedAt = Date.now();
154
+ var timeoutMs = getCleanLockTimeoutMs();
155
+ await mkdir(lockDir, { recursive: true });
156
+ var created = await joinLegacyLock(lockPath, startedAt, timeoutMs);
157
+ var releasePort;
158
+ try {
159
+ releasePort = await acquirePortLock(await getCacheCleanLockPort(lockDir), startedAt, timeoutMs);
160
+ } catch (err) {
161
+ if (created) {
162
+ try {
163
+ await removeOwnLegacyLock(lockPath);
164
+ } catch (unused) {}
165
+ }
166
+ throw err;
44
167
  }
45
168
  try {
46
169
  return await action();
47
170
  } finally {
48
- await rm(lockPath, { force: true });
171
+ await releasePort();
172
+ if (created) {
173
+ await removeOwnLegacyLock(lockPath);
174
+ }
49
175
  }
50
176
  }
51
177
  async function removeCachePaths(root, only) {
@@ -1 +1 @@
1
- {"version":3,"file":"clean.native.js","names":[],"sources":["exports/clean.native.js"],"sourcesContent":["import { mkdir, readFile, rm, writeFile } from \"fs/promises\";\nimport { dirname, join } from \"path\";\nimport { fillOptions } from \"../config/getOptionsFilled\";\nimport { getSSRExternalsCachePath } from \"../plugins/autoDepOptimizePlugin\";\nimport { getCacheDir } from \"../utils/getCacheDir\";\nimport { readState, writeState } from \"../utils/state\";\nvar CLEAN_LOCK_WAIT_MS = 25;\nvar CLEAN_LOCK_TIMEOUT_MS = 6e4;\nfunction getErrorCode(err) {\n if (err instanceof Error && \"code\" in err && typeof err.code === \"string\") {\n return err.code;\n }\n}\nasync function withCacheCleanLock(cacheDir, action) {\n var lockPath = join(dirname(cacheDir), \".vxrn-clean.lock\");\n var startedAt = Date.now();\n await mkdir(dirname(lockPath), {\n recursive: true\n });\n while (true) {\n try {\n await writeFile(lockPath, `${process.pid}\n`, {\n flag: \"wx\"\n });\n break;\n } catch (err) {\n if (getErrorCode(err) !== \"EEXIST\") {\n throw err;\n }\n if (Date.now() - startedAt >= CLEAN_LOCK_TIMEOUT_MS) {\n var owner = \"unknown process\";\n try {\n owner = `process ${(await readFile(lockPath, \"utf8\")).trim()}`;\n } catch (readErr) {\n if (getErrorCode(readErr) === \"ENOENT\") {\n continue;\n }\n throw readErr;\n }\n throw new Error(`Timed out waiting for VXRN cache cleanup lock held by ${owner}`);\n }\n await new Promise(function(resolve) {\n return setTimeout(resolve, CLEAN_LOCK_WAIT_MS);\n });\n }\n }\n try {\n return await action();\n } finally {\n await rm(lockPath, {\n force: true\n });\n }\n}\nasync function removeCachePaths(root, only) {\n var removeVxrnCache = process.env.VXRN_DONT_CLEAN_SELF ? rm(getSSRExternalsCachePath(root)).catch(throwIfNotMissingError) : rm(getCacheDir(root), {\n recursive: true,\n force: true\n }).catch(throwIfNotMissingError);\n console.info(`[vxrn] cleaning`);\n await Promise.all([\n rm(join(root, \"node_modules\", \".vite\"), {\n recursive: true,\n force: true\n }).catch(throwIfNotMissingError),\n removeVxrnCache,\n only === \"vite\" ? null : rm(join(root, \"dist\"), {\n recursive: true,\n force: true\n }).catch(throwIfNotMissingError)\n ]);\n}\nasync function prepareCacheForVersion(param) {\n var { root, cacheDir, versionHash, forceClean = false } = param;\n return withCacheCleanLock(cacheDir, async function() {\n var state = await readState(cacheDir);\n var versionChanged = !!state.versionHash && state.versionHash !== versionHash;\n var shouldClean = forceClean || versionChanged;\n if (shouldClean) {\n await removeCachePaths(root, \"vite\");\n }\n if (shouldClean || state.versionHash !== versionHash) {\n await writeState(cacheDir, {\n versionHash\n });\n }\n return shouldClean;\n });\n}\nvar clean = async function clean2(rest, only) {\n var options = await fillOptions(rest);\n await withCacheCleanLock(options.cacheDir, function() {\n return removeCachePaths(options.root, only);\n });\n};\nfunction throwIfNotMissingError(err) {\n if (getErrorCode(err) !== \"ENOENT\") {\n throw err;\n }\n}\nexport {\n clean,\n prepareCacheForVersion\n};\n//# sourceMappingURL=clean.js.map\n"],"mappings":";;;;;;;;AAMA,IAAI,qBAAqB;AACzB,IAAI,wBAAwB;AAC5B,SAAS,aAAa,KAAK;CACzB,IAAI,eAAe,SAAS,UAAU,OAAO,OAAO,IAAI,SAAS,UAAU;EACzE,OAAO,IAAI;CACb;AACF;AACA,eAAe,mBAAmB,UAAU,QAAQ;CAClD,IAAI,WAAW,KAAK,QAAQ,QAAQ,GAAG,kBAAkB;CACzD,IAAI,YAAY,KAAK,IAAI;CACzB,MAAM,MAAM,QAAQ,QAAQ,GAAG,EAC7B,WAAW,KACb,CAAC;CACD,OAAO,MAAM;EACX,IAAI;GACF,MAAM,UAAU,UAAU,GAAG,QAAQ,IAAI;GAC5C,EACK,MAAM,KACR,CAAC;GACD;EACF,SAAS,KAAK;GACZ,IAAI,aAAa,GAAG,MAAM,UAAU;IAClC,MAAM;GACR;GACA,IAAI,KAAK,IAAI,IAAI,aAAa,uBAAuB;IACnD,IAAI,QAAQ;IACZ,IAAI;KACF,QAAQ,YAAY,MAAM,SAAS,UAAU,MAAM,EAAC,CAAE,KAAK;IAC7D,SAAS,SAAS;KAChB,IAAI,aAAa,OAAO,MAAM,UAAU;MACtC;KACF;KACA,MAAM;IACR;IACA,MAAM,IAAI,MAAM,yDAAyD,OAAO;GAClF;GACA,MAAM,IAAI,QAAQ,SAAS,SAAS;IAClC,OAAO,WAAW,SAAS,kBAAkB;GAC/C,CAAC;EACH;CACF;CACA,IAAI;EACF,OAAO,MAAM,OAAO;CACtB,UAAU;EACR,MAAM,GAAG,UAAU,EACjB,OAAO,KACT,CAAC;CACH;AACF;AACA,eAAe,iBAAiB,MAAM,MAAM;CAC1C,IAAI,kBAAkB,QAAQ,IAAI,uBAAuB,GAAG,yBAAyB,IAAI,CAAC,CAAC,CAAC,MAAM,sBAAsB,IAAI,GAAG,YAAY,IAAI,GAAG;EAChJ,WAAW;EACX,OAAO;CACT,CAAC,CAAC,CAAC,MAAM,sBAAsB;CAC/B,QAAQ,KAAK,iBAAiB;CAC9B,MAAM,QAAQ,IAAI;EAChB,GAAG,KAAK,MAAM,gBAAgB,OAAO,GAAG;GACtC,WAAW;GACX,OAAO;EACT,CAAC,CAAC,CAAC,MAAM,sBAAsB;EAC/B;EACA,SAAS,SAAS,OAAO,GAAG,KAAK,MAAM,MAAM,GAAG;GAC9C,WAAW;GACX,OAAO;EACT,CAAC,CAAC,CAAC,MAAM,sBAAsB;CACjC,CAAC;AACH;AACA,eAAe,uBAAuB,OAAO;CAC3C,IAAI,EAAE,MAAM,UAAU,aAAa,aAAa,UAAU;CAC1D,OAAO,mBAAmB,UAAU,iBAAiB;EACnD,IAAI,QAAQ,MAAM,UAAU,QAAQ;EACpC,IAAI,iBAAiB,CAAC,CAAC,MAAM,eAAe,MAAM,gBAAgB;EAClE,IAAI,cAAc,cAAc;EAChC,IAAI,aAAa;GACf,MAAM,iBAAiB,MAAM,MAAM;EACrC;EACA,IAAI,eAAe,MAAM,gBAAgB,aAAa;GACpD,MAAM,WAAW,UAAU,EACzB,YACF,CAAC;EACH;EACA,OAAO;CACT,CAAC;AACH;AACA,IAAI,QAAQ,eAAe,OAAO,MAAM,MAAM;CAC5C,IAAI,UAAU,MAAM,YAAY,IAAI;CACpC,MAAM,mBAAmB,QAAQ,UAAU,WAAW;EACpD,OAAO,iBAAiB,QAAQ,MAAM,IAAI;CAC5C,CAAC;AACH;AACA,SAAS,uBAAuB,KAAK;CACnC,IAAI,aAAa,GAAG,MAAM,UAAU;EAClC,MAAM;CACR;AACF"}
1
+ {"version":3,"file":"clean.native.js","names":[],"sources":["exports/clean.native.js"],"sourcesContent":["import { mkdir, readFile, rm, stat, writeFile } from \"fs/promises\";\nimport { createServer } from \"net\";\nimport { dirname, join } from \"path\";\nimport { fillOptions } from \"../config/getOptionsFilled\";\nimport { getSSRExternalsCachePath } from \"../plugins/autoDepOptimizePlugin\";\nimport { getCacheDir } from \"../utils/getCacheDir\";\nimport { readState, writeState } from \"../utils/state\";\nfunction _type_of(obj) {\n \"@swc/helpers - typeof\";\n return obj && typeof Symbol !== \"undefined\" && obj.constructor === Symbol ? \"symbol\" : typeof obj;\n}\nvar CLEAN_LOCK_WAIT_MS = 25;\nvar CLEAN_LOCK_TIMEOUT_MS = 6e4;\nfunction getErrorCode(err) {\n if (err instanceof Error && \"code\" in err && typeof err.code === \"string\") {\n return err.code;\n }\n}\nfunction getCleanLockTimeoutMs() {\n var _process_env_VXRN_CLEAN_LOCK_TIMEOUT_MS;\n var override = Number.parseInt((_process_env_VXRN_CLEAN_LOCK_TIMEOUT_MS = process.env.VXRN_CLEAN_LOCK_TIMEOUT_MS) !== null && _process_env_VXRN_CLEAN_LOCK_TIMEOUT_MS !== void 0 ? _process_env_VXRN_CLEAN_LOCK_TIMEOUT_MS : \"\", 10);\n if (Number.isSafeInteger(override) && override > 0) {\n return override;\n }\n return CLEAN_LOCK_TIMEOUT_MS;\n}\nvar CLEAN_LOCK_PORT_BASE = 24e3;\nvar CLEAN_LOCK_PORT_COUNT = 1e3;\nasync function getCacheCleanLockPort(lockDir) {\n var info = await stat(lockDir);\n var hash = 2166136261;\n var identity = `${info.dev}:${info.ino}`;\n for (var index = 0; index < identity.length; index++) {\n hash ^= identity.charCodeAt(index);\n hash = Math.imul(hash, 16777619);\n }\n return CLEAN_LOCK_PORT_BASE + (hash >>> 0) % CLEAN_LOCK_PORT_COUNT;\n}\nfunction isLockOwnerAlive(pid) {\n try {\n process.kill(pid, 0);\n return true;\n } catch (err) {\n return getErrorCode(err) !== \"ESRCH\";\n }\n}\nfunction parseLockOwnerPid(content) {\n var trimmed = content.trim();\n if (!/^\\d+$/.test(trimmed)) {\n return void 0;\n }\n var pid = Number.parseInt(trimmed, 10);\n if (!Number.isSafeInteger(pid) || pid <= 0) {\n return void 0;\n }\n return pid;\n}\nasync function joinLegacyLock(lockPath, startedAt, timeoutMs) {\n while (true) {\n try {\n await writeFile(lockPath, `${process.pid}\n`, {\n flag: \"wx\"\n });\n return true;\n } catch (err) {\n if (getErrorCode(err) !== \"EEXIST\") {\n throw err;\n }\n }\n var content = void 0;\n try {\n content = await readFile(lockPath, \"utf8\");\n } catch (err) {\n if (getErrorCode(err) === \"ENOENT\") {\n continue;\n }\n throw err;\n }\n var pid = parseLockOwnerPid(content);\n if (pid !== void 0 && !isLockOwnerAlive(pid)) {\n return false;\n }\n if (Date.now() - startedAt >= timeoutMs) {\n var owner = pid === void 0 ? \"unknown process\" : `process ${pid}`;\n throw new Error(`Timed out waiting for VXRN cache cleanup lock held by ${owner}`);\n }\n await new Promise(function(resolve) {\n return setTimeout(resolve, CLEAN_LOCK_WAIT_MS);\n });\n }\n}\nfunction tryListen(server, port) {\n return new Promise(function(resolve) {\n server.once(\"error\", function(err) {\n return resolve(err);\n });\n server.once(\"listening\", function() {\n return resolve(void 0);\n });\n server.listen({\n port,\n host: \"127.0.0.1\",\n exclusive: true\n });\n });\n}\nasync function acquirePortLock(port, startedAt, timeoutMs) {\n var _loop = async function() {\n var server = createServer(function(socket) {\n socket.on(\"error\", function() {\n });\n socket.destroy();\n });\n var err = await tryListen(server, port);\n if (!err) {\n return {\n v: async function() {\n await new Promise(function(resolve) {\n server.close(function() {\n return resolve();\n });\n });\n }\n };\n }\n if (getErrorCode(err) !== \"EADDRINUSE\") {\n throw err;\n }\n if (Date.now() - startedAt >= timeoutMs) {\n throw new Error(`Timed out waiting for VXRN cache cleanup lock (127.0.0.1:${port})`);\n }\n await new Promise(function(resolve) {\n return setTimeout(resolve, CLEAN_LOCK_WAIT_MS);\n });\n };\n while (true) {\n var _ret = await _loop();\n if (_type_of(_ret) === \"object\") return _ret.v;\n }\n}\nasync function removeOwnLegacyLock(lockPath) {\n try {\n if (await readFile(lockPath, \"utf8\") === `${process.pid}\n`) {\n await rm(lockPath, {\n force: true\n });\n }\n } catch (err) {\n if (getErrorCode(err) !== \"ENOENT\") {\n throw err;\n }\n }\n}\nasync function withCacheCleanLock(cacheDir, action) {\n var lockDir = dirname(cacheDir);\n var lockPath = join(lockDir, \".vxrn-clean.lock\");\n var startedAt = Date.now();\n var timeoutMs = getCleanLockTimeoutMs();\n await mkdir(lockDir, {\n recursive: true\n });\n var created = await joinLegacyLock(lockPath, startedAt, timeoutMs);\n var releasePort;\n try {\n releasePort = await acquirePortLock(await getCacheCleanLockPort(lockDir), startedAt, timeoutMs);\n } catch (err) {\n if (created) {\n try {\n await removeOwnLegacyLock(lockPath);\n } catch (unused) {\n }\n }\n throw err;\n }\n try {\n return await action();\n } finally {\n await releasePort();\n if (created) {\n await removeOwnLegacyLock(lockPath);\n }\n }\n}\nasync function removeCachePaths(root, only) {\n var removeVxrnCache = process.env.VXRN_DONT_CLEAN_SELF ? rm(getSSRExternalsCachePath(root)).catch(throwIfNotMissingError) : rm(getCacheDir(root), {\n recursive: true,\n force: true\n }).catch(throwIfNotMissingError);\n console.info(`[vxrn] cleaning`);\n await Promise.all([\n rm(join(root, \"node_modules\", \".vite\"), {\n recursive: true,\n force: true\n }).catch(throwIfNotMissingError),\n removeVxrnCache,\n only === \"vite\" ? null : rm(join(root, \"dist\"), {\n recursive: true,\n force: true\n }).catch(throwIfNotMissingError)\n ]);\n}\nasync function prepareCacheForVersion(param) {\n var { root, cacheDir, versionHash, forceClean = false } = param;\n return withCacheCleanLock(cacheDir, async function() {\n var state = await readState(cacheDir);\n var versionChanged = !!state.versionHash && state.versionHash !== versionHash;\n var shouldClean = forceClean || versionChanged;\n if (shouldClean) {\n await removeCachePaths(root, \"vite\");\n }\n if (shouldClean || state.versionHash !== versionHash) {\n await writeState(cacheDir, {\n versionHash\n });\n }\n return shouldClean;\n });\n}\nvar clean = async function clean2(rest, only) {\n var options = await fillOptions(rest);\n await withCacheCleanLock(options.cacheDir, function() {\n return removeCachePaths(options.root, only);\n });\n};\nfunction throwIfNotMissingError(err) {\n if (getErrorCode(err) !== \"ENOENT\") {\n throw err;\n }\n}\nexport {\n clean,\n prepareCacheForVersion\n};\n//# sourceMappingURL=clean.js.map\n"],"mappings":"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"}
@@ -5,7 +5,7 @@ import { fillOptions } from "../config/getOptionsFilled.mjs";
5
5
  import { applyBuiltInPatches } from "../utils/patches.mjs";
6
6
  import { applyAndroidDependencyPatches, generateForPlatform, getNativeDependencyInventory, installNativeDependencies, validatePrebuildApp } from "./prebuildWithoutExpo.mjs";
7
7
 
8
- const prebuild = async ({ root, platform, "no-install": noInstall = false, app }) => {
8
+ const prebuild = async ({ root, platform, "no-install": noInstall = false, app, beforeInstall }) => {
9
9
  validatePrebuildApp(app, platform);
10
10
  const options = await fillOptions({ root });
11
11
  await applyBuiltInPatches(options);
@@ -35,6 +35,7 @@ const prebuild = async ({ root, platform, "no-install": noInstall = false, app }
35
35
  if (platform == "android" || !platform) {
36
36
  await generateForPlatform(root, "android", app);
37
37
  }
38
+ await beforeInstall?.();
38
39
  const inventory = await getNativeDependencyInventory(root);
39
40
  console.info(`[vxrn] native dependencies discovered through community autolinking: ${inventory.map((entry) => entry.name).join(", ") || "(none)"}`);
40
41
  if (platform == "android" || !platform) {
@@ -1 +1 @@
1
- {"version":3,"file":"prebuild.js","names":[],"sources":["exports/prebuild.js"],"sourcesContent":["import { detectPackageManager } from \"@vxrn/utils\";\nimport FSExtra from \"fs-extra\";\nimport path from \"node:path\";\nimport { fillOptions } from \"../config/getOptionsFilled\";\nimport { applyBuiltInPatches } from \"../utils/patches\";\nimport {\n applyAndroidDependencyPatches,\n generateForPlatform,\n getNativeDependencyInventory,\n installNativeDependencies,\n validatePrebuildApp\n} from \"./prebuildWithoutExpo\";\nconst prebuild = async ({\n root,\n platform,\n \"no-install\": noInstall = false,\n app\n}) => {\n validatePrebuildApp(app, platform);\n const options = await fillOptions({ root });\n await applyBuiltInPatches(options);\n try {\n const packageJsonPath = path.join(root, \"package.json\");\n const packageJsonContents = await FSExtra.readFile(packageJsonPath, \"utf8\");\n const { devDependencies } = JSON.parse(packageJsonContents);\n if (!devDependencies?.[\"@react-native-community/template\"]) {\n const installCommand = await (async () => {\n const found = await detectPackageManager();\n switch (true) {\n case found.bun:\n return `bun add -D @react-native-community/template`;\n case found.pnpm:\n return `pnpm install -D @react-native-community/template`;\n case found.yarn:\n return `yarn add -D @react-native-community/template`;\n default:\n return `npm install -D @react-native-community/template`;\n }\n })();\n throw new Error(\n `\"@react-native-community/template\" is not found in package.json, please install \"@react-native-community/template\" as dev dependency:\n\\`${installCommand}\\``\n );\n }\n } catch (error) {\n throw new Error(\"package.json checks are failing:\\n\" + error);\n }\n if (platform == \"ios\" || !platform) {\n await generateForPlatform(root, \"ios\", app);\n }\n if (platform == \"android\" || !platform) {\n await generateForPlatform(root, \"android\", app);\n }\n const inventory = await getNativeDependencyInventory(root);\n console.info(\n `[vxrn] native dependencies discovered through community autolinking: ${inventory.map((entry) => entry.name).join(\", \") || \"(none)\"}`\n );\n if (platform == \"android\" || !platform) {\n applyAndroidDependencyPatches({ root, app, inventory });\n }\n if (!noInstall) {\n installNativeDependencies({ root, platform });\n } else if (!platform || platform === \"ios\") {\n console.info(`Run cd ios && pod install`);\n console.info(\n \"Then run `open *.xcworkspace` in your terminal to open the prebuilt iOS project, then you can either run it via Xcode or archive it for distribution.\"\n );\n }\n if (!platform || platform === \"ios\") {\n console.info(\n `\niOS:\n\n Run \\`open ios/*.xcworkspace\\` in your terminal to open the prebuilt iOS project.\n Then you can either run it via Xcode or archive it for distribution.\n\n See https://onestack.dev/docs/guides-ios-native for more information.\n\n---\n`\n );\n }\n if (!platform || platform === \"android\") {\n console.info(\n `\nAndroid:\n\n \\`cd android\\` and run \\`./gradlew generateCodegenArtifactsFromSchema\\`, then \\`./gradlew assembleRelease\\` or \\`./gradlew assembleDebug\\` to build the Android project.\n\n Afterwards, you can find the built APK at \\`android/app/build/outputs/apk/release/app-release.apk\\` or\n \\`android/app/build/outputs/apk/debug/app-debug.apk\\`.\n\n`\n );\n }\n};\nasync function replaceInUTF8File(filePath, findThis, replaceWith) {\n const fileContent = await FSExtra.readFile(filePath, \"utf8\");\n const replacedFileContent = fileContent.replace(findThis, replaceWith);\n if (replacedFileContent !== fileContent) {\n await FSExtra.writeFile(filePath, replacedFileContent, \"utf8\");\n }\n}\nexport {\n prebuild,\n replaceInUTF8File\n};\n//# sourceMappingURL=prebuild.js.map\n"],"mappings":";;;;;;;;AAYA,MAAM,WAAW,OAAO,EACtB,MACA,UACA,cAAc,YAAY,OAC1B,UACI;CACJ,oBAAoB,KAAK,QAAQ;CACjC,MAAM,UAAU,MAAM,YAAY,EAAE,KAAK,CAAC;CAC1C,MAAM,oBAAoB,OAAO;CACjC,IAAI;EACF,MAAM,kBAAkB,KAAK,KAAK,MAAM,cAAc;EACtD,MAAM,sBAAsB,MAAM,QAAQ,SAAS,iBAAiB,MAAM;EAC1E,MAAM,EAAE,oBAAoB,KAAK,MAAM,mBAAmB;EAC1D,IAAI,CAAC,kBAAkB,qCAAqC;GAC1D,MAAM,iBAAiB,OAAO,YAAY;IACxC,MAAM,QAAQ,MAAM,qBAAqB;IACzC,QAAQ,MAAR;KACE,KAAK,MAAM,KACT,OAAO;KACT,KAAK,MAAM,MACT,OAAO;KACT,KAAK,MAAM,MACT,OAAO;KACT,SACE,OAAO;IACX;GACF,EAAC,CAAE;GACH,MAAM,IAAI,MACR;IACJ,eAAe,GACb;EACF;CACF,SAAS,OAAO;EACd,MAAM,IAAI,MAAM,uCAAuC,KAAK;CAC9D;CACA,IAAI,YAAY,SAAS,CAAC,UAAU;EAClC,MAAM,oBAAoB,MAAM,OAAO,GAAG;CAC5C;CACA,IAAI,YAAY,aAAa,CAAC,UAAU;EACtC,MAAM,oBAAoB,MAAM,WAAW,GAAG;CAChD;CACA,MAAM,YAAY,MAAM,6BAA6B,IAAI;CACzD,QAAQ,KACN,wEAAwE,UAAU,KAAK,UAAU,MAAM,IAAI,CAAC,CAAC,KAAK,IAAI,KAAK,UAC7H;CACA,IAAI,YAAY,aAAa,CAAC,UAAU;EACtC,8BAA8B;GAAE;GAAM;GAAK;EAAU,CAAC;CACxD;CACA,IAAI,CAAC,WAAW;EACd,0BAA0B;GAAE;GAAM;EAAS,CAAC;CAC9C,OAAO,IAAI,CAAC,YAAY,aAAa,OAAO;EAC1C,QAAQ,KAAK,2BAA2B;EACxC,QAAQ,KACN,uJACF;CACF;CACA,IAAI,CAAC,YAAY,aAAa,OAAO;EACnC,QAAQ,KACN;;;;;;;;;CAUF;CACF;CACA,IAAI,CAAC,YAAY,aAAa,WAAW;EACvC,QAAQ,KACN;;;;;;;;CASF;CACF;AACF;AACA,eAAe,kBAAkB,UAAU,UAAU,aAAa;CAChE,MAAM,cAAc,MAAM,QAAQ,SAAS,UAAU,MAAM;CAC3D,MAAM,sBAAsB,YAAY,QAAQ,UAAU,WAAW;CACrE,IAAI,wBAAwB,aAAa;EACvC,MAAM,QAAQ,UAAU,UAAU,qBAAqB,MAAM;CAC/D;AACF"}
1
+ {"version":3,"file":"prebuild.js","names":[],"sources":["exports/prebuild.js"],"sourcesContent":["import { detectPackageManager } from \"@vxrn/utils\";\nimport FSExtra from \"fs-extra\";\nimport path from \"node:path\";\nimport { fillOptions } from \"../config/getOptionsFilled\";\nimport { applyBuiltInPatches } from \"../utils/patches\";\nimport {\n applyAndroidDependencyPatches,\n generateForPlatform,\n getNativeDependencyInventory,\n installNativeDependencies,\n validatePrebuildApp\n} from \"./prebuildWithoutExpo\";\nconst prebuild = async ({\n root,\n platform,\n \"no-install\": noInstall = false,\n app,\n beforeInstall\n}) => {\n validatePrebuildApp(app, platform);\n const options = await fillOptions({ root });\n await applyBuiltInPatches(options);\n try {\n const packageJsonPath = path.join(root, \"package.json\");\n const packageJsonContents = await FSExtra.readFile(packageJsonPath, \"utf8\");\n const { devDependencies } = JSON.parse(packageJsonContents);\n if (!devDependencies?.[\"@react-native-community/template\"]) {\n const installCommand = await (async () => {\n const found = await detectPackageManager();\n switch (true) {\n case found.bun:\n return `bun add -D @react-native-community/template`;\n case found.pnpm:\n return `pnpm install -D @react-native-community/template`;\n case found.yarn:\n return `yarn add -D @react-native-community/template`;\n default:\n return `npm install -D @react-native-community/template`;\n }\n })();\n throw new Error(\n `\"@react-native-community/template\" is not found in package.json, please install \"@react-native-community/template\" as dev dependency:\n\\`${installCommand}\\``\n );\n }\n } catch (error) {\n throw new Error(\"package.json checks are failing:\\n\" + error);\n }\n if (platform == \"ios\" || !platform) {\n await generateForPlatform(root, \"ios\", app);\n }\n if (platform == \"android\" || !platform) {\n await generateForPlatform(root, \"android\", app);\n }\n await beforeInstall?.();\n const inventory = await getNativeDependencyInventory(root);\n console.info(\n `[vxrn] native dependencies discovered through community autolinking: ${inventory.map((entry) => entry.name).join(\", \") || \"(none)\"}`\n );\n if (platform == \"android\" || !platform) {\n applyAndroidDependencyPatches({ root, app, inventory });\n }\n if (!noInstall) {\n installNativeDependencies({ root, platform });\n } else if (!platform || platform === \"ios\") {\n console.info(`Run cd ios && pod install`);\n console.info(\n \"Then run `open *.xcworkspace` in your terminal to open the prebuilt iOS project, then you can either run it via Xcode or archive it for distribution.\"\n );\n }\n if (!platform || platform === \"ios\") {\n console.info(\n `\niOS:\n\n Run \\`open ios/*.xcworkspace\\` in your terminal to open the prebuilt iOS project.\n Then you can either run it via Xcode or archive it for distribution.\n\n See https://onestack.dev/docs/guides-ios-native for more information.\n\n---\n`\n );\n }\n if (!platform || platform === \"android\") {\n console.info(\n `\nAndroid:\n\n \\`cd android\\` and run \\`./gradlew generateCodegenArtifactsFromSchema\\`, then \\`./gradlew assembleRelease\\` or \\`./gradlew assembleDebug\\` to build the Android project.\n\n Afterwards, you can find the built APK at \\`android/app/build/outputs/apk/release/app-release.apk\\` or\n \\`android/app/build/outputs/apk/debug/app-debug.apk\\`.\n\n`\n );\n }\n};\nasync function replaceInUTF8File(filePath, findThis, replaceWith) {\n const fileContent = await FSExtra.readFile(filePath, \"utf8\");\n const replacedFileContent = fileContent.replace(findThis, replaceWith);\n if (replacedFileContent !== fileContent) {\n await FSExtra.writeFile(filePath, replacedFileContent, \"utf8\");\n }\n}\nexport {\n prebuild,\n replaceInUTF8File\n};\n//# sourceMappingURL=prebuild.js.map\n"],"mappings":";;;;;;;;AAYA,MAAM,WAAW,OAAO,EACtB,MACA,UACA,cAAc,YAAY,OAC1B,KACA,oBACI;CACJ,oBAAoB,KAAK,QAAQ;CACjC,MAAM,UAAU,MAAM,YAAY,EAAE,KAAK,CAAC;CAC1C,MAAM,oBAAoB,OAAO;CACjC,IAAI;EACF,MAAM,kBAAkB,KAAK,KAAK,MAAM,cAAc;EACtD,MAAM,sBAAsB,MAAM,QAAQ,SAAS,iBAAiB,MAAM;EAC1E,MAAM,EAAE,oBAAoB,KAAK,MAAM,mBAAmB;EAC1D,IAAI,CAAC,kBAAkB,qCAAqC;GAC1D,MAAM,iBAAiB,OAAO,YAAY;IACxC,MAAM,QAAQ,MAAM,qBAAqB;IACzC,QAAQ,MAAR;KACE,KAAK,MAAM,KACT,OAAO;KACT,KAAK,MAAM,MACT,OAAO;KACT,KAAK,MAAM,MACT,OAAO;KACT,SACE,OAAO;IACX;GACF,EAAC,CAAE;GACH,MAAM,IAAI,MACR;IACJ,eAAe,GACb;EACF;CACF,SAAS,OAAO;EACd,MAAM,IAAI,MAAM,uCAAuC,KAAK;CAC9D;CACA,IAAI,YAAY,SAAS,CAAC,UAAU;EAClC,MAAM,oBAAoB,MAAM,OAAO,GAAG;CAC5C;CACA,IAAI,YAAY,aAAa,CAAC,UAAU;EACtC,MAAM,oBAAoB,MAAM,WAAW,GAAG;CAChD;CACA,MAAM,gBAAgB;CACtB,MAAM,YAAY,MAAM,6BAA6B,IAAI;CACzD,QAAQ,KACN,wEAAwE,UAAU,KAAK,UAAU,MAAM,IAAI,CAAC,CAAC,KAAK,IAAI,KAAK,UAC7H;CACA,IAAI,YAAY,aAAa,CAAC,UAAU;EACtC,8BAA8B;GAAE;GAAM;GAAK;EAAU,CAAC;CACxD;CACA,IAAI,CAAC,WAAW;EACd,0BAA0B;GAAE;GAAM;EAAS,CAAC;CAC9C,OAAO,IAAI,CAAC,YAAY,aAAa,OAAO;EAC1C,QAAQ,KAAK,2BAA2B;EACxC,QAAQ,KACN,uJACF;CACF;CACA,IAAI,CAAC,YAAY,aAAa,OAAO;EACnC,QAAQ,KACN;;;;;;;;;CAUF;CACF;CACA,IAAI,CAAC,YAAY,aAAa,WAAW;EACvC,QAAQ,KACN;;;;;;;;CASF;CACF;AACF;AACA,eAAe,kBAAkB,UAAU,UAAU,aAAa;CAChE,MAAM,cAAc,MAAM,QAAQ,SAAS,UAAU,MAAM;CAC3D,MAAM,sBAAsB,YAAY,QAAQ,UAAU,WAAW;CACrE,IAAI,wBAAwB,aAAa;EACvC,MAAM,QAAQ,UAAU,UAAU,qBAAqB,MAAM;CAC/D;AACF"}
@@ -6,7 +6,7 @@ import { applyBuiltInPatches } from "../utils/patches.native.js";
6
6
  import { applyAndroidDependencyPatches, generateForPlatform, getNativeDependencyInventory, installNativeDependencies, validatePrebuildApp } from "./prebuildWithoutExpo.native.js";
7
7
 
8
8
  var prebuild = async function prebuild2(param) {
9
- var { root, platform, "no-install": noInstall = false, app } = param;
9
+ var { root, platform, "no-install": noInstall = false, app, beforeInstall } = param;
10
10
  validatePrebuildApp(app, platform);
11
11
  var options = await fillOptions({ root });
12
12
  await applyBuiltInPatches(options);
@@ -36,6 +36,7 @@ var prebuild = async function prebuild2(param) {
36
36
  if (platform == "android" || !platform) {
37
37
  await generateForPlatform(root, "android", app);
38
38
  }
39
+ await (beforeInstall === null || beforeInstall === void 0 ? void 0 : beforeInstall());
39
40
  var inventory = await getNativeDependencyInventory(root);
40
41
  console.info(`[vxrn] native dependencies discovered through community autolinking: ${inventory.map(function(entry) {
41
42
  return entry.name;
@@ -1 +1 @@
1
- {"version":3,"file":"prebuild.native.js","names":[],"sources":["exports/prebuild.native.js"],"sourcesContent":["import { detectPackageManager } from \"@vxrn/utils\";\nimport FSExtra from \"fs-extra\";\nimport path from \"path\";\nimport { fillOptions } from \"../config/getOptionsFilled\";\nimport { applyBuiltInPatches } from \"../utils/patches\";\nimport { applyAndroidDependencyPatches, generateForPlatform, getNativeDependencyInventory, installNativeDependencies, validatePrebuildApp } from \"./prebuildWithoutExpo\";\nvar prebuild = async function prebuild2(param) {\n var { root, platform, \"no-install\": noInstall = false, app } = param;\n validatePrebuildApp(app, platform);\n var options = await fillOptions({\n root\n });\n await applyBuiltInPatches(options);\n try {\n var packageJsonPath = path.join(root, \"package.json\");\n var packageJsonContents = await FSExtra.readFile(packageJsonPath, \"utf8\");\n var { devDependencies } = JSON.parse(packageJsonContents);\n if (!(devDependencies === null || devDependencies === void 0 ? void 0 : devDependencies[\"@react-native-community/template\"])) {\n var installCommand = await (async function() {\n var found = await detectPackageManager();\n switch (true) {\n case found.bun:\n return `bun add -D @react-native-community/template`;\n case found.pnpm:\n return `pnpm install -D @react-native-community/template`;\n case found.yarn:\n return `yarn add -D @react-native-community/template`;\n default:\n return `npm install -D @react-native-community/template`;\n }\n })();\n throw new Error(`\"@react-native-community/template\" is not found in package.json, please install \"@react-native-community/template\" as dev dependency:\n\\`${installCommand}\\``);\n }\n } catch (error) {\n throw new Error(\"package.json checks are failing:\\n\" + error);\n }\n if (platform == \"ios\" || !platform) {\n await generateForPlatform(root, \"ios\", app);\n }\n if (platform == \"android\" || !platform) {\n await generateForPlatform(root, \"android\", app);\n }\n var inventory = await getNativeDependencyInventory(root);\n console.info(`[vxrn] native dependencies discovered through community autolinking: ${inventory.map(function(entry) {\n return entry.name;\n }).join(\", \") || \"(none)\"}`);\n if (platform == \"android\" || !platform) {\n applyAndroidDependencyPatches({\n root,\n app,\n inventory\n });\n }\n if (!noInstall) {\n installNativeDependencies({\n root,\n platform\n });\n } else if (!platform || platform === \"ios\") {\n console.info(`Run cd ios && pod install`);\n console.info(\"Then run `open *.xcworkspace` in your terminal to open the prebuilt iOS project, then you can either run it via Xcode or archive it for distribution.\");\n }\n if (!platform || platform === \"ios\") {\n console.info(`\niOS:\n\n Run \\`open ios/*.xcworkspace\\` in your terminal to open the prebuilt iOS project.\n Then you can either run it via Xcode or archive it for distribution.\n\n See https://onestack.dev/docs/guides-ios-native for more information.\n\n---\n`);\n }\n if (!platform || platform === \"android\") {\n console.info(`\nAndroid:\n\n \\`cd android\\` and run \\`./gradlew generateCodegenArtifactsFromSchema\\`, then \\`./gradlew assembleRelease\\` or \\`./gradlew assembleDebug\\` to build the Android project.\n\n Afterwards, you can find the built APK at \\`android/app/build/outputs/apk/release/app-release.apk\\` or\n \\`android/app/build/outputs/apk/debug/app-debug.apk\\`.\n\n`);\n }\n};\nasync function replaceInUTF8File(filePath, findThis, replaceWith) {\n var fileContent = await FSExtra.readFile(filePath, \"utf8\");\n var replacedFileContent = fileContent.replace(findThis, replaceWith);\n if (replacedFileContent !== fileContent) {\n await FSExtra.writeFile(filePath, replacedFileContent, \"utf8\");\n }\n}\nexport {\n prebuild,\n replaceInUTF8File\n};\n//# sourceMappingURL=prebuild.js.map\n"],"mappings":";;;;;;;;AAMA,IAAI,WAAW,eAAe,UAAU,OAAO;CAC7C,IAAI,EAAE,MAAM,UAAU,cAAc,YAAY,OAAO,QAAQ;CAC/D,oBAAoB,KAAK,QAAQ;CACjC,IAAI,UAAU,MAAM,YAAY,EAC9B,KACF,CAAC;CACD,MAAM,oBAAoB,OAAO;CACjC,IAAI;EACF,IAAI,kBAAkB,KAAK,KAAK,MAAM,cAAc;EACpD,IAAI,sBAAsB,MAAM,QAAQ,SAAS,iBAAiB,MAAM;EACxE,IAAI,EAAE,oBAAoB,KAAK,MAAM,mBAAmB;EACxD,IAAI,EAAE,oBAAoB,QAAQ,oBAAoB,KAAK,IAAI,KAAK,IAAI,gBAAgB,sCAAsC;GAC5H,IAAI,iBAAiB,OAAO,iBAAiB;IAC3C,IAAI,QAAQ,MAAM,qBAAqB;IACvC,QAAQ,MAAR;KACE,KAAK,MAAM,KACT,OAAO;KACT,KAAK,MAAM,MACT,OAAO;KACT,KAAK,MAAM,MACT,OAAO;KACT,SACE,OAAO;IACX;GACF,EAAC,CAAE;GACH,MAAM,IAAI,MAAM;IAClB,eAAe,GAAG;EAClB;CACF,SAAS,OAAO;EACd,MAAM,IAAI,MAAM,uCAAuC,KAAK;CAC9D;CACA,IAAI,YAAY,SAAS,CAAC,UAAU;EAClC,MAAM,oBAAoB,MAAM,OAAO,GAAG;CAC5C;CACA,IAAI,YAAY,aAAa,CAAC,UAAU;EACtC,MAAM,oBAAoB,MAAM,WAAW,GAAG;CAChD;CACA,IAAI,YAAY,MAAM,6BAA6B,IAAI;CACvD,QAAQ,KAAK,wEAAwE,UAAU,IAAI,SAAS,OAAO;EACjH,OAAO,MAAM;CACf,CAAC,CAAC,CAAC,KAAK,IAAI,KAAK,UAAU;CAC3B,IAAI,YAAY,aAAa,CAAC,UAAU;EACtC,8BAA8B;GAC5B;GACA;GACA;EACF,CAAC;CACH;CACA,IAAI,CAAC,WAAW;EACd,0BAA0B;GACxB;GACA;EACF,CAAC;CACH,OAAO,IAAI,CAAC,YAAY,aAAa,OAAO;EAC1C,QAAQ,KAAK,2BAA2B;EACxC,QAAQ,KAAK,uJAAuJ;CACtK;CACA,IAAI,CAAC,YAAY,aAAa,OAAO;EACnC,QAAQ,KAAK;;;;;;;;;CAShB;CACC;CACA,IAAI,CAAC,YAAY,aAAa,WAAW;EACvC,QAAQ,KAAK;;;;;;;;CAQhB;CACC;AACF;AACA,eAAe,kBAAkB,UAAU,UAAU,aAAa;CAChE,IAAI,cAAc,MAAM,QAAQ,SAAS,UAAU,MAAM;CACzD,IAAI,sBAAsB,YAAY,QAAQ,UAAU,WAAW;CACnE,IAAI,wBAAwB,aAAa;EACvC,MAAM,QAAQ,UAAU,UAAU,qBAAqB,MAAM;CAC/D;AACF"}
1
+ {"version":3,"file":"prebuild.native.js","names":[],"sources":["exports/prebuild.native.js"],"sourcesContent":["import { detectPackageManager } from \"@vxrn/utils\";\nimport FSExtra from \"fs-extra\";\nimport path from \"path\";\nimport { fillOptions } from \"../config/getOptionsFilled\";\nimport { applyBuiltInPatches } from \"../utils/patches\";\nimport { applyAndroidDependencyPatches, generateForPlatform, getNativeDependencyInventory, installNativeDependencies, validatePrebuildApp } from \"./prebuildWithoutExpo\";\nvar prebuild = async function prebuild2(param) {\n var { root, platform, \"no-install\": noInstall = false, app, beforeInstall } = param;\n validatePrebuildApp(app, platform);\n var options = await fillOptions({\n root\n });\n await applyBuiltInPatches(options);\n try {\n var packageJsonPath = path.join(root, \"package.json\");\n var packageJsonContents = await FSExtra.readFile(packageJsonPath, \"utf8\");\n var { devDependencies } = JSON.parse(packageJsonContents);\n if (!(devDependencies === null || devDependencies === void 0 ? void 0 : devDependencies[\"@react-native-community/template\"])) {\n var installCommand = await (async function() {\n var found = await detectPackageManager();\n switch (true) {\n case found.bun:\n return `bun add -D @react-native-community/template`;\n case found.pnpm:\n return `pnpm install -D @react-native-community/template`;\n case found.yarn:\n return `yarn add -D @react-native-community/template`;\n default:\n return `npm install -D @react-native-community/template`;\n }\n })();\n throw new Error(`\"@react-native-community/template\" is not found in package.json, please install \"@react-native-community/template\" as dev dependency:\n\\`${installCommand}\\``);\n }\n } catch (error) {\n throw new Error(\"package.json checks are failing:\\n\" + error);\n }\n if (platform == \"ios\" || !platform) {\n await generateForPlatform(root, \"ios\", app);\n }\n if (platform == \"android\" || !platform) {\n await generateForPlatform(root, \"android\", app);\n }\n await (beforeInstall === null || beforeInstall === void 0 ? void 0 : beforeInstall());\n var inventory = await getNativeDependencyInventory(root);\n console.info(`[vxrn] native dependencies discovered through community autolinking: ${inventory.map(function(entry) {\n return entry.name;\n }).join(\", \") || \"(none)\"}`);\n if (platform == \"android\" || !platform) {\n applyAndroidDependencyPatches({\n root,\n app,\n inventory\n });\n }\n if (!noInstall) {\n installNativeDependencies({\n root,\n platform\n });\n } else if (!platform || platform === \"ios\") {\n console.info(`Run cd ios && pod install`);\n console.info(\"Then run `open *.xcworkspace` in your terminal to open the prebuilt iOS project, then you can either run it via Xcode or archive it for distribution.\");\n }\n if (!platform || platform === \"ios\") {\n console.info(`\niOS:\n\n Run \\`open ios/*.xcworkspace\\` in your terminal to open the prebuilt iOS project.\n Then you can either run it via Xcode or archive it for distribution.\n\n See https://onestack.dev/docs/guides-ios-native for more information.\n\n---\n`);\n }\n if (!platform || platform === \"android\") {\n console.info(`\nAndroid:\n\n \\`cd android\\` and run \\`./gradlew generateCodegenArtifactsFromSchema\\`, then \\`./gradlew assembleRelease\\` or \\`./gradlew assembleDebug\\` to build the Android project.\n\n Afterwards, you can find the built APK at \\`android/app/build/outputs/apk/release/app-release.apk\\` or\n \\`android/app/build/outputs/apk/debug/app-debug.apk\\`.\n\n`);\n }\n};\nasync function replaceInUTF8File(filePath, findThis, replaceWith) {\n var fileContent = await FSExtra.readFile(filePath, \"utf8\");\n var replacedFileContent = fileContent.replace(findThis, replaceWith);\n if (replacedFileContent !== fileContent) {\n await FSExtra.writeFile(filePath, replacedFileContent, \"utf8\");\n }\n}\nexport {\n prebuild,\n replaceInUTF8File\n};\n//# sourceMappingURL=prebuild.js.map\n"],"mappings":";;;;;;;;AAMA,IAAI,WAAW,eAAe,UAAU,OAAO;CAC7C,IAAI,EAAE,MAAM,UAAU,cAAc,YAAY,OAAO,KAAK,kBAAkB;CAC9E,oBAAoB,KAAK,QAAQ;CACjC,IAAI,UAAU,MAAM,YAAY,EAC9B,KACF,CAAC;CACD,MAAM,oBAAoB,OAAO;CACjC,IAAI;EACF,IAAI,kBAAkB,KAAK,KAAK,MAAM,cAAc;EACpD,IAAI,sBAAsB,MAAM,QAAQ,SAAS,iBAAiB,MAAM;EACxE,IAAI,EAAE,oBAAoB,KAAK,MAAM,mBAAmB;EACxD,IAAI,EAAE,oBAAoB,QAAQ,oBAAoB,KAAK,IAAI,KAAK,IAAI,gBAAgB,sCAAsC;GAC5H,IAAI,iBAAiB,OAAO,iBAAiB;IAC3C,IAAI,QAAQ,MAAM,qBAAqB;IACvC,QAAQ,MAAR;KACE,KAAK,MAAM,KACT,OAAO;KACT,KAAK,MAAM,MACT,OAAO;KACT,KAAK,MAAM,MACT,OAAO;KACT,SACE,OAAO;IACX;GACF,EAAC,CAAE;GACH,MAAM,IAAI,MAAM;IAClB,eAAe,GAAG;EAClB;CACF,SAAS,OAAO;EACd,MAAM,IAAI,MAAM,uCAAuC,KAAK;CAC9D;CACA,IAAI,YAAY,SAAS,CAAC,UAAU;EAClC,MAAM,oBAAoB,MAAM,OAAO,GAAG;CAC5C;CACA,IAAI,YAAY,aAAa,CAAC,UAAU;EACtC,MAAM,oBAAoB,MAAM,WAAW,GAAG;CAChD;CACA,OAAO,kBAAkB,QAAQ,kBAAkB,KAAK,IAAI,KAAK,IAAI,cAAc;CACnF,IAAI,YAAY,MAAM,6BAA6B,IAAI;CACvD,QAAQ,KAAK,wEAAwE,UAAU,IAAI,SAAS,OAAO;EACjH,OAAO,MAAM;CACf,CAAC,CAAC,CAAC,KAAK,IAAI,KAAK,UAAU;CAC3B,IAAI,YAAY,aAAa,CAAC,UAAU;EACtC,8BAA8B;GAC5B;GACA;GACA;EACF,CAAC;CACH;CACA,IAAI,CAAC,WAAW;EACd,0BAA0B;GACxB;GACA;EACF,CAAC;CACH,OAAO,IAAI,CAAC,YAAY,aAAa,OAAO;EAC1C,QAAQ,KAAK,2BAA2B;EACxC,QAAQ,KAAK,uJAAuJ;CACtK;CACA,IAAI,CAAC,YAAY,aAAa,OAAO;EACnC,QAAQ,KAAK;;;;;;;;;CAShB;CACC;CACA,IAAI,CAAC,YAAY,aAAa,WAAW;EACvC,QAAQ,KAAK;;;;;;;;CAQhB;CACC;AACF;AACA,eAAe,kBAAkB,UAAU,UAAU,aAAa;CAChE,IAAI,cAAc,MAAM,QAAQ,SAAS,UAAU,MAAM;CACzD,IAAI,sBAAsB,YAAY,QAAQ,UAAU,WAAW;CACnE,IAAI,wBAAwB,aAAa;EACvC,MAAM,QAAQ,UAAU,UAAU,qBAAqB,MAAM;CAC/D;AACF"}