@sanity/cli-core 0.0.2-alpha.2 → 0.1.0-alpha.10

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 (160) hide show
  1. package/dist/SanityCommand.js +34 -3
  2. package/dist/SanityCommand.js.map +1 -1
  3. package/dist/_exports/tree.d.ts +47 -0
  4. package/dist/_exports/tree.js +3 -0
  5. package/dist/_exports/tree.js.map +1 -0
  6. package/dist/_exports/ux.d.ts +40 -0
  7. package/dist/_exports/ux.js +6 -0
  8. package/dist/_exports/ux.js.map +1 -0
  9. package/dist/config/cli/getCliConfig.worker.js +2 -1
  10. package/dist/config/cli/getCliConfig.worker.js.map +1 -1
  11. package/dist/config/cli/schemas.js +5 -2
  12. package/dist/config/cli/schemas.js.map +1 -1
  13. package/dist/config/cli/types/cliConfig.js.map +1 -1
  14. package/dist/config/findProjectRoot.js +2 -2
  15. package/dist/config/findProjectRoot.js.map +1 -1
  16. package/dist/config/studio/getStudioConfig.js +0 -3
  17. package/dist/config/studio/getStudioConfig.js.map +1 -1
  18. package/dist/config/studio/getStudioWorkspaces.js +50 -0
  19. package/dist/config/studio/getStudioWorkspaces.js.map +1 -0
  20. package/dist/config/studio/isStudioConfig.js +19 -0
  21. package/dist/config/studio/isStudioConfig.js.map +1 -0
  22. package/dist/config/studio/readStudioConfig.js +13 -9
  23. package/dist/config/studio/readStudioConfig.js.map +1 -1
  24. package/dist/config/studio/readStudioConfig.worker.js +4 -30
  25. package/dist/config/studio/readStudioConfig.worker.js.map +1 -1
  26. package/dist/config/util/findStudioConfigPath.js +24 -3
  27. package/dist/config/util/findStudioConfigPath.js.map +1 -1
  28. package/dist/config/util/recursivelyResolveProjectRoot.js.map +1 -1
  29. package/dist/index.d.ts +6027 -36
  30. package/dist/index.js +14 -3
  31. package/dist/index.js.map +1 -1
  32. package/dist/loaders/studio/studioWorkerLoader.worker.js +10 -24
  33. package/dist/loaders/studio/studioWorkerLoader.worker.js.map +1 -1
  34. package/dist/loaders/studio/studioWorkerTask.js +41 -11
  35. package/dist/loaders/studio/studioWorkerTask.js.map +1 -1
  36. package/dist/loaders/tsx/tsxWorkerTask.js +3 -0
  37. package/dist/loaders/tsx/tsxWorkerTask.js.map +1 -1
  38. package/dist/services/apiClient.js +18 -17
  39. package/dist/services/apiClient.js.map +1 -1
  40. package/dist/telemetry/cleanupOldTelemetryFiles.js +30 -0
  41. package/dist/telemetry/cleanupOldTelemetryFiles.js.map +1 -0
  42. package/dist/telemetry/createTelemetryStore.js +95 -0
  43. package/dist/telemetry/createTelemetryStore.js.map +1 -0
  44. package/dist/telemetry/createTraceId.js +10 -0
  45. package/dist/telemetry/createTraceId.js.map +1 -0
  46. package/dist/telemetry/findTelemetryFiles.js +36 -0
  47. package/dist/telemetry/findTelemetryFiles.js.map +1 -0
  48. package/dist/telemetry/flushTelemetryFiles.js +107 -0
  49. package/dist/telemetry/flushTelemetryFiles.js.map +1 -0
  50. package/dist/telemetry/generateTelemetryFilePath.js +30 -0
  51. package/dist/telemetry/generateTelemetryFilePath.js.map +1 -0
  52. package/dist/telemetry/getTelemetryBaseInfo.js +33 -0
  53. package/dist/telemetry/getTelemetryBaseInfo.js.map +1 -0
  54. package/dist/telemetry/logger.js +54 -0
  55. package/dist/telemetry/logger.js.map +1 -0
  56. package/dist/telemetry/telemetryStoreDebug.js +7 -0
  57. package/dist/telemetry/telemetryStoreDebug.js.map +1 -0
  58. package/dist/telemetry/trace.js +150 -0
  59. package/dist/telemetry/trace.js.map +1 -0
  60. package/dist/telemetry/types.js +5 -0
  61. package/dist/telemetry/types.js.map +1 -0
  62. package/dist/types.js +2 -0
  63. package/dist/types.js.map +1 -1
  64. package/dist/util/doImport.js +16 -0
  65. package/dist/util/doImport.js.map +1 -0
  66. package/dist/util/environment/getStudioEnvironmentVariables.js +2 -1
  67. package/dist/util/environment/getStudioEnvironmentVariables.js.map +1 -1
  68. package/dist/util/getCliTelemetry.js +36 -0
  69. package/dist/util/getCliTelemetry.js.map +1 -0
  70. package/dist/util/isStaging.js +10 -0
  71. package/dist/util/isStaging.js.map +1 -0
  72. package/dist/util/normalizePath.js +12 -0
  73. package/dist/util/normalizePath.js.map +1 -0
  74. package/dist/util/parseStringFlag.js +19 -0
  75. package/dist/util/parseStringFlag.js.map +1 -0
  76. package/dist/util/readNDJSON.js +18 -0
  77. package/dist/util/readNDJSON.js.map +1 -0
  78. package/dist/util/resolveLocalPackage.js +34 -0
  79. package/dist/util/resolveLocalPackage.js.map +1 -0
  80. package/dist/util/tree.js +108 -0
  81. package/dist/util/tree.js.map +1 -0
  82. package/dist/util/waitForAsync.js +5 -0
  83. package/dist/util/waitForAsync.js.map +1 -0
  84. package/dist/ux/boxen.js +3 -0
  85. package/dist/ux/boxen.js.map +1 -0
  86. package/dist/ux/colorizeJson.js +6 -6
  87. package/dist/ux/colorizeJson.js.map +1 -1
  88. package/dist/ux/prompts.js +3 -0
  89. package/dist/ux/prompts.js.map +1 -0
  90. package/dist/ux/spinner.js +1 -1
  91. package/dist/ux/spinner.js.map +1 -1
  92. package/package.json +53 -28
  93. package/dist/SanityCommand.d.ts +0 -56
  94. package/dist/config/__tests__/cliToken.test.js +0 -74
  95. package/dist/config/__tests__/cliToken.test.js.map +0 -1
  96. package/dist/config/__tests__/cliUserConfig.test.js +0 -131
  97. package/dist/config/__tests__/cliUserConfig.test.js.map +0 -1
  98. package/dist/config/__tests__/findProjectRoot.test.js +0 -159
  99. package/dist/config/__tests__/findProjectRoot.test.js.map +0 -1
  100. package/dist/config/__tests__/findProjectRootSync.test.js +0 -112
  101. package/dist/config/__tests__/findProjectRootSync.test.js.map +0 -1
  102. package/dist/config/__tests__/getCliConfigSync.test.js +0 -31
  103. package/dist/config/__tests__/getCliConfigSync.test.js.map +0 -1
  104. package/dist/config/cli/getCliConfig.d.ts +0 -16
  105. package/dist/config/cli/getCliConfig.worker.d.ts +0 -1
  106. package/dist/config/cli/getCliConfigSync.d.ts +0 -12
  107. package/dist/config/cli/schemas.d.ts +0 -255
  108. package/dist/config/cli/types/cliConfig.d.ts +0 -74
  109. package/dist/config/cli/types/userViteConfig.d.ts +0 -5
  110. package/dist/config/findProjectRoot.d.ts +0 -14
  111. package/dist/config/findProjectRootSync.d.ts +0 -27
  112. package/dist/config/studio/getStudioConfig.d.ts +0 -14
  113. package/dist/config/studio/readStudioConfig.d.ts +0 -190
  114. package/dist/config/studio/readStudioConfig.worker.d.ts +0 -1
  115. package/dist/config/util/configPathsSync.d.ts +0 -17
  116. package/dist/config/util/findAppConfigPath.d.ts +0 -8
  117. package/dist/config/util/findConfigsPaths.d.ts +0 -16
  118. package/dist/config/util/findStudioConfigPath.d.ts +0 -9
  119. package/dist/config/util/isSanityV2StudioRoot.d.ts +0 -8
  120. package/dist/config/util/recursivelyResolveProjectRoot.d.ts +0 -27
  121. package/dist/debug.d.ts +0 -15
  122. package/dist/loaders/studio/studioWorkerLoader.worker.d.ts +0 -1
  123. package/dist/loaders/studio/studioWorkerTask.d.ts +0 -40
  124. package/dist/loaders/tsx/tsxWorkerLoader.worker.d.ts +0 -1
  125. package/dist/loaders/tsx/tsxWorkerTask.d.ts +0 -28
  126. package/dist/services/apiClient.d.ts +0 -53
  127. package/dist/services/cliUserConfig.d.ts +0 -57
  128. package/dist/services/getCliToken.d.ts +0 -7
  129. package/dist/types.d.ts +0 -7
  130. package/dist/util/NotFoundError.d.ts +0 -20
  131. package/dist/util/__tests__/createExpiringConfig.test.js +0 -400
  132. package/dist/util/__tests__/createExpiringConfig.test.js.map +0 -1
  133. package/dist/util/createExpiringConfig.d.ts +0 -37
  134. package/dist/util/environment/getStudioEnvironmentVariables.d.ts +0 -12
  135. package/dist/util/environment/mockBrowserEnvironment.d.ts +0 -17
  136. package/dist/util/environment/setupBrowserStubs.d.ts +0 -10
  137. package/dist/util/environment/stubs.d.ts +0 -254
  138. package/dist/util/fileExists.d.ts +0 -9
  139. package/dist/util/generateHelpUrl.d.ts +0 -8
  140. package/dist/util/getEmptyAuth.d.ts +0 -5
  141. package/dist/util/getSanityEnvVar.d.ts +0 -19
  142. package/dist/util/getSanityUrl.d.ts +0 -5
  143. package/dist/util/getUserConfig.d.ts +0 -2
  144. package/dist/util/isCi.d.ts +0 -1
  145. package/dist/util/isHttpError.d.ts +0 -29
  146. package/dist/util/isHttpError.js +0 -18
  147. package/dist/util/isHttpError.js.map +0 -1
  148. package/dist/util/isInteractive.d.ts +0 -1
  149. package/dist/util/isRecord.d.ts +0 -8
  150. package/dist/util/isTrueish.d.ts +0 -1
  151. package/dist/util/readJsonFile.d.ts +0 -14
  152. package/dist/util/safeStructuredClone.d.ts +0 -8
  153. package/dist/util/tryGetDefaultExport.d.ts +0 -5
  154. package/dist/util/writeJsonFile.d.ts +0 -9
  155. package/dist/ux/colorizeJson.d.ts +0 -1
  156. package/dist/ux/formatObject.d.ts +0 -1
  157. package/dist/ux/logSymbols.d.ts +0 -1
  158. package/dist/ux/printKeyValue.d.ts +0 -1
  159. package/dist/ux/spinner.d.ts +0 -1
  160. package/dist/ux/timer.d.ts +0 -12
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Checks if the environment is staging.
3
+ *
4
+ * @returns True if the environment is staging, false otherwise
5
+ * @internal
6
+ */ export function isStaging() {
7
+ return process.env.SANITY_INTERNAL_ENV === 'staging';
8
+ }
9
+
10
+ //# sourceMappingURL=isStaging.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/util/isStaging.ts"],"sourcesContent":["/**\n * Checks if the environment is staging.\n *\n * @returns True if the environment is staging, false otherwise\n * @internal\n */\nexport function isStaging(): boolean {\n return process.env.SANITY_INTERNAL_ENV === 'staging'\n}\n"],"names":["isStaging","process","env","SANITY_INTERNAL_ENV"],"mappings":"AAAA;;;;;CAKC,GACD,OAAO,SAASA;IACd,OAAOC,QAAQC,GAAG,CAACC,mBAAmB,KAAK;AAC7C"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Normalizes a path for cross-platform comparison by converting backslashes to forward slashes.
3
+ * Useful for converting windows paths to unix paths.
4
+ *
5
+ * @param path - Path to normalize
6
+ * @returns Normalized path with forward slashes
7
+ * @public
8
+ */ export function normalizePath(path) {
9
+ return path.replaceAll('\\', '/');
10
+ }
11
+
12
+ //# sourceMappingURL=normalizePath.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/util/normalizePath.ts"],"sourcesContent":["/**\n * Normalizes a path for cross-platform comparison by converting backslashes to forward slashes.\n * Useful for converting windows paths to unix paths.\n *\n * @param path - Path to normalize\n * @returns Normalized path with forward slashes\n * @public\n */\nexport function normalizePath(path: string): string {\n return path.replaceAll('\\\\', '/')\n}\n"],"names":["normalizePath","path","replaceAll"],"mappings":"AAAA;;;;;;;CAOC,GACD,OAAO,SAASA,cAAcC,IAAY;IACxC,OAAOA,KAAKC,UAAU,CAAC,MAAM;AAC/B"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Parses an optional string flag from oclif.
3
+ * If the input is undefined, return undefined
4
+ * but if the input is empty, throw an error.
5
+ *
6
+ *
7
+ * @param input - The input to parse
8
+ * Throws an error if the input is empty
9
+ */ export async function parseStringFlag(flagName, input) {
10
+ if (input === undefined) {
11
+ return input;
12
+ }
13
+ if (!input) {
14
+ throw new Error(`${flagName} argument is empty`);
15
+ }
16
+ return input;
17
+ }
18
+
19
+ //# sourceMappingURL=parseStringFlag.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/util/parseStringFlag.ts"],"sourcesContent":["/**\n * Parses an optional string flag from oclif.\n * If the input is undefined, return undefined\n * but if the input is empty, throw an error.\n *\n *\n * @param input - The input to parse\n * Throws an error if the input is empty\n */\nexport async function parseStringFlag(flagName: string, input?: string) {\n if (input === undefined) {\n return input\n }\n\n if (!input) {\n throw new Error(`${flagName} argument is empty`)\n }\n\n return input\n}\n"],"names":["parseStringFlag","flagName","input","undefined","Error"],"mappings":"AAAA;;;;;;;;CAQC,GACD,OAAO,eAAeA,gBAAgBC,QAAgB,EAAEC,KAAc;IACpE,IAAIA,UAAUC,WAAW;QACvB,OAAOD;IACT;IAEA,IAAI,CAACA,OAAO;QACV,MAAM,IAAIE,MAAM,GAAGH,SAAS,kBAAkB,CAAC;IACjD;IAEA,OAAOC;AACT"}
@@ -0,0 +1,18 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ /**
3
+ * Reads and parses an NDJSON (newline-delimited JSON) file containing telemetry events.
4
+ *
5
+ * @param filePath - Path to the NDJSON file
6
+ * @returns Promise resolving to array of parsed telemetry events
7
+ * @throws Error if file cannot be read or contains invalid JSON
8
+ *
9
+ * @internal
10
+ */ export async function readNDJSON(filePath) {
11
+ const content = await readFile(filePath, 'utf8');
12
+ if (!content.trim()) {
13
+ return [];
14
+ }
15
+ return content.trim().split('\n').filter(Boolean).map((line)=>JSON.parse(line));
16
+ }
17
+
18
+ //# sourceMappingURL=readNDJSON.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/util/readNDJSON.ts"],"sourcesContent":["import {readFile} from 'node:fs/promises'\n\n/**\n * Reads and parses an NDJSON (newline-delimited JSON) file containing telemetry events.\n *\n * @param filePath - Path to the NDJSON file\n * @returns Promise resolving to array of parsed telemetry events\n * @throws Error if file cannot be read or contains invalid JSON\n *\n * @internal\n */\nexport async function readNDJSON<T>(filePath: string): Promise<T[]> {\n const content = await readFile(filePath, 'utf8')\n\n if (!content.trim()) {\n return []\n }\n\n return content\n .trim()\n .split('\\n')\n .filter(Boolean)\n .map((line) => JSON.parse(line) as T)\n}\n"],"names":["readFile","readNDJSON","filePath","content","trim","split","filter","Boolean","map","line","JSON","parse"],"mappings":"AAAA,SAAQA,QAAQ,QAAO,mBAAkB;AAEzC;;;;;;;;CAQC,GACD,OAAO,eAAeC,WAAcC,QAAgB;IAClD,MAAMC,UAAU,MAAMH,SAASE,UAAU;IAEzC,IAAI,CAACC,QAAQC,IAAI,IAAI;QACnB,OAAO,EAAE;IACX;IAEA,OAAOD,QACJC,IAAI,GACJC,KAAK,CAAC,MACNC,MAAM,CAACC,SACPC,GAAG,CAAC,CAACC,OAASC,KAAKC,KAAK,CAACF;AAC9B"}
@@ -0,0 +1,34 @@
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
+ // Create a fake cli config URL - doesn't have to be correct, just need the root path
23
+ // This ensures we resolve packages relative to the user's repo, not the CLI package
24
+ const fakeCliConfigUrl = pathToFileURL(resolve(workDir, 'sanity.cli.mjs'));
25
+ try {
26
+ const packageUrl = moduleResolve(packageName, fakeCliConfigUrl);
27
+ const module = await doImport(packageUrl.href);
28
+ return module;
29
+ } catch (error) {
30
+ throw new Error(`Failed to resolve package "${packageName}" from "${workDir}": ${error instanceof Error ? error.message : String(error)}`);
31
+ }
32
+ }
33
+
34
+ //# 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 // Create a fake cli config URL - doesn't have to be correct, just need the root path\n // This ensures we resolve packages relative to the user's repo, not the CLI package\n const fakeCliConfigUrl = pathToFileURL(resolve(workDir, 'sanity.cli.mjs'))\n\n try {\n const packageUrl = moduleResolve(packageName, fakeCliConfigUrl)\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 \"${workDir}\": ${error instanceof Error ? error.message : String(error)}`,\n )\n }\n}\n"],"names":["resolve","pathToFileURL","moduleResolve","doImport","resolveLocalPackage","packageName","workDir","fakeCliConfigUrl","packageUrl","module","href","error","Error","message","String"],"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,qFAAqF;IACrF,oFAAoF;IACpF,MAAMC,mBAAmBN,cAAcD,QAAQM,SAAS;IAExD,IAAI;QACF,MAAME,aAAaN,cAAcG,aAAaE;QAC9C,MAAME,SAAS,MAAMN,SAASK,WAAWE,IAAI;QAC7C,OAAOD;IACT,EAAE,OAAOE,OAAO;QACd,MAAM,IAAIC,MACR,CAAC,2BAA2B,EAAEP,YAAY,QAAQ,EAAEC,QAAQ,GAAG,EAAEK,iBAAiBC,QAAQD,MAAME,OAAO,GAAGC,OAAOH,QAAQ;IAE7H;AACF"}
@@ -0,0 +1,108 @@
1
+ import { isIndexSegment, isIndexTuple, isKeySegment } from '@sanity/types';
2
+ // FIXME: de-dupe this
3
+ // copy/paste of `pathToString` from 'sanity' to prevent circular imports
4
+ function pathToString(path) {
5
+ if (!Array.isArray(path)) {
6
+ throw new TypeError('Path is not an array');
7
+ }
8
+ let target = '';
9
+ let i = 0;
10
+ for (const segment of path){
11
+ if (isIndexSegment(segment)) {
12
+ target = `${target}[${segment}]`;
13
+ } else if (isKeySegment(segment) && segment._key) {
14
+ target = `${target}[_key=="${segment._key}"]`;
15
+ } else if (isIndexTuple(segment)) {
16
+ const [from, to] = segment;
17
+ target = `${target}[${from}:${to}]`;
18
+ } else if (typeof segment === 'string') {
19
+ const separator = i === 0 ? '' : '.';
20
+ target = `${target}${separator}${segment}`;
21
+ } else {
22
+ throw new TypeError(`Unsupported path segment \`${JSON.stringify(segment)}\``);
23
+ }
24
+ i++;
25
+ }
26
+ return target;
27
+ }
28
+ /**
29
+ * Recursively calculates the max length of all the keys in the given validation
30
+ * tree respecting extra length due to indentation depth. Used to calculate the
31
+ * padding for the rest of the tree.
32
+ */ export const maxKeyLength = (children = {}, depth = 0)=>{
33
+ let max = 0;
34
+ for (const [key, child] of Object.entries(children)){
35
+ const currentMax = Math.max(key.length + depth * 2, maxKeyLength(child.children, depth + 1));
36
+ max = Math.max(max, currentMax);
37
+ }
38
+ return max;
39
+ };
40
+ /**
41
+ * Recursively formats a given tree into a printed user-friendly tree structure
42
+ */ export const formatTree = ({ getMessage, getNodes: getLeaves = ({ nodes })=>nodes, indent = '', node = {}, paddingLength })=>{
43
+ const entries = Object.entries(node);
44
+ return entries.map(([key, child], index)=>{
45
+ const isLast = index === entries.length - 1;
46
+ const nextIndent = `${indent}${isLast ? ' ' : '│ '}`;
47
+ const leaves = getLeaves(child);
48
+ const nested = formatTree({
49
+ getMessage,
50
+ getNodes: getLeaves,
51
+ indent: nextIndent,
52
+ node: child.children,
53
+ paddingLength
54
+ });
55
+ if (!leaves?.length) {
56
+ const current = `${indent}${isLast ? '└' : '├'}─ ${key}`;
57
+ return [
58
+ current,
59
+ nested
60
+ ].filter(Boolean).join('\n');
61
+ }
62
+ const [first, ...rest] = leaves;
63
+ const firstPadding = '.'.repeat(paddingLength - indent.length - key.length);
64
+ const elbow = isLast ? '└' : '├';
65
+ const subsequentPadding = ' '.repeat(paddingLength - indent.length + 2);
66
+ const firstMessage = `${indent}${elbow}─ ${key} ${firstPadding} ${getMessage(first)}`;
67
+ const subsequentMessages = rest.map((marker)=>`${nextIndent}${subsequentPadding} ${getMessage(marker)}`).join('\n');
68
+ const current = [
69
+ firstMessage,
70
+ subsequentMessages
71
+ ].filter(Boolean).join('\n');
72
+ return [
73
+ current,
74
+ nested
75
+ ].filter(Boolean).join('\n');
76
+ }).join('\n');
77
+ };
78
+ /**
79
+ * Converts a set of markers with paths into a tree of markers where the paths
80
+ * are embedded in the tree
81
+ */ export function convertToTree(nodes) {
82
+ const root = {};
83
+ // add the markers to the tree
84
+ function addNode(node, tree = root) {
85
+ // if we've traversed the whole path
86
+ if (node.path.length === 0) {
87
+ if (!tree.nodes) tree.nodes = []; // ensure markers is defined
88
+ // then add the marker to the front
89
+ tree.nodes.push(node);
90
+ return;
91
+ }
92
+ const [current, ...rest] = node.path;
93
+ const key = pathToString([
94
+ current
95
+ ]);
96
+ // ensure the current node has children and the next node
97
+ if (!tree.children) tree.children = {};
98
+ if (!(key in tree.children)) tree.children[key] = {};
99
+ addNode({
100
+ ...node,
101
+ path: rest
102
+ }, tree.children[key]);
103
+ }
104
+ for (const node of nodes)addNode(node);
105
+ return root;
106
+ }
107
+
108
+ //# sourceMappingURL=tree.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/util/tree.ts"],"sourcesContent":["import {isIndexSegment, isIndexTuple, isKeySegment, type Path} from '@sanity/types'\n\n// FIXME: de-dupe this\n// copy/paste of `pathToString` from 'sanity' to prevent circular imports\nfunction pathToString(path: Path): string {\n if (!Array.isArray(path)) {\n throw new TypeError('Path is not an array')\n }\n\n let target = ''\n let i = 0\n for (const segment of path) {\n if (isIndexSegment(segment)) {\n target = `${target}[${segment}]`\n } else if (isKeySegment(segment) && segment._key) {\n target = `${target}[_key==\"${segment._key}\"]`\n } else if (isIndexTuple(segment)) {\n const [from, to] = segment\n target = `${target}[${from}:${to}]`\n } else if (typeof segment === 'string') {\n const separator = i === 0 ? '' : '.'\n target = `${target}${separator}${segment}`\n } else {\n throw new TypeError(`Unsupported path segment \\`${JSON.stringify(segment)}\\``)\n }\n i++\n }\n return target\n}\n\ninterface BaseNode {\n path: Path\n}\n\nexport interface Tree<Node extends BaseNode> {\n children?: Record<string, Tree<Node>>\n nodes?: Node[]\n}\n\n/**\n * Recursively calculates the max length of all the keys in the given validation\n * tree respecting extra length due to indentation depth. Used to calculate the\n * padding for the rest of the tree.\n */\nexport const maxKeyLength = (children: Record<string, Tree<BaseNode>> = {}, depth = 0): number => {\n let max = 0\n for (const [key, child] of Object.entries(children)) {\n const currentMax = Math.max(key.length + depth * 2, maxKeyLength(child.children, depth + 1))\n max = Math.max(max, currentMax)\n }\n return max\n}\n\ninterface Options<Node extends BaseNode> {\n getMessage: (node: Node) => string\n paddingLength: number\n\n getNodes?: (node: Tree<Node>) => Node[] | undefined\n indent?: string\n node?: Record<string, Tree<Node>>\n}\n\n/**\n * Recursively formats a given tree into a printed user-friendly tree structure\n */\nexport const formatTree = <Node extends BaseNode>({\n getMessage,\n getNodes: getLeaves = ({nodes}) => nodes,\n indent = '',\n node = {},\n paddingLength,\n}: Options<Node>): string => {\n const entries = Object.entries(node)\n\n return entries\n .map(([key, child], index) => {\n const isLast = index === entries.length - 1\n const nextIndent = `${indent}${isLast ? ' ' : '│ '}`\n const leaves = getLeaves(child)\n\n const nested = formatTree({\n getMessage,\n getNodes: getLeaves,\n indent: nextIndent,\n node: child.children,\n paddingLength,\n })\n\n if (!leaves?.length) {\n const current = `${indent}${isLast ? '└' : '├'}─ ${key}`\n return [current, nested].filter(Boolean).join('\\n')\n }\n\n const [first, ...rest] = leaves\n const firstPadding = '.'.repeat(paddingLength - indent.length - key.length)\n const elbow = isLast ? '└' : '├'\n const subsequentPadding = ' '.repeat(paddingLength - indent.length + 2)\n\n const firstMessage = `${indent}${elbow}─ ${key} ${firstPadding} ${getMessage(first)}`\n const subsequentMessages = rest\n .map((marker) => `${nextIndent}${subsequentPadding} ${getMessage(marker)}`)\n .join('\\n')\n\n const current = [firstMessage, subsequentMessages].filter(Boolean).join('\\n')\n return [current, nested].filter(Boolean).join('\\n')\n })\n .join('\\n')\n}\n\n/**\n * Converts a set of markers with paths into a tree of markers where the paths\n * are embedded in the tree\n */\nexport function convertToTree<const Node extends BaseNode>(nodes: Node[]): Tree<Node> {\n const root: Tree<Node> = {}\n\n // add the markers to the tree\n function addNode(node: Node, tree: Tree<Node> = root) {\n // if we've traversed the whole path\n if (node.path.length === 0) {\n if (!tree.nodes) tree.nodes = [] // ensure markers is defined\n\n // then add the marker to the front\n tree.nodes.push(node)\n return\n }\n\n const [current, ...rest] = node.path\n const key = pathToString([current])\n\n // ensure the current node has children and the next node\n if (!tree.children) tree.children = {}\n if (!(key in tree.children)) tree.children[key] = {}\n\n addNode({...node, path: rest}, tree.children[key])\n }\n\n for (const node of nodes) addNode(node)\n return root\n}\n"],"names":["isIndexSegment","isIndexTuple","isKeySegment","pathToString","path","Array","isArray","TypeError","target","i","segment","_key","from","to","separator","JSON","stringify","maxKeyLength","children","depth","max","key","child","Object","entries","currentMax","Math","length","formatTree","getMessage","getNodes","getLeaves","nodes","indent","node","paddingLength","map","index","isLast","nextIndent","leaves","nested","current","filter","Boolean","join","first","rest","firstPadding","repeat","elbow","subsequentPadding","firstMessage","subsequentMessages","marker","convertToTree","root","addNode","tree","push"],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export const waitForAsync = (ms = 0)=>{
2
+ return new Promise((resolve)=>setTimeout(resolve, ms));
3
+ };
4
+
5
+ //# sourceMappingURL=waitForAsync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/util/waitForAsync.ts"],"sourcesContent":["export const waitForAsync = (ms = 0): Promise<void> => {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n"],"names":["waitForAsync","ms","Promise","resolve","setTimeout"],"mappings":"AAAA,OAAO,MAAMA,eAAe,CAACC,KAAK,CAAC;IACjC,OAAO,IAAIC,QAAQ,CAACC,UAAYC,WAAWD,SAASF;AACtD,EAAC"}
@@ -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"}
@@ -1,15 +1,15 @@
1
- import chalk from 'chalk';
1
+ import { styleText } from 'node:util';
2
2
  import tokenize from 'json-lexer';
