@soda-gql/common 0.11.10 → 0.11.11

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 (63) hide show
  1. package/dist/{canonical-id-BJahCcrS.mjs → canonical-id-9alor9gv.mjs} +66 -7
  2. package/dist/canonical-id-9alor9gv.mjs.map +1 -0
  3. package/dist/{canonical-id-CgMNOZyn.cjs → canonical-id-DHdeYIsT.cjs} +76 -5
  4. package/dist/canonical-id-DHdeYIsT.cjs.map +1 -0
  5. package/dist/canonical-id.cjs +5 -3
  6. package/dist/canonical-id.d.cts +2 -2
  7. package/dist/canonical-id.d.mts +2 -2
  8. package/dist/canonical-id.mjs +3 -3
  9. package/dist/{index-Cm2Zwk9m.d.cts → index-AqkJhrm3.d.mts} +53 -3
  10. package/dist/index-AqkJhrm3.d.mts.map +1 -0
  11. package/dist/index-BCu9PNbZ.d.mts +139 -0
  12. package/dist/index-BCu9PNbZ.d.mts.map +1 -0
  13. package/dist/{index-D1tzB3W5.d.cts → index-BMa2_rDb.d.mts} +6 -35
  14. package/dist/index-BMa2_rDb.d.mts.map +1 -0
  15. package/dist/index-BMl8pzFY.d.cts +139 -0
  16. package/dist/index-BMl8pzFY.d.cts.map +1 -0
  17. package/dist/{index-B424kKYS.d.mts → index-CbQyueYV.d.cts} +6 -35
  18. package/dist/index-CbQyueYV.d.cts.map +1 -0
  19. package/dist/{index-CPpVc8Id.d.mts → index-DZSebwar.d.cts} +53 -3
  20. package/dist/index-DZSebwar.d.cts.map +1 -0
  21. package/dist/index-Dit86qkX.d.mts.map +1 -1
  22. package/dist/index.cjs +9 -7
  23. package/dist/index.d.cts +4 -4
  24. package/dist/index.d.mts +4 -4
  25. package/dist/index.mjs +4 -4
  26. package/dist/portable-B3K3IE7E.cjs +239 -0
  27. package/dist/portable-B3K3IE7E.cjs.map +1 -0
  28. package/dist/portable-BFrcBOaX.mjs +196 -0
  29. package/dist/portable-BFrcBOaX.mjs.map +1 -0
  30. package/dist/portable.cjs +2 -5
  31. package/dist/portable.d.cts +2 -2
  32. package/dist/portable.d.mts +2 -2
  33. package/dist/portable.mjs +2 -2
  34. package/dist/utils-Rs7YbafF.cjs +431 -0
  35. package/dist/utils-Rs7YbafF.cjs.map +1 -0
  36. package/dist/utils-ZCE_eqCf.mjs +371 -0
  37. package/dist/utils-ZCE_eqCf.mjs.map +1 -0
  38. package/dist/utils.cjs +4 -1
  39. package/dist/utils.d.cts +2 -2
  40. package/dist/utils.d.mts +2 -2
  41. package/dist/utils.mjs +2 -2
  42. package/dist/{zod-C_6JfuYV.cjs → zod-DjI3IUH3.cjs} +2 -2
  43. package/dist/{zod-C_6JfuYV.cjs.map → zod-DjI3IUH3.cjs.map} +1 -1
  44. package/dist/zod.cjs +1 -1
  45. package/package.json +1 -1
  46. package/dist/canonical-id-BJahCcrS.mjs.map +0 -1
  47. package/dist/canonical-id-CgMNOZyn.cjs.map +0 -1
  48. package/dist/index-B424kKYS.d.mts.map +0 -1
  49. package/dist/index-CPpVc8Id.d.mts.map +0 -1
  50. package/dist/index-Cm2Zwk9m.d.cts.map +0 -1
  51. package/dist/index-D1tzB3W5.d.cts.map +0 -1
  52. package/dist/index-Dv8spPt0.d.mts +0 -61
  53. package/dist/index-Dv8spPt0.d.mts.map +0 -1
  54. package/dist/index-LaXfl_e_.d.cts +0 -61
  55. package/dist/index-LaXfl_e_.d.cts.map +0 -1
  56. package/dist/portable-BT3ahkQN.mjs +0 -391
  57. package/dist/portable-BT3ahkQN.mjs.map +0 -1
  58. package/dist/portable-cJqkfeHw.cjs +0 -451
  59. package/dist/portable-cJqkfeHw.cjs.map +0 -1
  60. package/dist/utils-CsTwS1dw.cjs +0 -148
  61. package/dist/utils-CsTwS1dw.cjs.map +0 -1
  62. package/dist/utils-DLEgAn7q.mjs +0 -106
  63. package/dist/utils-DLEgAn7q.mjs.map +0 -1
