@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,88 @@
1
+ import { dirname, resolve } from 'node:path';
2
+ import { ProjectRootNotFoundError } from '../errors/ProjectRootNotFoundError.js';
3
+ import { findAppConfigPathSync, findStudioConfigPathSync } from './util/configPathsSync.js';
4
+ /**
5
+ * Generic recursive search function for project configuration files (synchronous version).
6
+ *
7
+ * @param basePath - The base path to start searching from
8
+ * @param findConfigFn - Function that looks for config files in a given directory
9
+ * @param projectType - The type of project ('app' | 'studio')
10
+ * @param iterations - Current iteration count, passed internally to prevent infinite recursion
11
+ * @returns An object if config is found, false otherwise
12
+ * @internal
13
+ */ function recursivelyResolveProjectRootSync(basePath, findConfigFn, projectType, iterations = 0) {
14
+ const configPath = findConfigFn(basePath);
15
+ if (configPath) {
16
+ return {
17
+ directory: dirname(configPath),
18
+ path: configPath,
19
+ type: projectType
20
+ };
21
+ }
22
+ const parentDir = resolve(basePath, '..');
23
+ if (parentDir === basePath || iterations > 50) {
24
+ // Reached root (or max depth), give up
25
+ return false;
26
+ }
27
+ return recursivelyResolveProjectRootSync(parentDir, findConfigFn, projectType, iterations + 1);
28
+ }
29
+ /**
30
+ * Resolve project root directory and type synchronously.
31
+ *
32
+ * Project root is:
33
+ * - `studio` - A pre-blueprints Sanity studio root (containing `sanity.config.(ts|js)`)
34
+ * - `app` - A Sanity app root (containing `sanity.cli.(ts|js)`)
35
+ *
36
+ * If a Sanity Studio v2/v1 root is found (containing `sanity.json` with `root: true`),
37
+ * an error is thrown, as v2/v1 is no longer supported.
38
+ *
39
+ * @param cwd - Current working directory to start searching from
40
+ * @returns Project root result
41
+ * @internal
42
+ */ export function findProjectRootSync(cwd) {
43
+ try {
44
+ // First try to find a studio project root, looks for `sanity.config.(ts|js)`
45
+ const studioProjectRoot = resolveProjectRootForStudioSync(cwd);
46
+ if (studioProjectRoot) {
47
+ return studioProjectRoot;
48
+ }
49
+ // Second try to find a app project root, looks for `sanity.cli.(ts|js)`
50
+ const appProjectRoot = resolveProjectRootForAppSync(cwd);
51
+ if (appProjectRoot) {
52
+ return appProjectRoot;
53
+ }
54
+ // If nothing is found throw a specific error
55
+ throw new ProjectRootNotFoundError(`No project root found in ${cwd}`);
56
+ } catch (err) {
57
+ if (err instanceof ProjectRootNotFoundError) {
58
+ throw err;
59
+ }
60
+ const message = err instanceof Error ? err.message : `${err}`;
61
+ throw new Error(`Error occurred trying to resolve project root:\n${message}`, {
62
+ cause: err
63
+ });
64
+ }
65
+ }
66
+ /**
67
+ * Recursively searches for a project configuration file in the given directory and its parents.
68
+ * Throws if Sanity v2 studio root is found.
69
+ *
70
+ * @param basePath - The base path to start searching from
71
+ * @param iterations - Current iteration count, passed internally to prevent infinite recursion.
72
+ * @returns An object if config is found, false otherwise
73
+ * @internal
74
+ */ function resolveProjectRootForStudioSync(basePath, iterations = 0) {
75
+ return recursivelyResolveProjectRootSync(basePath, findStudioConfigPathSync, 'studio', iterations);
76
+ }
77
+ /**
78
+ * Recursively searches for a app project configuration file in the given directory and its parents.
79
+ *
80
+ * @param basePath - The base path to start searching from
81
+ * @param iterations - Current iteration count, passed internally to prevent infinite recursion.
82
+ * @returns An object if config is found, false otherwise
83
+ * @internal
84
+ */ function resolveProjectRootForAppSync(basePath, iterations = 0) {
85
+ return recursivelyResolveProjectRootSync(basePath, findAppConfigPathSync, 'app', iterations);
86
+ }
87
+
88
+ //# sourceMappingURL=findProjectRootSync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/config/findProjectRootSync.ts"],"sourcesContent":["import {dirname, resolve} from 'node:path'\n\nimport {ProjectRootNotFoundError} from '../errors/ProjectRootNotFoundError.js'\nimport {findAppConfigPathSync, findStudioConfigPathSync} from './util/configPathsSync.js'\nimport {ProjectRootResult} from './util/recursivelyResolveProjectRoot.js'\n\n/**\n * Generic recursive search function for project configuration files (synchronous version).\n *\n * @param basePath - The base path to start searching from\n * @param findConfigFn - Function that looks for config files in a given directory\n * @param projectType - The type of project ('app' | 'studio')\n * @param iterations - Current iteration count, passed internally to prevent infinite recursion\n * @returns An object if config is found, false otherwise\n * @internal\n */\nfunction recursivelyResolveProjectRootSync(\n basePath: string,\n findConfigFn: (path: string) => string | undefined,\n projectType: 'app' | 'studio',\n iterations = 0,\n): false | ProjectRootResult {\n const configPath = findConfigFn(basePath)\n\n if (configPath) {\n return {\n directory: dirname(configPath),\n path: configPath,\n type: projectType,\n }\n }\n\n const parentDir = resolve(basePath, '..')\n if (parentDir === basePath || iterations > 50) {\n // Reached root (or max depth), give up\n return false\n }\n\n return recursivelyResolveProjectRootSync(parentDir, findConfigFn, projectType, iterations + 1)\n}\n\n/**\n * Resolve project root directory and type synchronously.\n *\n * Project root is:\n * - `studio` - A pre-blueprints Sanity studio root (containing `sanity.config.(ts|js)`)\n * - `app` - A Sanity app root (containing `sanity.cli.(ts|js)`)\n *\n * If a Sanity Studio v2/v1 root is found (containing `sanity.json` with `root: true`),\n * an error is thrown, as v2/v1 is no longer supported.\n *\n * @param cwd - Current working directory to start searching from\n * @returns Project root result\n * @internal\n */\nexport function findProjectRootSync(cwd: string): ProjectRootResult {\n try {\n // First try to find a studio project root, looks for `sanity.config.(ts|js)`\n const studioProjectRoot = resolveProjectRootForStudioSync(cwd)\n if (studioProjectRoot) {\n return studioProjectRoot\n }\n\n // Second try to find a app project root, looks for `sanity.cli.(ts|js)`\n const appProjectRoot = resolveProjectRootForAppSync(cwd)\n if (appProjectRoot) {\n return appProjectRoot\n }\n\n // If nothing is found throw a specific error\n throw new ProjectRootNotFoundError(`No project root found in ${cwd}`)\n } catch (err: unknown) {\n if (err instanceof ProjectRootNotFoundError) {\n throw err\n }\n const message = err instanceof Error ? err.message : `${err}`\n throw new Error(`Error occurred trying to resolve project root:\\n${message}`, {cause: err})\n }\n}\n\n/**\n * Recursively searches for a project configuration file in the given directory and its parents.\n * Throws if Sanity v2 studio root is found.\n *\n * @param basePath - The base path to start searching from\n * @param iterations - Current iteration count, passed internally to prevent infinite recursion.\n * @returns An object if config is found, false otherwise\n * @internal\n */\nfunction resolveProjectRootForStudioSync(\n basePath: string,\n iterations = 0,\n): false | ProjectRootResult {\n return recursivelyResolveProjectRootSync(basePath, findStudioConfigPathSync, 'studio', iterations)\n}\n\n/**\n * Recursively searches for a app project configuration file in the given directory and its parents.\n *\n * @param basePath - The base path to start searching from\n * @param iterations - Current iteration count, passed internally to prevent infinite recursion.\n * @returns An object if config is found, false otherwise\n * @internal\n */\nfunction resolveProjectRootForAppSync(basePath: string, iterations = 0): false | ProjectRootResult {\n return recursivelyResolveProjectRootSync(basePath, findAppConfigPathSync, 'app', iterations)\n}\n"],"names":["dirname","resolve","ProjectRootNotFoundError","findAppConfigPathSync","findStudioConfigPathSync","recursivelyResolveProjectRootSync","basePath","findConfigFn","projectType","iterations","configPath","directory","path","type","parentDir","findProjectRootSync","cwd","studioProjectRoot","resolveProjectRootForStudioSync","appProjectRoot","resolveProjectRootForAppSync","err","message","Error","cause"],"mappings":"AAAA,SAAQA,OAAO,EAAEC,OAAO,QAAO,YAAW;AAE1C,SAAQC,wBAAwB,QAAO,wCAAuC;AAC9E,SAAQC,qBAAqB,EAAEC,wBAAwB,QAAO,4BAA2B;AAGzF;;;;;;;;;CASC,GACD,SAASC,kCACPC,QAAgB,EAChBC,YAAkD,EAClDC,WAA6B,EAC7BC,aAAa,CAAC;IAEd,MAAMC,aAAaH,aAAaD;IAEhC,IAAII,YAAY;QACd,OAAO;YACLC,WAAWX,QAAQU;YACnBE,MAAMF;YACNG,MAAML;QACR;IACF;IAEA,MAAMM,YAAYb,QAAQK,UAAU;IACpC,IAAIQ,cAAcR,YAAYG,aAAa,IAAI;QAC7C,uCAAuC;QACvC,OAAO;IACT;IAEA,OAAOJ,kCAAkCS,WAAWP,cAAcC,aAAaC,aAAa;AAC9F;AAEA;;;;;;;;;;;;;CAaC,GACD,OAAO,SAASM,oBAAoBC,GAAW;IAC7C,IAAI;QACF,6EAA6E;QAC7E,MAAMC,oBAAoBC,gCAAgCF;QAC1D,IAAIC,mBAAmB;YACrB,OAAOA;QACT;QAEA,wEAAwE;QACxE,MAAME,iBAAiBC,6BAA6BJ;QACpD,IAAIG,gBAAgB;YAClB,OAAOA;QACT;QAEA,6CAA6C;QAC7C,MAAM,IAAIjB,yBAAyB,CAAC,yBAAyB,EAAEc,KAAK;IACtE,EAAE,OAAOK,KAAc;QACrB,IAAIA,eAAenB,0BAA0B;YAC3C,MAAMmB;QACR;QACA,MAAMC,UAAUD,eAAeE,QAAQF,IAAIC,OAAO,GAAG,GAAGD,KAAK;QAC7D,MAAM,IAAIE,MAAM,CAAC,gDAAgD,EAAED,SAAS,EAAE;YAACE,OAAOH;QAAG;IAC3F;AACF;AAEA;;;;;;;;CAQC,GACD,SAASH,gCACPZ,QAAgB,EAChBG,aAAa,CAAC;IAEd,OAAOJ,kCAAkCC,UAAUF,0BAA0B,UAAUK;AACzF;AAEA;;;;;;;CAOC,GACD,SAASW,6BAA6Bd,QAAgB,EAAEG,aAAa,CAAC;IACpE,OAAOJ,kCAAkCC,UAAUH,uBAAuB,OAAOM;AACnF"}
@@ -0,0 +1,13 @@
1
+ import { findStudioConfigPath } from '../util/findStudioConfigPath.js';
2
+ import { readStudioConfig } from './readStudioConfig.js';
3
+ export async function getStudioConfig(rootPath, options) {
4
+ const studioConfigPath = await findStudioConfigPath(rootPath);
5
+ // TypeScript is not being very clever with our overloads :(
6
+ return options.resolvePlugins ? readStudioConfig(studioConfigPath, {
7
+ resolvePlugins: true
8
+ }) : readStudioConfig(studioConfigPath, {
9
+ resolvePlugins: false
10
+ });
11
+ }
12
+
13
+ //# sourceMappingURL=getStudioConfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/config/studio/getStudioConfig.ts"],"sourcesContent":["import {findStudioConfigPath} from '../util/findStudioConfigPath.js'\nimport {\n type RawStudioConfig,\n readStudioConfig,\n type ReadStudioConfigOptions,\n type ResolvedStudioConfig,\n} from './readStudioConfig.js'\n\n/**\n * Get the studio config for a project, given the root path.\n *\n * @param rootPath - The root path for the project\n * @returns The studio config (some properties may be missing)\n * @public\n */\nexport async function getStudioConfig(\n rootPath: string,\n options: {resolvePlugins: true},\n): Promise<ResolvedStudioConfig>\n\nexport async function getStudioConfig(\n rootPath: string,\n options: {resolvePlugins: false},\n): Promise<RawStudioConfig>\n\nexport async function getStudioConfig(\n rootPath: string,\n options: ReadStudioConfigOptions,\n): Promise<RawStudioConfig | ResolvedStudioConfig> {\n const studioConfigPath = await findStudioConfigPath(rootPath)\n\n // TypeScript is not being very clever with our overloads :(\n return options.resolvePlugins\n ? readStudioConfig(studioConfigPath, {resolvePlugins: true})\n : readStudioConfig(studioConfigPath, {resolvePlugins: false})\n}\n"],"names":["findStudioConfigPath","readStudioConfig","getStudioConfig","rootPath","options","studioConfigPath","resolvePlugins"],"mappings":"AAAA,SAAQA,oBAAoB,QAAO,kCAAiC;AACpE,SAEEC,gBAAgB,QAGX,wBAAuB;AAmB9B,OAAO,eAAeC,gBACpBC,QAAgB,EAChBC,OAAgC;IAEhC,MAAMC,mBAAmB,MAAML,qBAAqBG;IAEpD,4DAA4D;IAC5D,OAAOC,QAAQE,cAAc,GACzBL,iBAAiBI,kBAAkB;QAACC,gBAAgB;IAAI,KACxDL,iBAAiBI,kBAAkB;QAACC,gBAAgB;IAAK;AAC/D"}
@@ -0,0 +1,63 @@
1
+ import { stat } from 'node:fs/promises';
2
+ import { dirname } from 'node:path';
3
+ import { isMainThread } from 'node:worker_threads';
4
+ import { firstValueFrom, of } from 'rxjs';
5
+ import { subdebug } from '../../debug.js';
6
+ import { doImport } from '../../util/doImport.js';
7
+ import { getEmptyAuth } from '../../util/getEmptyAuth.js';
8
+ import { resolveLocalPackage } from '../../util/resolveLocalPackage.js';
9
+ import { findStudioConfigPath } from '../util/findStudioConfigPath.js';
10
+ import { isStudioConfig } from './isStudioConfig.js';
11
+ const debug = subdebug('worker:getStudioWorkspaces');
12
+ /**
13
+ * Resolves the workspaces from the studio config.
14
+ *
15
+ * NOTE: This function should only be called from a worker thread.
16
+ *
17
+ * @param configPath - The path to the studio config
18
+ * @returns The workspaces
19
+ * @internal
20
+ */ export async function getStudioWorkspaces(configPath) {
21
+ if (isMainThread) {
22
+ throw new Error('getStudioWorkspaces should only be called from a worker thread');
23
+ }
24
+ const isDirectory = (await stat(configPath)).isDirectory();
25
+ if (isDirectory) {
26
+ configPath = await findStudioConfigPath(configPath);
27
+ }
28
+ debug('Finding studio config path %s', configPath);
29
+ let config = await doImport(configPath);
30
+ debug('Imported config %o', config);
31
+ if (!isStudioConfig(config)) {
32
+ if (!('default' in config) || !isStudioConfig(config.default)) {
33
+ debug('Invalid studio config format in "%s"', configPath);
34
+ throw new TypeError(`Invalid studio config format in "${configPath}"`);
35
+ }
36
+ config = config.default;
37
+ }
38
+ const workDir = dirname(configPath);
39
+ debug('Work dir %s', workDir);
40
+ const { resolveConfig } = await resolveLocalPackage('sanity', workDir);
41
+ if (typeof resolveConfig !== 'function') {
42
+ throw new TypeError('Expected `resolveConfig` from `sanity` to be a function');
43
+ }
44
+ // We will also want to stub out some configuration - we don't need to resolve the
45
+ // users' logged in state, for instance - so let's disable the auth implementation.
46
+ const rawWorkspaces = Array.isArray(config) ? config : [
47
+ {
48
+ ...config,
49
+ basePath: config.basePath || '/',
50
+ name: config.name || 'default'
51
+ }
52
+ ];
53
+ const unauthedWorkspaces = rawWorkspaces.map((workspace)=>({
54
+ ...workspace,
55
+ auth: {
56
+ state: of(getEmptyAuth())
57
+ }
58
+ }));
59
+ debug('Unauthed workspaces %o', unauthedWorkspaces);
60
+ return firstValueFrom(resolveConfig(unauthedWorkspaces));
61
+ }
62
+
63
+ //# sourceMappingURL=getStudioWorkspaces.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/config/studio/getStudioWorkspaces.ts"],"sourcesContent":["import {stat} from 'node:fs/promises'\nimport {dirname} from 'node:path'\nimport {isMainThread} from 'node:worker_threads'\n\nimport {firstValueFrom, of} from 'rxjs'\nimport {type Workspace} from 'sanity'\n\nimport {subdebug} from '../../debug.js'\nimport {doImport} from '../../util/doImport.js'\nimport {getEmptyAuth} from '../../util/getEmptyAuth.js'\nimport {resolveLocalPackage} from '../../util/resolveLocalPackage.js'\nimport {findStudioConfigPath} from '../util/findStudioConfigPath.js'\nimport {isStudioConfig} from './isStudioConfig.js'\n\nconst debug = subdebug('worker:getStudioWorkspaces')\n\n/**\n * Resolves the workspaces from the studio config.\n *\n * NOTE: This function should only be called from a worker thread.\n *\n * @param configPath - The path to the studio config\n * @returns The workspaces\n * @internal\n */\nexport async function getStudioWorkspaces(configPath: string): Promise<Workspace[]> {\n if (isMainThread) {\n throw new Error('getStudioWorkspaces should only be called from a worker thread')\n }\n const isDirectory = (await stat(configPath)).isDirectory()\n if (isDirectory) {\n configPath = await findStudioConfigPath(configPath)\n }\n debug('Finding studio config path %s', configPath)\n let config = await doImport(configPath)\n\n debug('Imported config %o', config)\n if (!isStudioConfig(config)) {\n if (!('default' in config) || !isStudioConfig(config.default)) {\n debug('Invalid studio config format in \"%s\"', configPath)\n throw new TypeError(`Invalid studio config format in \"${configPath}\"`)\n }\n\n config = config.default\n }\n\n const workDir = dirname(configPath)\n debug('Work dir %s', workDir)\n const {resolveConfig} = await resolveLocalPackage<typeof import('sanity')>('sanity', workDir)\n if (typeof resolveConfig !== 'function') {\n throw new TypeError('Expected `resolveConfig` from `sanity` to be a function')\n }\n\n // We will also want to stub out some configuration - we don't need to resolve the\n // users' logged in state, for instance - so let's disable the auth implementation.\n const rawWorkspaces = Array.isArray(config)\n ? config\n : [{...config, basePath: config.basePath || '/', name: config.name || 'default'}]\n\n const unauthedWorkspaces = rawWorkspaces.map((workspace) => ({\n ...workspace,\n auth: {state: of(getEmptyAuth())},\n }))\n\n debug('Unauthed workspaces %o', unauthedWorkspaces)\n\n return firstValueFrom(resolveConfig(unauthedWorkspaces))\n}\n"],"names":["stat","dirname","isMainThread","firstValueFrom","of","subdebug","doImport","getEmptyAuth","resolveLocalPackage","findStudioConfigPath","isStudioConfig","debug","getStudioWorkspaces","configPath","Error","isDirectory","config","default","TypeError","workDir","resolveConfig","rawWorkspaces","Array","isArray","basePath","name","unauthedWorkspaces","map","workspace","auth","state"],"mappings":"AAAA,SAAQA,IAAI,QAAO,mBAAkB;AACrC,SAAQC,OAAO,QAAO,YAAW;AACjC,SAAQC,YAAY,QAAO,sBAAqB;AAEhD,SAAQC,cAAc,EAAEC,EAAE,QAAO,OAAM;AAGvC,SAAQC,QAAQ,QAAO,iBAAgB;AACvC,SAAQC,QAAQ,QAAO,yBAAwB;AAC/C,SAAQC,YAAY,QAAO,6BAA4B;AACvD,SAAQC,mBAAmB,QAAO,oCAAmC;AACrE,SAAQC,oBAAoB,QAAO,kCAAiC;AACpE,SAAQC,cAAc,QAAO,sBAAqB;AAElD,MAAMC,QAAQN,SAAS;AAEvB;;;;;;;;CAQC,GACD,OAAO,eAAeO,oBAAoBC,UAAkB;IAC1D,IAAIX,cAAc;QAChB,MAAM,IAAIY,MAAM;IAClB;IACA,MAAMC,cAAc,AAAC,CAAA,MAAMf,KAAKa,WAAU,EAAGE,WAAW;IACxD,IAAIA,aAAa;QACfF,aAAa,MAAMJ,qBAAqBI;IAC1C;IACAF,MAAM,iCAAiCE;IACvC,IAAIG,SAAS,MAAMV,SAASO;IAE5BF,MAAM,sBAAsBK;IAC5B,IAAI,CAACN,eAAeM,SAAS;QAC3B,IAAI,CAAE,CAAA,aAAaA,MAAK,KAAM,CAACN,eAAeM,OAAOC,OAAO,GAAG;YAC7DN,MAAM,wCAAwCE;YAC9C,MAAM,IAAIK,UAAU,CAAC,iCAAiC,EAAEL,WAAW,CAAC,CAAC;QACvE;QAEAG,SAASA,OAAOC,OAAO;IACzB;IAEA,MAAME,UAAUlB,QAAQY;IACxBF,MAAM,eAAeQ;IACrB,MAAM,EAACC,aAAa,EAAC,GAAG,MAAMZ,oBAA6C,UAAUW;IACrF,IAAI,OAAOC,kBAAkB,YAAY;QACvC,MAAM,IAAIF,UAAU;IACtB;IAEA,kFAAkF;IAClF,mFAAmF;IACnF,MAAMG,gBAAgBC,MAAMC,OAAO,CAACP,UAChCA,SACA;QAAC;YAAC,GAAGA,MAAM;YAAEQ,UAAUR,OAAOQ,QAAQ,IAAI;YAAKC,MAAMT,OAAOS,IAAI,IAAI;QAAS;KAAE;IAEnF,MAAMC,qBAAqBL,cAAcM,GAAG,CAAC,CAACC,YAAe,CAAA;YAC3D,GAAGA,SAAS;YACZC,MAAM;gBAACC,OAAO1B,GAAGG;YAAe;QAClC,CAAA;IAEAI,MAAM,0BAA0Be;IAEhC,OAAOvB,eAAeiB,cAAcM;AACtC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Checks if the given value conforms to a minimum studio config shape.
3
+ *
4
+ * @param value - The value to check
5
+ * @returns Whether the value is a studio config
6
+ * @internal
7
+ */ export function isStudioConfig(value) {
8
+ if (Array.isArray(value)) {
9
+ return value.every((item)=>isStudioConfig(item));
10
+ }
11
+ // Only actual properties marked as required by typescript are `projectId` and `dataset`,
12
+ // so this is a pretty weak check - but better than nothing.
13
+ if (typeof value === 'object' && value !== null) {
14
+ return 'projectId' in value && typeof value.projectId === 'string' && 'dataset' in value && typeof value.dataset === 'string';
15
+ }
16
+ return false;
17
+ }
18
+
19
+ //# sourceMappingURL=isStudioConfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/config/studio/isStudioConfig.ts"],"sourcesContent":["/**\n * Checks if the given value conforms to a minimum studio config shape.\n *\n * @param value - The value to check\n * @returns Whether the value is a studio config\n * @internal\n */\nexport function isStudioConfig(value: unknown): boolean {\n if (Array.isArray(value)) {\n return value.every((item) => isStudioConfig(item))\n }\n\n // Only actual properties marked as required by typescript are `projectId` and `dataset`,\n // so this is a pretty weak check - but better than nothing.\n if (typeof value === 'object' && value !== null) {\n return (\n 'projectId' in value &&\n typeof value.projectId === 'string' &&\n 'dataset' in value &&\n typeof value.dataset === 'string'\n )\n }\n\n return false\n}\n"],"names":["isStudioConfig","value","Array","isArray","every","item","projectId","dataset"],"mappings":"AAAA;;;;;;CAMC,GACD,OAAO,SAASA,eAAeC,KAAc;IAC3C,IAAIC,MAAMC,OAAO,CAACF,QAAQ;QACxB,OAAOA,MAAMG,KAAK,CAAC,CAACC,OAASL,eAAeK;IAC9C;IAEA,yFAAyF;IACzF,4DAA4D;IAC5D,IAAI,OAAOJ,UAAU,YAAYA,UAAU,MAAM;QAC/C,OACE,eAAeA,SACf,OAAOA,MAAMK,SAAS,KAAK,YAC3B,aAAaL,SACb,OAAOA,MAAMM,OAAO,KAAK;IAE7B;IAEA,OAAO;AACT"}
@@ -0,0 +1,82 @@
1
+ import { dirname } from 'node:path';
2
+ import { z } from 'zod/mini';
3
+ import { studioWorkerTask } from '../../loaders/studio/studioWorkerTask.js';
4
+ const schemaSchema = z.looseObject({
5
+ name: z.optional(z.string()),
6
+ types: z.array(z.looseObject({}))
7
+ });
8
+ const sourceSchema = z.looseObject({
9
+ dataset: z.string(),
10
+ projectId: z.string(),
11
+ schema: z.looseObject({
12
+ _original: schemaSchema
13
+ })
14
+ });
15
+ // Raw workspace schema (resolvePlugins: false) - unstable_sources not yet populated
16
+ const rawWorkspaceSchema = z.looseObject({
17
+ ...sourceSchema.shape,
18
+ basePath: z.optional(z.string()),
19
+ name: z.optional(z.string()),
20
+ plugins: z.optional(z.array(z.unknown())),
21
+ schema: z.optional(schemaSchema),
22
+ title: z.optional(z.string()),
23
+ unstable_sources: z.optional(z.array(sourceSchema))
24
+ });
25
+ // Resolved config schema (resolvePlugins: true) - all fields required
26
+ const resolvedWorkspaceSchema = z.looseObject({
27
+ ...sourceSchema.shape,
28
+ basePath: z.string(),
29
+ name: z.string(),
30
+ plugins: z.optional(z.array(z.unknown())),
31
+ title: z.string(),
32
+ unstable_sources: z.array(sourceSchema)
33
+ });
34
+ const rawConfigSchema = z.union([
35
+ z.array(rawWorkspaceSchema),
36
+ rawWorkspaceSchema
37
+ ]);
38
+ const resolvedConfigSchema = z.array(resolvedWorkspaceSchema);
39
+ export async function readStudioConfig(configPath, options) {
40
+ const result = await studioWorkerTask(new URL('readStudioConfig.worker.js', import.meta.url), {
41
+ name: 'studioConfig',
42
+ studioRootPath: dirname(configPath),
43
+ workerData: {
44
+ configPath,
45
+ resolvePlugins: options.resolvePlugins
46
+ }
47
+ });
48
+ try {
49
+ return options.resolvePlugins ? resolvedConfigSchema.parse(result) : rawConfigSchema.parse(result);
50
+ } catch (err) {
51
+ if (err instanceof z.core.$ZodError) {
52
+ throw new TypeError(`Invalid studio config at ${configPath}:\n${formatZodIssues(err.issues)}`, {
53
+ cause: err
54
+ });
55
+ }
56
+ throw err;
57
+ }
58
+ }
59
+ /**
60
+ * Recursively extracts leaf-level messages from Zod issues, including
61
+ * those nested inside union errors. Note that `prettifyError` from Zod
62
+ * only gives a high-level summary for union errors, so this function is
63
+ * needed to get the full details of all validation issues in a readable format.
64
+ *
65
+ * @internal exported for testing only
66
+ */ export function formatZodIssues(issues, indent = 2) {
67
+ const lines = [];
68
+ const prefix = ' '.repeat(indent);
69
+ for (const issue of issues){
70
+ if (issue.code === 'invalid_union' && 'errors' in issue && Array.isArray(issue.errors)) {
71
+ for (const [i, unionIssues] of issue.errors.entries()){
72
+ lines.push(`${prefix}Union option ${i + 1}:`, formatZodIssues(unionIssues, indent + 2));
73
+ }
74
+ } else {
75
+ const path = issue.path.length > 0 ? ` at "${issue.path.join('.')}"` : '';
76
+ lines.push(`${prefix}- ${issue.message}${path}`);
77
+ }
78
+ }
79
+ return lines.join('\n');
80
+ }
81
+
82
+ //# sourceMappingURL=readStudioConfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/config/studio/readStudioConfig.ts"],"sourcesContent":["import {dirname} from 'node:path'\n\nimport {z} from 'zod/mini'\n\nimport {studioWorkerTask} from '../../loaders/studio/studioWorkerTask.js'\n\nconst schemaSchema = z.looseObject({\n name: z.optional(z.string()),\n types: z.array(z.looseObject({})),\n})\n\nconst sourceSchema = z.looseObject({\n dataset: z.string(),\n projectId: z.string(),\n schema: z.looseObject({_original: schemaSchema}),\n})\n\n// Raw workspace schema (resolvePlugins: false) - unstable_sources not yet populated\nconst rawWorkspaceSchema = z.looseObject({\n ...sourceSchema.shape,\n basePath: z.optional(z.string()),\n name: z.optional(z.string()),\n plugins: z.optional(z.array(z.unknown())),\n schema: z.optional(schemaSchema),\n title: z.optional(z.string()),\n unstable_sources: z.optional(z.array(sourceSchema)),\n})\n\n// Resolved config schema (resolvePlugins: true) - all fields required\nconst resolvedWorkspaceSchema = z.looseObject({\n ...sourceSchema.shape,\n basePath: z.string(),\n name: z.string(),\n plugins: z.optional(z.array(z.unknown())),\n title: z.string(),\n unstable_sources: z.array(sourceSchema),\n})\n\nconst rawConfigSchema = z.union([z.array(rawWorkspaceSchema), rawWorkspaceSchema])\nconst resolvedConfigSchema = z.array(resolvedWorkspaceSchema)\n\nexport type RawStudioConfig = z.infer<typeof rawConfigSchema>\nexport type ResolvedStudioConfig = z.infer<typeof resolvedConfigSchema>\n\nexport interface ReadStudioConfigOptions {\n /**\n * Whether or not to resolve the plugins defined in the config.\n *\n * In some cases, you need this in order to have the full picture of what the studio\n * would \"see\". As an example, plugins can define schema types that are not explicitly\n * defined in the users' schema types. In order to get the full picture, you need to\n * resolve the plugins, which is an asyncronous operation.\n *\n * In other cases, it might be enough to only do a shallow pass. As an example, if you\n * only need to know about the defined workspace, or the user-defined schema types,\n * this can be set to `false` - which should resolve faster (and potentially \"safer\")\n * in terms of not triggering all kinds of browser behavior that may or may not be\n * loaded as the plugins are resolved.\n */\n resolvePlugins: boolean\n}\n\nexport async function readStudioConfig(\n configPath: string,\n options: {resolvePlugins: true},\n): Promise<ResolvedStudioConfig>\n\nexport async function readStudioConfig(\n configPath: string,\n options: {resolvePlugins: false},\n): Promise<RawStudioConfig>\n\nexport async function readStudioConfig(\n configPath: string,\n options: ReadStudioConfigOptions,\n): Promise<RawStudioConfig | ResolvedStudioConfig> {\n const result = await studioWorkerTask(new URL('readStudioConfig.worker.js', import.meta.url), {\n name: 'studioConfig',\n studioRootPath: dirname(configPath),\n workerData: {configPath, resolvePlugins: options.resolvePlugins},\n })\n\n try {\n return options.resolvePlugins\n ? resolvedConfigSchema.parse(result)\n : rawConfigSchema.parse(result)\n } catch (err) {\n if (err instanceof z.core.$ZodError) {\n throw new TypeError(\n `Invalid studio config at ${configPath}:\\n${formatZodIssues(err.issues)}`,\n {\n cause: err,\n },\n )\n }\n\n throw err\n }\n}\n\n/**\n * Recursively extracts leaf-level messages from Zod issues, including\n * those nested inside union errors. Note that `prettifyError` from Zod\n * only gives a high-level summary for union errors, so this function is\n * needed to get the full details of all validation issues in a readable format.\n *\n * @internal exported for testing only\n */\nexport function formatZodIssues(issues: z.core.$ZodIssue[], indent = 2): string {\n const lines: string[] = []\n const prefix = ' '.repeat(indent)\n\n for (const issue of issues) {\n if (issue.code === 'invalid_union' && 'errors' in issue && Array.isArray(issue.errors)) {\n for (const [i, unionIssues] of issue.errors.entries()) {\n lines.push(`${prefix}Union option ${i + 1}:`, formatZodIssues(unionIssues, indent + 2))\n }\n } else {\n const path = issue.path.length > 0 ? ` at \"${issue.path.join('.')}\"` : ''\n lines.push(`${prefix}- ${issue.message}${path}`)\n }\n }\n\n return lines.join('\\n')\n}\n"],"names":["dirname","z","studioWorkerTask","schemaSchema","looseObject","name","optional","string","types","array","sourceSchema","dataset","projectId","schema","_original","rawWorkspaceSchema","shape","basePath","plugins","unknown","title","unstable_sources","resolvedWorkspaceSchema","rawConfigSchema","union","resolvedConfigSchema","readStudioConfig","configPath","options","result","URL","url","studioRootPath","workerData","resolvePlugins","parse","err","core","$ZodError","TypeError","formatZodIssues","issues","cause","indent","lines","prefix","repeat","issue","code","Array","isArray","errors","i","unionIssues","entries","push","path","length","join","message"],"mappings":"AAAA,SAAQA,OAAO,QAAO,YAAW;AAEjC,SAAQC,CAAC,QAAO,WAAU;AAE1B,SAAQC,gBAAgB,QAAO,2CAA0C;AAEzE,MAAMC,eAAeF,EAAEG,WAAW,CAAC;IACjCC,MAAMJ,EAAEK,QAAQ,CAACL,EAAEM,MAAM;IACzBC,OAAOP,EAAEQ,KAAK,CAACR,EAAEG,WAAW,CAAC,CAAC;AAChC;AAEA,MAAMM,eAAeT,EAAEG,WAAW,CAAC;IACjCO,SAASV,EAAEM,MAAM;IACjBK,WAAWX,EAAEM,MAAM;IACnBM,QAAQZ,EAAEG,WAAW,CAAC;QAACU,WAAWX;IAAY;AAChD;AAEA,oFAAoF;AACpF,MAAMY,qBAAqBd,EAAEG,WAAW,CAAC;IACvC,GAAGM,aAAaM,KAAK;IACrBC,UAAUhB,EAAEK,QAAQ,CAACL,EAAEM,MAAM;IAC7BF,MAAMJ,EAAEK,QAAQ,CAACL,EAAEM,MAAM;IACzBW,SAASjB,EAAEK,QAAQ,CAACL,EAAEQ,KAAK,CAACR,EAAEkB,OAAO;IACrCN,QAAQZ,EAAEK,QAAQ,CAACH;IACnBiB,OAAOnB,EAAEK,QAAQ,CAACL,EAAEM,MAAM;IAC1Bc,kBAAkBpB,EAAEK,QAAQ,CAACL,EAAEQ,KAAK,CAACC;AACvC;AAEA,sEAAsE;AACtE,MAAMY,0BAA0BrB,EAAEG,WAAW,CAAC;IAC5C,GAAGM,aAAaM,KAAK;IACrBC,UAAUhB,EAAEM,MAAM;IAClBF,MAAMJ,EAAEM,MAAM;IACdW,SAASjB,EAAEK,QAAQ,CAACL,EAAEQ,KAAK,CAACR,EAAEkB,OAAO;IACrCC,OAAOnB,EAAEM,MAAM;IACfc,kBAAkBpB,EAAEQ,KAAK,CAACC;AAC5B;AAEA,MAAMa,kBAAkBtB,EAAEuB,KAAK,CAAC;IAACvB,EAAEQ,KAAK,CAACM;IAAqBA;CAAmB;AACjF,MAAMU,uBAAuBxB,EAAEQ,KAAK,CAACa;AAiCrC,OAAO,eAAeI,iBACpBC,UAAkB,EAClBC,OAAgC;IAEhC,MAAMC,SAAS,MAAM3B,iBAAiB,IAAI4B,IAAI,8BAA8B,YAAYC,GAAG,GAAG;QAC5F1B,MAAM;QACN2B,gBAAgBhC,QAAQ2B;QACxBM,YAAY;YAACN;YAAYO,gBAAgBN,QAAQM,cAAc;QAAA;IACjE;IAEA,IAAI;QACF,OAAON,QAAQM,cAAc,GACzBT,qBAAqBU,KAAK,CAACN,UAC3BN,gBAAgBY,KAAK,CAACN;IAC5B,EAAE,OAAOO,KAAK;QACZ,IAAIA,eAAenC,EAAEoC,IAAI,CAACC,SAAS,EAAE;YACnC,MAAM,IAAIC,UACR,CAAC,yBAAyB,EAAEZ,WAAW,GAAG,EAAEa,gBAAgBJ,IAAIK,MAAM,GAAG,EACzE;gBACEC,OAAON;YACT;QAEJ;QAEA,MAAMA;IACR;AACF;AAEA;;;;;;;CAOC,GACD,OAAO,SAASI,gBAAgBC,MAA0B,EAAEE,SAAS,CAAC;IACpE,MAAMC,QAAkB,EAAE;IAC1B,MAAMC,SAAS,IAAIC,MAAM,CAACH;IAE1B,KAAK,MAAMI,SAASN,OAAQ;QAC1B,IAAIM,MAAMC,IAAI,KAAK,mBAAmB,YAAYD,SAASE,MAAMC,OAAO,CAACH,MAAMI,MAAM,GAAG;YACtF,KAAK,MAAM,CAACC,GAAGC,YAAY,IAAIN,MAAMI,MAAM,CAACG,OAAO,GAAI;gBACrDV,MAAMW,IAAI,CAAC,GAAGV,OAAO,aAAa,EAAEO,IAAI,EAAE,CAAC,CAAC,EAAEZ,gBAAgBa,aAAaV,SAAS;YACtF;QACF,OAAO;YACL,MAAMa,OAAOT,MAAMS,IAAI,CAACC,MAAM,GAAG,IAAI,CAAC,KAAK,EAAEV,MAAMS,IAAI,CAACE,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG;YACvEd,MAAMW,IAAI,CAAC,GAAGV,OAAO,EAAE,EAAEE,MAAMY,OAAO,GAAGH,MAAM;QACjD;IACF;IAEA,OAAOZ,MAAMc,IAAI,CAAC;AACpB"}
@@ -0,0 +1,25 @@
1
+ import { isMainThread, parentPort, workerData } from 'node:worker_threads';
2
+ import { z } from 'zod/mini';
3
+ import { subdebug } from '../../debug.js';
4
+ import { doImport } from '../../util/doImport.js';
5
+ import { safeStructuredClone } from '../../util/safeStructuredClone.js';
6
+ import { getStudioWorkspaces } from './getStudioWorkspaces.js';
7
+ if (isMainThread || !parentPort) {
8
+ throw new Error('Should only be run in a worker!');
9
+ }
10
+ const debug = subdebug('readStudioConfig.worker');
11
+ const { configPath, resolvePlugins } = z.object({
12
+ configPath: z.string(),
13
+ resolvePlugins: z.boolean()
14
+ }).parse(workerData);
15
+ debug('Parsing config path %s', configPath);
16
+ let { default: config } = await doImport(configPath);
17
+ debug('Imported config %o', config);
18
+ if (resolvePlugins) {
19
+ debug('Resolving workspaces');
20
+ config = await getStudioWorkspaces(configPath);
21
+ debug('Resolved workspaces %o', config);
22
+ }
23
+ parentPort.postMessage(safeStructuredClone(config));
24
+
25
+ //# sourceMappingURL=readStudioConfig.worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/config/studio/readStudioConfig.worker.ts"],"sourcesContent":["import {isMainThread, parentPort, workerData} from 'node:worker_threads'\n\nimport {z} from 'zod/mini'\n\nimport {subdebug} from '../../debug.js'\nimport {doImport} from '../../util/doImport.js'\nimport {safeStructuredClone} from '../../util/safeStructuredClone.js'\nimport {getStudioWorkspaces} from './getStudioWorkspaces.js'\n\nif (isMainThread || !parentPort) {\n throw new Error('Should only be run in a worker!')\n}\n\nconst debug = subdebug('readStudioConfig.worker')\n\nconst {configPath, resolvePlugins} = z\n .object({configPath: z.string(), resolvePlugins: z.boolean()})\n .parse(workerData)\n\ndebug('Parsing config path %s', configPath)\n\nlet {default: config} = await doImport(configPath)\n\ndebug('Imported config %o', config)\n\nif (resolvePlugins) {\n debug('Resolving workspaces')\n config = await getStudioWorkspaces(configPath)\n debug('Resolved workspaces %o', config)\n}\n\nparentPort.postMessage(safeStructuredClone(config))\n"],"names":["isMainThread","parentPort","workerData","z","subdebug","doImport","safeStructuredClone","getStudioWorkspaces","Error","debug","configPath","resolvePlugins","object","string","boolean","parse","default","config","postMessage"],"mappings":"AAAA,SAAQA,YAAY,EAAEC,UAAU,EAAEC,UAAU,QAAO,sBAAqB;AAExE,SAAQC,CAAC,QAAO,WAAU;AAE1B,SAAQC,QAAQ,QAAO,iBAAgB;AACvC,SAAQC,QAAQ,QAAO,yBAAwB;AAC/C,SAAQC,mBAAmB,QAAO,oCAAmC;AACrE,SAAQC,mBAAmB,QAAO,2BAA0B;AAE5D,IAAIP,gBAAgB,CAACC,YAAY;IAC/B,MAAM,IAAIO,MAAM;AAClB;AAEA,MAAMC,QAAQL,SAAS;AAEvB,MAAM,EAACM,UAAU,EAAEC,cAAc,EAAC,GAAGR,EAClCS,MAAM,CAAC;IAACF,YAAYP,EAAEU,MAAM;IAAIF,gBAAgBR,EAAEW,OAAO;AAAE,GAC3DC,KAAK,CAACb;AAETO,MAAM,0BAA0BC;AAEhC,IAAI,EAACM,SAASC,MAAM,EAAC,GAAG,MAAMZ,SAASK;AAEvCD,MAAM,sBAAsBQ;AAE5B,IAAIN,gBAAgB;IAClBF,MAAM;IACNQ,SAAS,MAAMV,oBAAoBG;IACnCD,MAAM,0BAA0BQ;AAClC;AAEAhB,WAAWiB,WAAW,CAACZ,oBAAoBW"}
@@ -0,0 +1,85 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import { basename, join } from 'node:path';
3
+ /**
4
+ * Checks for a `sanity.json` file with `"root": true` in the given directory synchronously.
5
+ *
6
+ * @param basePath - The base path to look for a `sanity.json` in
7
+ * @returns true if a `sanity.json` with `"root": true` is found, false otherwise
8
+ * @internal
9
+ */ function isSanityV2StudioRootSync(basePath) {
10
+ try {
11
+ const content = readFileSync(join(basePath, 'sanity.json'), 'utf8');
12
+ const sanityJson = JSON.parse(content);
13
+ if (!sanityJson || typeof sanityJson !== 'object' || Array.isArray(sanityJson)) {
14
+ throw new Error('Invalid sanity.json, expected an object');
15
+ }
16
+ const isRoot = Boolean(sanityJson?.root);
17
+ return isRoot;
18
+ } catch {
19
+ return false;
20
+ }
21
+ }
22
+ /**
23
+ * Finds the path for a given set of files synchronously.
24
+ *
25
+ * @param basePath - The base path to search for files.
26
+ * @param files - The files to search for.
27
+ * @returns Array of path results
28
+ * @internal
29
+ */ function findPathForFilesSync(basePath, files) {
30
+ return files.map((file)=>{
31
+ const path = join(basePath, file);
32
+ const exists = existsSync(path);
33
+ return {
34
+ exists,
35
+ path
36
+ };
37
+ });
38
+ }
39
+ /**
40
+ * Resolves to a string containing the found config path, or `undefined` if not found.
41
+ * Throws if Sanity v2 studio root is found.
42
+ *
43
+ * @param basePath - The base path to start searching from
44
+ * @returns A string containing the found config path, or `undefined` if not found
45
+ * @internal
46
+ */ export function findStudioConfigPathSync(basePath) {
47
+ if (isSanityV2StudioRootSync(basePath)) {
48
+ throw new Error(`Found 'sanity.json' at ${basePath} - Sanity Studio < v3 is no longer supported`);
49
+ }
50
+ const paths = findPathForFilesSync(basePath, [
51
+ 'sanity.config.ts',
52
+ 'sanity.config.tsx',
53
+ 'sanity.config.js',
54
+ 'sanity.config.jsx'
55
+ ]);
56
+ const configPaths = paths.filter((path)=>path.exists);
57
+ if (configPaths.length > 1) {
58
+ const baseNames = configPaths.map((config)=>config.path).map((path)=>basename(path));
59
+ throw new Error(`Multiple studio config files found (${baseNames.join(', ')})`);
60
+ }
61
+ if (configPaths.length === 1) {
62
+ return configPaths[0].path;
63
+ }
64
+ }
65
+ /**
66
+ * Resolves to a string containing the found config path, or `undefined` if not found.
67
+ *
68
+ * @param basePath - The base path to start searching from
69
+ * @returns A string containing the found config path, or `undefined` if not found
70
+ * @internal
71
+ */ export function findAppConfigPathSync(basePath) {
72
+ const paths = findPathForFilesSync(basePath, [
73
+ 'sanity.cli.ts',
74
+ 'sanity.cli.js'
75
+ ]);
76
+ const configPaths = paths.filter((path)=>path.exists);
77
+ if (configPaths.length > 1) {
78
+ throw new Error(`Multiple app config files found (${configPaths.map((path)=>path.path).join(', ')})`);
79
+ }
80
+ if (configPaths.length === 1) {
81
+ return configPaths[0].path;
82
+ }
83
+ }
84
+
85
+ //# sourceMappingURL=configPathsSync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/config/util/configPathsSync.ts"],"sourcesContent":["import {existsSync, readFileSync} from 'node:fs'\nimport {basename, join} from 'node:path'\n\n/**\n * @internal\n */\ninterface PathResult {\n exists: boolean\n path: string\n}\n\n/**\n * Checks for a `sanity.json` file with `\"root\": true` in the given directory synchronously.\n *\n * @param basePath - The base path to look for a `sanity.json` in\n * @returns true if a `sanity.json` with `\"root\": true` is found, false otherwise\n * @internal\n */\nfunction isSanityV2StudioRootSync(basePath: string): boolean {\n try {\n const content = readFileSync(join(basePath, 'sanity.json'), 'utf8')\n const sanityJson = JSON.parse(content)\n if (!sanityJson || typeof sanityJson !== 'object' || Array.isArray(sanityJson)) {\n throw new Error('Invalid sanity.json, expected an object')\n }\n const isRoot = Boolean(sanityJson?.root)\n return isRoot\n } catch {\n return false\n }\n}\n\n/**\n * Finds the path for a given set of files synchronously.\n *\n * @param basePath - The base path to search for files.\n * @param files - The files to search for.\n * @returns Array of path results\n * @internal\n */\nfunction findPathForFilesSync(basePath: string, files: string[]): PathResult[] {\n return files.map((file) => {\n const path = join(basePath, file)\n const exists = existsSync(path)\n return {exists, path}\n })\n}\n\n/**\n * Resolves to a string containing the found config path, or `undefined` if not found.\n * Throws if Sanity v2 studio root is found.\n *\n * @param basePath - The base path to start searching from\n * @returns A string containing the found config path, or `undefined` if not found\n * @internal\n */\nexport function findStudioConfigPathSync(basePath: string): string | undefined {\n if (isSanityV2StudioRootSync(basePath)) {\n throw new Error(\n `Found 'sanity.json' at ${basePath} - Sanity Studio < v3 is no longer supported`,\n )\n }\n\n const paths = findPathForFilesSync(basePath, [\n 'sanity.config.ts',\n 'sanity.config.tsx',\n 'sanity.config.js',\n 'sanity.config.jsx',\n ])\n\n const configPaths = paths.filter((path) => path.exists)\n if (configPaths.length > 1) {\n const baseNames = configPaths.map((config) => config.path).map((path) => basename(path))\n throw new Error(`Multiple studio config files found (${baseNames.join(', ')})`)\n }\n\n if (configPaths.length === 1) {\n return configPaths[0].path\n }\n}\n\n/**\n * Resolves to a string containing the found config path, or `undefined` if not found.\n *\n * @param basePath - The base path to start searching from\n * @returns A string containing the found config path, or `undefined` if not found\n * @internal\n */\nexport function findAppConfigPathSync(basePath: string): string | undefined {\n const paths = findPathForFilesSync(basePath, ['sanity.cli.ts', 'sanity.cli.js'])\n const configPaths = paths.filter((path) => path.exists)\n if (configPaths.length > 1) {\n throw new Error(\n `Multiple app config files found (${configPaths.map((path) => path.path).join(', ')})`,\n )\n }\n\n if (configPaths.length === 1) {\n return configPaths[0].path\n }\n}\n"],"names":["existsSync","readFileSync","basename","join","isSanityV2StudioRootSync","basePath","content","sanityJson","JSON","parse","Array","isArray","Error","isRoot","Boolean","root","findPathForFilesSync","files","map","file","path","exists","findStudioConfigPathSync","paths","configPaths","filter","length","baseNames","config","findAppConfigPathSync"],"mappings":"AAAA,SAAQA,UAAU,EAAEC,YAAY,QAAO,UAAS;AAChD,SAAQC,QAAQ,EAAEC,IAAI,QAAO,YAAW;AAUxC;;;;;;CAMC,GACD,SAASC,yBAAyBC,QAAgB;IAChD,IAAI;QACF,MAAMC,UAAUL,aAAaE,KAAKE,UAAU,gBAAgB;QAC5D,MAAME,aAAaC,KAAKC,KAAK,CAACH;QAC9B,IAAI,CAACC,cAAc,OAAOA,eAAe,YAAYG,MAAMC,OAAO,CAACJ,aAAa;YAC9E,MAAM,IAAIK,MAAM;QAClB;QACA,MAAMC,SAASC,QAAQP,YAAYQ;QACnC,OAAOF;IACT,EAAE,OAAM;QACN,OAAO;IACT;AACF;AAEA;;;;;;;CAOC,GACD,SAASG,qBAAqBX,QAAgB,EAAEY,KAAe;IAC7D,OAAOA,MAAMC,GAAG,CAAC,CAACC;QAChB,MAAMC,OAAOjB,KAAKE,UAAUc;QAC5B,MAAME,SAASrB,WAAWoB;QAC1B,OAAO;YAACC;YAAQD;QAAI;IACtB;AACF;AAEA;;;;;;;CAOC,GACD,OAAO,SAASE,yBAAyBjB,QAAgB;IACvD,IAAID,yBAAyBC,WAAW;QACtC,MAAM,IAAIO,MACR,CAAC,uBAAuB,EAAEP,SAAS,4CAA4C,CAAC;IAEpF;IAEA,MAAMkB,QAAQP,qBAAqBX,UAAU;QAC3C;QACA;QACA;QACA;KACD;IAED,MAAMmB,cAAcD,MAAME,MAAM,CAAC,CAACL,OAASA,KAAKC,MAAM;IACtD,IAAIG,YAAYE,MAAM,GAAG,GAAG;QAC1B,MAAMC,YAAYH,YAAYN,GAAG,CAAC,CAACU,SAAWA,OAAOR,IAAI,EAAEF,GAAG,CAAC,CAACE,OAASlB,SAASkB;QAClF,MAAM,IAAIR,MAAM,CAAC,oCAAoC,EAAEe,UAAUxB,IAAI,CAAC,MAAM,CAAC,CAAC;IAChF;IAEA,IAAIqB,YAAYE,MAAM,KAAK,GAAG;QAC5B,OAAOF,WAAW,CAAC,EAAE,CAACJ,IAAI;IAC5B;AACF;AAEA;;;;;;CAMC,GACD,OAAO,SAASS,sBAAsBxB,QAAgB;IACpD,MAAMkB,QAAQP,qBAAqBX,UAAU;QAAC;QAAiB;KAAgB;IAC/E,MAAMmB,cAAcD,MAAME,MAAM,CAAC,CAACL,OAASA,KAAKC,MAAM;IACtD,IAAIG,YAAYE,MAAM,GAAG,GAAG;QAC1B,MAAM,IAAId,MACR,CAAC,iCAAiC,EAAEY,YAAYN,GAAG,CAAC,CAACE,OAASA,KAAKA,IAAI,EAAEjB,IAAI,CAAC,MAAM,CAAC,CAAC;IAE1F;IAEA,IAAIqB,YAAYE,MAAM,KAAK,GAAG;QAC5B,OAAOF,WAAW,CAAC,EAAE,CAACJ,IAAI;IAC5B;AACF"}
@@ -0,0 +1,22 @@
1
+ import { findPathForFiles } from './findConfigsPaths.js';
2
+ /**
3
+ * Resolves to a string containing the found config path, or `undefined` if not found.
4
+ *
5
+ * @param basePath - The base path to start searching from
6
+ * @returns A promise that resolves to a string containing the found config path, or `undefined` if not found
7
+ * @internal
8
+ */ export async function findAppConfigPath(basePath) {
9
+ const paths = await findPathForFiles(basePath, [
10
+ 'sanity.cli.ts',
11
+ 'sanity.cli.js'
12
+ ]);
13
+ const configPaths = paths.filter((path)=>path.exists);
14
+ if (configPaths.length > 1) {
15
+ throw new Error(`Multiple app config files found (${configPaths.map((path)=>path.path).join(', ')})`);
16
+ }
17
+ if (configPaths.length === 1) {
18
+ return configPaths[0].path;
19
+ }
20
+ }
21
+
22
+ //# sourceMappingURL=findAppConfigPath.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/config/util/findAppConfigPath.ts"],"sourcesContent":["import {findPathForFiles} from './findConfigsPaths.js'\n\n/**\n * Resolves to a string containing the found config path, or `undefined` if not found.\n *\n * @param basePath - The base path to start searching from\n * @returns A promise that resolves to a string containing the found config path, or `undefined` if not found\n * @internal\n */\nexport async function findAppConfigPath(basePath: string): Promise<string | undefined> {\n const paths = await findPathForFiles(basePath, ['sanity.cli.ts', 'sanity.cli.js'])\n const configPaths = paths.filter((path) => path.exists)\n if (configPaths.length > 1) {\n throw new Error(\n `Multiple app config files found (${configPaths.map((path) => path.path).join(', ')})`,\n )\n }\n\n if (configPaths.length === 1) {\n return configPaths[0].path\n }\n}\n"],"names":["findPathForFiles","findAppConfigPath","basePath","paths","configPaths","filter","path","exists","length","Error","map","join"],"mappings":"AAAA,SAAQA,gBAAgB,QAAO,wBAAuB;AAEtD;;;;;;CAMC,GACD,OAAO,eAAeC,kBAAkBC,QAAgB;IACtD,MAAMC,QAAQ,MAAMH,iBAAiBE,UAAU;QAAC;QAAiB;KAAgB;IACjF,MAAME,cAAcD,MAAME,MAAM,CAAC,CAACC,OAASA,KAAKC,MAAM;IACtD,IAAIH,YAAYI,MAAM,GAAG,GAAG;QAC1B,MAAM,IAAIC,MACR,CAAC,iCAAiC,EAAEL,YAAYM,GAAG,CAAC,CAACJ,OAASA,KAAKA,IAAI,EAAEK,IAAI,CAAC,MAAM,CAAC,CAAC;IAE1F;IAEA,IAAIP,YAAYI,MAAM,KAAK,GAAG;QAC5B,OAAOJ,WAAW,CAAC,EAAE,CAACE,IAAI;IAC5B;AACF"}
@@ -0,0 +1,21 @@
1
+ import { join } from 'node:path';
2
+ import { fileExists } from '../../util/fileExists.js';
3
+ /**
4
+ * Finds the path for a given set of files.
5
+ *
6
+ * @param basePath - The base path to search for files.
7
+ * @param files - The files to search for.
8
+ * @internal
9
+ */ export async function findPathForFiles(basePath, files) {
10
+ const paths = await Promise.all(files.map(async (file)=>{
11
+ const path = join(basePath, file);
12
+ const exists = await fileExists(path);
13
+ return {
14
+ exists,
15
+ path
16
+ };
17
+ }));
18
+ return paths;
19
+ }
20
+
21
+ //# sourceMappingURL=findConfigsPaths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/config/util/findConfigsPaths.ts"],"sourcesContent":["import {join} from 'node:path'\n\nimport {fileExists} from '../../util/fileExists.js'\n\n/**\n * @internal\n */\ninterface PathResult {\n exists: boolean\n path: string\n}\n\n/**\n * Finds the path for a given set of files.\n *\n * @param basePath - The base path to search for files.\n * @param files - The files to search for.\n * @internal\n */\nexport async function findPathForFiles(basePath: string, files: string[]): Promise<PathResult[]> {\n const paths = await Promise.all(\n files.map(async (file) => {\n const path = join(basePath, file)\n const exists = await fileExists(path)\n return {exists, path}\n }),\n )\n\n return paths\n}\n"],"names":["join","fileExists","findPathForFiles","basePath","files","paths","Promise","all","map","file","path","exists"],"mappings":"AAAA,SAAQA,IAAI,QAAO,YAAW;AAE9B,SAAQC,UAAU,QAAO,2BAA0B;AAUnD;;;;;;CAMC,GACD,OAAO,eAAeC,iBAAiBC,QAAgB,EAAEC,KAAe;IACtE,MAAMC,QAAQ,MAAMC,QAAQC,GAAG,CAC7BH,MAAMI,GAAG,CAAC,OAAOC;QACf,MAAMC,OAAOV,KAAKG,UAAUM;QAC5B,MAAME,SAAS,MAAMV,WAAWS;QAChC,OAAO;YAACC;YAAQD;QAAI;IACtB;IAGF,OAAOL;AACT"}
@@ -0,0 +1,52 @@
1
+ import { basename } from 'node:path';
2
+ import { findPathForFiles } from './findConfigsPaths.js';
3
+ import { isSanityV2StudioRoot } from './isSanityV2StudioRoot.js';
4
+ /**
5
+ * Resolves to a string containing the found config path, otherwise throws an error.
6
+ * Also throws if Sanity v2 studio root is found.
7
+ *
8
+ * @param basePath - The base path to start searching from
9
+ * @returns A promise that resolves to a string containing the found config path
10
+ * @throws On multiple config files found, if v2 studio root found, or no config found
11
+ * @internal
12
+ */ export async function findStudioConfigPath(basePath) {
13
+ if (await isSanityV2StudioRoot(basePath)) {
14
+ throw new Error(`Found 'sanity.json' at ${basePath} - Sanity Studio < v3 is no longer supported`);
15
+ }
16
+ const paths = await findPathForFiles(basePath, [
17
+ 'sanity.config.ts',
18
+ 'sanity.config.tsx',
19
+ 'sanity.config.js',
20
+ 'sanity.config.jsx'
21
+ ]);
22
+ const configPaths = paths.filter((path)=>path.exists);
23
+ if (configPaths.length > 1) {
24
+ const baseNames = configPaths.map((config)=>config.path).map((path)=>basename(path));
25
+ throw new Error(`Multiple studio config files found (${baseNames.join(', ')})`);
26
+ }
27
+ if (configPaths.length === 1) {
28
+ return configPaths[0].path;
29
+ }
30
+ throw new ConfigNotFoundError(`No studio config file found at ${basePath}`);
31
+ }
32
+ /**
33
+ * Tries to find the studio config path, returning `undefined` if not found.
34
+ *
35
+ * @param basePath - The base path to start searching from
36
+ * @returns A promise that resolves to a string containing the found config path, or `undefined` if not found
37
+ * @throws On errors other than config not found
38
+ * @internal
39
+ */ export async function tryFindStudioConfigPath(basePath) {
40
+ try {
41
+ return await findStudioConfigPath(basePath);
42
+ } catch (err) {
43
+ if (err instanceof ConfigNotFoundError) {
44
+ return undefined;
45
+ }
46
+ throw err;
47
+ }
48
+ }
49
+ class ConfigNotFoundError extends Error {
50
+ }
51
+
52
+ //# sourceMappingURL=findStudioConfigPath.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/config/util/findStudioConfigPath.ts"],"sourcesContent":["import {basename} from 'node:path'\n\nimport {findPathForFiles} from './findConfigsPaths.js'\nimport {isSanityV2StudioRoot} from './isSanityV2StudioRoot.js'\n\n/**\n * Resolves to a string containing the found config path, otherwise throws an error.\n * Also throws if Sanity v2 studio root is found.\n *\n * @param basePath - The base path to start searching from\n * @returns A promise that resolves to a string containing the found config path\n * @throws On multiple config files found, if v2 studio root found, or no config found\n * @internal\n */\nexport async function findStudioConfigPath(basePath: string): Promise<string> {\n if (await isSanityV2StudioRoot(basePath)) {\n throw new Error(\n `Found 'sanity.json' at ${basePath} - Sanity Studio < v3 is no longer supported`,\n )\n }\n\n const paths = await findPathForFiles(basePath, [\n 'sanity.config.ts',\n 'sanity.config.tsx',\n 'sanity.config.js',\n 'sanity.config.jsx',\n ])\n\n const configPaths = paths.filter((path) => path.exists)\n if (configPaths.length > 1) {\n const baseNames = configPaths.map((config) => config.path).map((path) => basename(path))\n throw new Error(`Multiple studio config files found (${baseNames.join(', ')})`)\n }\n\n if (configPaths.length === 1) {\n return configPaths[0].path\n }\n\n throw new ConfigNotFoundError(`No studio config file found at ${basePath}`)\n}\n\n/**\n * Tries to find the studio config path, returning `undefined` if not found.\n *\n * @param basePath - The base path to start searching from\n * @returns A promise that resolves to a string containing the found config path, or `undefined` if not found\n * @throws On errors other than config not found\n * @internal\n */\nexport async function tryFindStudioConfigPath(basePath: string): Promise<string | undefined> {\n try {\n return await findStudioConfigPath(basePath)\n } catch (err) {\n if (err instanceof ConfigNotFoundError) {\n return undefined\n }\n throw err\n }\n}\n\nclass ConfigNotFoundError extends Error {}\n"],"names":["basename","findPathForFiles","isSanityV2StudioRoot","findStudioConfigPath","basePath","Error","paths","configPaths","filter","path","exists","length","baseNames","map","config","join","ConfigNotFoundError","tryFindStudioConfigPath","err","undefined"],"mappings":"AAAA,SAAQA,QAAQ,QAAO,YAAW;AAElC,SAAQC,gBAAgB,QAAO,wBAAuB;AACtD,SAAQC,oBAAoB,QAAO,4BAA2B;AAE9D;;;;;;;;CAQC,GACD,OAAO,eAAeC,qBAAqBC,QAAgB;IACzD,IAAI,MAAMF,qBAAqBE,WAAW;QACxC,MAAM,IAAIC,MACR,CAAC,uBAAuB,EAAED,SAAS,4CAA4C,CAAC;IAEpF;IAEA,MAAME,QAAQ,MAAML,iBAAiBG,UAAU;QAC7C;QACA;QACA;QACA;KACD;IAED,MAAMG,cAAcD,MAAME,MAAM,CAAC,CAACC,OAASA,KAAKC,MAAM;IACtD,IAAIH,YAAYI,MAAM,GAAG,GAAG;QAC1B,MAAMC,YAAYL,YAAYM,GAAG,CAAC,CAACC,SAAWA,OAAOL,IAAI,EAAEI,GAAG,CAAC,CAACJ,OAAST,SAASS;QAClF,MAAM,IAAIJ,MAAM,CAAC,oCAAoC,EAAEO,UAAUG,IAAI,CAAC,MAAM,CAAC,CAAC;IAChF;IAEA,IAAIR,YAAYI,MAAM,KAAK,GAAG;QAC5B,OAAOJ,WAAW,CAAC,EAAE,CAACE,IAAI;IAC5B;IAEA,MAAM,IAAIO,oBAAoB,CAAC,+BAA+B,EAAEZ,UAAU;AAC5E;AAEA;;;;;;;CAOC,GACD,OAAO,eAAea,wBAAwBb,QAAgB;IAC5D,IAAI;QACF,OAAO,MAAMD,qBAAqBC;IACpC,EAAE,OAAOc,KAAK;QACZ,IAAIA,eAAeF,qBAAqB;YACtC,OAAOG;QACT;QACA,MAAMD;IACR;AACF;AAEA,MAAMF,4BAA4BX;AAAO"}
@@ -0,0 +1,22 @@
1
+ import { join } from 'node:path';
2
+ import { readJsonFile } from '../../util/readJsonFile.js';
3
+ /**
4
+ * Checks for a `sanity.json` file with `"root": true` in the given directory.
5
+ *
6
+ * @param basePath - The base path to look for a `sanity.json` in
7
+ * @returns Resolves to true if a `sanity.json` with `"root": true` is found, false otherwise
8
+ * @internal
9
+ */ export async function isSanityV2StudioRoot(basePath) {
10
+ try {
11
+ const sanityJson = await readJsonFile(join(basePath, 'sanity.json'));
12
+ if (!sanityJson || typeof sanityJson !== 'object' || Array.isArray(sanityJson)) {
13
+ throw new Error('Invalid sanity.json, expected an object');
14
+ }
15
+ const isRoot = Boolean(sanityJson?.root);
16
+ return isRoot;
17
+ } catch {
18
+ return false;
19
+ }
20
+ }
21
+
22
+ //# sourceMappingURL=isSanityV2StudioRoot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/config/util/isSanityV2StudioRoot.ts"],"sourcesContent":["import {join} from 'node:path'\n\nimport {readJsonFile} from '../../util/readJsonFile.js'\n\n/**\n * Checks for a `sanity.json` file with `\"root\": true` in the given directory.\n *\n * @param basePath - The base path to look for a `sanity.json` in\n * @returns Resolves to true if a `sanity.json` with `\"root\": true` is found, false otherwise\n * @internal\n */\nexport async function isSanityV2StudioRoot(basePath: string): Promise<boolean> {\n try {\n const sanityJson = await readJsonFile(join(basePath, 'sanity.json'))\n if (!sanityJson || typeof sanityJson !== 'object' || Array.isArray(sanityJson)) {\n throw new Error('Invalid sanity.json, expected an object')\n }\n const isRoot = Boolean(sanityJson?.root)\n return isRoot\n } catch {\n return false\n }\n}\n"],"names":["join","readJsonFile","isSanityV2StudioRoot","basePath","sanityJson","Array","isArray","Error","isRoot","Boolean","root"],"mappings":"AAAA,SAAQA,IAAI,QAAO,YAAW;AAE9B,SAAQC,YAAY,QAAO,6BAA4B;AAEvD;;;;;;CAMC,GACD,OAAO,eAAeC,qBAAqBC,QAAgB;IACzD,IAAI;QACF,MAAMC,aAAa,MAAMH,aAAaD,KAAKG,UAAU;QACrD,IAAI,CAACC,cAAc,OAAOA,eAAe,YAAYC,MAAMC,OAAO,CAACF,aAAa;YAC9E,MAAM,IAAIG,MAAM;QAClB;QACA,MAAMC,SAASC,QAAQL,YAAYM;QACnC,OAAOF;IACT,EAAE,OAAM;QACN,OAAO;IACT;AACF"}
@@ -0,0 +1,28 @@
1
+ import { dirname, resolve } from 'node:path';
2
+ /**
3
+ * Generic recursive search function for project configuration files.
4
+ *
5
+ * @param basePath - The base path to start searching from
6
+ * @param findConfigFn - Function that looks for config files in a given directory
7
+ * @param projectType - The type of project ('app' | 'studio')
8
+ * @param iterations - Current iteration count, passed internally to prevent infinite recursion
9
+ * @returns A promise that resolves to an object if config is found, false otherwise
10
+ * @internal
11
+ */ export async function recursivelyResolveProjectRoot(basePath, findConfigFn, projectType, iterations = 0) {
12
+ const configPath = await findConfigFn(basePath);
13
+ if (configPath) {
14
+ return {
15
+ directory: dirname(configPath),
16
+ path: configPath,
17
+ type: projectType
18
+ };
19
+ }
20
+ const parentDir = resolve(basePath, '..');
21
+ if (parentDir === basePath || iterations > 50) {
22
+ // Reached root (or max depth), give up
23
+ return false;
24
+ }
25
+ return recursivelyResolveProjectRoot(parentDir, findConfigFn, projectType, iterations + 1);
26
+ }
27
+
28
+ //# sourceMappingURL=recursivelyResolveProjectRoot.js.map