3
3
  /**
4
4
  * Colorize JSON output for better readability using simple regex patterns
5
5
  */ const identity = (inp)=>inp;
6
6
  export function colorizeJson(input) {
7
7
  const formatters = {
8
- key: chalk.white,
9
- literal: chalk.bold,
10
- number: chalk.yellow,
11
- punctuator: chalk.white,
12
- string: chalk.green,
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
13
  whitespace: identity
14
14
  };
15
15
  const json = JSON.stringify(input, null, 2);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/ux/colorizeJson.ts"],"sourcesContent":["import chalk from 'chalk'\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: chalk.white,\n literal: chalk.bold,\n number: chalk.yellow,\n punctuator: chalk.white,\n string: chalk.green,\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":["chalk","tokenize","identity","inp","colorizeJson","input","formatters","key","white","literal","bold","number","yellow","punctuator","string","green","whitespace","json","JSON","stringify","map","token","i","arr","prevToken","type","test","value","formatter","raw","join"],"mappings":"AAAA,OAAOA,WAAW,QAAO;AACzB,OAAOC,cAAiC,aAAY;AAUpD;;CAEC,GACD,MAAMC,WAAW,CAACC,MAAwBA;AAE1C,OAAO,SAASC,aAAaC,KAAc;IACzC,MAAMC,aAA0E;QAC9EC,KAAKP,MAAMQ,KAAK;QAChBC,SAAST,MAAMU,IAAI;QACnBC,QAAQX,MAAMY,MAAM;QACpBC,YAAYb,MAAMQ,KAAK;QACvBM,QAAQd,MAAMe,KAAK;QACnBC,YAAYd;IACd;IAEA,MAAMe,OAAOC,KAAKC,SAAS,CAACd,OAAO,MAAM;IAEzC,OAAOJ,SAASgB,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,YAAYtB,UAAU,CAACe,MAAMI,IAAI,CAAC,IAAIvB;QAC5C,OAAO0B,UAAUP,MAAMQ,GAAG;IAC5B,GACCC,IAAI,CAAC;AACV"}
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 * from '@inquirer/prompts';
2
+
3
+ //# sourceMappingURL=prompts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/ux/prompts.ts"],"sourcesContent":["export * from '@inquirer/prompts'\n"],"names":[],"mappings":"AAAA,cAAc,oBAAmB"}
@@ -1,3 +1,3 @@
1
- export { default as spinner } from 'ora';
1
+ export { default as spinner, oraPromise as spinnerPromise } from 'ora';
2
2
 
3
3
  //# sourceMappingURL=spinner.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/ux/spinner.ts"],"sourcesContent":["export {default as spinner} from 'ora'\n"],"names":["default","spinner"],"mappings":"AAAA,SAAQA,WAAWC,OAAO,QAAO,MAAK"}
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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanity/cli-core",
3
- "version": "0.0.2-alpha.2",
3
+ "version": "0.1.0-alpha.10",
4
4
  "description": "Sanity CLI core package",
5
5
  "keywords": [
6
6
  "sanity",
@@ -13,54 +13,78 @@
13
13
  ],
14
14
  "homepage": "https://github.com/sanity-io/cli",
15
15
  "bugs": "https://github.com/sanity-io/cli/issues",
16
- "repository": "sanity-io/cli",
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/sanity-io/cli.git",
19
+ "directory": "packages/@sanity/cli-core"
20
+ },
17
21
  "license": "MIT",