@@ -1,451 +0,0 @@
1
-
2
- //#region packages/common/src/portable/runtime.ts
3
- /**
4
- * Runtime detection utilities for portable API implementation
5
- */
6
- const runtime = {
7
- isBun: typeof Bun !== "undefined",
8
- isNode: typeof process !== "undefined" && typeof Bun === "undefined",
9
- supportsWebCrypto: typeof crypto !== "undefined" && typeof crypto.subtle !== "undefined"
10
- };
11
- /**
12
- * Helper to cache module imports to avoid repeated dynamic imports
13
- */
14
- function once(fn) {
15
- let result;
16
- let called = false;
17
- return () => {
18
- if (!called) {
19
- result = fn();
20
- called = true;
21
- }
22
- return result;
23
- };
24
- }
25
- /**
26
- * Reset runtime state for testing purposes only
27
- * @internal
28
- */
29
- function resetPortableForTests() {}
30
-
31
- //#endregion
32
- //#region packages/common/src/portable/fs.ts
33
- /**
34
- * Portable filesystem API that works on both Bun and Node.js
35
- */
36
- const getNodeFS = once(async () => {
37
- const fs = await import("node:fs/promises");
38
- return fs;
39
- });
40
- let nodeFsSync = null;
41
- const getNodeFSSync = () => {
42
- if (!nodeFsSync) {
43
- nodeFsSync = require("node:fs");
44
- }
45
- return nodeFsSync;
46
- };
47
- let pathModule = null;
48
- const getPathModule = () => {
49
- if (!pathModule) {
50
- pathModule = require("node:path");
51
- }
52
- return pathModule;
53
- };
54
- /**
55
- * Generate a unique temp file path for atomic write.
56
- */
57
- const getTempPath = (targetPath) => {
58
- return `${targetPath}.${process.pid}.${Date.now()}.tmp`;
59
- };
60
- function createPortableFS() {
61
- if (runtime.isBun) {
62
- return {
63
- async readFile(path) {
64
- const file = Bun.file(path);
65
- return await file.text();
66
- },
67
- async writeFile(path, content) {
68
- await Bun.write(path, content);
69
- },
70
- async writeFileAtomic(path, content) {
71
- const tempPath = getTempPath(path);
72
- try {
73
- await Bun.write(tempPath, content);
74
- const nodeFS = await getNodeFS();
75
- await nodeFS.rename(tempPath, path);
76
- } catch (error) {
77
- try {
78
- const nodeFS = await getNodeFS();
79
- await nodeFS.unlink(tempPath);
80
- } catch {}
81
- throw error;
82
- }
83
- },
84
- async exists(path) {
85
- const nodeFS = await getNodeFS();
86
- try {
87
- await nodeFS.stat(path);
88
- return true;
89
- } catch {
90
- return false;
91
- }
92
- },
93
- async stat(path) {
94
- const file = Bun.file(path);
95
- const size = file.size;
96
- const nodeFS = await getNodeFS();
97
- const { mtime } = await nodeFS.stat(path);
98
- return {
99
- mtime,
100
- size
101
- };
102
- },
103
- async rename(oldPath, newPath) {
104
- const nodeFS = await getNodeFS();
105
- await nodeFS.rename(oldPath, newPath);
106
- },
107
- async mkdir(path, options) {
108
- const nodeFS = await getNodeFS();
109
- await nodeFS.mkdir(path, options);
110
- },
111
- writeFileSyncAtomic(path, content) {
112
- const fsSync = getNodeFSSync();
113
- const pathMod = getPathModule();
114
- const tempPath = getTempPath(path);
115
- const dir = pathMod.dirname(path);
116
- fsSync.mkdirSync(dir, { recursive: true });
117
- try {
118
- fsSync.writeFileSync(tempPath, content, "utf-8");
119
- fsSync.renameSync(tempPath, path);
120
- } catch (error) {
121
- try {
122
- fsSync.unlinkSync(tempPath);
123
- } catch {}
124
- throw error;
125
- }
126
- },
127
- async unlink(path) {
128
- const nodeFS = await getNodeFS();
129
- try {
130
- await nodeFS.unlink(path);
131
- } catch (error) {
132
- if (error.code !== "ENOENT") {
133
- throw error;
134
- }
135
- }
136
- },
137
- unlinkSync(path) {
138
- const fsSync = getNodeFSSync();
139
- try {
140
- fsSync.unlinkSync(path);
141
- } catch (error) {
142
- if (error.code !== "ENOENT") {
143
- throw error;
144
- }
145
- }
146
- },
147
- readFileSync(path) {
148
- const fsSync = getNodeFSSync();
149
- return fsSync.readFileSync(path, "utf-8");
150
- }
151
- };
152
- }
153
- return {
154
- async readFile(path) {
155
- const nodeFS = await getNodeFS();
156
- return await nodeFS.readFile(path, "utf-8");
157
- },
158
- async writeFile(path, content) {
159
- const nodeFS = await getNodeFS();
160
- const pathModule$1 = await import("node:path");
161
- const dir = pathModule$1.dirname(path);
162
- await nodeFS.mkdir(dir, { recursive: true });
163
- await nodeFS.writeFile(path, content, "utf-8");
164
- },
165
- async writeFileAtomic(path, content) {
166
- const nodeFS = await getNodeFS();
167
- const pathMod = await import("node:path");
168
- const dir = pathMod.dirname(path);
169
- const tempPath = getTempPath(path);
170
- try {
171
- await nodeFS.mkdir(dir, { recursive: true });
172
- await nodeFS.writeFile(tempPath, content, "utf-8");
173
- await nodeFS.rename(tempPath, path);
174
- } catch (error) {
175
- try {
176
- await nodeFS.unlink(tempPath);
177
- } catch {}
178
- throw error;
179
- }
180
- },
181
- async exists(path) {
182
- const nodeFS = await getNodeFS();
183
- try {
184
- await nodeFS.access(path);
185
- return true;
186
- } catch {
187
- return false;
188
- }
189
- },
190
- async stat(path) {
191
- const nodeFS = await getNodeFS();
192
- const stats = await nodeFS.stat(path);
193
- return {
194
- mtime: stats.mtime,
195
- size: stats.size
196
- };
197
- },
198
- async rename(oldPath, newPath) {
199
- const nodeFS = await getNodeFS();
200
- await nodeFS.rename(oldPath, newPath);
201
- },
202
- async mkdir(path, options) {
203
- const nodeFS = await getNodeFS();
204
- await nodeFS.mkdir(path, options);
205
- },
206
- writeFileSyncAtomic(path, content) {
207
- const fsSync = getNodeFSSync();
208
- const pathMod = getPathModule();
209
- const tempPath = getTempPath(path);
210
- const dir = pathMod.dirname(path);
211
- fsSync.mkdirSync(dir, { recursive: true });
212
- try {
213
- fsSync.writeFileSync(tempPath, content, "utf-8");
214
- fsSync.renameSync(tempPath, path);
215
- } catch (error) {
216
- try {
217
- fsSync.unlinkSync(tempPath);
218
- } catch {}
219
- throw error;
220
- }
221
- },
222
- async unlink(path) {
223
- const nodeFS = await getNodeFS();
224
- try {
225
- await nodeFS.unlink(path);
226
- } catch (error) {
227
- if (error.code !== "ENOENT") {
228
- throw error;
229
- }
230
- }
231
- },
232
- unlinkSync(path) {
233
- const fsSync = getNodeFSSync();
234
- try {
235
- fsSync.unlinkSync(path);
236
- } catch (error) {
237
- if (error.code !== "ENOENT") {
238
- throw error;
239
- }
240
- }
241
- },
242
- readFileSync(path) {
243
- const fsSync = getNodeFSSync();
244
- return fsSync.readFileSync(path, "utf-8");
245
- }
246
- };
247
- }
248
- let fsInstance = null;
249
- function getPortableFS() {
250
- if (!fsInstance) {
251
- fsInstance = createPortableFS();
252
- }
253
- return fsInstance;
254
- }
255
- /**
256
- * Reset the filesystem singleton for testing
257
- * @internal
258
- */
259
- function __resetPortableFSForTests() {
260
- fsInstance = null;
261
- }
262
-
263
- //#endregion
264
- //#region packages/common/src/portable/hash.ts
265
- /**
266
- * Portable hashing API that works on both Bun and Node.js
267
- */
268
- /**
269
- * Pads a hex string to the specified length
270
- */
271
- function padHex(hex, length) {
272
- return hex.padStart(length, "0");
273
- }
274
- function createPortableHasher() {
275
- if (runtime.isBun) {
276
- return { hash(content, algorithm = "xxhash") {
277
- if (algorithm === "sha256") {
278
- const hasher = new Bun.CryptoHasher("sha256");
279
- hasher.update(content);
280
- return hasher.digest("hex");
281
- }
282
- const hashNum = Bun.hash(content);
283
- return padHex(hashNum.toString(16), 16);
284
- } };
285
- }
286
- return { hash(content, algorithm = "xxhash") {
287
- if (algorithm === "sha256") {
288
- const crypto$2 = require("node:crypto");
289
- return crypto$2.createHash("sha256").update(content).digest("hex");
290
- }
291
- const crypto$1 = require("node:crypto");
292
- const sha256Hash = crypto$1.createHash("sha256").update(content).digest("hex");
293
- return sha256Hash.substring(0, 16);
294
- } };
295
- }
296
- let hasherInstance = null;
297
- function getPortableHasher() {
298
- if (!hasherInstance) {
299
- hasherInstance = createPortableHasher();
300
- }
301
- return hasherInstance;
302
- }
303
- /**
304
- * Reset the hasher singleton for testing
305
- * @internal
306
- */
307
- function __resetPortableHasherForTests() {
308
- hasherInstance = null;
309
- }
310
-
311
- //#endregion
312
- //#region packages/common/src/portable/id.ts
313
- /**
314
- * Portable ID generation that works on both Bun and Node.js
315
- */
316
- /**
317
- * Generate a unique ID
318
- * Uses UUIDv7 on Bun (monotonic), falls back to randomUUID on Node.js
319
- */
320
- function generateId() {
321
- if (runtime.isBun && typeof Bun !== "undefined" && typeof Bun.randomUUIDv7 === "function") {
322
- return Bun.randomUUIDv7();
323
- }
324
- const crypto$1 = require("node:crypto");
325
- return crypto$1.randomUUID();
326
- }
327
-
328
- //#endregion
329
- //#region packages/common/src/portable/spawn.ts
330
- /**
331
- * Portable subprocess spawning that works on both Bun and Node.js
332
- */
333
- async function spawn(options) {
334
- if (runtime.isBun) {
335
- const proc = Bun.spawn(options.cmd, {
336
- cwd: options.cwd,
337
- env: options.env,
338
- stdout: "pipe",
339
- stderr: "pipe"
340
- });
341
- const [stdout, stderr] = await Promise.all([new Response(proc.stdout).text(), new Response(proc.stderr).text()]);
342
- const exitCode = await proc.exited;
343
- return {
344
- stdout,
345
- stderr,
346
- exitCode
347
- };
348
- }
349
- const { execFile } = await import("node:child_process");
350
- const { promisify } = await import("node:util");
351
- const execFilePromise = promisify(execFile);
352
- const [command, ...args] = options.cmd;
353
- if (!command) {
354
- return {
355
- stdout: "",
356
- stderr: "Error: No command provided",
357
- exitCode: 1
358
- };
359
- }
360
- try {
361
- const execOptions = { encoding: "utf-8" };
362
- if (options.cwd) {
363
- execOptions.cwd = options.cwd;
364
- }
365
- if (options.env) {
366
- execOptions.env = options.env;
367
- }
368
- const { stdout, stderr } = await execFilePromise(command, args, execOptions);
369
- return {
370
- stdout: stdout || "",
371
- stderr: stderr || "",
372
- exitCode: 0
373
- };
374
- } catch (error) {
375
- const err = error;
376
- return {
377
- stdout: err.stdout || "",
378
- stderr: err.stderr || "",
379
- exitCode: err.code || 1
380
- };
381
- }
382
- }
383
-
384
- //#endregion
385
- Object.defineProperty(exports, '__resetPortableFSForTests', {
386
- enumerable: true,
387
- get: function () {
388
- return __resetPortableFSForTests;
389
- }
390
- });
391
- Object.defineProperty(exports, '__resetPortableHasherForTests', {
392
- enumerable: true,
393
- get: function () {
394
- return __resetPortableHasherForTests;
395
- }
396
- });
397
- Object.defineProperty(exports, 'createPortableFS', {
398
- enumerable: true,
399
- get: function () {
400
- return createPortableFS;
401
- }
402
- });
403
- Object.defineProperty(exports, 'createPortableHasher', {
404
- enumerable: true,
405
- get: function () {
406
- return createPortableHasher;
407
- }
408
- });
409
- Object.defineProperty(exports, 'generateId', {
410
- enumerable: true,
411
- get: function () {
412
- return generateId;
413
- }
414
- });
415
- Object.defineProperty(exports, 'getPortableFS', {
416
- enumerable: true,
417
- get: function () {
418
- return getPortableFS;
419
- }
420
- });
421
- Object.defineProperty(exports, 'getPortableHasher', {
422
- enumerable: true,
423
- get: function () {
424
- return getPortableHasher;
425
- }
426
- });
427
- Object.defineProperty(exports, 'once', {
428
- enumerable: true,
429
- get: function () {
430
- return once;
431
- }
432
- });
433
- Object.defineProperty(exports, 'resetPortableForTests', {
434
- enumerable: true,
435
- get: function () {
436
- return resetPortableForTests;
437
- }
438
- });
439
- Object.defineProperty(exports, 'runtime', {
440
- enumerable: true,
441
- get: function () {
442
- return runtime;
443
- }
444
- });
445
- Object.defineProperty(exports, 'spawn', {
446
- enumerable: true,
447
- get: function () {
448
- return spawn;
449
- }
450
- });
451
- //# sourceMappingURL=portable-cJqkfeHw.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"portable-cJqkfeHw.cjs","names":["result: T | undefined","nodeFsSync: FSSync | null","pathModule: { dirname: (path: string) => string } | null","pathModule","fsInstance: PortableFS | null","crypto","hasherInstance: PortableHasher | null","crypto","execOptions: {\n cwd?: string;\n env?: NodeJS.ProcessEnv;\n encoding: BufferEncoding;\n }","error: unknown"],"sources":["../src/portable/runtime.ts","../src/portable/fs.ts","../src/portable/hash.ts","../src/portable/id.ts","../src/portable/spawn.ts"],"sourcesContent":["/**\n * Runtime detection utilities for portable API implementation\n */\n\nexport const runtime = {\n isBun: typeof Bun !== \"undefined\",\n isNode: typeof process !== \"undefined\" && typeof Bun === \"undefined\",\n supportsWebCrypto: typeof crypto !== \"undefined\" && typeof crypto.subtle !== \"undefined\",\n} as const;\n\n/**\n * Helper to cache module imports to avoid repeated dynamic imports\n */\nexport function once<T>(fn: () => T): () => T {\n let result: T | undefined;\n let called = false;\n\n return () => {\n if (!called) {\n result = fn();\n called = true;\n }\n return result as T;\n };\n}\n\n/**\n * Reset runtime state for testing purposes only\n * @internal\n */\nexport function resetPortableForTests(): void {\n // This is a marker function that portable modules can use\n // to reset their singleton state in tests\n}\n","/**\n * Portable filesystem API that works on both Bun and Node.js\n */\n\nimport { once, runtime } from \"./runtime\";\n\nexport interface PortableFS {\n readFile(path: string): Promise<string>;\n writeFile(path: string, content: string): Promise<void>;\n /**\n * Write a file atomically using temp file + rename pattern.\n * This prevents partial/corrupt writes on crash.\n */\n writeFileAtomic(path: string, content: string): Promise<void>;\n exists(path: string): Promise<boolean>;\n stat(path: string): Promise<{ mtime: Date; size: number }>;\n rename(oldPath: string, newPath: string): Promise<void>;\n mkdir(path: string, options?: { recursive?: boolean }): Promise<void>;\n /**\n * Write a file synchronously and atomically using temp file + rename pattern.\n * Safe for use in beforeExit handlers.\n */\n writeFileSyncAtomic(path: string, content: string): void;\n /**\n * Remove a file. Does not throw if file doesn't exist.\n */\n unlink(path: string): Promise<void>;\n /**\n * Remove a file synchronously. Does not throw if file doesn't exist.\n */\n unlinkSync(path: string): void;\n /**\n * Read a file synchronously.\n */\n readFileSync(path: string): string;\n}\n\ninterface FSPromises {\n readFile: (path: string, encoding: string) => Promise<string>;\n writeFile: (path: string, content: string, encoding: string) => Promise<void>;\n access: (path: string) => Promise<void>;\n stat: (path: string) => Promise<{\n mtime: Date;\n size: number;\n isDirectory: () => boolean;\n }>;\n rename: (oldPath: string, newPath: string) => Promise<void>;\n mkdir: (path: string, options?: { recursive?: boolean }) => Promise<void>;\n unlink: (path: string) => Promise<void>;\n}\n\ninterface FSSync {\n writeFileSync: (path: string, content: string, encoding: string) => void;\n renameSync: (oldPath: string, newPath: string) => void;\n unlinkSync: (path: string) => void;\n readFileSync: (path: string, encoding: string) => string;\n mkdirSync: (path: string, options?: { recursive?: boolean }) => void;\n}\n\n// Cache the fs/promises import\nconst getNodeFS = once(async (): Promise<FSPromises> => {\n const fs = await import(\"node:fs/promises\");\n return fs as FSPromises;\n});\n\n// Cache the sync fs import\nlet nodeFsSync: FSSync | null = null;\nconst getNodeFSSync = (): FSSync => {\n if (!nodeFsSync) {\n // Use require for sync loading\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n nodeFsSync = require(\"node:fs\") as FSSync;\n }\n return nodeFsSync;\n};\n\n// Cache path module\nlet pathModule: { dirname: (path: string) => string } | null = null;\nconst getPathModule = (): { dirname: (path: string) => string } => {\n if (!pathModule) {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n pathModule = require(\"node:path\") as { dirname: (path: string) => string };\n }\n return pathModule;\n};\n\n/**\n * Generate a unique temp file path for atomic write.\n */\nconst getTempPath = (targetPath: string): string => {\n return `${targetPath}.${process.pid}.${Date.now()}.tmp`;\n};\n\nexport function createPortableFS(): PortableFS {\n if (runtime.isBun) {\n return {\n async readFile(path) {\n const file = Bun.file(path);\n return await file.text();\n },\n\n async writeFile(path, content) {\n // Bun.write auto-creates parent directories\n await Bun.write(path, content);\n },\n\n async writeFileAtomic(path, content) {\n const tempPath = getTempPath(path);\n try {\n await Bun.write(tempPath, content);\n const nodeFS = await getNodeFS();\n await nodeFS.rename(tempPath, path);\n } catch (error) {\n // Clean up temp file on failure\n try {\n const nodeFS = await getNodeFS();\n await nodeFS.unlink(tempPath);\n } catch {\n // Ignore cleanup errors\n }\n throw error;\n }\n },\n\n async exists(path) {\n // Bun.file().exists() only works for files, use fs.stat for both files and dirs\n const nodeFS = await getNodeFS();\n try {\n await nodeFS.stat(path);\n return true;\n } catch {\n return false;\n }\n },\n\n async stat(path) {\n const file = Bun.file(path);\n const size = file.size;\n // Bun doesn't expose mtime directly, use Node fs.stat\n const nodeFS = await getNodeFS();\n const { mtime } = await nodeFS.stat(path);\n return { mtime, size };\n },\n\n async rename(oldPath, newPath) {\n const nodeFS = await getNodeFS();\n await nodeFS.rename(oldPath, newPath);\n },\n\n async mkdir(path, options) {\n const nodeFS = await getNodeFS();\n await nodeFS.mkdir(path, options);\n },\n\n writeFileSyncAtomic(path, content) {\n const fsSync = getNodeFSSync();\n const pathMod = getPathModule();\n const tempPath = getTempPath(path);\n\n // Ensure parent directory exists\n const dir = pathMod.dirname(path);\n fsSync.mkdirSync(dir, { recursive: true });\n\n try {\n fsSync.writeFileSync(tempPath, content, \"utf-8\");\n fsSync.renameSync(tempPath, path);\n } catch (error) {\n // Clean up temp file on failure\n try {\n fsSync.unlinkSync(tempPath);\n } catch {\n // Ignore cleanup errors\n }\n throw error;\n }\n },\n\n async unlink(path) {\n const nodeFS = await getNodeFS();\n try {\n await nodeFS.unlink(path);\n } catch (error) {\n // Ignore ENOENT (file not found)\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n throw error;\n }\n }\n },\n\n unlinkSync(path) {\n const fsSync = getNodeFSSync();\n try {\n fsSync.unlinkSync(path);\n } catch (error) {\n // Ignore ENOENT (file not found)\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n throw error;\n }\n }\n },\n\n readFileSync(path) {\n const fsSync = getNodeFSSync();\n return fsSync.readFileSync(path, \"utf-8\");\n },\n };\n }\n\n // Node.js implementation\n return {\n async readFile(path) {\n const nodeFS = await getNodeFS();\n return await nodeFS.readFile(path, \"utf-8\");\n },\n\n async writeFile(path, content) {\n const nodeFS = await getNodeFS();\n // Auto-create parent directories like Bun.write does\n const pathModule = await import(\"node:path\");\n const dir = pathModule.dirname(path);\n await nodeFS.mkdir(dir, { recursive: true });\n await nodeFS.writeFile(path, content, \"utf-8\");\n },\n\n async writeFileAtomic(path, content) {\n const nodeFS = await getNodeFS();\n const pathMod = await import(\"node:path\");\n const dir = pathMod.dirname(path);\n const tempPath = getTempPath(path);\n\n try {\n await nodeFS.mkdir(dir, { recursive: true });\n await nodeFS.writeFile(tempPath, content, \"utf-8\");\n await nodeFS.rename(tempPath, path);\n } catch (error) {\n // Clean up temp file on failure\n try {\n await nodeFS.unlink(tempPath);\n } catch {\n // Ignore cleanup errors\n }\n throw error;\n }\n },\n\n async exists(path) {\n const nodeFS = await getNodeFS();\n try {\n await nodeFS.access(path);\n return true;\n } catch {\n return false;\n }\n },\n\n async stat(path) {\n const nodeFS = await getNodeFS();\n const stats = await nodeFS.stat(path);\n return { mtime: stats.mtime, size: stats.size };\n },\n\n async rename(oldPath, newPath) {\n const nodeFS = await getNodeFS();\n await nodeFS.rename(oldPath, newPath);\n },\n\n async mkdir(path, options) {\n const nodeFS = await getNodeFS();\n await nodeFS.mkdir(path, options);\n },\n\n writeFileSyncAtomic(path, content) {\n const fsSync = getNodeFSSync();\n const pathMod = getPathModule();\n const tempPath = getTempPath(path);\n\n // Ensure parent directory exists\n const dir = pathMod.dirname(path);\n fsSync.mkdirSync(dir, { recursive: true });\n\n try {\n fsSync.writeFileSync(tempPath, content, \"utf-8\");\n fsSync.renameSync(tempPath, path);\n } catch (error) {\n // Clean up temp file on failure\n try {\n fsSync.unlinkSync(tempPath);\n } catch {\n // Ignore cleanup errors\n }\n throw error;\n }\n },\n\n async unlink(path) {\n const nodeFS = await getNodeFS();\n try {\n await nodeFS.unlink(path);\n } catch (error) {\n // Ignore ENOENT (file not found)\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n throw error;\n }\n }\n },\n\n unlinkSync(path) {\n const fsSync = getNodeFSSync();\n try {\n fsSync.unlinkSync(path);\n } catch (error) {\n // Ignore ENOENT (file not found)\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n throw error;\n }\n }\n },\n\n readFileSync(path) {\n const fsSync = getNodeFSSync();\n return fsSync.readFileSync(path, \"utf-8\");\n },\n };\n}\n\n// Singleton to avoid recreating instances\nlet fsInstance: PortableFS | null = null;\n\nexport function getPortableFS(): PortableFS {\n if (!fsInstance) {\n fsInstance = createPortableFS();\n }\n return fsInstance;\n}\n\n/**\n * Reset the filesystem singleton for testing\n * @internal\n */\nexport function __resetPortableFSForTests(): void {\n fsInstance = null;\n}\n","/**\n * Portable hashing API that works on both Bun and Node.js\n */\n\nimport { runtime } from \"./runtime\";\n\nexport type HashAlgorithm = \"sha256\" | \"xxhash\";\n\nexport interface PortableHasher {\n hash(content: string, algorithm?: HashAlgorithm): string;\n}\n\n/**\n * Pads a hex string to the specified length\n */\nfunction padHex(hex: string, length: number): string {\n return hex.padStart(length, \"0\");\n}\n\nexport function createPortableHasher(): PortableHasher {\n if (runtime.isBun) {\n return {\n hash(content, algorithm = \"xxhash\") {\n if (algorithm === \"sha256\") {\n const hasher = new Bun.CryptoHasher(\"sha256\");\n hasher.update(content);\n return hasher.digest(\"hex\");\n }\n // xxhash - Bun.hash returns a number\n const hashNum = Bun.hash(content);\n // Convert to hex and pad to 16 chars for consistency\n return padHex(hashNum.toString(16), 16);\n },\n };\n }\n\n // Node.js implementation\n return {\n hash(content, algorithm = \"xxhash\") {\n if (algorithm === \"sha256\") {\n const crypto = require(\"node:crypto\");\n return crypto.createHash(\"sha256\").update(content).digest(\"hex\");\n }\n // xxhash fallback: use sha256 for now (can add xxhash package later if needed)\n // This ensures consistent behavior across runtimes\n const crypto = require(\"node:crypto\");\n const sha256Hash = crypto.createHash(\"sha256\").update(content).digest(\"hex\");\n // Take first 16 chars to match xxhash output length\n return sha256Hash.substring(0, 16);\n },\n };\n}\n\n// Singleton to avoid recreating instances\nlet hasherInstance: PortableHasher | null = null;\n\nexport function getPortableHasher(): PortableHasher {\n if (!hasherInstance) {\n hasherInstance = createPortableHasher();\n }\n return hasherInstance;\n}\n\n/**\n * Reset the hasher singleton for testing\n * @internal\n */\nexport function __resetPortableHasherForTests(): void {\n hasherInstance = null;\n}\n","/**\n * Portable ID generation that works on both Bun and Node.js\n */\n\nimport { runtime } from \"./runtime\";\n\n/**\n * Generate a unique ID\n * Uses UUIDv7 on Bun (monotonic), falls back to randomUUID on Node.js\n */\nexport function generateId(): string {\n if (runtime.isBun && typeof Bun !== \"undefined\" && typeof Bun.randomUUIDv7 === \"function\") {\n return Bun.randomUUIDv7();\n }\n\n // Node.js fallback: use crypto.randomUUID\n const crypto = require(\"node:crypto\");\n return crypto.randomUUID();\n}\n","/**\n * Portable subprocess spawning that works on both Bun and Node.js\n */\n\nimport { runtime } from \"./runtime\";\n\nexport interface SpawnOptions {\n cmd: string[];\n cwd?: string;\n env?: Record<string, string>;\n}\n\nexport interface SpawnResult {\n stdout: string;\n stderr: string;\n exitCode: number;\n}\n\nexport async function spawn(options: SpawnOptions): Promise<SpawnResult> {\n if (runtime.isBun) {\n const proc = Bun.spawn(options.cmd, {\n cwd: options.cwd,\n env: options.env,\n stdout: \"pipe\",\n stderr: \"pipe\",\n });\n\n const [stdout, stderr] = await Promise.all([new Response(proc.stdout).text(), new Response(proc.stderr).text()]);\n\n const exitCode = await proc.exited;\n\n return { stdout, stderr, exitCode };\n }\n\n // Node.js implementation\n const { execFile } = await import(\"node:child_process\");\n const { promisify } = await import(\"node:util\");\n const execFilePromise = promisify(execFile);\n\n const [command, ...args] = options.cmd;\n if (!command) {\n return {\n stdout: \"\",\n stderr: \"Error: No command provided\",\n exitCode: 1,\n };\n }\n\n try {\n const execOptions: {\n cwd?: string;\n env?: NodeJS.ProcessEnv;\n encoding: BufferEncoding;\n } = {\n encoding: \"utf-8\",\n };\n\n if (options.cwd) {\n execOptions.cwd = options.cwd;\n }\n if (options.env) {\n execOptions.env = options.env as NodeJS.ProcessEnv;\n }\n\n const { stdout, stderr } = await execFilePromise(command, args, execOptions);\n return {\n stdout: stdout || \"\",\n stderr: stderr || \"\",\n exitCode: 0,\n };\n } catch (error: unknown) {\n const err = error as {\n stdout?: string;\n stderr?: string;\n code?: number;\n };\n return {\n stdout: err.stdout || \"\",\n stderr: err.stderr || \"\",\n exitCode: err.code || 1,\n };\n }\n}\n"],"mappings":"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"}
@@ -1,148 +0,0 @@
1
- const require_canonical_id = require('./canonical-id-CgMNOZyn.cjs');
2
- let node_path = require("node:path");
3
- let node_fs = require("node:fs");
4
-
5
- //#region packages/common/src/utils/cached-fn.ts
6
- const cachedFn = (fn) => {
7
- let cached = null;
8
- const ensure = () => (cached ??= { value: fn() }).value;
9
- ensure.clear = () => {
10
- cached = null;
11
- };
12
- return ensure;
13
- };
14
-
15
- //#endregion
16
- //#region packages/common/src/utils/path.ts
17
- /**
18
- * File extensions to try when resolving module specifiers.
19
- * Ordered to match TypeScript's module resolution order.
20
- * @see https://www.typescriptlang.org/docs/handbook/module-resolution.html
21
- */
22
- const MODULE_EXTENSION_CANDIDATES = [
23
- ".ts",
24
- ".tsx",
25
- ".mts",
26
- ".cts",
27
- ".js",
28
- ".mjs",
29
- ".cjs",
30
- ".jsx"
31
- ];
32
- /**
33
- * Normalize path to use forward slashes (cross-platform).
34
- * Ensures consistent path handling across platforms.
35
- */
36
- const normalizePath = (value) => (0, node_path.normalize)(value).replace(/\\/g, "/");
37
- /**
38
- * Resolve a relative import specifier to an absolute file path.
39
- * Tries the specifier as-is, with extensions, and as a directory with index files.
40
- *
41
- * @param from - Absolute path to the importing file
42
- * @param specifier - Relative module specifier (must start with '.')
43
- * @returns Absolute POSIX path to the resolved file, or null if not found
44
- */
45
- const resolveRelativeImportWithExistenceCheck = ({ filePath, specifier }) => {
46
- const base = (0, node_path.resolve)((0, node_path.dirname)(filePath), specifier);
47
- for (const ext of MODULE_EXTENSION_CANDIDATES) {
48
- const candidate = `${base}${ext}`;
49
- if ((0, node_fs.existsSync)(candidate)) {
50
- return normalizePath(candidate);
51
- }
52
- }
53
- for (const ext of MODULE_EXTENSION_CANDIDATES) {
54
- const candidate = (0, node_path.join)(base, `index${ext}`);
55
- if ((0, node_fs.existsSync)(candidate)) {
56
- return normalizePath(candidate);
57
- }
58
- }
59
- if ((0, node_fs.existsSync)(base)) {
60
- try {
61
- const stat = (0, node_fs.statSync)(base);
62
- if (stat.isFile()) {
63
- return normalizePath(base);
64
- }
65
- } catch {}
66
- }
67
- return null;
68
- };
69
- /**
70
- * Resolve a relative import specifier to an absolute file path.
71
- * Tries the specifier as-is, with extensions, and as a directory with index files.
72
- *
73
- * @param from - Absolute path to the importing file
74
- * @param specifier - Relative module specifier (must start with '.')
75
- * @returns Absolute POSIX path to the resolved file, or null if not found
76
- */
77
- const resolveRelativeImportWithReferences = ({ filePath, specifier, references }) => {
78
- const base = (0, node_path.resolve)((0, node_path.dirname)(filePath), specifier);
79
- if (references.has(base)) {
80
- return normalizePath(base);
81
- }
82
- for (const ext of MODULE_EXTENSION_CANDIDATES) {
83
- const candidate = `${base}${ext}`;
84
- if (references.has(candidate)) {
85
- return normalizePath(candidate);
86
- }
87
- }
88
- for (const ext of MODULE_EXTENSION_CANDIDATES) {
89
- const candidate = (0, node_path.join)(base, `index${ext}`);
90
- if (references.has(candidate)) {
91
- return normalizePath(candidate);
92
- }
93
- }
94
- return null;
95
- };
96
- /**
97
- * Check if a module specifier is relative (starts with '.' or '..')
98
- */
99
- const isRelativeSpecifier = (specifier) => specifier.startsWith("./") || specifier.startsWith("../");
100
- /**
101
- * Check if a module specifier is external (package name, not relative)
102
- */
103
- const isExternalSpecifier = (specifier) => !isRelativeSpecifier(specifier);
104
-
105
- //#endregion
106
- Object.defineProperty(exports, 'MODULE_EXTENSION_CANDIDATES', {
107
- enumerable: true,
108
- get: function () {
109
- return MODULE_EXTENSION_CANDIDATES;
110
- }
111
- });
112
- Object.defineProperty(exports, 'cachedFn', {
113
- enumerable: true,
114
- get: function () {
115
- return cachedFn;
116
- }
117
- });
118
- Object.defineProperty(exports, 'isExternalSpecifier', {
119
- enumerable: true,
120
- get: function () {
121
- return isExternalSpecifier;
122
- }
123
- });
124
- Object.defineProperty(exports, 'isRelativeSpecifier', {
125
- enumerable: true,
126
- get: function () {
127
- return isRelativeSpecifier;
128
- }
129
- });
130
- Object.defineProperty(exports, 'normalizePath', {
131
- enumerable: true,
132
- get: function () {
133
- return normalizePath;
134
- }
135
- });
136
- Object.defineProperty(exports, 'resolveRelativeImportWithExistenceCheck', {
137
- enumerable: true,
138
- get: function () {
139
- return resolveRelativeImportWithExistenceCheck;
140
- }
141
- });
142
- Object.defineProperty(exports, 'resolveRelativeImportWithReferences', {
143
- enumerable: true,
144
- get: function () {
145
- return resolveRelativeImportWithReferences;
146
- }
147
- });
148
- //# sourceMappingURL=utils-CsTwS1dw.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils-CsTwS1dw.cjs","names":["cached: { value: T } | null"],"sources":["../src/utils/cached-fn.ts","../src/utils/path.ts"],"sourcesContent":["export const cachedFn = <T>(fn: () => T) => {\n let cached: { value: T } | null = null;\n\n const ensure = () => (cached ??= { value: fn() }).value;\n ensure.clear = () => {\n cached = null;\n };\n\n return ensure;\n};\n","import { existsSync, statSync } from \"node:fs\";\nimport { dirname, join, normalize, resolve } from \"node:path\";\n\n/**\n * File extensions to try when resolving module specifiers.\n * Ordered to match TypeScript's module resolution order.\n * @see https://www.typescriptlang.org/docs/handbook/module-resolution.html\n */\nexport const MODULE_EXTENSION_CANDIDATES = [\".ts\", \".tsx\", \".mts\", \".cts\", \".js\", \".mjs\", \".cjs\", \".jsx\"] as const;\n\n/**\n * Normalize path to use forward slashes (cross-platform).\n * Ensures consistent path handling across platforms.\n */\nexport const normalizePath = (value: string): string => normalize(value).replace(/\\\\/g, \"/\");\n\n/**\n * Resolve a relative import specifier to an absolute file path.\n * Tries the specifier as-is, with extensions, and as a directory with index files.\n *\n * @param from - Absolute path to the importing file\n * @param specifier - Relative module specifier (must start with '.')\n * @returns Absolute POSIX path to the resolved file, or null if not found\n */\nexport const resolveRelativeImportWithExistenceCheck = ({\n filePath,\n specifier,\n}: {\n filePath: string;\n specifier: string;\n}): string | null => {\n const base = resolve(dirname(filePath), specifier);\n\n // Try with extensions first (most common case)\n // This handles cases like \"./constants\" resolving to \"./constants.ts\"\n // even when a \"./constants\" directory exists\n for (const ext of MODULE_EXTENSION_CANDIDATES) {\n const candidate = `${base}${ext}`;\n if (existsSync(candidate)) {\n return normalizePath(candidate);\n }\n }\n\n // Try as directory with index files\n for (const ext of MODULE_EXTENSION_CANDIDATES) {\n const candidate = join(base, `index${ext}`);\n if (existsSync(candidate)) {\n return normalizePath(candidate);\n }\n }\n\n // Try exact path last (only if it's a file, not directory)\n if (existsSync(base)) {\n try {\n const stat = statSync(base);\n if (stat.isFile()) {\n return normalizePath(base);\n }\n } catch {\n // Ignore stat errors\n }\n }\n\n return null;\n};\n\n/**\n * Resolve a relative import specifier to an absolute file path.\n * Tries the specifier as-is, with extensions, and as a directory with index files.\n *\n * @param from - Absolute path to the importing file\n * @param specifier - Relative module specifier (must start with '.')\n * @returns Absolute POSIX path to the resolved file, or null if not found\n */\nexport const resolveRelativeImportWithReferences = <_>({\n filePath,\n specifier,\n references,\n}: {\n filePath: string;\n specifier: string;\n references: Map<string, _> | Set<string>;\n}): string | null => {\n const base = resolve(dirname(filePath), specifier);\n\n // Try exact path first\n if (references.has(base)) {\n return normalizePath(base);\n }\n\n // Try with extensions\n for (const ext of MODULE_EXTENSION_CANDIDATES) {\n const candidate = `${base}${ext}`;\n if (references.has(candidate)) {\n return normalizePath(candidate);\n }\n }\n\n // Try as directory with index files\n for (const ext of MODULE_EXTENSION_CANDIDATES) {\n const candidate = join(base, `index${ext}`);\n if (references.has(candidate)) {\n return normalizePath(candidate);\n }\n }\n\n return null;\n};\n\n/**\n * Check if a module specifier is relative (starts with '.' or '..')\n */\nexport const isRelativeSpecifier = (specifier: string): boolean => specifier.startsWith(\"./\") || specifier.startsWith(\"../\");\n\n/**\n * Check if a module specifier is external (package name, not relative)\n */\nexport const isExternalSpecifier = (specifier: string): boolean => !isRelativeSpecifier(specifier);\n"],"mappings":";;;;;AAAA,MAAa,YAAe,OAAgB;CAC1C,IAAIA,SAA8B;CAElC,MAAM,gBAAgB,WAAW,EAAE,OAAO,IAAI,EAAE,EAAE;AAClD,QAAO,cAAc;AACnB,WAAS;;AAGX,QAAO;;;;;;;;;;ACAT,MAAa,8BAA8B;CAAC;CAAO;CAAQ;CAAQ;CAAQ;CAAO;CAAQ;CAAQ;CAAO;;;;;AAMzG,MAAa,iBAAiB,mCAAoC,MAAM,CAAC,QAAQ,OAAO,IAAI;;;;;;;;;AAU5F,MAAa,2CAA2C,EACtD,UACA,gBAImB;CACnB,MAAM,qDAAuB,SAAS,EAAE,UAAU;AAKlD,MAAK,MAAM,OAAO,6BAA6B;EAC7C,MAAM,YAAY,GAAG,OAAO;AAC5B,8BAAe,UAAU,EAAE;AACzB,UAAO,cAAc,UAAU;;;AAKnC,MAAK,MAAM,OAAO,6BAA6B;EAC7C,MAAM,gCAAiB,MAAM,QAAQ,MAAM;AAC3C,8BAAe,UAAU,EAAE;AACzB,UAAO,cAAc,UAAU;;;AAKnC,6BAAe,KAAK,EAAE;AACpB,MAAI;GACF,MAAM,6BAAgB,KAAK;AAC3B,OAAI,KAAK,QAAQ,EAAE;AACjB,WAAO,cAAc,KAAK;;UAEtB;;AAKV,QAAO;;;;;;;;;;AAWT,MAAa,uCAA0C,EACrD,UACA,WACA,iBAKmB;CACnB,MAAM,qDAAuB,SAAS,EAAE,UAAU;AAGlD,KAAI,WAAW,IAAI,KAAK,EAAE;AACxB,SAAO,cAAc,KAAK;;AAI5B,MAAK,MAAM,OAAO,6BAA6B;EAC7C,MAAM,YAAY,GAAG,OAAO;AAC5B,MAAI,WAAW,IAAI,UAAU,EAAE;AAC7B,UAAO,cAAc,UAAU;;;AAKnC,MAAK,MAAM,OAAO,6BAA6B;EAC7C,MAAM,gCAAiB,MAAM,QAAQ,MAAM;AAC3C,MAAI,WAAW,IAAI,UAAU,EAAE;AAC7B,UAAO,cAAc,UAAU;;;AAInC,QAAO;;;;;AAMT,MAAa,uBAAuB,cAA+B,UAAU,WAAW,KAAK,IAAI,UAAU,WAAW,MAAM;;;;AAK5H,MAAa,uBAAuB,cAA+B,CAAC,oBAAoB,UAAU"}