@sanity/cli-core 0.0.0-20260410130107

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 (155) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +3 -0
  3. package/dist/SanityCommand.js +196 -0
  4. package/dist/SanityCommand.js.map +1 -0
  5. package/dist/_exports/index.d.ts +1391 -0
  6. package/dist/_exports/index.js +39 -0
  7. package/dist/_exports/index.js.map +1 -0
  8. package/dist/_exports/package-manager.d.ts +33 -0
  9. package/dist/_exports/package-manager.js +3 -0
  10. package/dist/_exports/package-manager.js.map +1 -0
  11. package/dist/_exports/request.d.ts +79 -0
  12. package/dist/_exports/request.js +7 -0
  13. package/dist/_exports/request.js.map +1 -0
  14. package/dist/_exports/ux.d.ts +75 -0
  15. package/dist/_exports/ux.js +7 -0
  16. package/dist/_exports/ux.js.map +1 -0
  17. package/dist/config/cli/getCliConfig.js +68 -0
  18. package/dist/config/cli/getCliConfig.js.map +1 -0
  19. package/dist/config/cli/getCliConfigSync.js +51 -0
  20. package/dist/config/cli/getCliConfigSync.js.map +1 -0
  21. package/dist/config/cli/schemas.js +62 -0
  22. package/dist/config/cli/schemas.js.map +1 -0
  23. package/dist/config/cli/types/cliConfig.js +5 -0
  24. package/dist/config/cli/types/cliConfig.js.map +1 -0
  25. package/dist/config/cli/types/userViteConfig.js +5 -0
  26. package/dist/config/cli/types/userViteConfig.js.map +1 -0
  27. package/dist/config/findProjectRoot.js +62 -0
  28. package/dist/config/findProjectRoot.js.map +1 -0
  29. package/dist/config/findProjectRootSync.js +88 -0
  30. package/dist/config/findProjectRootSync.js.map +1 -0
  31. package/dist/config/studio/getStudioConfig.js +13 -0
  32. package/dist/config/studio/getStudioConfig.js.map +1 -0
  33. package/dist/config/studio/getStudioWorkspaces.js +63 -0
  34. package/dist/config/studio/getStudioWorkspaces.js.map +1 -0
  35. package/dist/config/studio/isStudioConfig.js +19 -0
  36. package/dist/config/studio/isStudioConfig.js.map +1 -0
  37. package/dist/config/studio/readStudioConfig.js +82 -0
  38. package/dist/config/studio/readStudioConfig.js.map +1 -0
  39. package/dist/config/studio/readStudioConfig.worker.js +25 -0
  40. package/dist/config/studio/readStudioConfig.worker.js.map +1 -0
  41. package/dist/config/util/configPathsSync.js +85 -0
  42. package/dist/config/util/configPathsSync.js.map +1 -0
  43. package/dist/config/util/findAppConfigPath.js +22 -0
  44. package/dist/config/util/findAppConfigPath.js.map +1 -0
  45. package/dist/config/util/findConfigsPaths.js +21 -0
  46. package/dist/config/util/findConfigsPaths.js.map +1 -0
  47. package/dist/config/util/findStudioConfigPath.js +52 -0
  48. package/dist/config/util/findStudioConfigPath.js.map +1 -0
  49. package/dist/config/util/isSanityV2StudioRoot.js +22 -0
  50. package/dist/config/util/isSanityV2StudioRoot.js.map +1 -0
  51. package/dist/config/util/recursivelyResolveProjectRoot.js +28 -0
  52. package/dist/config/util/recursivelyResolveProjectRoot.js.map +1 -0
  53. package/dist/debug.js +15 -0
  54. package/dist/debug.js.map +1 -0
  55. package/dist/errors/NonInteractiveError.js +18 -0
  56. package/dist/errors/NonInteractiveError.js.map +1 -0
  57. package/dist/errors/NotFoundError.js +27 -0
  58. package/dist/errors/NotFoundError.js.map +1 -0
  59. package/dist/errors/ProjectRootNotFoundError.js +35 -0
  60. package/dist/errors/ProjectRootNotFoundError.js.map +1 -0
  61. package/dist/exitCodes.js +17 -0
  62. package/dist/exitCodes.js.map +1 -0
  63. package/dist/loaders/studio/studioWorkerLoader.worker.js +205 -0
  64. package/dist/loaders/studio/studioWorkerLoader.worker.js.map +1 -0
  65. package/dist/loaders/studio/studioWorkerTask.js +90 -0
  66. package/dist/loaders/studio/studioWorkerTask.js.map +1 -0
  67. package/dist/loaders/tsx/tsxWorkerLoader.worker.js +11 -0
  68. package/dist/loaders/tsx/tsxWorkerLoader.worker.js.map +1 -0
  69. package/dist/loaders/tsx/tsxWorkerTask.js +34 -0
  70. package/dist/loaders/tsx/tsxWorkerTask.js.map +1 -0
  71. package/dist/request/createRequester.js +83 -0
  72. package/dist/request/createRequester.js.map +1 -0
  73. package/dist/services/apiClient.js +97 -0
  74. package/dist/services/apiClient.js.map +1 -0
  75. package/dist/services/cliTokenCache.js +25 -0
  76. package/dist/services/cliTokenCache.js.map +1 -0
  77. package/dist/services/cliUserConfig.js +144 -0
  78. package/dist/services/cliUserConfig.js.map +1 -0
  79. package/dist/services/getCliToken.js +26 -0
  80. package/dist/services/getCliToken.js.map +1 -0
  81. package/dist/telemetry/getCliTelemetry.js +47 -0
  82. package/dist/telemetry/getCliTelemetry.js.map +1 -0
  83. package/dist/telemetry/getTelemetryBaseInfo.js +33 -0
  84. package/dist/telemetry/getTelemetryBaseInfo.js.map +1 -0
  85. package/dist/telemetry/readNDJSON.js +18 -0
  86. package/dist/telemetry/readNDJSON.js.map +1 -0
  87. package/dist/telemetry/types.js +5 -0
  88. package/dist/telemetry/types.js.map +1 -0
  89. package/dist/types.js +5 -0
  90. package/dist/types.js.map +1 -0
  91. package/dist/util/doImport.js +17 -0
  92. package/dist/util/doImport.js.map +1 -0
  93. package/dist/util/environment/getStudioEnvironmentVariables.js +36 -0
  94. package/dist/util/environment/getStudioEnvironmentVariables.js.map +1 -0
  95. package/dist/util/environment/mockBrowserEnvironment.js +47 -0
  96. package/dist/util/environment/mockBrowserEnvironment.js.map +1 -0
  97. package/dist/util/environment/setupBrowserStubs.js +42 -0
  98. package/dist/util/environment/setupBrowserStubs.js.map +1 -0
  99. package/dist/util/environment/stubs.js +142 -0
  100. package/dist/util/environment/stubs.js.map +1 -0
  101. package/dist/util/fileExists.js +13 -0
  102. package/dist/util/fileExists.js.map +1 -0
  103. package/dist/util/generateHelpUrl.js +11 -0
  104. package/dist/util/generateHelpUrl.js.map +1 -0
  105. package/dist/util/getEmptyAuth.js +16 -0
  106. package/dist/util/getEmptyAuth.js.map +1 -0
  107. package/dist/util/getSanityEnvVar.js +24 -0
  108. package/dist/util/getSanityEnvVar.js.map +1 -0
  109. package/dist/util/getSanityUrl.js +9 -0
  110. package/dist/util/getSanityUrl.js.map +1 -0
  111. package/dist/util/importModule.js +32 -0
  112. package/dist/util/importModule.js.map +1 -0
  113. package/dist/util/isCi.js +7 -0
  114. package/dist/util/isCi.js.map +1 -0
  115. package/dist/util/isInteractive.js +5 -0
  116. package/dist/util/isInteractive.js.map +1 -0
  117. package/dist/util/isRecord.js +11 -0
  118. package/dist/util/isRecord.js.map +1 -0
  119. package/dist/util/isStaging.js +10 -0
  120. package/dist/util/isStaging.js.map +1 -0
  121. package/dist/util/isTrueish.js +10 -0
  122. package/dist/util/isTrueish.js.map +1 -0
  123. package/dist/util/normalizePath.js +12 -0
  124. package/dist/util/normalizePath.js.map +1 -0
  125. package/dist/util/packageManager.js +55 -0
  126. package/dist/util/packageManager.js.map +1 -0
  127. package/dist/util/promisifyWorker.js +72 -0
  128. package/dist/util/promisifyWorker.js.map +1 -0
  129. package/dist/util/readJsonFile.js +26 -0
  130. package/dist/util/readJsonFile.js.map +1 -0
  131. package/dist/util/readJsonFileSync.js +26 -0
  132. package/dist/util/readJsonFileSync.js.map +1 -0
  133. package/dist/util/readPackageJson.js +74 -0
  134. package/dist/util/readPackageJson.js.map +1 -0
  135. package/dist/util/resolveLocalPackage.js +82 -0
  136. package/dist/util/resolveLocalPackage.js.map +1 -0
  137. package/dist/util/safeStructuredClone.js +43 -0
  138. package/dist/util/safeStructuredClone.js.map +1 -0
  139. package/dist/util/tryGetDefaultExport.js +18 -0
  140. package/dist/util/tryGetDefaultExport.js.map +1 -0
  141. package/dist/util/writeJsonFileSync.js +19 -0
  142. package/dist/util/writeJsonFileSync.js.map +1 -0
  143. package/dist/ux/boxen.js +3 -0
  144. package/dist/ux/boxen.js.map +1 -0
  145. package/dist/ux/colorizeJson.js +32 -0
  146. package/dist/ux/colorizeJson.js.map +1 -0
  147. package/dist/ux/logSymbols.js +3 -0
  148. package/dist/ux/logSymbols.js.map +1 -0
  149. package/dist/ux/prompts.js +51 -0
  150. package/dist/ux/prompts.js.map +1 -0
  151. package/dist/ux/spinner.js +3 -0
  152. package/dist/ux/spinner.js.map +1 -0
  153. package/dist/ux/timer.js +29 -0
  154. package/dist/ux/timer.js.map +1 -0
  155. package/package.json +111 -0