18
22
  "author": "Sanity.io <hello@sanity.io>",
23
+ "sideEffects": false,
19
24
  "type": "module",
20
25
  "exports": {
21
26
  ".": {
22
27
  "source": "./src/index.ts",
23
- "require": "./dist/index.js",
24
- "import": "./dist/index.js"
28
+ "default": "./dist/index.js"
29
+ },
30
+ "./tree": {
31
+ "source": "./src/_exports/tree.ts",
32
+ "default": "./dist/_exports/tree.js"
33
+ },
34
+ "./ux": {
35
+ "source": "./src/_exports/ux.ts",
36
+ "default": "./dist/_exports/ux.js"
25
37
  },
26
38
  "./package.json": "./package.json"
27
39
  },
28
- "main": "dist/index.js",
40
+ "main": "./dist/index.js",
29
41
  "types": "dist/index.d.ts",
30
42
  "files": [
31
43
  "./dist"
32
44
  ],
33
45
  "dependencies": {
34
- "@oclif/core": "^4.5.3",
35
- "@sanity/client": "^7.11.2",
46
+ "@inquirer/prompts": "^8.2.0",
47
+ "@oclif/core": "^4.8.0",
48
+ "@sanity/client": "^7.14.1",
49
+ "@sanity/types": "^5.8.1",
36
50
  "babel-plugin-react-compiler": "^1.0.0",
37
- "chalk": "^5.4.1",
51
+ "boxen": "^8.0.1",
38
52
  "configstore": "^7.0.0",
39
53
  "debug": "^4.4.3",
40
- "get-tsconfig": "^4.10.1",
54
+ "get-tsconfig": "^4.13.1",
41
55
  "import-meta-resolve": "^4.1.0",
42
- "jsdom": "^26.0.0",
56
+ "jsdom": "^27.4.0",
43
57
  "json-lexer": "^1.2.0",
44
58
  "log-symbols": "^7.0.1",
45
- "ora": "^8.2.0",
46
- "tsx": "^4.20.3",
47
- "vite": "^7.1.6",
48
- "vite-node": "^3.0.8",
49
- "zod": "^3.24.2"
59
+ "ora": "^9.0.0",
60
+ "rxjs": "^7.8.2",
61
+ "tinyglobby": "^0.2.15",
62
+ "tsx": "^4.21.0",
63
+ "typeid-js": "^1.2.0",
64
+ "vite": "^7.3.1",
65
+ "zod": "^4.3.6"
50
66
  },
51
67
  "devDependencies": {
52
- "@eslint/compat": "^2.0.0",
53
- "@swc/cli": "^0.7.8",
54
- "@swc/core": "^1.14.0",
55
- "@types/configstore": "^6.0.2",
68
+ "@eslint/compat": "^2.0.2",
69
+ "@sanity/codegen": "^5.9.2",
70
+ "@sanity/pkg-utils": "^10.4.4",
71
+ "@sanity/telemetry": "^0.8.1",
72
+ "@swc/cli": "^0.7.10",
73
+ "@swc/core": "^1.15.11",
56
74
  "@types/debug": "^4.1.12",
57
- "@types/jsdom": "^21.1.7",
58
- "@types/node": "^20.19.24",
59
- "eslint": "^9.39.1",
60
- "typescript": "^5.8.3",
61
- "vitest": "^3.2.4",
62
- "@repo/eslint-config": "0.0.0",
63
- "@repo/tsconfig": "3.70.0"
75
+ "@types/jsdom": "^27.0.0",
76
+ "@types/node": "^20.19.30",
77
+ "eslint": "^9.39.2",
78
+ "publint": "^0.3.17",
79
+ "sanity": "^5.8.1",
80
+ "typescript": "^5.9.3",
81
+ "vitest": "^4.0.18",
82
+ "@repo/package.config": "0.0.1",
83
+ "@repo/tsconfig": "3.70.0",
84
+ "@sanity/eslint-config-cli": "0.0.0-alpha.2"
85
+ },
86
+ "peerDependencies": {
87
+ "@sanity/telemetry": ">=0.8.1 <0.9.0"
64
88
  },