@@ -0,0 +1,72 @@
1
+ import { Worker } from 'node:worker_threads';
2
+ import { subdebug } from '../debug.js';
3
+ const debug = subdebug('promisifyWorker');
4
+ /**
5
+ * Creates a Node.js Worker from the given file path and options, and wraps it
6
+ * in a Promise that resolves with the first message the worker sends, and
7
+ * rejects on error, message deserialization failure, or non-zero exit code.
8
+ * The worker is terminated after a message or error is received.
9
+ *
10
+ * @param filePath - URL to the worker file
11
+ * @param options - Options to pass to the Worker constructor
12
+ * @returns A promise that resolves with the first message from the worker
13
+ * @throws If the worker emits an error, a message deserialization error, or exits with a non-zero code
14
+ * @internal
15
+ */ export function promisifyWorker(filePath, options) {
16
+ const { timeout, ...workerOptions } = options ?? {};
17
+ const worker = new Worker(filePath, workerOptions);
18
+ const fileName = `[${filePath.pathname}]`;
19
+ return new Promise((resolve, reject)=>{
20
+ let settled = false;
21
+ let timeoutId;
22
+ if (timeout !== undefined && timeout > 0) {
23
+ timeoutId = setTimeout(()=>{
24
+ settled = true;
25
+ reject(new Error(`Worker timed out after ${timeout}ms`));
26
+ void worker.terminate();
27
+ worker.removeAllListeners();
28
+ }, timeout);
29
+ }
30
+ worker.addListener('error', function onWorkerError(err) {
31
+ settled = true;
32
+ clearTimeout(timeoutId);
33
+ debug(`Worker error: ${err.message}`, err);
34
+ reject(new Error(`Worker error: ${err.message}`, {
35
+ cause: err
36
+ }));
37
+ cleanup();
38
+ });
39
+ // No cleanup() here — the worker is already dead after exiting,
40
+ // so there is nothing to terminate or remove listeners from.
41
+ worker.addListener('exit', function onWorkerExit(code) {
42
+ clearTimeout(timeoutId);
43
+ if (code > 0) {
44
+ debug(`${fileName} exited with code ${code}`);
45
+ reject(new Error(`Worker exited with code ${code}`));
46
+ } else if (!settled) {
47
+ debug(`${fileName} exited with code 0 without sending a message`);
48
+ reject(new Error('Worker exited without sending a message'));
49
+ }
50
+ });
51
+ worker.addListener('messageerror', function onWorkerMessageError(err) {
52
+ settled = true;
53
+ clearTimeout(timeoutId);
54
+ debug(`${fileName} message error: ${err.message}`, err);
55
+ reject(new Error(`Failed to deserialize worker message: ${err}`));
56
+ cleanup();
57
+ });
58
+ worker.addListener('message', function onWorkerMessage(message) {
59
+ settled = true;
60
+ clearTimeout(timeoutId);
61
+ debug(`${fileName} message %o`, message);
62
+ resolve(message);
63
+ cleanup();
64
+ });
65
+ function cleanup() {
66
+ setImmediate(()=>worker.terminate());
67
+ worker.removeAllListeners();
68
+ }
69
+ });
70
+ }
71
+
72
+ //# sourceMappingURL=promisifyWorker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/util/promisifyWorker.ts"],"sourcesContent":["import {Worker, type WorkerOptions} from 'node:worker_threads'\n\nimport {subdebug} from '../debug.js'\n\nconst debug = subdebug('promisifyWorker')\n\ninterface PromisifyWorkerOptions extends WorkerOptions {\n /** Optional timeout in milliseconds. If the worker does not respond within this time, it will be terminated and the promise rejected. */\n timeout?: number\n}\n\n/**\n * Creates a Node.js Worker from the given file path and options, and wraps it\n * in a Promise that resolves with the first message the worker sends, and\n * rejects on error, message deserialization failure, or non-zero exit code.\n * The worker is terminated after a message or error is received.\n *\n * @param filePath - URL to the worker file\n * @param options - Options to pass to the Worker constructor\n * @returns A promise that resolves with the first message from the worker\n * @throws If the worker emits an error, a message deserialization error, or exits with a non-zero code\n * @internal\n */\nexport function promisifyWorker<T = unknown>(\n filePath: URL,\n options?: PromisifyWorkerOptions,\n): Promise<T> {\n const {timeout, ...workerOptions} = options ?? {}\n const worker = new Worker(filePath, workerOptions)\n\n const fileName = `[${filePath.pathname}]`\n\n return new Promise<T>((resolve, reject) => {\n let settled = false\n let timeoutId: ReturnType<typeof setTimeout> | undefined\n\n if (timeout !== undefined && timeout > 0) {\n timeoutId = setTimeout(() => {\n settled = true\n reject(new Error(`Worker timed out after ${timeout}ms`))\n void worker.terminate()\n worker.removeAllListeners()\n }, timeout)\n }\n\n worker.addListener('error', function onWorkerError(err) {\n settled = true\n clearTimeout(timeoutId)\n debug(`Worker error: ${err.message}`, err)\n reject(new Error(`Worker error: ${err.message}`, {cause: err}))\n cleanup()\n })\n // No cleanup() here — the worker is already dead after exiting,\n // so there is nothing to terminate or remove listeners from.\n worker.addListener('exit', function onWorkerExit(code) {\n clearTimeout(timeoutId)\n if (code > 0) {\n debug(`${fileName} exited with code ${code}`)\n reject(new Error(`Worker exited with code ${code}`))\n } else if (!settled) {\n debug(`${fileName} exited with code 0 without sending a message`)\n reject(new Error('Worker exited without sending a message'))\n }\n })\n worker.addListener('messageerror', function onWorkerMessageError(err) {\n settled = true\n clearTimeout(timeoutId)\n debug(`${fileName} message error: ${err.message}`, err)\n reject(new Error(`Failed to deserialize worker message: ${err}`))\n cleanup()\n })\n worker.addListener('message', function onWorkerMessage(message) {\n settled = true\n clearTimeout(timeoutId)\n debug(`${fileName} message %o`, message)\n resolve(message)\n cleanup()\n })\n\n function cleanup() {\n setImmediate(() => worker.terminate())\n worker.removeAllListeners()\n }\n })\n}\n"],"names":["Worker","subdebug","debug","promisifyWorker","filePath","options","timeout","workerOptions","worker","fileName","pathname","Promise","resolve","reject","settled","timeoutId","undefined","setTimeout","Error","terminate","removeAllListeners","addListener","onWorkerError","err","clearTimeout","message","cause","cleanup","onWorkerExit","code","onWorkerMessageError","onWorkerMessage","setImmediate"],"mappings":"AAAA,SAAQA,MAAM,QAA2B,sBAAqB;AAE9D,SAAQC,QAAQ,QAAO,cAAa;AAEpC,MAAMC,QAAQD,SAAS;AAOvB;;;;;;;;;;;CAWC,GACD,OAAO,SAASE,gBACdC,QAAa,EACbC,OAAgC;IAEhC,MAAM,EAACC,OAAO,EAAE,GAAGC,eAAc,GAAGF,WAAW,CAAC;IAChD,MAAMG,SAAS,IAAIR,OAAOI,UAAUG;IAEpC,MAAME,WAAW,CAAC,CAAC,EAAEL,SAASM,QAAQ,CAAC,CAAC,CAAC;IAEzC,OAAO,IAAIC,QAAW,CAACC,SAASC;QAC9B,IAAIC,UAAU;QACd,IAAIC;QAEJ,IAAIT,YAAYU,aAAaV,UAAU,GAAG;YACxCS,YAAYE,WAAW;gBACrBH,UAAU;gBACVD,OAAO,IAAIK,MAAM,CAAC,uBAAuB,EAAEZ,QAAQ,EAAE,CAAC;gBACtD,KAAKE,OAAOW,SAAS;gBACrBX,OAAOY,kBAAkB;YAC3B,GAAGd;QACL;QAEAE,OAAOa,WAAW,CAAC,SAAS,SAASC,cAAcC,GAAG;YACpDT,UAAU;YACVU,aAAaT;YACbb,MAAM,CAAC,cAAc,EAAEqB,IAAIE,OAAO,EAAE,EAAEF;YACtCV,OAAO,IAAIK,MAAM,CAAC,cAAc,EAAEK,IAAIE,OAAO,EAAE,EAAE;gBAACC,OAAOH;YAAG;YAC5DI;QACF;QACA,gEAAgE;QAChE,6DAA6D;QAC7DnB,OAAOa,WAAW,CAAC,QAAQ,SAASO,aAAaC,IAAI;YACnDL,aAAaT;YACb,IAAIc,OAAO,GAAG;gBACZ3B,MAAM,GAAGO,SAAS,kBAAkB,EAAEoB,MAAM;gBAC5ChB,OAAO,IAAIK,MAAM,CAAC,wBAAwB,EAAEW,MAAM;YACpD,OAAO,IAAI,CAACf,SAAS;gBACnBZ,MAAM,GAAGO,SAAS,6CAA6C,CAAC;gBAChEI,OAAO,IAAIK,MAAM;YACnB;QACF;QACAV,OAAOa,WAAW,CAAC,gBAAgB,SAASS,qBAAqBP,GAAG;YAClET,UAAU;YACVU,aAAaT;YACbb,MAAM,GAAGO,SAAS,gBAAgB,EAAEc,IAAIE,OAAO,EAAE,EAAEF;YACnDV,OAAO,IAAIK,MAAM,CAAC,sCAAsC,EAAEK,KAAK;YAC/DI;QACF;QACAnB,OAAOa,WAAW,CAAC,WAAW,SAASU,gBAAgBN,OAAO;YAC5DX,UAAU;YACVU,aAAaT;YACbb,MAAM,GAAGO,SAAS,WAAW,CAAC,EAAEgB;YAChCb,QAAQa;YACRE;QACF;QAEA,SAASA;YACPK,aAAa,IAAMxB,OAAOW,SAAS;YACnCX,OAAOY,kBAAkB;QAC3B;IACF;AACF"}
@@ -0,0 +1,26 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ /**
3
+ * Read the file at the given path and parse it as JSON.
4
+ *
5
+ * @param filePath - Path to JSON file to read
6
+ * @returns The parsed file
7
+ * @internal
8
+ */ export async function readJsonFile(filePath) {
9
+ let content;
10
+ try {
11
+ content = await readFile(filePath, 'utf8');
12
+ } catch (err) {
13
+ throw new Error(`Failed to read "${filePath}"`, {
14
+ cause: err
15
+ });
16
+ }
17
+ try {
18
+ return JSON.parse(content);
19
+ } catch (err) {
20
+ throw new Error(`Failed to parse "${filePath}" as JSON`, {
21
+ cause: err
22
+ });
23
+ }
24
+ }
25
+
26
+ //# sourceMappingURL=readJsonFile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/util/readJsonFile.ts"],"sourcesContent":["import {readFile} from 'node:fs/promises'\n\ntype JSONValue = boolean | JSONArray | JSONObject | number | string | null\n\ntype JSONObject = {[key: string]: JSONValue}\n\ntype JSONArray = Array<JSONValue>\n\n/**\n * Read the file at the given path and parse it as JSON.\n *\n * @param filePath - Path to JSON file to read\n * @returns The parsed file\n * @internal\n */\nexport async function readJsonFile(filePath: string): Promise<JSONValue> {\n let content: string\n try {\n content = await readFile(filePath, 'utf8')\n } catch (err: unknown) {\n throw new Error(`Failed to read \"${filePath}\"`, {cause: err})\n }\n\n try {\n return JSON.parse(content)\n } catch (err: unknown) {\n throw new Error(`Failed to parse \"${filePath}\" as JSON`, {cause: err})\n }\n}\n"],"names":["readFile","readJsonFile","filePath","content","err","Error","cause","JSON","parse"],"mappings":"AAAA,SAAQA,QAAQ,QAAO,mBAAkB;AAQzC;;;;;;CAMC,GACD,OAAO,eAAeC,aAAaC,QAAgB;IACjD,IAAIC;IACJ,IAAI;QACFA,UAAU,MAAMH,SAASE,UAAU;IACrC,EAAE,OAAOE,KAAc;QACrB,MAAM,IAAIC,MAAM,CAAC,gBAAgB,EAAEH,SAAS,CAAC,CAAC,EAAE;YAACI,OAAOF;QAAG;IAC7D;IAEA,IAAI;QACF,OAAOG,KAAKC,KAAK,CAACL;IACpB,EAAE,OAAOC,KAAc;QACrB,MAAM,IAAIC,MAAM,CAAC,iBAAiB,EAAEH,SAAS,SAAS,CAAC,EAAE;YAACI,OAAOF;QAAG;IACtE;AACF"}
@@ -0,0 +1,26 @@
1
+ import { readFileSync } from 'node:fs';
2
+ /**
3
+ * Read the file at the given path synchronously and parse it as JSON.
4
+ *
5
+ * @param filePath - Path to JSON file to read
6
+ * @returns The parsed file
7
+ * @internal
8
+ */ export function readJsonFileSync(filePath) {
9
+ let content;
10
+ try {
11
+ content = readFileSync(filePath, 'utf8');
12
+ } catch (err) {
13
+ throw new Error(`Failed to read "${filePath}"`, {
14
+ cause: err
15
+ });
16
+ }
17
+ try {
18
+ return JSON.parse(content);
19
+ } catch (err) {
20
+ throw new Error(`Failed to parse "${filePath}" as JSON`, {
21
+ cause: err
22
+ });
23
+ }
24
+ }
25
+
26
+ //# sourceMappingURL=readJsonFileSync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/util/readJsonFileSync.ts"],"sourcesContent":["import {readFileSync} from 'node:fs'\n\ntype JSONValue = boolean | JSONArray | JSONObject | number | string | null\n\ntype JSONObject = {[key: string]: JSONValue}\n\ntype JSONArray = Array<JSONValue>\n\n/**\n * Read the file at the given path synchronously and parse it as JSON.\n *\n * @param filePath - Path to JSON file to read\n * @returns The parsed file\n * @internal\n */\nexport function readJsonFileSync(filePath: string): JSONValue {\n let content: string\n try {\n content = readFileSync(filePath, 'utf8')\n } catch (err: unknown) {\n throw new Error(`Failed to read \"${filePath}\"`, {cause: err})\n }\n\n try {\n return JSON.parse(content)\n } catch (err: unknown) {\n throw new Error(`Failed to parse \"${filePath}\" as JSON`, {cause: err})\n }\n}\n"],"names":["readFileSync","readJsonFileSync","filePath","content","err","Error","cause","JSON","parse"],"mappings":"AAAA,SAAQA,YAAY,QAAO,UAAS;AAQpC;;;;;;CAMC,GACD,OAAO,SAASC,iBAAiBC,QAAgB;IAC/C,IAAIC;IACJ,IAAI;QACFA,UAAUH,aAAaE,UAAU;IACnC,EAAE,OAAOE,KAAc;QACrB,MAAM,IAAIC,MAAM,CAAC,gBAAgB,EAAEH,SAAS,CAAC,CAAC,EAAE;YAACI,OAAOF;QAAG;IAC7D;IAEA,IAAI;QACF,OAAOG,KAAKC,KAAK,CAACL;IACpB,EAAE,OAAOC,KAAc;QACrB,MAAM,IAAIC,MAAM,CAAC,iBAAiB,EAAEH,SAAS,SAAS,CAAC,EAAE;YAACI,OAAOF;QAAG;IACtE;AACF"}
@@ -0,0 +1,74 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { z } from 'zod/mini';
3
+ /**
4
+ * Comprehensive package.json schema including all common properties.
5
+ * Feel free to add properties to this,
6
+ * 🟠ℹ️ BUT ENSURE OPTIONAL STUFF IS ACTUALLY OPTIONAL ℹ️🟠
7
+ * 🟠ℹ️ SINCE THIS IS USED IN A NUMBER OF LOCATIONS WHERE ℹ️🟠
8
+ * 🟠ℹ️ WE CANNOT ENFORCE/GUARANTEE ANY PARTICULAR PROPS ℹ️🟠
9
+ */ const packageJsonSchema = z.looseObject({
10
+ // Required fields
11
+ name: z.string(),
12
+ version: z.string(),
13
+ // Dependencies (optional)
14
+ dependencies: z.optional(z.record(z.string(), z.string())),
15
+ devDependencies: z.optional(z.record(z.string(), z.string())),
16
+ peerDependencies: z.optional(z.record(z.string(), z.string())),
17
+ // Module structure (optional)
18
+ exports: z.optional(z.record(z.string(), z.any())),
19
+ main: z.optional(z.string()),
20
+ types: z.optional(z.string()),
21
+ // Metadata (optional)
22
+ author: z.optional(z.string()),
23
+ description: z.optional(z.string()),
24
+ engines: z.optional(z.record(z.string(), z.string())),
25
+ license: z.optional(z.string()),
26
+ private: z.optional(z.boolean()),
27
+ repository: z.optional(z.object({
28
+ type: z.string(),
29
+ url: z.string()
30
+ })),
31
+ scripts: z.optional(z.record(z.string(), z.string())),
32
+ type: z.optional(z.enum([
33
+ 'module',
34
+ 'commonjs'
35
+ ]))
36
+ });
37
+ /**
38
+ * Read the `package.json` file at the given path
39
+ *
40
+ * @param filePath - Path to package.json to read
41
+ * @param options - Options object for controlling read behavior
42
+ * @returns The parsed package.json
43
+ * @public
44
+ */ export async function readPackageJson(filePath, options = {}) {
45
+ const { defaults = {}, skipSchemaValidation = false } = options;
46
+ // Read and parse the file
47
+ let pkg;
48
+ try {
49
+ pkg = JSON.parse(await readFile(filePath, 'utf8'));
50
+ } catch (err) {
51
+ throw new Error(`Failed to read "${filePath}"`, {
52
+ cause: err
53
+ });
54
+ }
55
+ // Merge with defaults (parsed values take precedence)
56
+ const merged = {
57
+ ...defaults,
58
+ ...pkg
59
+ };
60
+ // Validate with schema unless skipped
61
+ let validated;
62
+ if (skipSchemaValidation) {
63
+ validated = merged;
64
+ } else {
65
+ const { data, error, success } = packageJsonSchema.safeParse(merged);
66
+ if (!success) {
67
+ throw new Error(`Invalid package.json at "${filePath}": ${error.issues.map((err)=>err.message).join('\n')}`);
68
+ }
69
+ validated = data;
70
+ }
71
+ return validated;
72
+ }
73
+
74
+ //# sourceMappingURL=readPackageJson.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/util/readPackageJson.ts"],"sourcesContent":["import {readFile} from 'node:fs/promises'\n\nimport {z} from 'zod/mini'\n\n/**\n * Comprehensive package.json schema including all common properties.\n * Feel free to add properties to this,\n * 🟠ℹ️ BUT ENSURE OPTIONAL STUFF IS ACTUALLY OPTIONAL ℹ️🟠\n * 🟠ℹ️ SINCE THIS IS USED IN A NUMBER OF LOCATIONS WHERE ℹ️🟠\n * 🟠ℹ️ WE CANNOT ENFORCE/GUARANTEE ANY PARTICULAR PROPS ℹ️🟠\n */\nconst packageJsonSchema = z.looseObject({\n // Required fields\n name: z.string(),\n version: z.string(),\n\n // Dependencies (optional)\n dependencies: z.optional(z.record(z.string(), z.string())),\n devDependencies: z.optional(z.record(z.string(), z.string())),\n peerDependencies: z.optional(z.record(z.string(), z.string())),\n\n // Module structure (optional)\n exports: z.optional(z.record(z.string(), z.any())),\n main: z.optional(z.string()),\n types: z.optional(z.string()),\n\n // Metadata (optional)\n author: z.optional(z.string()),\n description: z.optional(z.string()),\n engines: z.optional(z.record(z.string(), z.string())),\n license: z.optional(z.string()),\n private: z.optional(z.boolean()),\n repository: z.optional(\n z.object({\n type: z.string(),\n url: z.string(),\n }),\n ),\n scripts: z.optional(z.record(z.string(), z.string())),\n type: z.optional(z.enum(['module', 'commonjs'])),\n})\n\n/**\n * Comprehensive representation of a package.json file.\n * Consolidates all properties from previous type definitions.\n *\n * @public\n */\nexport type PackageJson = z.infer<typeof packageJsonSchema>\n\n/**\n * Options for reading package.json files\n *\n * @public\n */\nexport interface ReadPackageJsonOptions {\n /**\n * Default values to merge with the parsed package.json.\n * Parsed values take precedence over defaults.\n */\n defaults?: Partial<PackageJson>\n\n /**\n * Skip Zod schema validation. When true, the file is parsed but not validated.\n * Defaults to false.\n */\n skipSchemaValidation?: boolean\n}\n\n/**\n * Read the `package.json` file at the given path\n *\n * @param filePath - Path to package.json to read\n * @param options - Options object for controlling read behavior\n * @returns The parsed package.json\n * @public\n */\nexport async function readPackageJson(\n filePath: string | URL,\n options: ReadPackageJsonOptions = {},\n): Promise<PackageJson> {\n const {defaults = {}, skipSchemaValidation = false} = options\n\n // Read and parse the file\n let pkg: Record<string, unknown>\n try {\n pkg = JSON.parse(await readFile(filePath, 'utf8'))\n } catch (err: unknown) {\n throw new Error(`Failed to read \"${filePath}\"`, {cause: err})\n }\n\n // Merge with defaults (parsed values take precedence)\n const merged = {...defaults, ...pkg}\n\n // Validate with schema unless skipped\n let validated: PackageJson\n if (skipSchemaValidation) {\n validated = merged as PackageJson\n } else {\n const {data, error, success} = packageJsonSchema.safeParse(merged)\n if (!success) {\n throw new Error(\n `Invalid package.json at \"${filePath}\": ${error.issues.map((err) => err.message).join('\\n')}`,\n )\n }\n validated = data\n }\n\n return validated\n}\n"],"names":["readFile","z","packageJsonSchema","looseObject","name","string","version","dependencies","optional","record","devDependencies","peerDependencies","exports","any","main","types","author","description","engines","license","private","boolean","repository","object","type","url","scripts","enum","readPackageJson","filePath","options","defaults","skipSchemaValidation","pkg","JSON","parse","err","Error","cause","merged","validated","data","error","success","safeParse","issues","map","message","join"],"mappings":"AAAA,SAAQA,QAAQ,QAAO,mBAAkB;AAEzC,SAAQC,CAAC,QAAO,WAAU;AAE1B;;;;;;CAMC,GACD,MAAMC,oBAAoBD,EAAEE,WAAW,CAAC;IACtC,kBAAkB;IAClBC,MAAMH,EAAEI,MAAM;IACdC,SAASL,EAAEI,MAAM;IAEjB,0BAA0B;IAC1BE,cAAcN,EAAEO,QAAQ,CAACP,EAAEQ,MAAM,CAACR,EAAEI,MAAM,IAAIJ,EAAEI,MAAM;IACtDK,iBAAiBT,EAAEO,QAAQ,CAACP,EAAEQ,MAAM,CAACR,EAAEI,MAAM,IAAIJ,EAAEI,MAAM;IACzDM,kBAAkBV,EAAEO,QAAQ,CAACP,EAAEQ,MAAM,CAACR,EAAEI,MAAM,IAAIJ,EAAEI,MAAM;IAE1D,8BAA8B;IAC9BO,SAASX,EAAEO,QAAQ,CAACP,EAAEQ,MAAM,CAACR,EAAEI,MAAM,IAAIJ,EAAEY,GAAG;IAC9CC,MAAMb,EAAEO,QAAQ,CAACP,EAAEI,MAAM;IACzBU,OAAOd,EAAEO,QAAQ,CAACP,EAAEI,MAAM;IAE1B,sBAAsB;IACtBW,QAAQf,EAAEO,QAAQ,CAACP,EAAEI,MAAM;IAC3BY,aAAahB,EAAEO,QAAQ,CAACP,EAAEI,MAAM;IAChCa,SAASjB,EAAEO,QAAQ,CAACP,EAAEQ,MAAM,CAACR,EAAEI,MAAM,IAAIJ,EAAEI,MAAM;IACjDc,SAASlB,EAAEO,QAAQ,CAACP,EAAEI,MAAM;IAC5Be,SAASnB,EAAEO,QAAQ,CAACP,EAAEoB,OAAO;IAC7BC,YAAYrB,EAAEO,QAAQ,CACpBP,EAAEsB,MAAM,CAAC;QACPC,MAAMvB,EAAEI,MAAM;QACdoB,KAAKxB,EAAEI,MAAM;IACf;IAEFqB,SAASzB,EAAEO,QAAQ,CAACP,EAAEQ,MAAM,CAACR,EAAEI,MAAM,IAAIJ,EAAEI,MAAM;IACjDmB,MAAMvB,EAAEO,QAAQ,CAACP,EAAE0B,IAAI,CAAC;QAAC;QAAU;KAAW;AAChD;AA6BA;;;;;;;CAOC,GACD,OAAO,eAAeC,gBACpBC,QAAsB,EACtBC,UAAkC,CAAC,CAAC;IAEpC,MAAM,EAACC,WAAW,CAAC,CAAC,EAAEC,uBAAuB,KAAK,EAAC,GAAGF;IAEtD,0BAA0B;IAC1B,IAAIG;IACJ,IAAI;QACFA,MAAMC,KAAKC,KAAK,CAAC,MAAMnC,SAAS6B,UAAU;IAC5C,EAAE,OAAOO,KAAc;QACrB,MAAM,IAAIC,MAAM,CAAC,gBAAgB,EAAER,SAAS,CAAC,CAAC,EAAE;YAACS,OAAOF;QAAG;IAC7D;IAEA,sDAAsD;IACtD,MAAMG,SAAS;QAAC,GAAGR,QAAQ;QAAE,GAAGE,GAAG;IAAA;IAEnC,sCAAsC;IACtC,IAAIO;IACJ,IAAIR,sBAAsB;QACxBQ,YAAYD;IACd,OAAO;QACL,MAAM,EAACE,IAAI,EAAEC,KAAK,EAAEC,OAAO,EAAC,GAAGzC,kBAAkB0C,SAAS,CAACL;QAC3D,IAAI,CAACI,SAAS;YACZ,MAAM,IAAIN,MACR,CAAC,yBAAyB,EAAER,SAAS,GAAG,EAAEa,MAAMG,MAAM,CAACC,GAAG,CAAC,CAACV,MAAQA,IAAIW,OAAO,EAAEC,IAAI,CAAC,OAAO;QAEjG;QACAR,YAAYC;IACd;IAEA,OAAOD;AACT"}
@@ -0,0 +1,82 @@
1
+ import { resolve } from 'node:path';
2
+ import { pathToFileURL } from 'node:url';
3
+ import { moduleResolve } from 'import-meta-resolve';
4
+ import { doImport } from './doImport.js';
5
+ /**
6
+ * Resolves and imports a package from the local project's node_modules,
7
+ * relative to the given working directory. This avoids circular dependencies
8
+ * and ensures the correct version of the package is used.
9
+ *
10
+ * @param packageName - The name of the package to resolve (e.g., 'sanity')
11
+ * @param workDir - The working directory to resolve the package from
12
+ * @returns The imported module
13
+ * @throws If the package cannot be resolved or imported
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * const {createSchema} = await resolveLocalPackage('sanity', workDir)
18
+ * ```
19
+ *
20
+ * @internal
21
+ */ export async function resolveLocalPackage(packageName, workDir) {
22
+ const packageUrl = resolveLocalPackagePath(packageName, workDir);
23
+ const module = await doImport(packageUrl.href);
24
+ return module;
25
+ }
26
+ /**
27
+ * Resolves the URL of a package from the local project's node_modules,
28
+ * relative to the given working directory, without importing it.
29
+ *
30
+ * @param packageName - The name of the package to resolve (e.g., 'sanity')
31
+ * @param workDir - The working directory to resolve the package from
32
+ * @returns The resolved URL of the package entry point
33
+ * @throws If the package cannot be resolved
34
+ *
35
+ * @example
36
+ * ```ts
37
+ * // Resolve a transitive dependency via its parent package:
38
+ * const sanityUrl = resolveLocalPackagePath('sanity', workDir)
39
+ * const uiUrl = resolveLocalPackagePathFrom('@sanity/ui', sanityUrl)
40
+ * ```
41
+ *
42
+ * @internal
43
+ */ export function resolveLocalPackagePath(packageName, workDir) {
44
+ const fakeCliConfigUrl = pathToFileURL(resolve(workDir, 'sanity.cli.mjs'));
45
+ try {
46
+ return moduleResolve(packageName, fakeCliConfigUrl);
47
+ } catch (error) {
48
+ throw new Error(`Failed to resolve package "${packageName}" from "${workDir}": ${error instanceof Error ? error.message : String(error)}`, {
49
+ cause: error
50
+ });
51
+ }
52
+ }
53
+ /**
54
+ * Resolves and imports a package relative to another resolved module URL.
55
+ * Useful for resolving transitive dependencies that may not be directly
56
+ * accessible from the project root (e.g., in pnpm strict mode).
57
+ *
58
+ * @param packageName - The name of the package to resolve
59
+ * @param parentUrl - The URL of the parent module to resolve from
60
+ * @returns The imported module
61
+ * @throws If the package cannot be resolved or imported
62
+ *
63
+ * @example
64
+ * ```ts
65
+ * const sanityUrl = resolveLocalPackagePath('sanity', workDir)
66
+ * const ui = await resolveLocalPackageFrom<typeof import('@sanity/ui')>('@sanity/ui', sanityUrl)
67
+ * ```
68
+ *
69
+ * @internal
70
+ */ export async function resolveLocalPackageFrom(packageName, parentUrl) {
71
+ try {
72
+ const packageUrl = moduleResolve(packageName, parentUrl);
73
+ const module = await doImport(packageUrl.href);
74
+ return module;
75
+ } catch (error) {
76
+ throw new Error(`Failed to resolve package "${packageName}" from "${parentUrl.href}": ${error instanceof Error ? error.message : String(error)}`, {
77
+ cause: error
78
+ });
79
+ }
80
+ }
81
+
82
+ //# sourceMappingURL=resolveLocalPackage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/util/resolveLocalPackage.ts"],"sourcesContent":["import {resolve} from 'node:path'\nimport {pathToFileURL} from 'node:url'\n\nimport {moduleResolve} from 'import-meta-resolve'\n\nimport {doImport} from './doImport.js'\n\n/**\n * Resolves and imports a package from the local project's node_modules,\n * relative to the given working directory. This avoids circular dependencies\n * and ensures the correct version of the package is used.\n *\n * @param packageName - The name of the package to resolve (e.g., 'sanity')\n * @param workDir - The working directory to resolve the package from\n * @returns The imported module\n * @throws If the package cannot be resolved or imported\n *\n * @example\n * ```ts\n * const {createSchema} = await resolveLocalPackage('sanity', workDir)\n * ```\n *\n * @internal\n */\nexport async function resolveLocalPackage<T = unknown>(\n packageName: string,\n workDir: string,\n): Promise<T> {\n const packageUrl = resolveLocalPackagePath(packageName, workDir)\n const module = await doImport(packageUrl.href)\n return module as T\n}\n\n/**\n * Resolves the URL of a package from the local project's node_modules,\n * relative to the given working directory, without importing it.\n *\n * @param packageName - The name of the package to resolve (e.g., 'sanity')\n * @param workDir - The working directory to resolve the package from\n * @returns The resolved URL of the package entry point\n * @throws If the package cannot be resolved\n *\n * @example\n * ```ts\n * // Resolve a transitive dependency via its parent package:\n * const sanityUrl = resolveLocalPackagePath('sanity', workDir)\n * const uiUrl = resolveLocalPackagePathFrom('@sanity/ui', sanityUrl)\n * ```\n *\n * @internal\n */\nexport function resolveLocalPackagePath(packageName: string, workDir: string): URL {\n const fakeCliConfigUrl = pathToFileURL(resolve(workDir, 'sanity.cli.mjs'))\n\n try {\n return moduleResolve(packageName, fakeCliConfigUrl)\n } catch (error) {\n throw new Error(\n `Failed to resolve package \"${packageName}\" from \"${workDir}\": ${error instanceof Error ? error.message : String(error)}`,\n {cause: error},\n )\n }\n}\n\n/**\n * Resolves and imports a package relative to another resolved module URL.\n * Useful for resolving transitive dependencies that may not be directly\n * accessible from the project root (e.g., in pnpm strict mode).\n *\n * @param packageName - The name of the package to resolve\n * @param parentUrl - The URL of the parent module to resolve from\n * @returns The imported module\n * @throws If the package cannot be resolved or imported\n *\n * @example\n * ```ts\n * const sanityUrl = resolveLocalPackagePath('sanity', workDir)\n * const ui = await resolveLocalPackageFrom<typeof import('@sanity/ui')>('@sanity/ui', sanityUrl)\n * ```\n *\n * @internal\n */\nexport async function resolveLocalPackageFrom<T = unknown>(\n packageName: string,\n parentUrl: URL,\n): Promise<T> {\n try {\n const packageUrl = moduleResolve(packageName, parentUrl)\n const module = await doImport(packageUrl.href)\n return module as T\n } catch (error) {\n throw new Error(\n `Failed to resolve package \"${packageName}\" from \"${parentUrl.href}\": ${error instanceof Error ? error.message : String(error)}`,\n {cause: error},\n )\n }\n}\n"],"names":["resolve","pathToFileURL","moduleResolve","doImport","resolveLocalPackage","packageName","workDir","packageUrl","resolveLocalPackagePath","module","href","fakeCliConfigUrl","error","Error","message","String","cause","resolveLocalPackageFrom","parentUrl"],"mappings":"AAAA,SAAQA,OAAO,QAAO,YAAW;AACjC,SAAQC,aAAa,QAAO,WAAU;AAEtC,SAAQC,aAAa,QAAO,sBAAqB;AAEjD,SAAQC,QAAQ,QAAO,gBAAe;AAEtC;;;;;;;;;;;;;;;;CAgBC,GACD,OAAO,eAAeC,oBACpBC,WAAmB,EACnBC,OAAe;IAEf,MAAMC,aAAaC,wBAAwBH,aAAaC;IACxD,MAAMG,SAAS,MAAMN,SAASI,WAAWG,IAAI;IAC7C,OAAOD;AACT;AAEA;;;;;;;;;;;;;;;;;CAiBC,GACD,OAAO,SAASD,wBAAwBH,WAAmB,EAAEC,OAAe;IAC1E,MAAMK,mBAAmBV,cAAcD,QAAQM,SAAS;IAExD,IAAI;QACF,OAAOJ,cAAcG,aAAaM;IACpC,EAAE,OAAOC,OAAO;QACd,MAAM,IAAIC,MACR,CAAC,2BAA2B,EAAER,YAAY,QAAQ,EAAEC,QAAQ,GAAG,EAAEM,iBAAiBC,QAAQD,MAAME,OAAO,GAAGC,OAAOH,QAAQ,EACzH;YAACI,OAAOJ;QAAK;IAEjB;AACF;AAEA;;;;;;;;;;;;;;;;;CAiBC,GACD,OAAO,eAAeK,wBACpBZ,WAAmB,EACnBa,SAAc;IAEd,IAAI;QACF,MAAMX,aAAaL,cAAcG,aAAaa;QAC9C,MAAMT,SAAS,MAAMN,SAASI,WAAWG,IAAI;QAC7C,OAAOD;IACT,EAAE,OAAOG,OAAO;QACd,MAAM,IAAIC,MACR,CAAC,2BAA2B,EAAER,YAAY,QAAQ,EAAEa,UAAUR,IAAI,CAAC,GAAG,EAAEE,iBAAiBC,QAAQD,MAAME,OAAO,GAAGC,OAAOH,QAAQ,EAChI;YAACI,OAAOJ;QAAK;IAEjB;AACF"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * `structuredClone()`, but doesn't throw on non-clonable values - instead it drops them.
3
+ *
4
+ * @param obj - The object to clone.
5
+ * @returns The cloned object.
6
+ * @internal
7
+ */ export function safeStructuredClone(obj) {
8
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
9
+ const seen = new WeakMap();
10
+ function clone(value) {
11
+ if (typeof value === 'function' || typeof value === 'symbol') {
12
+ return undefined; // Drop non-clonable values
13
+ }
14
+ if (value !== null && typeof value === 'object') {
15
+ if (seen.has(value)) return seen.get(value);
16
+ if (value instanceof Date) return new Date(value);
17
+ if (value instanceof RegExp) return new RegExp(value);
18
+ if (value instanceof Set) return new Set([
19
+ ...value
20
+ ].map((item)=>clone(item)));
21
+ if (value instanceof Map) return new Map([
22
+ ...value.entries()
23
+ ].map(([k, v])=>[
24
+ clone(k),
25
+ clone(v)
26
+ ]));
27
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
28
+ if (ArrayBuffer.isView(value)) return new value.constructor(value);
29
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
30
+ const result = Array.isArray(value) ? [] : {};
31
+ seen.set(value, result);
32
+ for(const key in value){
33
+ const clonedValue = clone(value[key]);
34
+ if (clonedValue !== undefined) result[key] = clonedValue;
35
+ }
36
+ return result;
37
+ }
38
+ return value;
39
+ }
40
+ return clone(obj);
41
+ }
42
+
43
+ //# sourceMappingURL=safeStructuredClone.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/util/safeStructuredClone.ts"],"sourcesContent":["/**\n * `structuredClone()`, but doesn't throw on non-clonable values - instead it drops them.\n *\n * @param obj - The object to clone.\n * @returns The cloned object.\n * @internal\n */\nexport function safeStructuredClone<T>(obj: T): T {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const seen = new WeakMap<object, any>()\n\n function clone<T>(value: T): T {\n if (typeof value === 'function' || typeof value === 'symbol') {\n return undefined as unknown as T // Drop non-clonable values\n }\n if (value !== null && typeof value === 'object') {\n if (seen.has(value)) return seen.get(value)\n\n if (value instanceof Date) return new Date(value) as T\n if (value instanceof RegExp) return new RegExp(value) as T\n if (value instanceof Set) return new Set([...value].map((item) => clone(item))) as T\n if (value instanceof Map)\n return new Map([...value.entries()].map(([k, v]) => [clone(k), clone(v)])) as T\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if (ArrayBuffer.isView(value)) return new (value.constructor as any)(value) as T\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const result: any = Array.isArray(value) ? [] : {}\n seen.set(value, result)\n\n for (const key in value) {\n const clonedValue = clone(value[key])\n if (clonedValue !== undefined) result[key] = clonedValue\n }\n return result as T\n }\n return value\n }\n\n return clone(obj)\n}\n"],"names":["safeStructuredClone","obj","seen","WeakMap","clone","value","undefined","has","get","Date","RegExp","Set","map","item","Map","entries","k","v","ArrayBuffer","isView","result","Array","isArray","set","key","clonedValue"],"mappings":"AAAA;;;;;;CAMC,GACD,OAAO,SAASA,oBAAuBC,GAAM;IAC3C,8DAA8D;IAC9D,MAAMC,OAAO,IAAIC;IAEjB,SAASC,MAASC,KAAQ;QACxB,IAAI,OAAOA,UAAU,cAAc,OAAOA,UAAU,UAAU;YAC5D,OAAOC,WAA0B,2BAA2B;QAC9D;QACA,IAAID,UAAU,QAAQ,OAAOA,UAAU,UAAU;YAC/C,IAAIH,KAAKK,GAAG,CAACF,QAAQ,OAAOH,KAAKM,GAAG,CAACH;YAErC,IAAIA,iBAAiBI,MAAM,OAAO,IAAIA,KAAKJ;YAC3C,IAAIA,iBAAiBK,QAAQ,OAAO,IAAIA,OAAOL;YAC/C,IAAIA,iBAAiBM,KAAK,OAAO,IAAIA,IAAI;mBAAIN;aAAM,CAACO,GAAG,CAAC,CAACC,OAAST,MAAMS;YACxE,IAAIR,iBAAiBS,KACnB,OAAO,IAAIA,IAAI;mBAAIT,MAAMU,OAAO;aAAG,CAACH,GAAG,CAAC,CAAC,CAACI,GAAGC,EAAE,GAAK;oBAACb,MAAMY;oBAAIZ,MAAMa;iBAAG;YAC1E,8DAA8D;YAC9D,IAAIC,YAAYC,MAAM,CAACd,QAAQ,OAAO,IAAKA,MAAM,WAAW,CAASA;YAErE,8DAA8D;YAC9D,MAAMe,SAAcC,MAAMC,OAAO,CAACjB,SAAS,EAAE,GAAG,CAAC;YACjDH,KAAKqB,GAAG,CAAClB,OAAOe;YAEhB,IAAK,MAAMI,OAAOnB,MAAO;gBACvB,MAAMoB,cAAcrB,MAAMC,KAAK,CAACmB,IAAI;gBACpC,IAAIC,gBAAgBnB,WAAWc,MAAM,CAACI,IAAI,GAAGC;YAC/C;YACA,OAAOL;QACT;QACA,OAAOf;IACT;IAEA,OAAOD,MAAMH;AACf"}
@@ -0,0 +1,18 @@
1
+ import { isRecord } from './isRecord.js';
2
+ /**
3
+ * Try to get the default export of a module of the cli config.
4
+ * This can be either ESM or CJS.
5
+ */ export function tryGetDefaultExport(mod) {
6
+ // If the module is a record and has a default property, return the default property
7
+ if (isRecord(mod) && 'default' in mod) {
8
+ // If the default property is a record and has a default property, return the default property
9
+ // This is for CJS modules
10
+ if (isRecord(mod.default) && 'default' in mod.default) {
11
+ return mod.default.default;
12
+ }
13
+ return mod.default;
14
+ }
15
+ return null;
16
+ }
17
+
18
+ //# sourceMappingURL=tryGetDefaultExport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/util/tryGetDefaultExport.ts"],"sourcesContent":["import {isRecord} from './isRecord.js'\n\n/**\n * Try to get the default export of a module of the cli config.\n * This can be either ESM or CJS.\n */\nexport function tryGetDefaultExport(mod: unknown) {\n // If the module is a record and has a default property, return the default property\n if (isRecord(mod) && 'default' in mod) {\n // If the default property is a record and has a default property, return the default property\n // This is for CJS modules\n if (isRecord(mod.default) && 'default' in mod.default) {\n return mod.default.default\n }\n\n return mod.default\n }\n\n return null\n}\n"],"names":["isRecord","tryGetDefaultExport","mod","default"],"mappings":"AAAA,SAAQA,QAAQ,QAAO,gBAAe;AAEtC;;;CAGC,GACD,OAAO,SAASC,oBAAoBC,GAAY;IAC9C,oFAAoF;IACpF,IAAIF,SAASE,QAAQ,aAAaA,KAAK;QACrC,8FAA8F;QAC9F,0BAA0B;QAC1B,IAAIF,SAASE,IAAIC,OAAO,KAAK,aAAaD,IAAIC,OAAO,EAAE;YACrD,OAAOD,IAAIC,OAAO,CAACA,OAAO;QAC5B;QAEA,OAAOD,IAAIC,OAAO;IACpB;IAEA,OAAO;AACT"}
@@ -0,0 +1,19 @@
1
+ import { writeFileSync } from 'node:fs';
2
+ /**
3
+ * Serialize the given `data` as JSON and write it synchronously to the given path.
4
+ *
5
+ * @param filePath - Path to JSON file to write
6
+ * @internal
7
+ */ export function writeJsonFileSync(filePath, data, options = {}) {
8
+ const { pretty = false } = options;
9
+ try {
10
+ const stringified = pretty ? JSON.stringify(data, null, 2) : JSON.stringify(data);
11
+ writeFileSync(filePath, `${stringified}\n`, 'utf8');
12
+ } catch (err) {
13
+ throw new Error(`Failed to write "${filePath}"`, {
14
+ cause: err
15
+ });
16
+ }
17
+ }
18
+
19
+ //# sourceMappingURL=writeJsonFileSync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/util/writeJsonFileSync.ts"],"sourcesContent":["import {writeFileSync} from 'node:fs'\n\n/**\n * Serialize the given `data` as JSON and write it synchronously to the given path.\n *\n * @param filePath - Path to JSON file to write\n * @internal\n */\nexport function writeJsonFileSync(\n filePath: string,\n data: unknown,\n options: {pretty?: boolean} = {},\n): void {\n const {pretty = false} = options\n try {\n const stringified = pretty ? JSON.stringify(data, null, 2) : JSON.stringify(data)\n writeFileSync(filePath, `${stringified}\\n`, 'utf8')\n } catch (err: unknown) {\n throw new Error(`Failed to write \"${filePath}\"`, {cause: err})\n }\n}\n"],"names":["writeFileSync","writeJsonFileSync","filePath","data","options","pretty","stringified","JSON","stringify","err","Error","cause"],"mappings":"AAAA,SAAQA,aAAa,QAAO,UAAS;AAErC;;;;;CAKC,GACD,OAAO,SAASC,kBACdC,QAAgB,EAChBC,IAAa,EACbC,UAA8B,CAAC,CAAC;IAEhC,MAAM,EAACC,SAAS,KAAK,EAAC,GAAGD;IACzB,IAAI;QACF,MAAME,cAAcD,SAASE,KAAKC,SAAS,CAACL,MAAM,MAAM,KAAKI,KAAKC,SAAS,CAACL;QAC5EH,cAAcE,UAAU,GAAGI,YAAY,EAAE,CAAC,EAAE;IAC9C,EAAE,OAAOG,KAAc;QACrB,MAAM,IAAIC,MAAM,CAAC,iBAAiB,EAAER,SAAS,CAAC,CAAC,EAAE;YAACS,OAAOF;QAAG;IAC9D;AACF"}
@@ -0,0 +1,3 @@
1
+ export { default as boxen } from 'boxen';
2
+
3
+ //# sourceMappingURL=boxen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/ux/boxen.ts"],"sourcesContent":["export {\n default as boxen,\n type Options as BoxenOptions,\n type Boxes,\n type CustomBorderStyle,\n type Spacing,\n} from 'boxen'\n"],"names":["default","boxen"],"mappings":"AAAA,SACEA,WAAWC,KAAK,QAKX,QAAO"}
@@ -0,0 +1,32 @@
1
+ import { styleText } from 'node:util';
2
+ import tokenize from 'json-lexer';
3
+ /**
4
+ * Colorize JSON output for better readability using simple regex patterns
5
+ */ const identity = (inp)=>inp;
6
+ export function colorizeJson(input) {
7
+ const formatters = {
8
+ key: (s)=>styleText('white', s),
9
+ literal: (s)=>styleText('bold', s),
10
+ number: (s)=>styleText('yellow', s),
11
+ punctuator: (s)=>styleText('white', s),
12
+ string: (s)=>styleText('green', s),
13
+ whitespace: identity
14
+ };
15
+ const json = JSON.stringify(input, null, 2);
16
+ return tokenize(json).map((token, i, arr)=>{
17
+ // Note how the following only works because we pretty-print the JSON
18
+ const prevToken = i === 0 ? token : arr[i - 1];
19
+ if (token.type === 'string' && prevToken.type === 'whitespace' && /^\n\s+$/.test(prevToken.value)) {
20
+ return {
21
+ ...token,
22
+ type: 'key'
23
+ };
24
+ }
25
+ return token;
26
+ }).map((token)=>{
27
+ const formatter = formatters[token.type] || identity;
28
+ return formatter(token.raw);
29
+ }).join('');
30
+ }
31
+
32
+ //# sourceMappingURL=colorizeJson.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/ux/colorizeJson.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport tokenize, {type LexerToken} from 'json-lexer'\n\ninterface KeyToken {\n raw: string\n type: 'key'\n value: string\n}\n\ntype ExtendedLexerToken = KeyToken | LexerToken\n\n/**\n * Colorize JSON output for better readability using simple regex patterns\n */\nconst identity = (inp: string): string => inp\n\nexport function colorizeJson(input: unknown): string {\n const formatters: Record<ExtendedLexerToken['type'], (str: string) => string> = {\n key: (s) => styleText('white', s),\n literal: (s) => styleText('bold', s),\n number: (s) => styleText('yellow', s),\n punctuator: (s) => styleText('white', s),\n string: (s) => styleText('green', s),\n whitespace: identity,\n }\n\n const json = JSON.stringify(input, null, 2)\n\n return tokenize(json)\n .map((token, i, arr): ExtendedLexerToken => {\n // Note how the following only works because we pretty-print the JSON\n const prevToken = i === 0 ? token : arr[i - 1]\n if (\n token.type === 'string' &&\n prevToken.type === 'whitespace' &&\n /^\\n\\s+$/.test(prevToken.value)\n ) {\n return {...token, type: 'key'}\n }\n\n return token\n })\n .map((token) => {\n const formatter = formatters[token.type] || identity\n return formatter(token.raw)\n })\n .join('')\n}\n"],"names":["styleText","tokenize","identity","inp","colorizeJson","input","formatters","key","s","literal","number","punctuator","string","whitespace","json","JSON","stringify","map","token","i","arr","prevToken","type","test","value","formatter","raw","join"],"mappings":"AAAA,SAAQA,SAAS,QAAO,YAAW;AAEnC,OAAOC,cAAiC,aAAY;AAUpD;;CAEC,GACD,MAAMC,WAAW,CAACC,MAAwBA;AAE1C,OAAO,SAASC,aAAaC,KAAc;IACzC,MAAMC,aAA0E;QAC9EC,KAAK,CAACC,IAAMR,UAAU,SAASQ;QAC/BC,SAAS,CAACD,IAAMR,UAAU,QAAQQ;QAClCE,QAAQ,CAACF,IAAMR,UAAU,UAAUQ;QACnCG,YAAY,CAACH,IAAMR,UAAU,SAASQ;QACtCI,QAAQ,CAACJ,IAAMR,UAAU,SAASQ;QAClCK,YAAYX;IACd;IAEA,MAAMY,OAAOC,KAAKC,SAAS,CAACX,OAAO,MAAM;IAEzC,OAAOJ,SAASa,MACbG,GAAG,CAAC,CAACC,OAAOC,GAAGC;QACd,qEAAqE;QACrE,MAAMC,YAAYF,MAAM,IAAID,QAAQE,GAAG,CAACD,IAAI,EAAE;QAC9C,IACED,MAAMI,IAAI,KAAK,YACfD,UAAUC,IAAI,KAAK,gBACnB,UAAUC,IAAI,CAACF,UAAUG,KAAK,GAC9B;YACA,OAAO;gBAAC,GAAGN,KAAK;gBAAEI,MAAM;YAAK;QAC/B;QAEA,OAAOJ;IACT,GACCD,GAAG,CAAC,CAACC;QACJ,MAAMO,YAAYnB,UAAU,CAACY,MAAMI,IAAI,CAAC,IAAIpB;QAC5C,OAAOuB,UAAUP,MAAMQ,GAAG;IAC5B,GACCC,IAAI,CAAC;AACV"}
@@ -0,0 +1,3 @@
1
+ export { default as logSymbols } from 'log-symbols';
2
+
3
+ //# sourceMappingURL=logSymbols.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/ux/logSymbols.ts"],"sourcesContent":["export {default as logSymbols} from 'log-symbols'\n"],"names":["default","logSymbols"],"mappings":"AAAA,SAAQA,WAAWC,UAAU,QAAO,cAAa"}
@@ -0,0 +1,51 @@
1
+ import * as inquirer from '@inquirer/prompts';
2
+ import { NonInteractiveError } from '../errors/NonInteractiveError.js';
3
+ import { isInteractive } from '../util/isInteractive.js';
4
+ export { Separator } from '@inquirer/prompts';
5
+ function assertInteractive(promptName) {
6
+ if (!isInteractive()) {
7
+ throw new NonInteractiveError(promptName);
8
+ }
9
+ }
10
+ export const checkbox = (...args)=>{
11
+ assertInteractive('checkbox');
12
+ return inquirer.checkbox(...args);
13
+ };
14
+ export const confirm = (...args)=>{
15
+ assertInteractive('confirm');
16
+ return inquirer.confirm(...args);
17
+ };
18
+ export const editor = (...args)=>{
19
+ assertInteractive('editor');
20
+ return inquirer.editor(...args);
21
+ };
22
+ export const expand = (...args)=>{
23
+ assertInteractive('expand');
24
+ return inquirer.expand(...args);
25
+ };
26
+ export const input = (...args)=>{
27
+ assertInteractive('input');
28
+ return inquirer.input(...args);
29
+ };
30
+ export const number = (...args)=>{
31
+ assertInteractive('number');
32
+ return inquirer.number(...args);
33
+ };
34
+ export const password = (...args)=>{
35
+ assertInteractive('password');
36
+ return inquirer.password(...args);
37
+ };
38
+ export const rawlist = (...args)=>{
39
+ assertInteractive('rawlist');
40
+ return inquirer.rawlist(...args);
41
+ };
42
+ export const search = (...args)=>{
43
+ assertInteractive('search');
44
+ return inquirer.search(...args);
45
+ };
46
+ export const select = (...args)=>{
47
+ assertInteractive('select');
48
+ return inquirer.select(...args);
49
+ };
50
+
51
+ //# sourceMappingURL=prompts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/ux/prompts.ts"],"sourcesContent":["import * as inquirer from '@inquirer/prompts'\n\nimport {NonInteractiveError} from '../errors/NonInteractiveError.js'\nimport {isInteractive} from '../util/isInteractive.js'\n\nexport {Separator} from '@inquirer/prompts'\n\nfunction assertInteractive(promptName: string): void {\n if (!isInteractive()) {\n throw new NonInteractiveError(promptName)\n }\n}\n\nexport const checkbox: typeof inquirer.checkbox = (...args) => {\n assertInteractive('checkbox')\n return inquirer.checkbox(...args)\n}\n\nexport const confirm: typeof inquirer.confirm = (...args) => {\n assertInteractive('confirm')\n return inquirer.confirm(...args)\n}\n\nexport const editor: typeof inquirer.editor = (...args) => {\n assertInteractive('editor')\n return inquirer.editor(...args)\n}\n\nexport const expand: typeof inquirer.expand = (...args) => {\n assertInteractive('expand')\n return inquirer.expand(...args)\n}\n\nexport const input: typeof inquirer.input = (...args) => {\n assertInteractive('input')\n return inquirer.input(...args)\n}\n\nexport const number: typeof inquirer.number = (...args) => {\n assertInteractive('number')\n return inquirer.number(...args)\n}\n\nexport const password: typeof inquirer.password = (...args) => {\n assertInteractive('password')\n return inquirer.password(...args)\n}\n\nexport const rawlist: typeof inquirer.rawlist = (...args) => {\n assertInteractive('rawlist')\n return inquirer.rawlist(...args)\n}\n\nexport const search: typeof inquirer.search = (...args) => {\n assertInteractive('search')\n return inquirer.search(...args)\n}\n\nexport const select: typeof inquirer.select = (...args) => {\n assertInteractive('select')\n return inquirer.select(...args)\n}\n"],"names":["inquirer","NonInteractiveError","isInteractive","Separator","assertInteractive","promptName","checkbox","args","confirm","editor","expand","input","number","password","rawlist","search","select"],"mappings":"AAAA,YAAYA,cAAc,oBAAmB;AAE7C,SAAQC,mBAAmB,QAAO,mCAAkC;AACpE,SAAQC,aAAa,QAAO,2BAA0B;AAEtD,SAAQC,SAAS,QAAO,oBAAmB;AAE3C,SAASC,kBAAkBC,UAAkB;IAC3C,IAAI,CAACH,iBAAiB;QACpB,MAAM,IAAID,oBAAoBI;IAChC;AACF;AAEA,OAAO,MAAMC,WAAqC,CAAC,GAAGC;IACpDH,kBAAkB;IAClB,OAAOJ,SAASM,QAAQ,IAAIC;AAC9B,EAAC;AAED,OAAO,MAAMC,UAAmC,CAAC,GAAGD;IAClDH,kBAAkB;IAClB,OAAOJ,SAASQ,OAAO,IAAID;AAC7B,EAAC;AAED,OAAO,MAAME,SAAiC,CAAC,GAAGF;IAChDH,kBAAkB;IAClB,OAAOJ,SAASS,MAAM,IAAIF;AAC5B,EAAC;AAED,OAAO,MAAMG,SAAiC,CAAC,GAAGH;IAChDH,kBAAkB;IAClB,OAAOJ,SAASU,MAAM,IAAIH;AAC5B,EAAC;AAED,OAAO,MAAMI,QAA+B,CAAC,GAAGJ;IAC9CH,kBAAkB;IAClB,OAAOJ,SAASW,KAAK,IAAIJ;AAC3B,EAAC;AAED,OAAO,MAAMK,SAAiC,CAAC,GAAGL;IAChDH,kBAAkB;IAClB,OAAOJ,SAASY,MAAM,IAAIL;AAC5B,EAAC;AAED,OAAO,MAAMM,WAAqC,CAAC,GAAGN;IACpDH,kBAAkB;IAClB,OAAOJ,SAASa,QAAQ,IAAIN;AAC9B,EAAC;AAED,OAAO,MAAMO,UAAmC,CAAC,GAAGP;IAClDH,kBAAkB;IAClB,OAAOJ,SAASc,OAAO,IAAIP;AAC7B,EAAC;AAED,OAAO,MAAMQ,SAAiC,CAAC,GAAGR;IAChDH,kBAAkB;IAClB,OAAOJ,SAASe,MAAM,IAAIR;AAC5B,EAAC;AAED,OAAO,MAAMS,SAAiC,CAAC,GAAGT;IAChDH,kBAAkB;IAClB,OAAOJ,SAASgB,MAAM,IAAIT;AAC5B,EAAC"}
@@ -0,0 +1,3 @@
1
+ export { default as spinner, oraPromise as spinnerPromise } from 'ora';
2
+
3
+ //# sourceMappingURL=spinner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/ux/spinner.ts"],"sourcesContent":["export {\n default as spinner,\n type Spinner,\n type Ora as SpinnerInstance,\n type Options as SpinnerOptions,\n oraPromise as spinnerPromise,\n type PromiseOptions as SpinnerPromiseOptions,\n} from 'ora'\n"],"names":["default","spinner","oraPromise","spinnerPromise"],"mappings":"AAAA,SACEA,WAAWC,OAAO,EAIlBC,cAAcC,cAAc,QAEvB,MAAK"}
@@ -0,0 +1,29 @@
1
+ import { performance } from 'node:perf_hooks';
2
+ /**
3
+ * Starts a terminal timer
4
+ *
5
+ * @internal
6
+ */ export function getTimer() {
7
+ const timings = {};
8
+ const startTimes = {};
9
+ function start(name) {
10
+ if (startTimes[name] !== undefined) {
11
+ throw new TypeError(`Timer "${name}" already started, cannot overwrite`);
12
+ }
13
+ startTimes[name] = performance.now();
14
+ }
15
+ function end(name) {
16
+ if (startTimes[name] === undefined) {
17
+ throw new TypeError(`Timer "${name}" never started, cannot end`);
18
+ }
19
+ timings[name] = performance.now() - startTimes[name];
20
+ return timings[name];
21
+ }
22
+ return {
23
+ end,
24
+ getTimings: ()=>timings,
25
+ start
26
+ };
27
+ }
28
+
29
+ //# sourceMappingURL=timer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/ux/timer.ts"],"sourcesContent":["import {performance} from 'node:perf_hooks'\n\ninterface TimeMeasurer {\n end: (name: string) => number\n getTimings: () => Record<string, number>\n start: (name: string) => void\n}\n\n/**\n * Starts a terminal timer\n *\n * @internal\n */\nexport function getTimer(): TimeMeasurer {\n const timings: Record<string, number> = {}\n const startTimes: Record<string, number> = {}\n\n function start(name: string): void {\n if (startTimes[name] !== undefined) {\n throw new TypeError(`Timer \"${name}\" already started, cannot overwrite`)\n }\n\n startTimes[name] = performance.now()\n }\n\n function end(name: string): number {\n if (startTimes[name] === undefined) {\n throw new TypeError(`Timer \"${name}\" never started, cannot end`)\n }\n\n timings[name] = performance.now() - startTimes[name]\n return timings[name]\n }\n\n return {end, getTimings: () => timings, start}\n}\n"],"names":["performance","getTimer","timings","startTimes","start","name","undefined","TypeError","now","end","getTimings"],"mappings":"AAAA,SAAQA,WAAW,QAAO,kBAAiB;AAQ3C;;;;CAIC,GACD,OAAO,SAASC;IACd,MAAMC,UAAkC,CAAC;IACzC,MAAMC,aAAqC,CAAC;IAE5C,SAASC,MAAMC,IAAY;QACzB,IAAIF,UAAU,CAACE,KAAK,KAAKC,WAAW;YAClC,MAAM,IAAIC,UAAU,CAAC,OAAO,EAAEF,KAAK,mCAAmC,CAAC;QACzE;QAEAF,UAAU,CAACE,KAAK,GAAGL,YAAYQ,GAAG;IACpC;IAEA,SAASC,IAAIJ,IAAY;QACvB,IAAIF,UAAU,CAACE,KAAK,KAAKC,WAAW;YAClC,MAAM,IAAIC,UAAU,CAAC,OAAO,EAAEF,KAAK,2BAA2B,CAAC;QACjE;QAEAH,OAAO,CAACG,KAAK,GAAGL,YAAYQ,GAAG,KAAKL,UAAU,CAACE,KAAK;QACpD,OAAOH,OAAO,CAACG,KAAK;IACtB;IAEA,OAAO;QAACI;QAAKC,YAAY,IAAMR;QAASE;IAAK;AAC/C"}