65
89
  "engines": {
66
90
  "node": ">=20.19.1 <22 || >=22.12"
@@ -69,10 +93,11 @@
69
93
  "access": "public"
70
94
  },
71
95
  "scripts": {
72
- "build": "swc --delete-dir-on-start --strip-leading-paths --out-dir dist/ src",
73
- "build:types": "tsc --project tsconfig.lib.json",
96
+ "build": "swc --delete-dir-on-start --strip-leading-paths --out-dir dist/ src --ignore '**/*.test.ts'",
97
+ "build:types": "pkg-utils build --emitDeclarationOnly",
74
98
  "check:types": "tsc --noEmit",
75
99
  "lint": "eslint .",
100
+ "publint": "publint",
76
101
  "test": "vitest run",
77
102
  "posttest": "pnpm run lint",
78
103
  "test:coverage": "vitest run --coverage",
@@ -1,56 +0,0 @@
1
- import { Command, Interfaces } from '@oclif/core';
2
- import { type CliConfig } from './config/cli/types/cliConfig.js';
3
- import { type ProjectRootResult } from './config/util/recursivelyResolveProjectRoot.js';
4
- import { type GlobalCliClientOptions, type ProjectCliClientOptions } from './services/apiClient.js';
5
- import { type Output } from './types.js';
6
- type Flags<T extends typeof Command> = Interfaces.InferredFlags<(typeof SanityCommand)['baseFlags'] & T['flags']>;
7
- type Args<T extends typeof Command> = Interfaces.InferredArgs<T['args']>;
8
- export declare abstract class SanityCommand<T extends typeof Command> extends Command {
9
- protected args: Args<T>;
10
- protected flags: Flags<T>;
11
- /**
12
- * Get the global API client.
13
- *
14
- * @param args - The global API client options.
15
- * @returns The global API client.
16
- */
17
- protected getGlobalApiClient: (args: GlobalCliClientOptions) => Promise<import("@sanity/client").SanityClient>;
18
- /**
19
- * Get the project API client.
20
- *
21
- * @param args - The project API client options.
22
- * @returns The project API client.
23
- */
24
- protected getProjectApiClient: (args: ProjectCliClientOptions) => Promise<import("@sanity/client").SanityClient>;
25
- /**
26
- * Helper for outputting to the console.
27
- *
28
- * @example
29
- * ```ts
30
- * this.output.log('Hello')
31
- * this.output.warn('Warning')
32
- * this.output.error('Error')
33
- * ```
34
- */
35
- protected output: Output;
36
- /**
37
- * Get the CLI config.
38
- *
39
- * @returns The CLI config.
40
- */
41
- protected getCliConfig(): Promise<CliConfig>;
42
- /**
43
- * Get the project ID from the CLI config.
44
- *
45
- * @returns The project ID or `undefined` if it's not set.
46
- */
47
- protected getProjectId(): Promise<string | undefined>;
48
- /**
49
- * Get the project's root directory by resolving the config
50
- *
51
- * @returns The root project root.
52
- */
53
- protected getProjectRoot(): Promise<ProjectRootResult>;
54
- init(): Promise<void>;
55
- }
56
- export {};
@@ -1,74 +0,0 @@
1
- import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
2
- import { getConfig } from '../../services/cliUserConfig';
3
- import * as cliTokenModule from '../../services/getCliToken';
4
- vi.mock('../../services/cliUserConfig', ()=>({
5
- getConfig: vi.fn()
6
- }));
7
- describe('getCliToken', ()=>{
8
- const originalEnv = process.env;
9
- let cachedToken;
10
- beforeEach(()=>{
11
- process.env = {
12
- ...originalEnv
13
- };
14
- vi.clearAllMocks();
15
- vi.resetModules();
16
- cachedToken = undefined;
17
- vi.spyOn(cliTokenModule, 'getCliToken').mockImplementation(async ()=>{
18
- if (cachedToken !== undefined) {
19
- return cachedToken;
20
- }
21
- const token = process.env.SANITY_AUTH_TOKEN;
22
- if (token) {
23
- cachedToken = token.trim();
24
- return cachedToken;
25
- }
26
- cachedToken = await getConfig('authToken');
27
- return cachedToken;
28
- });
29
- });
30
- afterEach(()=>{
31
- process.env = originalEnv;
32
- vi.restoreAllMocks();
33
- });
34
- it('should return token from environment variable', async ()=>{
35
- process.env.SANITY_AUTH_TOKEN = 'test-token';
36
- const token = await cliTokenModule.getCliToken();
37
- expect(token).toBe('test-token');
38
- expect(getConfig).not.toHaveBeenCalled();
39
- });
40
- it('should return token from config if no environment variable is set', async ()=>{
41
- delete process.env.SANITY_AUTH_TOKEN;
42
- vi.mocked(getConfig).mockResolvedValueOnce('config-token');
43
- const token = await cliTokenModule.getCliToken();
44
- expect(token).toBe('config-token');
45
- expect(getConfig).toHaveBeenCalledWith('authToken');
46
- });
47
- it('should return undefined if no token is available', async ()=>{
48
- delete process.env.SANITY_AUTH_TOKEN;
49
- vi.mocked(getConfig).mockResolvedValueOnce(undefined);
50
- const token = await cliTokenModule.getCliToken();
51
- expect(token).toBeUndefined();
52
- expect(getConfig).toHaveBeenCalledWith('authToken');
53
- });
54
- it('should cache the token from environment variable', async ()=>{
55
- process.env.SANITY_AUTH_TOKEN = 'cached-env-token';
56
- const firstCall = await cliTokenModule.getCliToken();
57
- process.env.SANITY_AUTH_TOKEN = 'new-token';
58
- const secondCall = await cliTokenModule.getCliToken();
59
- expect(firstCall).toBe('cached-env-token');
60
- expect(secondCall).toBe('cached-env-token');
61
- expect(getConfig).not.toHaveBeenCalled();
62
- });
63
- it('should cache the token from config', async ()=>{
64
- delete process.env.SANITY_AUTH_TOKEN;
65
- vi.mocked(getConfig).mockResolvedValueOnce('cached-config-token');
66
- const firstCall = await cliTokenModule.getCliToken();
67
- const secondCall = await cliTokenModule.getCliToken();
68
- expect(firstCall).toBe('cached-config-token');
69
- expect(secondCall).toBe('cached-config-token');
70
- expect(getConfig).toHaveBeenCalledTimes(1);
71
- });
72
- });
73
-
74
- //# sourceMappingURL=cliToken.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../src/config/__tests__/cliToken.test.ts"],"sourcesContent":["import {afterEach, beforeEach, describe, expect, it, vi} from 'vitest'\n\nimport {getConfig} from '../../services/cliUserConfig'\nimport * as cliTokenModule from '../../services/getCliToken'\n\nvi.mock('../../services/cliUserConfig', () => ({\n getConfig: vi.fn(),\n}))\n\ndescribe('getCliToken', () => {\n const originalEnv = process.env\n let cachedToken: string | undefined\n\n beforeEach(() => {\n process.env = {...originalEnv}\n vi.clearAllMocks()\n vi.resetModules()\n cachedToken = undefined\n vi.spyOn(cliTokenModule, 'getCliToken').mockImplementation(async () => {\n if (cachedToken !== undefined) {\n return cachedToken\n }\n\n const token = process.env.SANITY_AUTH_TOKEN\n if (token) {\n cachedToken = token.trim()\n return cachedToken\n }\n\n cachedToken = await getConfig('authToken')\n return cachedToken\n })\n })\n\n afterEach(() => {\n process.env = originalEnv\n vi.restoreAllMocks()\n })\n\n it('should return token from environment variable', async () => {\n process.env.SANITY_AUTH_TOKEN = 'test-token'\n const token = await cliTokenModule.getCliToken()\n expect(token).toBe('test-token')\n expect(getConfig).not.toHaveBeenCalled()\n })\n\n it('should return token from config if no environment variable is set', async () => {\n delete process.env.SANITY_AUTH_TOKEN\n vi.mocked(getConfig).mockResolvedValueOnce('config-token')\n\n const token = await cliTokenModule.getCliToken()\n expect(token).toBe('config-token')\n expect(getConfig).toHaveBeenCalledWith('authToken')\n })\n\n it('should return undefined if no token is available', async () => {\n delete process.env.SANITY_AUTH_TOKEN\n vi.mocked(getConfig).mockResolvedValueOnce(undefined)\n\n const token = await cliTokenModule.getCliToken()\n expect(token).toBeUndefined()\n expect(getConfig).toHaveBeenCalledWith('authToken')\n })\n\n it('should cache the token from environment variable', async () => {\n process.env.SANITY_AUTH_TOKEN = 'cached-env-token'\n\n const firstCall = await cliTokenModule.getCliToken()\n process.env.SANITY_AUTH_TOKEN = 'new-token'\n const secondCall = await cliTokenModule.getCliToken()\n\n expect(firstCall).toBe('cached-env-token')\n expect(secondCall).toBe('cached-env-token')\n expect(getConfig).not.toHaveBeenCalled()\n })\n\n it('should cache the token from config', async () => {\n delete process.env.SANITY_AUTH_TOKEN\n vi.mocked(getConfig).mockResolvedValueOnce('cached-config-token')\n\n const firstCall = await cliTokenModule.getCliToken()\n const secondCall = await cliTokenModule.getCliToken()\n\n expect(firstCall).toBe('cached-config-token')\n expect(secondCall).toBe('cached-config-token')\n expect(getConfig).toHaveBeenCalledTimes(1)\n })\n})\n"],"names":["afterEach","beforeEach","describe","expect","it","vi","getConfig","cliTokenModule","mock","fn","originalEnv","process","env","cachedToken","clearAllMocks","resetModules","undefined","spyOn","mockImplementation","token","SANITY_AUTH_TOKEN","trim","restoreAllMocks","getCliToken","toBe","not","toHaveBeenCalled","mocked","mockResolvedValueOnce","toHaveBeenCalledWith","toBeUndefined","firstCall","secondCall","toHaveBeenCalledTimes"],"mappings":"AAAA,SAAQA,SAAS,EAAEC,UAAU,EAAEC,QAAQ,EAAEC,MAAM,EAAEC,EAAE,EAAEC,EAAE,QAAO,SAAQ;AAEtE,SAAQC,SAAS,QAAO,+BAA8B;AACtD,YAAYC,oBAAoB,6BAA4B;AAE5DF,GAAGG,IAAI,CAAC,gCAAgC,IAAO,CAAA;QAC7CF,WAAWD,GAAGI,EAAE;IAClB,CAAA;AAEAP,SAAS,eAAe;IACtB,MAAMQ,cAAcC,QAAQC,GAAG;IAC/B,IAAIC;IAEJZ,WAAW;QACTU,QAAQC,GAAG,GAAG;YAAC,GAAGF,WAAW;QAAA;QAC7BL,GAAGS,aAAa;QAChBT,GAAGU,YAAY;QACfF,cAAcG;QACdX,GAAGY,KAAK,CAACV,gBAAgB,eAAeW,kBAAkB,CAAC;YACzD,IAAIL,gBAAgBG,WAAW;gBAC7B,OAAOH;YACT;YAEA,MAAMM,QAAQR,QAAQC,GAAG,CAACQ,iBAAiB;YAC3C,IAAID,OAAO;gBACTN,cAAcM,MAAME,IAAI;gBACxB,OAAOR;YACT;YAEAA,cAAc,MAAMP,UAAU;YAC9B,OAAOO;QACT;IACF;IAEAb,UAAU;QACRW,QAAQC,GAAG,GAAGF;QACdL,GAAGiB,eAAe;IACpB;IAEAlB,GAAG,iDAAiD;QAClDO,QAAQC,GAAG,CAACQ,iBAAiB,GAAG;QAChC,MAAMD,QAAQ,MAAMZ,eAAegB,WAAW;QAC9CpB,OAAOgB,OAAOK,IAAI,CAAC;QACnBrB,OAAOG,WAAWmB,GAAG,CAACC,gBAAgB;IACxC;IAEAtB,GAAG,qEAAqE;QACtE,OAAOO,QAAQC,GAAG,CAACQ,iBAAiB;QACpCf,GAAGsB,MAAM,CAACrB,WAAWsB,qBAAqB,CAAC;QAE3C,MAAMT,QAAQ,MAAMZ,eAAegB,WAAW;QAC9CpB,OAAOgB,OAAOK,IAAI,CAAC;QACnBrB,OAAOG,WAAWuB,oBAAoB,CAAC;IACzC;IAEAzB,GAAG,oDAAoD;QACrD,OAAOO,QAAQC,GAAG,CAACQ,iBAAiB;QACpCf,GAAGsB,MAAM,CAACrB,WAAWsB,qBAAqB,CAACZ;QAE3C,MAAMG,QAAQ,MAAMZ,eAAegB,WAAW;QAC9CpB,OAAOgB,OAAOW,aAAa;QAC3B3B,OAAOG,WAAWuB,oBAAoB,CAAC;IACzC;IAEAzB,GAAG,oDAAoD;QACrDO,QAAQC,GAAG,CAACQ,iBAAiB,GAAG;QAEhC,MAAMW,YAAY,MAAMxB,eAAegB,WAAW;QAClDZ,QAAQC,GAAG,CAACQ,iBAAiB,GAAG;QAChC,MAAMY,aAAa,MAAMzB,eAAegB,WAAW;QAEnDpB,OAAO4B,WAAWP,IAAI,CAAC;QACvBrB,OAAO6B,YAAYR,IAAI,CAAC;QACxBrB,OAAOG,WAAWmB,GAAG,CAACC,gBAAgB;IACxC;IAEAtB,GAAG,sCAAsC;QACvC,OAAOO,QAAQC,GAAG,CAACQ,iBAAiB;QACpCf,GAAGsB,MAAM,CAACrB,WAAWsB,qBAAqB,CAAC;QAE3C,MAAMG,YAAY,MAAMxB,eAAegB,WAAW;QAClD,MAAMS,aAAa,MAAMzB,eAAegB,WAAW;QAEnDpB,OAAO4B,WAAWP,IAAI,CAAC;QACvBrB,OAAO6B,YAAYR,IAAI,CAAC;QACxBrB,OAAOG,WAAW2B,qBAAqB,CAAC;IAC1C;AACF"}