@sanity/cli 6.5.3 → 6.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (188) hide show
  1. package/README.md +18 -5
  2. package/bin/run.js +3 -1
  3. package/dist/actions/auth/login/login.js +39 -13
  4. package/dist/actions/auth/login/login.js.map +1 -1
  5. package/dist/actions/auth/login/validateToken.js +39 -0
  6. package/dist/actions/auth/login/validateToken.js.map +1 -0
  7. package/dist/actions/build/buildApp.js +4 -5
  8. package/dist/actions/build/buildApp.js.map +1 -1
  9. package/dist/actions/build/buildStaticFiles.js +12 -4
  10. package/dist/actions/build/buildStaticFiles.js.map +1 -1
  11. package/dist/actions/build/buildStudio.js +6 -14
  12. package/dist/actions/build/buildStudio.js.map +1 -1
  13. package/dist/actions/build/{getStudioEnvironmentVariables.js → getEnvironmentVariables.js} +15 -19
  14. package/dist/actions/build/getEnvironmentVariables.js.map +1 -0
  15. package/dist/actions/deploy/deployStudio.js +1 -2
  16. package/dist/actions/deploy/deployStudio.js.map +1 -1
  17. package/dist/actions/deploy/deployStudioSchemasAndManifests.js +1 -2
  18. package/dist/actions/deploy/deployStudioSchemasAndManifests.js.map +1 -1
  19. package/dist/actions/deploy/deployStudioSchemasAndManifests.worker.js +1 -1
  20. package/dist/actions/deploy/deployStudioSchemasAndManifests.worker.js.map +1 -1
  21. package/dist/actions/dev/startStudioDevServer.js +1 -1
  22. package/dist/actions/dev/startStudioDevServer.js.map +1 -1
  23. package/dist/actions/documents/validateDocuments.worker.js +1 -2
  24. package/dist/actions/documents/validateDocuments.worker.js.map +1 -1
  25. package/dist/actions/graphql/SchemaError.js +1 -1
  26. package/dist/actions/graphql/SchemaError.js.map +1 -1
  27. package/dist/actions/init/initAction.js +32 -1
  28. package/dist/actions/init/initAction.js.map +1 -1
  29. package/dist/actions/init/scaffoldTemplate.js +32 -18
  30. package/dist/actions/init/scaffoldTemplate.js.map +1 -1
  31. package/dist/actions/init/templates/index.js +2 -0
  32. package/dist/actions/init/templates/index.js.map +1 -1
  33. package/dist/actions/init/templates/pageBuilder.js +32 -0
  34. package/dist/actions/init/templates/pageBuilder.js.map +1 -0
  35. package/dist/actions/init/types.js +2 -1
  36. package/dist/actions/init/types.js.map +1 -1
  37. package/dist/actions/manifest/extractManifest.js +1 -1
  38. package/dist/actions/manifest/extractManifest.js.map +1 -1
  39. package/dist/actions/manifest/extractManifest.worker.js +1 -1
  40. package/dist/actions/manifest/extractManifest.worker.js.map +1 -1
  41. package/dist/actions/mcp/editorConfigs.js +51 -11
  42. package/dist/actions/mcp/editorConfigs.js.map +1 -1
  43. package/dist/actions/mcp/promptForMCPSetup.js +16 -11
  44. package/dist/actions/mcp/promptForMCPSetup.js.map +1 -1
  45. package/dist/actions/mcp/setupMCP.js +180 -61
  46. package/dist/actions/mcp/setupMCP.js.map +1 -1
  47. package/dist/actions/mcp/types.js.map +1 -1
  48. package/dist/actions/schema/deploySchemas.js +1 -1
  49. package/dist/actions/schema/deploySchemas.js.map +1 -1
  50. package/dist/actions/schema/extractSanityWorkspace.worker.js +1 -1
  51. package/dist/actions/schema/extractSanityWorkspace.worker.js.map +1 -1
  52. package/dist/actions/schema/extractSchema.js +1 -4
  53. package/dist/actions/schema/extractSchema.js.map +1 -1
  54. package/dist/actions/schema/extractSchemaWatcher.js +1 -4
  55. package/dist/actions/schema/extractSchemaWatcher.js.map +1 -1
  56. package/dist/actions/schema/getExtractOptions.js +8 -18
  57. package/dist/actions/schema/getExtractOptions.js.map +1 -1
  58. package/dist/actions/schema/types.js +0 -6
  59. package/dist/actions/schema/types.js.map +1 -1
  60. package/dist/actions/schema/validateAction.js +1 -1
  61. package/dist/actions/schema/validateAction.js.map +1 -1
  62. package/dist/actions/schema/validateSchema.worker.js +1 -2
  63. package/dist/actions/schema/validateSchema.worker.js.map +1 -1
  64. package/dist/actions/schema/watchExtractSchema.js +1 -1
  65. package/dist/actions/schema/watchExtractSchema.js.map +1 -1
  66. package/dist/actions/skills/readSkillState.js +54 -0
  67. package/dist/actions/skills/readSkillState.js.map +1 -0
  68. package/dist/actions/skills/setupSkills.js +73 -0
  69. package/dist/actions/skills/setupSkills.js.map +1 -0
  70. package/dist/commands/build.js +9 -22
  71. package/dist/commands/build.js.map +1 -1
  72. package/dist/commands/cors/add.js +5 -5
  73. package/dist/commands/cors/add.js.map +1 -1
  74. package/dist/commands/datasets/export.js +9 -0
  75. package/dist/commands/datasets/export.js.map +1 -1
  76. package/dist/commands/docs/read.js +33 -12
  77. package/dist/commands/docs/read.js.map +1 -1
  78. package/dist/commands/init.js +12 -1
  79. package/dist/commands/init.js.map +1 -1
  80. package/dist/commands/login.js +28 -5
  81. package/dist/commands/login.js.map +1 -1
  82. package/dist/commands/manifest/extract.js +1 -2
  83. package/dist/commands/manifest/extract.js.map +1 -1
  84. package/dist/commands/mcp/configure.js +2 -1
  85. package/dist/commands/mcp/configure.js.map +1 -1
  86. package/dist/commands/schemas/deploy.js +1 -2
  87. package/dist/commands/schemas/deploy.js.map +1 -1
  88. package/dist/exports/_internal.d.ts +2 -1
  89. package/dist/exports/_internal.js +1 -1
  90. package/dist/exports/_internal.js.map +1 -1
  91. package/dist/server/devServer.js +25 -4
  92. package/dist/server/devServer.js.map +1 -1
  93. package/dist/server/previewServer.js +1 -1
  94. package/dist/server/previewServer.js.map +1 -1
  95. package/dist/services/mcp.js +1 -1
  96. package/dist/services/mcp.js.map +1 -1
  97. package/dist/telemetry/init.telemetry.js.map +1 -1
  98. package/oclif.manifest.json +237 -205
  99. package/package.json +15 -16
  100. package/templates/page-builder/README.md +9 -0
  101. package/templates/page-builder/schemaTypes/hero.js +31 -0
  102. package/templates/page-builder/schemaTypes/index.js +19 -0
  103. package/templates/page-builder/static/.gitkeep +0 -0
  104. package/dist/actions/build/buildDebug.js +0 -4
  105. package/dist/actions/build/buildDebug.js.map +0 -1
  106. package/dist/actions/build/buildVendorDependencies.js +0 -149
  107. package/dist/actions/build/buildVendorDependencies.js.map +0 -1
  108. package/dist/actions/build/checkStudioDependencyVersions.js +0 -155
  109. package/dist/actions/build/checkStudioDependencyVersions.js.map +0 -1
  110. package/dist/actions/build/createExternalFromImportMap.js +0 -11
  111. package/dist/actions/build/createExternalFromImportMap.js.map +0 -1
  112. package/dist/actions/build/decorateIndexWithAutoGeneratedWarning.js +0 -13
  113. package/dist/actions/build/decorateIndexWithAutoGeneratedWarning.js.map +0 -1
  114. package/dist/actions/build/decorateIndexWithBridgeScript.js +0 -17
  115. package/dist/actions/build/decorateIndexWithBridgeScript.js.map +0 -1
  116. package/dist/actions/build/decorateIndexWithStagingScript.js +0 -16
  117. package/dist/actions/build/decorateIndexWithStagingScript.js.map +0 -1
  118. package/dist/actions/build/getAppEnvVars.js +0 -9
  119. package/dist/actions/build/getAppEnvVars.js.map +0 -1
  120. package/dist/actions/build/getEntryModule.js +0 -46
  121. package/dist/actions/build/getEntryModule.js.map +0 -1
  122. package/dist/actions/build/getPossibleDocumentComponentLocations.js +0 -11
  123. package/dist/actions/build/getPossibleDocumentComponentLocations.js.map +0 -1
  124. package/dist/actions/build/getStudioEnvVars.js +0 -9
  125. package/dist/actions/build/getStudioEnvVars.js.map +0 -1
  126. package/dist/actions/build/getStudioEnvironmentVariables.js.map +0 -1
  127. package/dist/actions/build/getViteConfig.js +0 -219
  128. package/dist/actions/build/getViteConfig.js.map +0 -1
  129. package/dist/actions/build/normalizeBasePath.js +0 -9
  130. package/dist/actions/build/normalizeBasePath.js.map +0 -1
  131. package/dist/actions/build/renderDocument.js +0 -50
  132. package/dist/actions/build/renderDocument.js.map +0 -1
  133. package/dist/actions/build/renderDocument.worker.js +0 -9
  134. package/dist/actions/build/renderDocument.worker.js.map +0 -1
  135. package/dist/actions/build/renderDocumentWorker/addTimestampImportMapScriptToHtml.js +0 -79
  136. package/dist/actions/build/renderDocumentWorker/addTimestampImportMapScriptToHtml.js.map +0 -1
  137. package/dist/actions/build/renderDocumentWorker/components/BasicDocument.js +0 -61
  138. package/dist/actions/build/renderDocumentWorker/components/BasicDocument.js.map +0 -1
  139. package/dist/actions/build/renderDocumentWorker/components/DefaultDocument.js +0 -165
  140. package/dist/actions/build/renderDocumentWorker/components/DefaultDocument.js.map +0 -1
  141. package/dist/actions/build/renderDocumentWorker/components/Favicons.js +0 -28
  142. package/dist/actions/build/renderDocumentWorker/components/Favicons.js.map +0 -1
  143. package/dist/actions/build/renderDocumentWorker/components/GlobalErrorHandler.js +0 -178
  144. package/dist/actions/build/renderDocumentWorker/components/GlobalErrorHandler.js.map +0 -1
  145. package/dist/actions/build/renderDocumentWorker/components/NoJavascript.js +0 -51
  146. package/dist/actions/build/renderDocumentWorker/components/NoJavascript.js.map +0 -1
  147. package/dist/actions/build/renderDocumentWorker/getDocumentComponent.js +0 -41
  148. package/dist/actions/build/renderDocumentWorker/getDocumentComponent.js.map +0 -1
  149. package/dist/actions/build/renderDocumentWorker/getDocumentHtml.js +0 -55
  150. package/dist/actions/build/renderDocumentWorker/getDocumentHtml.js.map +0 -1
  151. package/dist/actions/build/renderDocumentWorker/renderDocumentWorker.js +0 -31
  152. package/dist/actions/build/renderDocumentWorker/renderDocumentWorker.js.map +0 -1
  153. package/dist/actions/build/renderDocumentWorker/tryLoadDocumentComponent.js +0 -30
  154. package/dist/actions/build/renderDocumentWorker/tryLoadDocumentComponent.js.map +0 -1
  155. package/dist/actions/build/renderDocumentWorker/types.js +0 -5
  156. package/dist/actions/build/renderDocumentWorker/types.js.map +0 -1
  157. package/dist/actions/build/writeSanityRuntime.js +0 -64
  158. package/dist/actions/build/writeSanityRuntime.js.map +0 -1
  159. package/dist/actions/docs/normalizeDocsPath.js +0 -15
  160. package/dist/actions/docs/normalizeDocsPath.js.map +0 -1
  161. package/dist/actions/schema/extractSanitySchema.worker.js +0 -33
  162. package/dist/actions/schema/extractSanitySchema.worker.js.map +0 -1
  163. package/dist/actions/schema/formatSchemaValidation.js +0 -78
  164. package/dist/actions/schema/formatSchemaValidation.js.map +0 -1
  165. package/dist/actions/schema/matchSchemaPattern.js +0 -22
  166. package/dist/actions/schema/matchSchemaPattern.js.map +0 -1
  167. package/dist/actions/schema/runSchemaExtraction.js +0 -39
  168. package/dist/actions/schema/runSchemaExtraction.js.map +0 -1
  169. package/dist/actions/schema/utils/SchemaExtractionError.js +0 -10
  170. package/dist/actions/schema/utils/SchemaExtractionError.js.map +0 -1
  171. package/dist/actions/schema/utils/extractValidationFromSchemaError.js +0 -12
  172. package/dist/actions/schema/utils/extractValidationFromSchemaError.js.map +0 -1
  173. package/dist/constants.js +0 -8
  174. package/dist/constants.js.map +0 -1
  175. package/dist/server/vite/plugin-sanity-build-entries.js +0 -67
  176. package/dist/server/vite/plugin-sanity-build-entries.js.map +0 -1
  177. package/dist/server/vite/plugin-sanity-favicons.js +0 -72
  178. package/dist/server/vite/plugin-sanity-favicons.js.map +0 -1
  179. package/dist/server/vite/plugin-sanity-runtime-rewrite.js +0 -18
  180. package/dist/server/vite/plugin-sanity-runtime-rewrite.js.map +0 -1
  181. package/dist/server/vite/plugin-schema-extraction.js +0 -201
  182. package/dist/server/vite/plugin-schema-extraction.js.map +0 -1
  183. package/dist/telemetry/build.telemetry.js +0 -13
  184. package/dist/telemetry/build.telemetry.js.map +0 -1
  185. package/dist/telemetry/extractSchema.telemetry.js +0 -18
  186. package/dist/telemetry/extractSchema.telemetry.js.map +0 -1
  187. package/dist/util/getWorkspace.js +0 -18
  188. package/dist/util/getWorkspace.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/actions/schema/extractSanityWorkspace.worker.ts"],"sourcesContent":["import {isMainThread, parentPort, workerData} from 'node:worker_threads'\n\nimport {getStudioWorkspaces, safeStructuredClone} from '@sanity/cli-core'\nimport {type Schema} from '@sanity/types'\n\nimport {extractManifestSchemaTypes} from '../manifest/extractWorkspaceManifest.js'\nimport {extractWorkspaceWorkerData} from './types.js'\nimport {extractValidationFromSchemaError} from './utils/extractValidationFromSchemaError.js'\n\nif (isMainThread || !parentPort) {\n throw new Error('Should only be run in a worker!')\n}\n\nconst {configPath, workDir} = extractWorkspaceWorkerData.parse(workerData)\n\ntry {\n const workspaces = await getStudioWorkspaces(configPath)\n\n // Extract manifest schemas while Schema objects are still live (before structured clone\n // strips class methods like getTypeNames/get). The API expects ManifestSchemaType[], not\n // the runtime Schema class instance.\n const workspacesWithManifest = await Promise.all(\n workspaces.map(async (workspace) => ({\n ...safeStructuredClone(workspace),\n manifestSchema: await extractManifestSchemaTypes(workspace.schema as Schema, workDir),\n })),\n )\n\n parentPort.postMessage({\n type: 'success',\n workspaces: workspacesWithManifest,\n })\n} catch (error) {\n const validation = await extractValidationFromSchemaError(error, workDir)\n parentPort.postMessage({\n error: error instanceof Error ? error.message : String(error),\n type: 'error',\n validation,\n })\n}\n"],"names":["isMainThread","parentPort","workerData","getStudioWorkspaces","safeStructuredClone","extractManifestSchemaTypes","extractWorkspaceWorkerData","extractValidationFromSchemaError","Error","configPath","workDir","parse","workspaces","workspacesWithManifest","Promise","all","map","workspace","manifestSchema","schema","postMessage","type","error","validation","message","String"],"mappings":"AAAA,SAAQA,YAAY,EAAEC,UAAU,EAAEC,UAAU,QAAO,sBAAqB;AAExE,SAAQC,mBAAmB,EAAEC,mBAAmB,QAAO,mBAAkB;AAGzE,SAAQC,0BAA0B,QAAO,0CAAyC;AAClF,SAAQC,0BAA0B,QAAO,aAAY;AACrD,SAAQC,gCAAgC,QAAO,8CAA6C;AAE5F,IAAIP,gBAAgB,CAACC,YAAY;IAC/B,MAAM,IAAIO,MAAM;AAClB;AAEA,MAAM,EAACC,UAAU,EAAEC,OAAO,EAAC,GAAGJ,2BAA2BK,KAAK,CAACT;AAE/D,IAAI;IACF,MAAMU,aAAa,MAAMT,oBAAoBM;IAE7C,wFAAwF;IACxF,yFAAyF;IACzF,qCAAqC;IACrC,MAAMI,yBAAyB,MAAMC,QAAQC,GAAG,CAC9CH,WAAWI,GAAG,CAAC,OAAOC,YAAe,CAAA;YACnC,GAAGb,oBAAoBa,UAAU;YACjCC,gBAAgB,MAAMb,2BAA2BY,UAAUE,MAAM,EAAYT;QAC/E,CAAA;IAGFT,WAAWmB,WAAW,CAAC;QACrBC,MAAM;QACNT,YAAYC;IACd;AACF,EAAE,OAAOS,OAAO;IACd,MAAMC,aAAa,MAAMhB,iCAAiCe,OAAOZ;IACjET,WAAWmB,WAAW,CAAC;QACrBE,OAAOA,iBAAiBd,QAAQc,MAAME,OAAO,GAAGC,OAAOH;QACvDD,MAAM;QACNE;IACF;AACF"}
1
+ {"version":3,"sources":["../../../src/actions/schema/extractSanityWorkspace.worker.ts"],"sourcesContent":["import {isMainThread, parentPort, workerData} from 'node:worker_threads'\n\nimport {extractValidationFromSchemaError} from '@sanity/cli-build/_internal/extract'\nimport {getStudioWorkspaces, safeStructuredClone} from '@sanity/cli-core'\nimport {type Schema} from '@sanity/types'\n\nimport {extractManifestSchemaTypes} from '../manifest/extractWorkspaceManifest.js'\nimport {extractWorkspaceWorkerData} from './types.js'\n\nif (isMainThread || !parentPort) {\n throw new Error('Should only be run in a worker!')\n}\n\nconst {configPath, workDir} = extractWorkspaceWorkerData.parse(workerData)\n\ntry {\n const workspaces = await getStudioWorkspaces(configPath)\n\n // Extract manifest schemas while Schema objects are still live (before structured clone\n // strips class methods like getTypeNames/get). The API expects ManifestSchemaType[], not\n // the runtime Schema class instance.\n const workspacesWithManifest = await Promise.all(\n workspaces.map(async (workspace) => ({\n ...safeStructuredClone(workspace),\n manifestSchema: await extractManifestSchemaTypes(workspace.schema as Schema, workDir),\n })),\n )\n\n parentPort.postMessage({\n type: 'success',\n workspaces: workspacesWithManifest,\n })\n} catch (error) {\n const validation = await extractValidationFromSchemaError(error, workDir)\n parentPort.postMessage({\n error: error instanceof Error ? error.message : String(error),\n type: 'error',\n validation,\n })\n}\n"],"names":["isMainThread","parentPort","workerData","extractValidationFromSchemaError","getStudioWorkspaces","safeStructuredClone","extractManifestSchemaTypes","extractWorkspaceWorkerData","Error","configPath","workDir","parse","workspaces","workspacesWithManifest","Promise","all","map","workspace","manifestSchema","schema","postMessage","type","error","validation","message","String"],"mappings":"AAAA,SAAQA,YAAY,EAAEC,UAAU,EAAEC,UAAU,QAAO,sBAAqB;AAExE,SAAQC,gCAAgC,QAAO,sCAAqC;AACpF,SAAQC,mBAAmB,EAAEC,mBAAmB,QAAO,mBAAkB;AAGzE,SAAQC,0BAA0B,QAAO,0CAAyC;AAClF,SAAQC,0BAA0B,QAAO,aAAY;AAErD,IAAIP,gBAAgB,CAACC,YAAY;IAC/B,MAAM,IAAIO,MAAM;AAClB;AAEA,MAAM,EAACC,UAAU,EAAEC,OAAO,EAAC,GAAGH,2BAA2BI,KAAK,CAACT;AAE/D,IAAI;IACF,MAAMU,aAAa,MAAMR,oBAAoBK;IAE7C,wFAAwF;IACxF,yFAAyF;IACzF,qCAAqC;IACrC,MAAMI,yBAAyB,MAAMC,QAAQC,GAAG,CAC9CH,WAAWI,GAAG,CAAC,OAAOC,YAAe,CAAA;YACnC,GAAGZ,oBAAoBY,UAAU;YACjCC,gBAAgB,MAAMZ,2BAA2BW,UAAUE,MAAM,EAAYT;QAC/E,CAAA;IAGFT,WAAWmB,WAAW,CAAC;QACrBC,MAAM;QACNT,YAAYC;IACd;AACF,EAAE,OAAOS,OAAO;IACd,MAAMC,aAAa,MAAMpB,iCAAiCmB,OAAOZ;IACjET,WAAWmB,WAAW,CAAC;QACrBE,OAAOA,iBAAiBd,QAAQc,MAAME,OAAO,GAAGC,OAAOH;QACvDD,MAAM;QACNE;IACF;AACF"}
@@ -1,11 +1,8 @@
1
1
  import { exit } from '@oclif/core/errors';
2
+ import { formatSchemaValidation, runSchemaExtraction, SchemaExtractedTrace, SchemaExtractionError } from '@sanity/cli-build/_internal/extract';
2
3
  import { getCliTelemetry } from '@sanity/cli-core';
3
4
  import { spinner } from '@sanity/cli-core/ux';
4
- import { SchemaExtractedTrace } from '../../telemetry/extractSchema.telemetry.js';
5
- import { formatSchemaValidation } from './formatSchemaValidation.js';
6
- import { runSchemaExtraction } from './runSchemaExtraction.js';
7
5
  import { schemasExtractDebug } from './utils/debug.js';
8
- import { SchemaExtractionError } from './utils/SchemaExtractionError.js';
9
6
  export async function extractSchema(options) {
10
7
  const { extractOptions, output } = options;
11
8
  const { enforceRequiredFields, format, outputPath } = extractOptions;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/actions/schema/extractSchema.ts"],"sourcesContent":["import {exit} from '@oclif/core/errors'\nimport {getCliTelemetry, type Output} from '@sanity/cli-core'\nimport {spinner} from '@sanity/cli-core/ux'\n\nimport {SchemaExtractedTrace} from '../../telemetry/extractSchema.telemetry.js'\nimport {formatSchemaValidation} from './formatSchemaValidation.js'\nimport {type ExtractOptions} from './getExtractOptions.js'\nimport {runSchemaExtraction} from './runSchemaExtraction.js'\nimport {schemasExtractDebug} from './utils/debug.js'\nimport {SchemaExtractionError} from './utils/SchemaExtractionError.js'\n\ninterface ExtractSchemaActionOptions {\n extractOptions: ExtractOptions\n output: Output\n}\n\nexport async function extractSchema(options: ExtractSchemaActionOptions): Promise<void> {\n const {extractOptions, output} = options\n const {enforceRequiredFields, format, outputPath} = extractOptions\n\n const spin = spinner(\n enforceRequiredFields ? 'Extracting schema with enforced required fields' : 'Extracting schema',\n ).start()\n\n const trace = getCliTelemetry().trace(SchemaExtractedTrace)\n trace.start()\n\n try {\n spin.text = `Writing schema to ${outputPath}`\n\n const schema = await runSchemaExtraction(extractOptions)\n\n trace.log({\n enforceRequiredFields,\n schemaAllTypesCount: schema.length,\n schemaDocumentTypesCount: schema.filter((type) => type.type === 'document').length,\n schemaFormat: format,\n schemaTypesCount: schema.filter((type) => type.type === 'type').length,\n })\n\n spin.succeed(\n enforceRequiredFields\n ? `Extracted schema to ${outputPath} with enforced required fields`\n : `Extracted schema to ${outputPath}`,\n )\n\n trace.complete()\n } catch (err) {\n trace.error(err)\n schemasExtractDebug('Failed to extract schema', err)\n spin.fail(\n enforceRequiredFields\n ? 'Failed to extract schema with enforced required fields'\n : 'Failed to extract schema',\n )\n\n // Display validation errors if available and exit\n if (err instanceof SchemaExtractionError && err.validation && err.validation.length > 0) {\n output.log('')\n output.log(formatSchemaValidation(err.validation))\n exit(1)\n }\n\n output.error(err instanceof Error ? err.message : 'Failed to extract schema', {exit: 1})\n }\n}\n"],"names":["exit","getCliTelemetry","spinner","SchemaExtractedTrace","formatSchemaValidation","runSchemaExtraction","schemasExtractDebug","SchemaExtractionError","extractSchema","options","extractOptions","output","enforceRequiredFields","format","outputPath","spin","start","trace","text","schema","log","schemaAllTypesCount","length","schemaDocumentTypesCount","filter","type","schemaFormat","schemaTypesCount","succeed","complete","err","error","fail","validation","Error","message"],"mappings":"AAAA,SAAQA,IAAI,QAAO,qBAAoB;AACvC,SAAQC,eAAe,QAAoB,mBAAkB;AAC7D,SAAQC,OAAO,QAAO,sBAAqB;AAE3C,SAAQC,oBAAoB,QAAO,6CAA4C;AAC/E,SAAQC,sBAAsB,QAAO,8BAA6B;AAElE,SAAQC,mBAAmB,QAAO,2BAA0B;AAC5D,SAAQC,mBAAmB,QAAO,mBAAkB;AACpD,SAAQC,qBAAqB,QAAO,mCAAkC;AAOtE,OAAO,eAAeC,cAAcC,OAAmC;IACrE,MAAM,EAACC,cAAc,EAAEC,MAAM,EAAC,GAAGF;IACjC,MAAM,EAACG,qBAAqB,EAAEC,MAAM,EAAEC,UAAU,EAAC,GAAGJ;IAEpD,MAAMK,OAAOb,QACXU,wBAAwB,oDAAoD,qBAC5EI,KAAK;IAEP,MAAMC,QAAQhB,kBAAkBgB,KAAK,CAACd;IACtCc,MAAMD,KAAK;IAEX,IAAI;QACFD,KAAKG,IAAI,GAAG,CAAC,kBAAkB,EAAEJ,YAAY;QAE7C,MAAMK,SAAS,MAAMd,oBAAoBK;QAEzCO,MAAMG,GAAG,CAAC;YACRR;YACAS,qBAAqBF,OAAOG,MAAM;YAClCC,0BAA0BJ,OAAOK,MAAM,CAAC,CAACC,OAASA,KAAKA,IAAI,KAAK,YAAYH,MAAM;YAClFI,cAAcb;YACdc,kBAAkBR,OAAOK,MAAM,CAAC,CAACC,OAASA,KAAKA,IAAI,KAAK,QAAQH,MAAM;QACxE;QAEAP,KAAKa,OAAO,CACVhB,wBACI,CAAC,oBAAoB,EAAEE,WAAW,8BAA8B,CAAC,GACjE,CAAC,oBAAoB,EAAEA,YAAY;QAGzCG,MAAMY,QAAQ;IAChB,EAAE,OAAOC,KAAK;QACZb,MAAMc,KAAK,CAACD;QACZxB,oBAAoB,4BAA4BwB;QAChDf,KAAKiB,IAAI,CACPpB,wBACI,2DACA;QAGN,kDAAkD;QAClD,IAAIkB,eAAevB,yBAAyBuB,IAAIG,UAAU,IAAIH,IAAIG,UAAU,CAACX,MAAM,GAAG,GAAG;YACvFX,OAAOS,GAAG,CAAC;YACXT,OAAOS,GAAG,CAAChB,uBAAuB0B,IAAIG,UAAU;YAChDjC,KAAK;QACP;QAEAW,OAAOoB,KAAK,CAACD,eAAeI,QAAQJ,IAAIK,OAAO,GAAG,4BAA4B;YAACnC,MAAM;QAAC;IACxF;AACF"}
1
+ {"version":3,"sources":["../../../src/actions/schema/extractSchema.ts"],"sourcesContent":["import {exit} from '@oclif/core/errors'\nimport {\n type ExtractOptions,\n formatSchemaValidation,\n runSchemaExtraction,\n SchemaExtractedTrace,\n SchemaExtractionError,\n} from '@sanity/cli-build/_internal/extract'\nimport {getCliTelemetry, type Output} from '@sanity/cli-core'\nimport {spinner} from '@sanity/cli-core/ux'\n\nimport {schemasExtractDebug} from './utils/debug.js'\n\ninterface ExtractSchemaActionOptions {\n extractOptions: ExtractOptions\n output: Output\n}\n\nexport async function extractSchema(options: ExtractSchemaActionOptions): Promise<void> {\n const {extractOptions, output} = options\n const {enforceRequiredFields, format, outputPath} = extractOptions\n\n const spin = spinner(\n enforceRequiredFields ? 'Extracting schema with enforced required fields' : 'Extracting schema',\n ).start()\n\n const trace = getCliTelemetry().trace(SchemaExtractedTrace)\n trace.start()\n\n try {\n spin.text = `Writing schema to ${outputPath}`\n\n const schema = await runSchemaExtraction(extractOptions)\n\n trace.log({\n enforceRequiredFields,\n schemaAllTypesCount: schema.length,\n schemaDocumentTypesCount: schema.filter((type) => type.type === 'document').length,\n schemaFormat: format,\n schemaTypesCount: schema.filter((type) => type.type === 'type').length,\n })\n\n spin.succeed(\n enforceRequiredFields\n ? `Extracted schema to ${outputPath} with enforced required fields`\n : `Extracted schema to ${outputPath}`,\n )\n\n trace.complete()\n } catch (err) {\n trace.error(err)\n schemasExtractDebug('Failed to extract schema', err)\n spin.fail(\n enforceRequiredFields\n ? 'Failed to extract schema with enforced required fields'\n : 'Failed to extract schema',\n )\n\n // Display validation errors if available and exit\n if (err instanceof SchemaExtractionError && err.validation && err.validation.length > 0) {\n output.log('')\n output.log(formatSchemaValidation(err.validation))\n exit(1)\n }\n\n output.error(err instanceof Error ? err.message : 'Failed to extract schema', {exit: 1})\n }\n}\n"],"names":["exit","formatSchemaValidation","runSchemaExtraction","SchemaExtractedTrace","SchemaExtractionError","getCliTelemetry","spinner","schemasExtractDebug","extractSchema","options","extractOptions","output","enforceRequiredFields","format","outputPath","spin","start","trace","text","schema","log","schemaAllTypesCount","length","schemaDocumentTypesCount","filter","type","schemaFormat","schemaTypesCount","succeed","complete","err","error","fail","validation","Error","message"],"mappings":"AAAA,SAAQA,IAAI,QAAO,qBAAoB;AACvC,SAEEC,sBAAsB,EACtBC,mBAAmB,EACnBC,oBAAoB,EACpBC,qBAAqB,QAChB,sCAAqC;AAC5C,SAAQC,eAAe,QAAoB,mBAAkB;AAC7D,SAAQC,OAAO,QAAO,sBAAqB;AAE3C,SAAQC,mBAAmB,QAAO,mBAAkB;AAOpD,OAAO,eAAeC,cAAcC,OAAmC;IACrE,MAAM,EAACC,cAAc,EAAEC,MAAM,EAAC,GAAGF;IACjC,MAAM,EAACG,qBAAqB,EAAEC,MAAM,EAAEC,UAAU,EAAC,GAAGJ;IAEpD,MAAMK,OAAOT,QACXM,wBAAwB,oDAAoD,qBAC5EI,KAAK;IAEP,MAAMC,QAAQZ,kBAAkBY,KAAK,CAACd;IACtCc,MAAMD,KAAK;IAEX,IAAI;QACFD,KAAKG,IAAI,GAAG,CAAC,kBAAkB,EAAEJ,YAAY;QAE7C,MAAMK,SAAS,MAAMjB,oBAAoBQ;QAEzCO,MAAMG,GAAG,CAAC;YACRR;YACAS,qBAAqBF,OAAOG,MAAM;YAClCC,0BAA0BJ,OAAOK,MAAM,CAAC,CAACC,OAASA,KAAKA,IAAI,KAAK,YAAYH,MAAM;YAClFI,cAAcb;YACdc,kBAAkBR,OAAOK,MAAM,CAAC,CAACC,OAASA,KAAKA,IAAI,KAAK,QAAQH,MAAM;QACxE;QAEAP,KAAKa,OAAO,CACVhB,wBACI,CAAC,oBAAoB,EAAEE,WAAW,8BAA8B,CAAC,GACjE,CAAC,oBAAoB,EAAEA,YAAY;QAGzCG,MAAMY,QAAQ;IAChB,EAAE,OAAOC,KAAK;QACZb,MAAMc,KAAK,CAACD;QACZvB,oBAAoB,4BAA4BuB;QAChDf,KAAKiB,IAAI,CACPpB,wBACI,2DACA;QAGN,kDAAkD;QAClD,IAAIkB,eAAe1B,yBAAyB0B,IAAIG,UAAU,IAAIH,IAAIG,UAAU,CAACX,MAAM,GAAG,GAAG;YACvFX,OAAOS,GAAG,CAAC;YACXT,OAAOS,GAAG,CAACnB,uBAAuB6B,IAAIG,UAAU;YAChDjC,KAAK;QACP;QAEAW,OAAOoB,KAAK,CAACD,eAAeI,QAAQJ,IAAIK,OAAO,GAAG,4BAA4B;YAACnC,MAAM;QAAC;IACxF;AACF"}
@@ -1,12 +1,9 @@
1
1
  import { dirname, isAbsolute, join, relative } from 'node:path';
2
+ import { createSchemaPatternMatcher, formatSchemaValidation, runSchemaExtraction, SchemaExtractionError } from '@sanity/cli-build/_internal/extract';
2
3
  import { spinner } from '@sanity/cli-core/ux';
3
4
  import { watch as chokidarWatch } from 'chokidar';
4
5
  import debounce from 'lodash-es/debounce.js';
5
- import { formatSchemaValidation } from './formatSchemaValidation.js';
6
- import { createSchemaPatternMatcher } from './matchSchemaPattern.js';
7
- import { runSchemaExtraction } from './runSchemaExtraction.js';
8
6
  import { schemasExtractDebug } from './utils/debug.js';
9
- import { SchemaExtractionError } from './utils/SchemaExtractionError.js';
10
7
  /** Default glob patterns to watch for schema changes */ export const DEFAULT_WATCH_PATTERNS = [
11
8
  'sanity.config.{js,jsx,ts,tsx,mjs}',
12
9
  'schema*/**/*.{js,jsx,ts,tsx,mjs}'
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/actions/schema/extractSchemaWatcher.ts"],"sourcesContent":["import {dirname, isAbsolute, join, relative} from 'node:path'\n\nimport {type Output} from '@sanity/cli-core'\nimport {spinner} from '@sanity/cli-core/ux'\nimport {watch as chokidarWatch, type FSWatcher} from 'chokidar'\nimport debounce from 'lodash-es/debounce.js'\n\nimport {formatSchemaValidation} from './formatSchemaValidation.js'\nimport {type ExtractOptions} from './getExtractOptions.js'\nimport {createSchemaPatternMatcher} from './matchSchemaPattern.js'\nimport {runSchemaExtraction} from './runSchemaExtraction.js'\nimport {schemasExtractDebug} from './utils/debug.js'\nimport {SchemaExtractionError} from './utils/SchemaExtractionError.js'\n\n/** Default glob patterns to watch for schema changes */\nexport const DEFAULT_WATCH_PATTERNS = [\n 'sanity.config.{js,jsx,ts,tsx,mjs}',\n 'schema*/**/*.{js,jsx,ts,tsx,mjs}',\n]\n\n/** Default patterns to ignore when watching */\nconst IGNORED_PATTERNS = [\n '**/node_modules/**',\n '**/.git/**',\n '**/dist/**',\n '**/lib/**',\n '**/.sanity/**',\n]\n\ninterface ExtractSchemaWatcherOptions {\n extractOptions: ExtractOptions\n output: Output\n watchPatterns: string[]\n\n onExtraction?: (result: {duration: number; success: boolean}) => void\n}\n\ninterface ExtractSchemaWatcher {\n close: () => Promise<void>\n watcher: FSWatcher\n}\n\n/** State for tracking extraction status */\ninterface WatchState {\n isExtracting: boolean\n pendingExtraction: boolean\n}\n\n/** Return type for createExtractionRunner */\ninterface ExtractionRunner {\n runExtraction: () => Promise<void>\n state: WatchState\n}\n\n/**\n * Creates an extraction runner with concurrency control.\n * If extraction is already running, queues one more extraction to run after completion.\n * Multiple queued requests are coalesced into a single pending extraction.\n */\nfunction createExtractionRunner(onExtract: () => Promise<void>): ExtractionRunner {\n const state: WatchState = {\n isExtracting: false,\n pendingExtraction: false,\n }\n\n async function runExtraction(): Promise<void> {\n if (state.isExtracting) {\n state.pendingExtraction = true\n return\n }\n\n state.isExtracting = true\n state.pendingExtraction = false\n\n try {\n await onExtract()\n } finally {\n state.isExtracting = false\n\n // If a change came in during extraction, run again\n if (state.pendingExtraction) {\n state.pendingExtraction = false\n await runExtraction()\n }\n }\n }\n\n return {runExtraction, state}\n}\n\n/**\n * Starts a schema watcher that extracts schema on file changes.\n * Returns a watcher instance and a stop function.\n */\nexport async function startExtractSchemaWatcher(\n options: ExtractSchemaWatcherOptions,\n): Promise<ExtractSchemaWatcher> {\n const {extractOptions, onExtraction, output, watchPatterns} = options\n\n const {configPath, enforceRequiredFields, outputPath} = extractOptions\n const workDir = dirname(configPath)\n\n // Helper function to run extraction with spinner and error handling\n const runExtraction = async (): Promise<boolean> => {\n const spin = spinner(\n enforceRequiredFields\n ? 'Extracting schema with enforced required fields'\n : 'Extracting schema...',\n ).start()\n const extractionStartTime = Date.now()\n\n try {\n await runSchemaExtraction(extractOptions)\n\n spin.succeed(\n enforceRequiredFields\n ? `Extracted schema to ${outputPath} with enforced required fields`\n : `Extracted schema to ${outputPath}`,\n )\n\n const duration = Date.now() - extractionStartTime\n onExtraction?.({duration, success: true})\n\n return true\n } catch (err) {\n const duration = Date.now() - extractionStartTime\n onExtraction?.({duration, success: false})\n\n schemasExtractDebug('Failed to extract schema', err)\n spin.fail('Extraction failed')\n\n // Display validation errors if available\n if (err instanceof SchemaExtractionError && err.validation && err.validation.length > 0) {\n output.log('')\n output.log(formatSchemaValidation(err.validation))\n } else if (err instanceof Error) {\n output.error(err.message, {exit: 1})\n }\n\n return false\n }\n }\n\n // Run initial extraction\n await runExtraction()\n\n const absoluteWatchPatterns = watchPatterns.map((pattern) => join(workDir, pattern))\n\n // Create extraction runner with concurrency control\n const {runExtraction: runConcurrentExtraction} = createExtractionRunner(async () => {\n await runExtraction()\n })\n\n // Debounced extraction trigger (1 second delay)\n const debouncedExtract = debounce(() => {\n void runConcurrentExtraction()\n }, 1000)\n\n const {isMatch} = createSchemaPatternMatcher(watchPatterns)\n\n const watcher: FSWatcher = chokidarWatch(absoluteWatchPatterns, {\n cwd: workDir,\n ignored: IGNORED_PATTERNS,\n ignoreInitial: true,\n })\n\n watcher.on('all', (event, filePath) => {\n if (!isMatch(filePath, workDir)) {\n return\n }\n\n const timestamp = new Date().toLocaleTimeString()\n const relativePath = isAbsolute(filePath) ? relative(workDir, filePath) : filePath\n output.log(`[${timestamp}] ${event}: ${relativePath}`)\n debouncedExtract()\n })\n\n watcher.on('error', (err) => {\n output.error(`Watcher error: ${err instanceof Error ? err.message : String(err)}`)\n })\n\n return {\n close: () => watcher.close(),\n watcher,\n }\n}\n"],"names":["dirname","isAbsolute","join","relative","spinner","watch","chokidarWatch","debounce","formatSchemaValidation","createSchemaPatternMatcher","runSchemaExtraction","schemasExtractDebug","SchemaExtractionError","DEFAULT_WATCH_PATTERNS","IGNORED_PATTERNS","createExtractionRunner","onExtract","state","isExtracting","pendingExtraction","runExtraction","startExtractSchemaWatcher","options","extractOptions","onExtraction","output","watchPatterns","configPath","enforceRequiredFields","outputPath","workDir","spin","start","extractionStartTime","Date","now","succeed","duration","success","err","fail","validation","length","log","Error","error","message","exit","absoluteWatchPatterns","map","pattern","runConcurrentExtraction","debouncedExtract","isMatch","watcher","cwd","ignored","ignoreInitial","on","event","filePath","timestamp","toLocaleTimeString","relativePath","String","close"],"mappings":"AAAA,SAAQA,OAAO,EAAEC,UAAU,EAAEC,IAAI,EAAEC,QAAQ,QAAO,YAAW;AAG7D,SAAQC,OAAO,QAAO,sBAAqB;AAC3C,SAAQC,SAASC,aAAa,QAAuB,WAAU;AAC/D,OAAOC,cAAc,wBAAuB;AAE5C,SAAQC,sBAAsB,QAAO,8BAA6B;AAElE,SAAQC,0BAA0B,QAAO,0BAAyB;AAClE,SAAQC,mBAAmB,QAAO,2BAA0B;AAC5D,SAAQC,mBAAmB,QAAO,mBAAkB;AACpD,SAAQC,qBAAqB,QAAO,mCAAkC;AAEtE,sDAAsD,GACtD,OAAO,MAAMC,yBAAyB;IACpC;IACA;CACD,CAAA;AAED,6CAA6C,GAC7C,MAAMC,mBAAmB;IACvB;IACA;IACA;IACA;IACA;CACD;AA2BD;;;;CAIC,GACD,SAASC,uBAAuBC,SAA8B;IAC5D,MAAMC,QAAoB;QACxBC,cAAc;QACdC,mBAAmB;IACrB;IAEA,eAAeC;QACb,IAAIH,MAAMC,YAAY,EAAE;YACtBD,MAAME,iBAAiB,GAAG;YAC1B;QACF;QAEAF,MAAMC,YAAY,GAAG;QACrBD,MAAME,iBAAiB,GAAG;QAE1B,IAAI;YACF,MAAMH;QACR,SAAU;YACRC,MAAMC,YAAY,GAAG;YAErB,mDAAmD;YACnD,IAAID,MAAME,iBAAiB,EAAE;gBAC3BF,MAAME,iBAAiB,GAAG;gBAC1B,MAAMC;YACR;QACF;IACF;IAEA,OAAO;QAACA;QAAeH;IAAK;AAC9B;AAEA;;;CAGC,GACD,OAAO,eAAeI,0BACpBC,OAAoC;IAEpC,MAAM,EAACC,cAAc,EAAEC,YAAY,EAAEC,MAAM,EAAEC,aAAa,EAAC,GAAGJ;IAE9D,MAAM,EAACK,UAAU,EAAEC,qBAAqB,EAAEC,UAAU,EAAC,GAAGN;IACxD,MAAMO,UAAU9B,QAAQ2B;IAExB,oEAAoE;IACpE,MAAMP,gBAAgB;QACpB,MAAMW,OAAO3B,QACXwB,wBACI,oDACA,wBACJI,KAAK;QACP,MAAMC,sBAAsBC,KAAKC,GAAG;QAEpC,IAAI;YACF,MAAMzB,oBAAoBa;YAE1BQ,KAAKK,OAAO,CACVR,wBACI,CAAC,oBAAoB,EAAEC,WAAW,8BAA8B,CAAC,GACjE,CAAC,oBAAoB,EAAEA,YAAY;YAGzC,MAAMQ,WAAWH,KAAKC,GAAG,KAAKF;YAC9BT,eAAe;gBAACa;gBAAUC,SAAS;YAAI;YAEvC,OAAO;QACT,EAAE,OAAOC,KAAK;YACZ,MAAMF,WAAWH,KAAKC,GAAG,KAAKF;YAC9BT,eAAe;gBAACa;gBAAUC,SAAS;YAAK;YAExC3B,oBAAoB,4BAA4B4B;YAChDR,KAAKS,IAAI,CAAC;YAEV,yCAAyC;YACzC,IAAID,eAAe3B,yBAAyB2B,IAAIE,UAAU,IAAIF,IAAIE,UAAU,CAACC,MAAM,GAAG,GAAG;gBACvFjB,OAAOkB,GAAG,CAAC;gBACXlB,OAAOkB,GAAG,CAACnC,uBAAuB+B,IAAIE,UAAU;YAClD,OAAO,IAAIF,eAAeK,OAAO;gBAC/BnB,OAAOoB,KAAK,CAACN,IAAIO,OAAO,EAAE;oBAACC,MAAM;gBAAC;YACpC;YAEA,OAAO;QACT;IACF;IAEA,yBAAyB;IACzB,MAAM3B;IAEN,MAAM4B,wBAAwBtB,cAAcuB,GAAG,CAAC,CAACC,UAAYhD,KAAK4B,SAASoB;IAE3E,oDAAoD;IACpD,MAAM,EAAC9B,eAAe+B,uBAAuB,EAAC,GAAGpC,uBAAuB;QACtE,MAAMK;IACR;IAEA,gDAAgD;IAChD,MAAMgC,mBAAmB7C,SAAS;QAChC,KAAK4C;IACP,GAAG;IAEH,MAAM,EAACE,OAAO,EAAC,GAAG5C,2BAA2BiB;IAE7C,MAAM4B,UAAqBhD,cAAc0C,uBAAuB;QAC9DO,KAAKzB;QACL0B,SAAS1C;QACT2C,eAAe;IACjB;IAEAH,QAAQI,EAAE,CAAC,OAAO,CAACC,OAAOC;QACxB,IAAI,CAACP,QAAQO,UAAU9B,UAAU;YAC/B;QACF;QAEA,MAAM+B,YAAY,IAAI3B,OAAO4B,kBAAkB;QAC/C,MAAMC,eAAe9D,WAAW2D,YAAYzD,SAAS2B,SAAS8B,YAAYA;QAC1EnC,OAAOkB,GAAG,CAAC,CAAC,CAAC,EAAEkB,UAAU,EAAE,EAAEF,MAAM,EAAE,EAAEI,cAAc;QACrDX;IACF;IAEAE,QAAQI,EAAE,CAAC,SAAS,CAACnB;QACnBd,OAAOoB,KAAK,CAAC,CAAC,eAAe,EAAEN,eAAeK,QAAQL,IAAIO,OAAO,GAAGkB,OAAOzB,MAAM;IACnF;IAEA,OAAO;QACL0B,OAAO,IAAMX,QAAQW,KAAK;QAC1BX;IACF;AACF"}
1
+ {"version":3,"sources":["../../../src/actions/schema/extractSchemaWatcher.ts"],"sourcesContent":["import {dirname, isAbsolute, join, relative} from 'node:path'\n\nimport {\n createSchemaPatternMatcher,\n type ExtractOptions,\n formatSchemaValidation,\n runSchemaExtraction,\n SchemaExtractionError,\n} from '@sanity/cli-build/_internal/extract'\nimport {type Output} from '@sanity/cli-core'\nimport {spinner} from '@sanity/cli-core/ux'\nimport {watch as chokidarWatch, type FSWatcher} from 'chokidar'\nimport debounce from 'lodash-es/debounce.js'\n\nimport {schemasExtractDebug} from './utils/debug.js'\n\n/** Default glob patterns to watch for schema changes */\nexport const DEFAULT_WATCH_PATTERNS = [\n 'sanity.config.{js,jsx,ts,tsx,mjs}',\n 'schema*/**/*.{js,jsx,ts,tsx,mjs}',\n]\n\n/** Default patterns to ignore when watching */\nconst IGNORED_PATTERNS = [\n '**/node_modules/**',\n '**/.git/**',\n '**/dist/**',\n '**/lib/**',\n '**/.sanity/**',\n]\n\ninterface ExtractSchemaWatcherOptions {\n extractOptions: ExtractOptions\n output: Output\n watchPatterns: string[]\n\n onExtraction?: (result: {duration: number; success: boolean}) => void\n}\n\ninterface ExtractSchemaWatcher {\n close: () => Promise<void>\n watcher: FSWatcher\n}\n\n/** State for tracking extraction status */\ninterface WatchState {\n isExtracting: boolean\n pendingExtraction: boolean\n}\n\n/** Return type for createExtractionRunner */\ninterface ExtractionRunner {\n runExtraction: () => Promise<void>\n state: WatchState\n}\n\n/**\n * Creates an extraction runner with concurrency control.\n * If extraction is already running, queues one more extraction to run after completion.\n * Multiple queued requests are coalesced into a single pending extraction.\n */\nfunction createExtractionRunner(onExtract: () => Promise<void>): ExtractionRunner {\n const state: WatchState = {\n isExtracting: false,\n pendingExtraction: false,\n }\n\n async function runExtraction(): Promise<void> {\n if (state.isExtracting) {\n state.pendingExtraction = true\n return\n }\n\n state.isExtracting = true\n state.pendingExtraction = false\n\n try {\n await onExtract()\n } finally {\n state.isExtracting = false\n\n // If a change came in during extraction, run again\n if (state.pendingExtraction) {\n state.pendingExtraction = false\n await runExtraction()\n }\n }\n }\n\n return {runExtraction, state}\n}\n\n/**\n * Starts a schema watcher that extracts schema on file changes.\n * Returns a watcher instance and a stop function.\n */\nexport async function startExtractSchemaWatcher(\n options: ExtractSchemaWatcherOptions,\n): Promise<ExtractSchemaWatcher> {\n const {extractOptions, onExtraction, output, watchPatterns} = options\n\n const {configPath, enforceRequiredFields, outputPath} = extractOptions\n const workDir = dirname(configPath)\n\n // Helper function to run extraction with spinner and error handling\n const runExtraction = async (): Promise<boolean> => {\n const spin = spinner(\n enforceRequiredFields\n ? 'Extracting schema with enforced required fields'\n : 'Extracting schema...',\n ).start()\n const extractionStartTime = Date.now()\n\n try {\n await runSchemaExtraction(extractOptions)\n\n spin.succeed(\n enforceRequiredFields\n ? `Extracted schema to ${outputPath} with enforced required fields`\n : `Extracted schema to ${outputPath}`,\n )\n\n const duration = Date.now() - extractionStartTime\n onExtraction?.({duration, success: true})\n\n return true\n } catch (err) {\n const duration = Date.now() - extractionStartTime\n onExtraction?.({duration, success: false})\n\n schemasExtractDebug('Failed to extract schema', err)\n spin.fail('Extraction failed')\n\n // Display validation errors if available\n if (err instanceof SchemaExtractionError && err.validation && err.validation.length > 0) {\n output.log('')\n output.log(formatSchemaValidation(err.validation))\n } else if (err instanceof Error) {\n output.error(err.message, {exit: 1})\n }\n\n return false\n }\n }\n\n // Run initial extraction\n await runExtraction()\n\n const absoluteWatchPatterns = watchPatterns.map((pattern) => join(workDir, pattern))\n\n // Create extraction runner with concurrency control\n const {runExtraction: runConcurrentExtraction} = createExtractionRunner(async () => {\n await runExtraction()\n })\n\n // Debounced extraction trigger (1 second delay)\n const debouncedExtract = debounce(() => {\n void runConcurrentExtraction()\n }, 1000)\n\n const {isMatch} = createSchemaPatternMatcher(watchPatterns)\n\n const watcher: FSWatcher = chokidarWatch(absoluteWatchPatterns, {\n cwd: workDir,\n ignored: IGNORED_PATTERNS,\n ignoreInitial: true,\n })\n\n watcher.on('all', (event, filePath) => {\n if (!isMatch(filePath, workDir)) {\n return\n }\n\n const timestamp = new Date().toLocaleTimeString()\n const relativePath = isAbsolute(filePath) ? relative(workDir, filePath) : filePath\n output.log(`[${timestamp}] ${event}: ${relativePath}`)\n debouncedExtract()\n })\n\n watcher.on('error', (err) => {\n output.error(`Watcher error: ${err instanceof Error ? err.message : String(err)}`)\n })\n\n return {\n close: () => watcher.close(),\n watcher,\n }\n}\n"],"names":["dirname","isAbsolute","join","relative","createSchemaPatternMatcher","formatSchemaValidation","runSchemaExtraction","SchemaExtractionError","spinner","watch","chokidarWatch","debounce","schemasExtractDebug","DEFAULT_WATCH_PATTERNS","IGNORED_PATTERNS","createExtractionRunner","onExtract","state","isExtracting","pendingExtraction","runExtraction","startExtractSchemaWatcher","options","extractOptions","onExtraction","output","watchPatterns","configPath","enforceRequiredFields","outputPath","workDir","spin","start","extractionStartTime","Date","now","succeed","duration","success","err","fail","validation","length","log","Error","error","message","exit","absoluteWatchPatterns","map","pattern","runConcurrentExtraction","debouncedExtract","isMatch","watcher","cwd","ignored","ignoreInitial","on","event","filePath","timestamp","toLocaleTimeString","relativePath","String","close"],"mappings":"AAAA,SAAQA,OAAO,EAAEC,UAAU,EAAEC,IAAI,EAAEC,QAAQ,QAAO,YAAW;AAE7D,SACEC,0BAA0B,EAE1BC,sBAAsB,EACtBC,mBAAmB,EACnBC,qBAAqB,QAChB,sCAAqC;AAE5C,SAAQC,OAAO,QAAO,sBAAqB;AAC3C,SAAQC,SAASC,aAAa,QAAuB,WAAU;AAC/D,OAAOC,cAAc,wBAAuB;AAE5C,SAAQC,mBAAmB,QAAO,mBAAkB;AAEpD,sDAAsD,GACtD,OAAO,MAAMC,yBAAyB;IACpC;IACA;CACD,CAAA;AAED,6CAA6C,GAC7C,MAAMC,mBAAmB;IACvB;IACA;IACA;IACA;IACA;CACD;AA2BD;;;;CAIC,GACD,SAASC,uBAAuBC,SAA8B;IAC5D,MAAMC,QAAoB;QACxBC,cAAc;QACdC,mBAAmB;IACrB;IAEA,eAAeC;QACb,IAAIH,MAAMC,YAAY,EAAE;YACtBD,MAAME,iBAAiB,GAAG;YAC1B;QACF;QAEAF,MAAMC,YAAY,GAAG;QACrBD,MAAME,iBAAiB,GAAG;QAE1B,IAAI;YACF,MAAMH;QACR,SAAU;YACRC,MAAMC,YAAY,GAAG;YAErB,mDAAmD;YACnD,IAAID,MAAME,iBAAiB,EAAE;gBAC3BF,MAAME,iBAAiB,GAAG;gBAC1B,MAAMC;YACR;QACF;IACF;IAEA,OAAO;QAACA;QAAeH;IAAK;AAC9B;AAEA;;;CAGC,GACD,OAAO,eAAeI,0BACpBC,OAAoC;IAEpC,MAAM,EAACC,cAAc,EAAEC,YAAY,EAAEC,MAAM,EAAEC,aAAa,EAAC,GAAGJ;IAE9D,MAAM,EAACK,UAAU,EAAEC,qBAAqB,EAAEC,UAAU,EAAC,GAAGN;IACxD,MAAMO,UAAU9B,QAAQ2B;IAExB,oEAAoE;IACpE,MAAMP,gBAAgB;QACpB,MAAMW,OAAOvB,QACXoB,wBACI,oDACA,wBACJI,KAAK;QACP,MAAMC,sBAAsBC,KAAKC,GAAG;QAEpC,IAAI;YACF,MAAM7B,oBAAoBiB;YAE1BQ,KAAKK,OAAO,CACVR,wBACI,CAAC,oBAAoB,EAAEC,WAAW,8BAA8B,CAAC,GACjE,CAAC,oBAAoB,EAAEA,YAAY;YAGzC,MAAMQ,WAAWH,KAAKC,GAAG,KAAKF;YAC9BT,eAAe;gBAACa;gBAAUC,SAAS;YAAI;YAEvC,OAAO;QACT,EAAE,OAAOC,KAAK;YACZ,MAAMF,WAAWH,KAAKC,GAAG,KAAKF;YAC9BT,eAAe;gBAACa;gBAAUC,SAAS;YAAK;YAExC1B,oBAAoB,4BAA4B2B;YAChDR,KAAKS,IAAI,CAAC;YAEV,yCAAyC;YACzC,IAAID,eAAehC,yBAAyBgC,IAAIE,UAAU,IAAIF,IAAIE,UAAU,CAACC,MAAM,GAAG,GAAG;gBACvFjB,OAAOkB,GAAG,CAAC;gBACXlB,OAAOkB,GAAG,CAACtC,uBAAuBkC,IAAIE,UAAU;YAClD,OAAO,IAAIF,eAAeK,OAAO;gBAC/BnB,OAAOoB,KAAK,CAACN,IAAIO,OAAO,EAAE;oBAACC,MAAM;gBAAC;YACpC;YAEA,OAAO;QACT;IACF;IAEA,yBAAyB;IACzB,MAAM3B;IAEN,MAAM4B,wBAAwBtB,cAAcuB,GAAG,CAAC,CAACC,UAAYhD,KAAK4B,SAASoB;IAE3E,oDAAoD;IACpD,MAAM,EAAC9B,eAAe+B,uBAAuB,EAAC,GAAGpC,uBAAuB;QACtE,MAAMK;IACR;IAEA,gDAAgD;IAChD,MAAMgC,mBAAmBzC,SAAS;QAChC,KAAKwC;IACP,GAAG;IAEH,MAAM,EAACE,OAAO,EAAC,GAAGjD,2BAA2BsB;IAE7C,MAAM4B,UAAqB5C,cAAcsC,uBAAuB;QAC9DO,KAAKzB;QACL0B,SAAS1C;QACT2C,eAAe;IACjB;IAEAH,QAAQI,EAAE,CAAC,OAAO,CAACC,OAAOC;QACxB,IAAI,CAACP,QAAQO,UAAU9B,UAAU;YAC/B;QACF;QAEA,MAAM+B,YAAY,IAAI3B,OAAO4B,kBAAkB;QAC/C,MAAMC,eAAe9D,WAAW2D,YAAYzD,SAAS2B,SAAS8B,YAAYA;QAC1EnC,OAAOkB,GAAG,CAAC,CAAC,CAAC,EAAEkB,UAAU,EAAE,EAAEF,MAAM,EAAE,EAAEI,cAAc;QACrDX;IACF;IAEAE,QAAQI,EAAE,CAAC,SAAS,CAACnB;QACnBd,OAAOoB,KAAK,CAAC,CAAC,eAAe,EAAEN,eAAeK,QAAQL,IAAIO,OAAO,GAAGkB,OAAOzB,MAAM;IACnF;IAEA,OAAO;QACL0B,OAAO,IAAMX,QAAQW,KAAK;QAC1BX;IACF;AACF"}
@@ -1,23 +1,13 @@
1
- import { existsSync, statSync } from 'node:fs';
2
- import { extname, join, resolve } from 'node:path';
1
+ import { getExtractOptions as internalExtractOptions } from '@sanity/cli-build/_internal/extract';
3
2
  export function getExtractOptions({ flags, projectRoot, schemaExtraction }) {
4
- const pathFlag = flags.path ?? schemaExtraction?.path;
5
- let outputPath;
6
- if (pathFlag) {
7
- const resolved = resolve(join(projectRoot.directory, pathFlag));
8
- const isExistingDirectory = existsSync(resolved) && statSync(resolved).isDirectory();
9
- outputPath = isExistingDirectory || !extname(resolved) ? join(resolved, 'schema.json') : resolved;
10
- } else {
11
- outputPath = resolve(join(projectRoot.directory, 'schema.json'));
12
- }
13
- return {
14
- configPath: projectRoot.path,
15
- enforceRequiredFields: flags['enforce-required-fields'] ?? schemaExtraction?.enforceRequiredFields ?? false,
16
- format: flags.format ?? 'groq-type-nodes',
17
- outputPath,
18
- watchPatterns: flags['watch-patterns'] ?? schemaExtraction?.watchPatterns ?? [],
3
+ return internalExtractOptions({
4
+ enforceRequiredFields: flags['enforce-required-fields'] ?? schemaExtraction?.enforceRequiredFields,
5
+ format: flags.format,
6
+ path: flags.path ?? schemaExtraction?.path,
7
+ projectRoot: projectRoot,
8
+ watchPatterns: flags['watch-patterns'] ?? schemaExtraction?.watchPatterns,
19
9
  workspace: flags.workspace ?? schemaExtraction?.workspace
20
- };
10
+ });
21
11
  }
22
12
 
23
13
  //# sourceMappingURL=getExtractOptions.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/actions/schema/getExtractOptions.ts"],"sourcesContent":["import {existsSync, statSync} from 'node:fs'\nimport {extname, join, resolve} from 'node:path'\n\nimport {type CliConfig, ProjectRootResult} from '@sanity/cli-core'\n\nimport {type ExtractSchemaCommand} from '../../commands/schemas/extract.js'\n\nexport interface ExtractOptions {\n configPath: string\n enforceRequiredFields: boolean\n format: string\n outputPath: string\n watchPatterns: string[]\n workspace: string | undefined\n}\n\ninterface GetExtractionOptions {\n flags: ExtractSchemaCommand['flags']\n projectRoot: ProjectRootResult\n schemaExtraction: CliConfig['schemaExtraction']\n}\n\nexport function getExtractOptions({\n flags,\n projectRoot,\n schemaExtraction,\n}: GetExtractionOptions): ExtractOptions {\n const pathFlag = flags.path ?? schemaExtraction?.path\n let outputPath: string\n if (pathFlag) {\n const resolved = resolve(join(projectRoot.directory, pathFlag))\n const isExistingDirectory = existsSync(resolved) && statSync(resolved).isDirectory()\n\n outputPath =\n isExistingDirectory || !extname(resolved) ? join(resolved, 'schema.json') : resolved\n } else {\n outputPath = resolve(join(projectRoot.directory, 'schema.json'))\n }\n\n return {\n configPath: projectRoot.path,\n enforceRequiredFields:\n flags['enforce-required-fields'] ?? schemaExtraction?.enforceRequiredFields ?? false,\n format: flags.format ?? 'groq-type-nodes',\n outputPath,\n watchPatterns: flags['watch-patterns'] ?? schemaExtraction?.watchPatterns ?? [],\n workspace: flags.workspace ?? schemaExtraction?.workspace,\n }\n}\n"],"names":["existsSync","statSync","extname","join","resolve","getExtractOptions","flags","projectRoot","schemaExtraction","pathFlag","path","outputPath","resolved","directory","isExistingDirectory","isDirectory","configPath","enforceRequiredFields","format","watchPatterns","workspace"],"mappings":"AAAA,SAAQA,UAAU,EAAEC,QAAQ,QAAO,UAAS;AAC5C,SAAQC,OAAO,EAAEC,IAAI,EAAEC,OAAO,QAAO,YAAW;AAqBhD,OAAO,SAASC,kBAAkB,EAChCC,KAAK,EACLC,WAAW,EACXC,gBAAgB,EACK;IACrB,MAAMC,WAAWH,MAAMI,IAAI,IAAIF,kBAAkBE;IACjD,IAAIC;IACJ,IAAIF,UAAU;QACZ,MAAMG,WAAWR,QAAQD,KAAKI,YAAYM,SAAS,EAAEJ;QACrD,MAAMK,sBAAsBd,WAAWY,aAAaX,SAASW,UAAUG,WAAW;QAElFJ,aACEG,uBAAuB,CAACZ,QAAQU,YAAYT,KAAKS,UAAU,iBAAiBA;IAChF,OAAO;QACLD,aAAaP,QAAQD,KAAKI,YAAYM,SAAS,EAAE;IACnD;IAEA,OAAO;QACLG,YAAYT,YAAYG,IAAI;QAC5BO,uBACEX,KAAK,CAAC,0BAA0B,IAAIE,kBAAkBS,yBAAyB;QACjFC,QAAQZ,MAAMY,MAAM,IAAI;QACxBP;QACAQ,eAAeb,KAAK,CAAC,iBAAiB,IAAIE,kBAAkBW,iBAAiB,EAAE;QAC/EC,WAAWd,MAAMc,SAAS,IAAIZ,kBAAkBY;IAClD;AACF"}
1
+ {"version":3,"sources":["../../../src/actions/schema/getExtractOptions.ts"],"sourcesContent":["import {\n type ExtractOptions,\n getExtractOptions as internalExtractOptions,\n} from '@sanity/cli-build/_internal/extract'\nimport {type CliConfig, type ProjectRootResult} from '@sanity/cli-core'\n\nimport {type ExtractSchemaCommand} from '../../commands/schemas/extract.js'\n\ninterface GetExtractionOptions {\n flags: ExtractSchemaCommand['flags']\n projectRoot: ProjectRootResult\n schemaExtraction: CliConfig['schemaExtraction']\n}\n\nexport function getExtractOptions({\n flags,\n projectRoot,\n schemaExtraction,\n}: GetExtractionOptions): ExtractOptions {\n return internalExtractOptions({\n enforceRequiredFields:\n flags['enforce-required-fields'] ?? schemaExtraction?.enforceRequiredFields,\n format: flags.format,\n path: flags.path ?? schemaExtraction?.path,\n projectRoot: projectRoot,\n watchPatterns: flags['watch-patterns'] ?? schemaExtraction?.watchPatterns,\n workspace: flags.workspace ?? schemaExtraction?.workspace,\n })\n}\n"],"names":["getExtractOptions","internalExtractOptions","flags","projectRoot","schemaExtraction","enforceRequiredFields","format","path","watchPatterns","workspace"],"mappings":"AAAA,SAEEA,qBAAqBC,sBAAsB,QACtC,sCAAqC;AAW5C,OAAO,SAASD,kBAAkB,EAChCE,KAAK,EACLC,WAAW,EACXC,gBAAgB,EACK;IACrB,OAAOH,uBAAuB;QAC5BI,uBACEH,KAAK,CAAC,0BAA0B,IAAIE,kBAAkBC;QACxDC,QAAQJ,MAAMI,MAAM;QACpBC,MAAML,MAAMK,IAAI,IAAIH,kBAAkBG;QACtCJ,aAAaA;QACbK,eAAeN,KAAK,CAAC,iBAAiB,IAAIE,kBAAkBI;QAC5DC,WAAWP,MAAMO,SAAS,IAAIL,kBAAkBK;IAClD;AACF"}
@@ -1,10 +1,4 @@
1
1
  import { z } from 'zod/mini';
2
- export const extractSchemaWorkerData = z.object({
3
- configPath: z.string(),
4
- enforceRequiredFields: z.boolean(),
5
- workDir: z.string(),
6
- workspaceName: z.optional(z.string())
7
- });
8
2
  export const uniqWorkspaceWorkerDataSchema = z.object({
9
3
  configPath: z.string(),
10
4
  dataset: z.optional(z.string())
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/actions/schema/types.ts"],"sourcesContent":["import {type SchemaValidationProblemGroup} from '@sanity/types'\nimport {z} from 'zod/mini'\n\nexport const extractSchemaWorkerData = z.object({\n configPath: z.string(),\n enforceRequiredFields: z.boolean(),\n workDir: z.string(),\n workspaceName: z.optional(z.string()),\n})\n\nexport type ExtractSchemaWorkerData = z.infer<typeof extractSchemaWorkerData>\n\n/**\n * Contains debug information about the serialized schema.\n *\n * @internal\n **/\nexport type SerializedSchemaDebug = {\n hoisted: Record<string, SerializedTypeDebug>\n parent?: SerializedSchemaDebug\n size: number\n types: Record<string, SerializedTypeDebug>\n}\n\n/**\n * Contains debug information about a serialized type.\n *\n * @internal\n **/\nexport type SerializedTypeDebug = {\n extends: string\n fields?: Record<string, SerializedTypeDebug>\n of?: Record<string, SerializedTypeDebug>\n size: number\n}\n\n/** @internal */\nexport interface ExtractSchemaWorkerError {\n error: string\n type: 'error'\n\n validation?: SchemaValidationProblemGroup[]\n}\n\nexport const uniqWorkspaceWorkerDataSchema = z.object({\n configPath: z.string(),\n dataset: z.optional(z.string()),\n})\n\nexport type UniqWorkspaceWorkerData = z.infer<typeof uniqWorkspaceWorkerDataSchema>\n\nexport const extractWorkspaceWorkerData = z.object({\n configPath: z.string(),\n workDir: z.string(),\n})\n\nexport type ExtractWorkspaceWorkerData = z.infer<typeof extractWorkspaceWorkerData>\n"],"names":["z","extractSchemaWorkerData","object","configPath","string","enforceRequiredFields","boolean","workDir","workspaceName","optional","uniqWorkspaceWorkerDataSchema","dataset","extractWorkspaceWorkerData"],"mappings":"AACA,SAAQA,CAAC,QAAO,WAAU;AAE1B,OAAO,MAAMC,0BAA0BD,EAAEE,MAAM,CAAC;IAC9CC,YAAYH,EAAEI,MAAM;IACpBC,uBAAuBL,EAAEM,OAAO;IAChCC,SAASP,EAAEI,MAAM;IACjBI,eAAeR,EAAES,QAAQ,CAACT,EAAEI,MAAM;AACpC,GAAE;AAoCF,OAAO,MAAMM,gCAAgCV,EAAEE,MAAM,CAAC;IACpDC,YAAYH,EAAEI,MAAM;IACpBO,SAASX,EAAES,QAAQ,CAACT,EAAEI,MAAM;AAC9B,GAAE;AAIF,OAAO,MAAMQ,6BAA6BZ,EAAEE,MAAM,CAAC;IACjDC,YAAYH,EAAEI,MAAM;IACpBG,SAASP,EAAEI,MAAM;AACnB,GAAE"}
1
+ {"version":3,"sources":["../../../src/actions/schema/types.ts"],"sourcesContent":["import {z} from 'zod/mini'\n\n/**\n * Contains debug information about the serialized schema.\n *\n * @internal\n **/\nexport type SerializedSchemaDebug = {\n hoisted: Record<string, SerializedTypeDebug>\n parent?: SerializedSchemaDebug\n size: number\n types: Record<string, SerializedTypeDebug>\n}\n\n/**\n * Contains debug information about a serialized type.\n *\n * @internal\n **/\nexport type SerializedTypeDebug = {\n extends: string\n fields?: Record<string, SerializedTypeDebug>\n of?: Record<string, SerializedTypeDebug>\n size: number\n}\n\nexport const uniqWorkspaceWorkerDataSchema = z.object({\n configPath: z.string(),\n dataset: z.optional(z.string()),\n})\n\nexport type UniqWorkspaceWorkerData = z.infer<typeof uniqWorkspaceWorkerDataSchema>\n\nexport const extractWorkspaceWorkerData = z.object({\n configPath: z.string(),\n workDir: z.string(),\n})\n\nexport type ExtractWorkspaceWorkerData = z.infer<typeof extractWorkspaceWorkerData>\n"],"names":["z","uniqWorkspaceWorkerDataSchema","object","configPath","string","dataset","optional","extractWorkspaceWorkerData","workDir"],"mappings":"AAAA,SAAQA,CAAC,QAAO,WAAU;AA0B1B,OAAO,MAAMC,gCAAgCD,EAAEE,MAAM,CAAC;IACpDC,YAAYH,EAAEI,MAAM;IACpBC,SAASL,EAAEM,QAAQ,CAACN,EAAEI,MAAM;AAC9B,GAAE;AAIF,OAAO,MAAMG,6BAA6BP,EAAEE,MAAM,CAAC;IACjDC,YAAYH,EAAEI,MAAM;IACpBI,SAASR,EAAEI,MAAM;AACnB,GAAE"}
@@ -1,7 +1,7 @@
1
1
  import { writeFileSync } from 'node:fs';
2
+ import { formatSchemaValidation, getAggregatedSeverity } from '@sanity/cli-build/_internal/extract';
2
3
  import { studioWorkerTask } from '@sanity/cli-core';
3
4
  import { logSymbols, spinner } from '@sanity/cli-core/ux';
4
- import { formatSchemaValidation, getAggregatedSeverity } from './formatSchemaValidation.js';
5
5
  import { generateMetafile } from './metafile.js';
6
6
  export async function validateAction(options) {
7
7
  const { debugMetafilePath, format, level, output, workDir, workspace } = options;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/actions/schema/validateAction.ts"],"sourcesContent":["import {writeFileSync} from 'node:fs'\n\nimport {Output, studioWorkerTask} from '@sanity/cli-core'\nimport {logSymbols, spinner} from '@sanity/cli-core/ux'\n\nimport {formatSchemaValidation, getAggregatedSeverity} from './formatSchemaValidation.js'\nimport {generateMetafile} from './metafile.js'\nimport {\n type ValidateSchemaWorkerData,\n type ValidateSchemaWorkerResult,\n} from './validateSchema.worker.js'\n\ninterface Options {\n output: Output\n workDir: string\n\n debugMetafilePath?: string\n format?: string\n level?: 'error' | 'warning'\n workspace?: string\n}\n\nexport async function validateAction(options: Options): Promise<void> {\n const {debugMetafilePath, format, level, output, workDir, workspace} = options\n\n let spin\n\n if (format === 'pretty') {\n spin = spinner(\n workspace ? `Validating schema from workspace '${workspace}'…` : 'Validating schema…',\n ).start()\n }\n\n const {serializedDebug, validation} = await studioWorkerTask<ValidateSchemaWorkerResult>(\n new URL('validateSchema.worker.js', import.meta.url),\n {\n name: 'validateSchema',\n studioRootPath: workDir,\n workerData: {\n debugSerialize: Boolean(debugMetafilePath),\n level,\n workDir,\n workspace: workspace,\n } satisfies ValidateSchemaWorkerData,\n },\n )\n\n const problems = validation.flatMap((group) => group.problems)\n const errorCount = problems.filter((problem) => problem.severity === 'error').length\n const warningCount = problems.filter((problem) => problem.severity === 'warning').length\n\n const overallSeverity = getAggregatedSeverity(validation)\n const didFail = overallSeverity === 'error'\n\n if (debugMetafilePath && !didFail) {\n if (!serializedDebug) throw new Error('serializedDebug should always be produced')\n const metafile = generateMetafile(serializedDebug)\n writeFileSync(debugMetafilePath, JSON.stringify(metafile), 'utf8')\n }\n\n switch (format) {\n case 'json': {\n output.log(JSON.stringify(validation))\n break\n }\n case 'ndjson': {\n for (const group of validation) {\n output.log(JSON.stringify(group))\n }\n break\n }\n default: {\n spin?.succeed('Validated schema')\n output.log(`\\nValidation results:`)\n output.log(\n `${logSymbols.error} Errors: ${errorCount.toLocaleString('en-US')} error${\n errorCount === 1 ? '' : 's'\n }`,\n )\n if (level !== 'error') {\n output.log(\n `${logSymbols.warning} Warnings: ${warningCount.toLocaleString('en-US')} warning${\n warningCount === 1 ? '' : 's'\n }`,\n )\n }\n output.log()\n\n output.log(formatSchemaValidation(validation))\n\n if (debugMetafilePath) {\n output.log()\n if (didFail) {\n output.log(`${logSymbols.info} Metafile not written due to validation errors`)\n } else {\n output.log(`${logSymbols.info} Metafile written to: ${debugMetafilePath}`)\n output.log(` This can be analyzed at https://esbuild.github.io/analyze/`)\n }\n }\n }\n }\n\n if (didFail) {\n throw new Error('Schema validation failed')\n }\n}\n"],"names":["writeFileSync","studioWorkerTask","logSymbols","spinner","formatSchemaValidation","getAggregatedSeverity","generateMetafile","validateAction","options","debugMetafilePath","format","level","output","workDir","workspace","spin","start","serializedDebug","validation","URL","url","name","studioRootPath","workerData","debugSerialize","Boolean","problems","flatMap","group","errorCount","filter","problem","severity","length","warningCount","overallSeverity","didFail","Error","metafile","JSON","stringify","log","succeed","error","toLocaleString","warning","info"],"mappings":"AAAA,SAAQA,aAAa,QAAO,UAAS;AAErC,SAAgBC,gBAAgB,QAAO,mBAAkB;AACzD,SAAQC,UAAU,EAAEC,OAAO,QAAO,sBAAqB;AAEvD,SAAQC,sBAAsB,EAAEC,qBAAqB,QAAO,8BAA6B;AACzF,SAAQC,gBAAgB,QAAO,gBAAe;AAgB9C,OAAO,eAAeC,eAAeC,OAAgB;IACnD,MAAM,EAACC,iBAAiB,EAAEC,MAAM,EAAEC,KAAK,EAAEC,MAAM,EAAEC,OAAO,EAAEC,SAAS,EAAC,GAAGN;IAEvE,IAAIO;IAEJ,IAAIL,WAAW,UAAU;QACvBK,OAAOZ,QACLW,YAAY,CAAC,kCAAkC,EAAEA,UAAU,EAAE,CAAC,GAAG,sBACjEE,KAAK;IACT;IAEA,MAAM,EAACC,eAAe,EAAEC,UAAU,EAAC,GAAG,MAAMjB,iBAC1C,IAAIkB,IAAI,4BAA4B,YAAYC,GAAG,GACnD;QACEC,MAAM;QACNC,gBAAgBT;QAChBU,YAAY;YACVC,gBAAgBC,QAAQhB;YACxBE;YACAE;YACAC,WAAWA;QACb;IACF;IAGF,MAAMY,WAAWR,WAAWS,OAAO,CAAC,CAACC,QAAUA,MAAMF,QAAQ;IAC7D,MAAMG,aAAaH,SAASI,MAAM,CAAC,CAACC,UAAYA,QAAQC,QAAQ,KAAK,SAASC,MAAM;IACpF,MAAMC,eAAeR,SAASI,MAAM,CAAC,CAACC,UAAYA,QAAQC,QAAQ,KAAK,WAAWC,MAAM;IAExF,MAAME,kBAAkB9B,sBAAsBa;IAC9C,MAAMkB,UAAUD,oBAAoB;IAEpC,IAAI1B,qBAAqB,CAAC2B,SAAS;QACjC,IAAI,CAACnB,iBAAiB,MAAM,IAAIoB,MAAM;QACtC,MAAMC,WAAWhC,iBAAiBW;QAClCjB,cAAcS,mBAAmB8B,KAAKC,SAAS,CAACF,WAAW;IAC7D;IAEA,OAAQ5B;QACN,KAAK;YAAQ;gBACXE,OAAO6B,GAAG,CAACF,KAAKC,SAAS,CAACtB;gBAC1B;YACF;QACA,KAAK;YAAU;gBACb,KAAK,MAAMU,SAASV,WAAY;oBAC9BN,OAAO6B,GAAG,CAACF,KAAKC,SAAS,CAACZ;gBAC5B;gBACA;YACF;QACA;YAAS;gBACPb,MAAM2B,QAAQ;gBACd9B,OAAO6B,GAAG,CAAC,CAAC,qBAAqB,CAAC;gBAClC7B,OAAO6B,GAAG,CACR,GAAGvC,WAAWyC,KAAK,CAAC,WAAW,EAAEd,WAAWe,cAAc,CAAC,SAAS,MAAM,EACxEf,eAAe,IAAI,KAAK,KACxB;gBAEJ,IAAIlB,UAAU,SAAS;oBACrBC,OAAO6B,GAAG,CACR,GAAGvC,WAAW2C,OAAO,CAAC,WAAW,EAAEX,aAAaU,cAAc,CAAC,SAAS,QAAQ,EAC9EV,iBAAiB,IAAI,KAAK,KAC1B;gBAEN;gBACAtB,OAAO6B,GAAG;gBAEV7B,OAAO6B,GAAG,CAACrC,uBAAuBc;gBAElC,IAAIT,mBAAmB;oBACrBG,OAAO6B,GAAG;oBACV,IAAIL,SAAS;wBACXxB,OAAO6B,GAAG,CAAC,GAAGvC,WAAW4C,IAAI,CAAC,8CAA8C,CAAC;oBAC/E,OAAO;wBACLlC,OAAO6B,GAAG,CAAC,GAAGvC,WAAW4C,IAAI,CAAC,sBAAsB,EAAErC,mBAAmB;wBACzEG,OAAO6B,GAAG,CAAC,CAAC,4DAA4D,CAAC;oBAC3E;gBACF;YACF;IACF;IAEA,IAAIL,SAAS;QACX,MAAM,IAAIC,MAAM;IAClB;AACF"}
1
+ {"version":3,"sources":["../../../src/actions/schema/validateAction.ts"],"sourcesContent":["import {writeFileSync} from 'node:fs'\n\nimport {formatSchemaValidation, getAggregatedSeverity} from '@sanity/cli-build/_internal/extract'\nimport {Output, studioWorkerTask} from '@sanity/cli-core'\nimport {logSymbols, spinner} from '@sanity/cli-core/ux'\n\nimport {generateMetafile} from './metafile.js'\nimport {\n type ValidateSchemaWorkerData,\n type ValidateSchemaWorkerResult,\n} from './validateSchema.worker.js'\n\ninterface Options {\n output: Output\n workDir: string\n\n debugMetafilePath?: string\n format?: string\n level?: 'error' | 'warning'\n workspace?: string\n}\n\nexport async function validateAction(options: Options): Promise<void> {\n const {debugMetafilePath, format, level, output, workDir, workspace} = options\n\n let spin\n\n if (format === 'pretty') {\n spin = spinner(\n workspace ? `Validating schema from workspace '${workspace}'…` : 'Validating schema…',\n ).start()\n }\n\n const {serializedDebug, validation} = await studioWorkerTask<ValidateSchemaWorkerResult>(\n new URL('validateSchema.worker.js', import.meta.url),\n {\n name: 'validateSchema',\n studioRootPath: workDir,\n workerData: {\n debugSerialize: Boolean(debugMetafilePath),\n level,\n workDir,\n workspace: workspace,\n } satisfies ValidateSchemaWorkerData,\n },\n )\n\n const problems = validation.flatMap((group) => group.problems)\n const errorCount = problems.filter((problem) => problem.severity === 'error').length\n const warningCount = problems.filter((problem) => problem.severity === 'warning').length\n\n const overallSeverity = getAggregatedSeverity(validation)\n const didFail = overallSeverity === 'error'\n\n if (debugMetafilePath && !didFail) {\n if (!serializedDebug) throw new Error('serializedDebug should always be produced')\n const metafile = generateMetafile(serializedDebug)\n writeFileSync(debugMetafilePath, JSON.stringify(metafile), 'utf8')\n }\n\n switch (format) {\n case 'json': {\n output.log(JSON.stringify(validation))\n break\n }\n case 'ndjson': {\n for (const group of validation) {\n output.log(JSON.stringify(group))\n }\n break\n }\n default: {\n spin?.succeed('Validated schema')\n output.log(`\\nValidation results:`)\n output.log(\n `${logSymbols.error} Errors: ${errorCount.toLocaleString('en-US')} error${\n errorCount === 1 ? '' : 's'\n }`,\n )\n if (level !== 'error') {\n output.log(\n `${logSymbols.warning} Warnings: ${warningCount.toLocaleString('en-US')} warning${\n warningCount === 1 ? '' : 's'\n }`,\n )\n }\n output.log()\n\n output.log(formatSchemaValidation(validation))\n\n if (debugMetafilePath) {\n output.log()\n if (didFail) {\n output.log(`${logSymbols.info} Metafile not written due to validation errors`)\n } else {\n output.log(`${logSymbols.info} Metafile written to: ${debugMetafilePath}`)\n output.log(` This can be analyzed at https://esbuild.github.io/analyze/`)\n }\n }\n }\n }\n\n if (didFail) {\n throw new Error('Schema validation failed')\n }\n}\n"],"names":["writeFileSync","formatSchemaValidation","getAggregatedSeverity","studioWorkerTask","logSymbols","spinner","generateMetafile","validateAction","options","debugMetafilePath","format","level","output","workDir","workspace","spin","start","serializedDebug","validation","URL","url","name","studioRootPath","workerData","debugSerialize","Boolean","problems","flatMap","group","errorCount","filter","problem","severity","length","warningCount","overallSeverity","didFail","Error","metafile","JSON","stringify","log","succeed","error","toLocaleString","warning","info"],"mappings":"AAAA,SAAQA,aAAa,QAAO,UAAS;AAErC,SAAQC,sBAAsB,EAAEC,qBAAqB,QAAO,sCAAqC;AACjG,SAAgBC,gBAAgB,QAAO,mBAAkB;AACzD,SAAQC,UAAU,EAAEC,OAAO,QAAO,sBAAqB;AAEvD,SAAQC,gBAAgB,QAAO,gBAAe;AAgB9C,OAAO,eAAeC,eAAeC,OAAgB;IACnD,MAAM,EAACC,iBAAiB,EAAEC,MAAM,EAAEC,KAAK,EAAEC,MAAM,EAAEC,OAAO,EAAEC,SAAS,EAAC,GAAGN;IAEvE,IAAIO;IAEJ,IAAIL,WAAW,UAAU;QACvBK,OAAOV,QACLS,YAAY,CAAC,kCAAkC,EAAEA,UAAU,EAAE,CAAC,GAAG,sBACjEE,KAAK;IACT;IAEA,MAAM,EAACC,eAAe,EAAEC,UAAU,EAAC,GAAG,MAAMf,iBAC1C,IAAIgB,IAAI,4BAA4B,YAAYC,GAAG,GACnD;QACEC,MAAM;QACNC,gBAAgBT;QAChBU,YAAY;YACVC,gBAAgBC,QAAQhB;YACxBE;YACAE;YACAC,WAAWA;QACb;IACF;IAGF,MAAMY,WAAWR,WAAWS,OAAO,CAAC,CAACC,QAAUA,MAAMF,QAAQ;IAC7D,MAAMG,aAAaH,SAASI,MAAM,CAAC,CAACC,UAAYA,QAAQC,QAAQ,KAAK,SAASC,MAAM;IACpF,MAAMC,eAAeR,SAASI,MAAM,CAAC,CAACC,UAAYA,QAAQC,QAAQ,KAAK,WAAWC,MAAM;IAExF,MAAME,kBAAkBjC,sBAAsBgB;IAC9C,MAAMkB,UAAUD,oBAAoB;IAEpC,IAAI1B,qBAAqB,CAAC2B,SAAS;QACjC,IAAI,CAACnB,iBAAiB,MAAM,IAAIoB,MAAM;QACtC,MAAMC,WAAWhC,iBAAiBW;QAClCjB,cAAcS,mBAAmB8B,KAAKC,SAAS,CAACF,WAAW;IAC7D;IAEA,OAAQ5B;QACN,KAAK;YAAQ;gBACXE,OAAO6B,GAAG,CAACF,KAAKC,SAAS,CAACtB;gBAC1B;YACF;QACA,KAAK;YAAU;gBACb,KAAK,MAAMU,SAASV,WAAY;oBAC9BN,OAAO6B,GAAG,CAACF,KAAKC,SAAS,CAACZ;gBAC5B;gBACA;YACF;QACA;YAAS;gBACPb,MAAM2B,QAAQ;gBACd9B,OAAO6B,GAAG,CAAC,CAAC,qBAAqB,CAAC;gBAClC7B,OAAO6B,GAAG,CACR,GAAGrC,WAAWuC,KAAK,CAAC,WAAW,EAAEd,WAAWe,cAAc,CAAC,SAAS,MAAM,EACxEf,eAAe,IAAI,KAAK,KACxB;gBAEJ,IAAIlB,UAAU,SAAS;oBACrBC,OAAO6B,GAAG,CACR,GAAGrC,WAAWyC,OAAO,CAAC,WAAW,EAAEX,aAAaU,cAAc,CAAC,SAAS,QAAQ,EAC9EV,iBAAiB,IAAI,KAAK,KAC1B;gBAEN;gBACAtB,OAAO6B,GAAG;gBAEV7B,OAAO6B,GAAG,CAACxC,uBAAuBiB;gBAElC,IAAIT,mBAAmB;oBACrBG,OAAO6B,GAAG;oBACV,IAAIL,SAAS;wBACXxB,OAAO6B,GAAG,CAAC,GAAGrC,WAAW0C,IAAI,CAAC,8CAA8C,CAAC;oBAC/E,OAAO;wBACLlC,OAAO6B,GAAG,CAAC,GAAGrC,WAAW0C,IAAI,CAAC,sBAAsB,EAAErC,mBAAmB;wBACzEG,OAAO6B,GAAG,CAAC,CAAC,4DAA4D,CAAC;oBAC3E;gBACF;YACF;IACF;IAEA,IAAIL,SAAS;QACX,MAAM,IAAIC,MAAM;IAClB;AACF"}
@@ -1,7 +1,6 @@
1
1
  import { isMainThread, parentPort, workerData } from 'node:worker_threads';
2
- import { findStudioConfigPath, getStudioWorkspaces } from '@sanity/cli-core';
2
+ import { findStudioConfigPath, getStudioWorkspaces, getWorkspace } from '@sanity/cli-core';
3
3
  import { DescriptorConverter } from '@sanity/schema/_internal';
4
- import { getWorkspace } from '../../util/getWorkspace.js';
5
4
  import { isSchemaError } from '../../util/isSchemaError.js';
6
5
  const { debugSerialize, level = 'warning', workDir, workspace: workspaceName } = workerData;
7
6
  async function main() {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/actions/schema/validateSchema.worker.ts"],"sourcesContent":["import {isMainThread, parentPort, workerData} from 'node:worker_threads'\n\nimport {findStudioConfigPath, getStudioWorkspaces} from '@sanity/cli-core'\nimport {\n type EncodableObject,\n type EncodableValue,\n type SetSynchronization,\n} from '@sanity/descriptors'\nimport {DescriptorConverter} from '@sanity/schema/_internal'\nimport {\n type Schema,\n type SchemaValidationProblem,\n type SchemaValidationProblemGroup,\n} from '@sanity/types'\n\nimport {getWorkspace} from '../../util/getWorkspace.js'\nimport {isSchemaError} from '../../util/isSchemaError.js'\nimport {type SerializedSchemaDebug, type SerializedTypeDebug} from './types.js'\n\n/** @internal */\nexport interface ValidateSchemaWorkerData {\n workDir: string\n\n debugSerialize?: boolean\n level?: SchemaValidationProblem['severity']\n workspace?: string\n}\n\n/** @internal */\nexport interface ValidateSchemaWorkerResult {\n validation: SchemaValidationProblemGroup[]\n\n serializedDebug?: SerializedSchemaDebug\n}\n\nconst {\n debugSerialize,\n level = 'warning',\n workDir,\n workspace: workspaceName,\n} = workerData as ValidateSchemaWorkerData\n\nasync function main() {\n if (isMainThread || !parentPort) {\n throw new Error('This module must be run as a worker thread')\n }\n\n try {\n const configPath = await findStudioConfigPath(workDir)\n const workspaces = await getStudioWorkspaces(configPath)\n const workspace = getWorkspace(workspaces, workspaceName)\n const schema = workspace.schema\n parentPort?.postMessage(await resultFromSchema(schema))\n } catch (err: unknown) {\n if (isSchemaError(err)) {\n parentPort?.postMessage(await resultFromSchema(err.schema))\n return\n }\n\n throw err\n }\n}\n\nasync function resultFromSchema(schema: Schema): Promise<ValidateSchemaWorkerResult> {\n let serializedDebug: ValidateSchemaWorkerResult['serializedDebug']\n\n if (debugSerialize) {\n const conv = new DescriptorConverter()\n const set = await conv.get(schema)\n serializedDebug = getSerializedSchemaDebug(set)\n }\n\n const validation = schema._validation ?? []\n\n const result: ValidateSchemaWorkerResult = {\n serializedDebug,\n validation: validation\n .map((group) => ({\n ...group,\n problems: group.problems.filter((problem) =>\n level === 'error' ? problem.severity === 'error' : true,\n ),\n }))\n .filter((group) => group.problems.length),\n }\n\n return result\n}\n\nfunction getSerializedSchemaDebug(set: SetSynchronization<string>): SerializedSchemaDebug {\n let size = 0\n const types: Record<string, SerializedTypeDebug> = {}\n const hoisted: Record<string, SerializedTypeDebug> = {}\n\n for (const [id, value] of Object.entries(set.objectValues)) {\n const descType = typeof value.type === 'string' ? value.type : '<unknown>'\n switch (descType) {\n case 'sanity.schema.hoisted': {\n const key = typeof value.key === 'string' ? value.key : id\n // The `hoisted` can technically hoist _anything_,\n // but we detect the common case of field + array element.\n if (isEncodableObject(value.value) && isEncodableObject(value.value.typeDef)) {\n const debug = getSerializedTypeDebug(value.value.typeDef)\n hoisted[key] = debug\n size += debug.size\n }\n break\n }\n case 'sanity.schema.namedType': {\n const typeName = typeof value.name === 'string' ? value.name : id\n if (isEncodableObject(value.typeDef)) {\n const debug = getSerializedTypeDebug(value.typeDef)\n types[typeName] = debug\n size += debug.size\n }\n break\n }\n default:\n }\n size += JSON.stringify(value).length\n }\n\n return {\n hoisted,\n size,\n types,\n }\n}\n\nfunction isEncodableObject(val: EncodableValue | undefined): val is EncodableObject {\n return typeof val === 'object' && val !== null && !Array.isArray(val)\n}\n\nfunction getSerializedTypeDebug(typeDef: EncodableObject): SerializedTypeDebug {\n const ext = typeof typeDef.extends === 'string' ? typeDef.extends : '<unknown>'\n let fields: SerializedTypeDebug['fields']\n let of: SerializedTypeDebug['of']\n\n if (Array.isArray(typeDef.fields)) {\n fields = {}\n\n for (const field of typeDef.fields) {\n if (!isEncodableObject(field)) continue\n const name = field.name\n const fieldTypeDef = field.typeDef\n if (typeof name !== 'string' || !isEncodableObject(fieldTypeDef)) continue\n\n fields[name] = getSerializedTypeDebug(fieldTypeDef)\n }\n }\n\n if (Array.isArray(typeDef.of)) {\n of = {}\n\n for (const field of typeDef.of) {\n if (!isEncodableObject(field)) continue\n const name = field.name\n const arrayTypeDef = field.typeDef\n if (typeof name !== 'string' || !isEncodableObject(arrayTypeDef)) continue\n\n of[name] = getSerializedTypeDebug(arrayTypeDef)\n }\n }\n\n return {\n extends: ext,\n fields,\n of,\n size: JSON.stringify(typeDef).length,\n }\n}\n\nawait main()\n"],"names":["isMainThread","parentPort","workerData","findStudioConfigPath","getStudioWorkspaces","DescriptorConverter","getWorkspace","isSchemaError","debugSerialize","level","workDir","workspace","workspaceName","main","Error","configPath","workspaces","schema","postMessage","resultFromSchema","err","serializedDebug","conv","set","get","getSerializedSchemaDebug","validation","_validation","result","map","group","problems","filter","problem","severity","length","size","types","hoisted","id","value","Object","entries","objectValues","descType","type","key","isEncodableObject","typeDef","debug","getSerializedTypeDebug","typeName","name","JSON","stringify","val","Array","isArray","ext","extends","fields","of","field","fieldTypeDef","arrayTypeDef"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/actions/schema/validateSchema.worker.ts"],"sourcesContent":["import {isMainThread, parentPort, workerData} from 'node:worker_threads'\n\nimport {findStudioConfigPath, getStudioWorkspaces, getWorkspace} from '@sanity/cli-core'\nimport {\n type EncodableObject,\n type EncodableValue,\n type SetSynchronization,\n} from '@sanity/descriptors'\nimport {DescriptorConverter} from '@sanity/schema/_internal'\nimport {\n type Schema,\n type SchemaValidationProblem,\n type SchemaValidationProblemGroup,\n} from '@sanity/types'\n\nimport {isSchemaError} from '../../util/isSchemaError.js'\nimport {type SerializedSchemaDebug, type SerializedTypeDebug} from './types.js'\n\n/** @internal */\nexport interface ValidateSchemaWorkerData {\n workDir: string\n\n debugSerialize?: boolean\n level?: SchemaValidationProblem['severity']\n workspace?: string\n}\n\n/** @internal */\nexport interface ValidateSchemaWorkerResult {\n validation: SchemaValidationProblemGroup[]\n\n serializedDebug?: SerializedSchemaDebug\n}\n\nconst {\n debugSerialize,\n level = 'warning',\n workDir,\n workspace: workspaceName,\n} = workerData as ValidateSchemaWorkerData\n\nasync function main() {\n if (isMainThread || !parentPort) {\n throw new Error('This module must be run as a worker thread')\n }\n\n try {\n const configPath = await findStudioConfigPath(workDir)\n const workspaces = await getStudioWorkspaces(configPath)\n const workspace = getWorkspace(workspaces, workspaceName)\n const schema = workspace.schema\n parentPort?.postMessage(await resultFromSchema(schema))\n } catch (err: unknown) {\n if (isSchemaError(err)) {\n parentPort?.postMessage(await resultFromSchema(err.schema))\n return\n }\n\n throw err\n }\n}\n\nasync function resultFromSchema(schema: Schema): Promise<ValidateSchemaWorkerResult> {\n let serializedDebug: ValidateSchemaWorkerResult['serializedDebug']\n\n if (debugSerialize) {\n const conv = new DescriptorConverter()\n const set = await conv.get(schema)\n serializedDebug = getSerializedSchemaDebug(set)\n }\n\n const validation = schema._validation ?? []\n\n const result: ValidateSchemaWorkerResult = {\n serializedDebug,\n validation: validation\n .map((group) => ({\n ...group,\n problems: group.problems.filter((problem) =>\n level === 'error' ? problem.severity === 'error' : true,\n ),\n }))\n .filter((group) => group.problems.length),\n }\n\n return result\n}\n\nfunction getSerializedSchemaDebug(set: SetSynchronization<string>): SerializedSchemaDebug {\n let size = 0\n const types: Record<string, SerializedTypeDebug> = {}\n const hoisted: Record<string, SerializedTypeDebug> = {}\n\n for (const [id, value] of Object.entries(set.objectValues)) {\n const descType = typeof value.type === 'string' ? value.type : '<unknown>'\n switch (descType) {\n case 'sanity.schema.hoisted': {\n const key = typeof value.key === 'string' ? value.key : id\n // The `hoisted` can technically hoist _anything_,\n // but we detect the common case of field + array element.\n if (isEncodableObject(value.value) && isEncodableObject(value.value.typeDef)) {\n const debug = getSerializedTypeDebug(value.value.typeDef)\n hoisted[key] = debug\n size += debug.size\n }\n break\n }\n case 'sanity.schema.namedType': {\n const typeName = typeof value.name === 'string' ? value.name : id\n if (isEncodableObject(value.typeDef)) {\n const debug = getSerializedTypeDebug(value.typeDef)\n types[typeName] = debug\n size += debug.size\n }\n break\n }\n default:\n }\n size += JSON.stringify(value).length\n }\n\n return {\n hoisted,\n size,\n types,\n }\n}\n\nfunction isEncodableObject(val: EncodableValue | undefined): val is EncodableObject {\n return typeof val === 'object' && val !== null && !Array.isArray(val)\n}\n\nfunction getSerializedTypeDebug(typeDef: EncodableObject): SerializedTypeDebug {\n const ext = typeof typeDef.extends === 'string' ? typeDef.extends : '<unknown>'\n let fields: SerializedTypeDebug['fields']\n let of: SerializedTypeDebug['of']\n\n if (Array.isArray(typeDef.fields)) {\n fields = {}\n\n for (const field of typeDef.fields) {\n if (!isEncodableObject(field)) continue\n const name = field.name\n const fieldTypeDef = field.typeDef\n if (typeof name !== 'string' || !isEncodableObject(fieldTypeDef)) continue\n\n fields[name] = getSerializedTypeDebug(fieldTypeDef)\n }\n }\n\n if (Array.isArray(typeDef.of)) {\n of = {}\n\n for (const field of typeDef.of) {\n if (!isEncodableObject(field)) continue\n const name = field.name\n const arrayTypeDef = field.typeDef\n if (typeof name !== 'string' || !isEncodableObject(arrayTypeDef)) continue\n\n of[name] = getSerializedTypeDebug(arrayTypeDef)\n }\n }\n\n return {\n extends: ext,\n fields,\n of,\n size: JSON.stringify(typeDef).length,\n }\n}\n\nawait main()\n"],"names":["isMainThread","parentPort","workerData","findStudioConfigPath","getStudioWorkspaces","getWorkspace","DescriptorConverter","isSchemaError","debugSerialize","level","workDir","workspace","workspaceName","main","Error","configPath","workspaces","schema","postMessage","resultFromSchema","err","serializedDebug","conv","set","get","getSerializedSchemaDebug","validation","_validation","result","map","group","problems","filter","problem","severity","length","size","types","hoisted","id","value","Object","entries","objectValues","descType","type","key","isEncodableObject","typeDef","debug","getSerializedTypeDebug","typeName","name","JSON","stringify","val","Array","isArray","ext","extends","fields","of","field","fieldTypeDef","arrayTypeDef"],"mappings":"AAAA,SAAQA,YAAY,EAAEC,UAAU,EAAEC,UAAU,QAAO,sBAAqB;AAExE,SAAQC,oBAAoB,EAAEC,mBAAmB,EAAEC,YAAY,QAAO,mBAAkB;AAMxF,SAAQC,mBAAmB,QAAO,2BAA0B;AAO5D,SAAQC,aAAa,QAAO,8BAA6B;AAmBzD,MAAM,EACJC,cAAc,EACdC,QAAQ,SAAS,EACjBC,OAAO,EACPC,WAAWC,aAAa,EACzB,GAAGV;AAEJ,eAAeW;IACb,IAAIb,gBAAgB,CAACC,YAAY;QAC/B,MAAM,IAAIa,MAAM;IAClB;IAEA,IAAI;QACF,MAAMC,aAAa,MAAMZ,qBAAqBO;QAC9C,MAAMM,aAAa,MAAMZ,oBAAoBW;QAC7C,MAAMJ,YAAYN,aAAaW,YAAYJ;QAC3C,MAAMK,SAASN,UAAUM,MAAM;QAC/BhB,YAAYiB,YAAY,MAAMC,iBAAiBF;IACjD,EAAE,OAAOG,KAAc;QACrB,IAAIb,cAAca,MAAM;YACtBnB,YAAYiB,YAAY,MAAMC,iBAAiBC,IAAIH,MAAM;YACzD;QACF;QAEA,MAAMG;IACR;AACF;AAEA,eAAeD,iBAAiBF,MAAc;IAC5C,IAAII;IAEJ,IAAIb,gBAAgB;QAClB,MAAMc,OAAO,IAAIhB;QACjB,MAAMiB,MAAM,MAAMD,KAAKE,GAAG,CAACP;QAC3BI,kBAAkBI,yBAAyBF;IAC7C;IAEA,MAAMG,aAAaT,OAAOU,WAAW,IAAI,EAAE;IAE3C,MAAMC,SAAqC;QACzCP;QACAK,YAAYA,WACTG,GAAG,CAAC,CAACC,QAAW,CAAA;gBACf,GAAGA,KAAK;gBACRC,UAAUD,MAAMC,QAAQ,CAACC,MAAM,CAAC,CAACC,UAC/BxB,UAAU,UAAUwB,QAAQC,QAAQ,KAAK,UAAU;YAEvD,CAAA,GACCF,MAAM,CAAC,CAACF,QAAUA,MAAMC,QAAQ,CAACI,MAAM;IAC5C;IAEA,OAAOP;AACT;AAEA,SAASH,yBAAyBF,GAA+B;IAC/D,IAAIa,OAAO;IACX,MAAMC,QAA6C,CAAC;IACpD,MAAMC,UAA+C,CAAC;IAEtD,KAAK,MAAM,CAACC,IAAIC,MAAM,IAAIC,OAAOC,OAAO,CAACnB,IAAIoB,YAAY,EAAG;QAC1D,MAAMC,WAAW,OAAOJ,MAAMK,IAAI,KAAK,WAAWL,MAAMK,IAAI,GAAG;QAC/D,OAAQD;YACN,KAAK;gBAAyB;oBAC5B,MAAME,MAAM,OAAON,MAAMM,GAAG,KAAK,WAAWN,MAAMM,GAAG,GAAGP;oBACxD,mDAAmD;oBACnD,0DAA0D;oBAC1D,IAAIQ,kBAAkBP,MAAMA,KAAK,KAAKO,kBAAkBP,MAAMA,KAAK,CAACQ,OAAO,GAAG;wBAC5E,MAAMC,QAAQC,uBAAuBV,MAAMA,KAAK,CAACQ,OAAO;wBACxDV,OAAO,CAACQ,IAAI,GAAGG;wBACfb,QAAQa,MAAMb,IAAI;oBACpB;oBACA;gBACF;YACA,KAAK;gBAA2B;oBAC9B,MAAMe,WAAW,OAAOX,MAAMY,IAAI,KAAK,WAAWZ,MAAMY,IAAI,GAAGb;oBAC/D,IAAIQ,kBAAkBP,MAAMQ,OAAO,GAAG;wBACpC,MAAMC,QAAQC,uBAAuBV,MAAMQ,OAAO;wBAClDX,KAAK,CAACc,SAAS,GAAGF;wBAClBb,QAAQa,MAAMb,IAAI;oBACpB;oBACA;gBACF;YACA;QACF;QACAA,QAAQiB,KAAKC,SAAS,CAACd,OAAOL,MAAM;IACtC;IAEA,OAAO;QACLG;QACAF;QACAC;IACF;AACF;AAEA,SAASU,kBAAkBQ,GAA+B;IACxD,OAAO,OAAOA,QAAQ,YAAYA,QAAQ,QAAQ,CAACC,MAAMC,OAAO,CAACF;AACnE;AAEA,SAASL,uBAAuBF,OAAwB;IACtD,MAAMU,MAAM,OAAOV,QAAQW,OAAO,KAAK,WAAWX,QAAQW,OAAO,GAAG;IACpE,IAAIC;IACJ,IAAIC;IAEJ,IAAIL,MAAMC,OAAO,CAACT,QAAQY,MAAM,GAAG;QACjCA,SAAS,CAAC;QAEV,KAAK,MAAME,SAASd,QAAQY,MAAM,CAAE;YAClC,IAAI,CAACb,kBAAkBe,QAAQ;YAC/B,MAAMV,OAAOU,MAAMV,IAAI;YACvB,MAAMW,eAAeD,MAAMd,OAAO;YAClC,IAAI,OAAOI,SAAS,YAAY,CAACL,kBAAkBgB,eAAe;YAElEH,MAAM,CAACR,KAAK,GAAGF,uBAAuBa;QACxC;IACF;IAEA,IAAIP,MAAMC,OAAO,CAACT,QAAQa,EAAE,GAAG;QAC7BA,KAAK,CAAC;QAEN,KAAK,MAAMC,SAASd,QAAQa,EAAE,CAAE;YAC9B,IAAI,CAACd,kBAAkBe,QAAQ;YAC/B,MAAMV,OAAOU,MAAMV,IAAI;YACvB,MAAMY,eAAeF,MAAMd,OAAO;YAClC,IAAI,OAAOI,SAAS,YAAY,CAACL,kBAAkBiB,eAAe;YAElEH,EAAE,CAACT,KAAK,GAAGF,uBAAuBc;QACpC;IACF;IAEA,OAAO;QACLL,SAASD;QACTE;QACAC;QACAzB,MAAMiB,KAAKC,SAAS,CAACN,SAASb,MAAM;IACtC;AACF;AAEA,MAAMtB"}
@@ -1,7 +1,7 @@
1
+ import { SchemaExtractionWatchModeTrace } from '@sanity/cli-build/_internal/extract';
1
2
  import { getCliTelemetry } from '@sanity/cli-core';
2
3
  import mean from 'lodash-es/mean.js';
3
4
  import once from 'lodash-es/once.js';
4
- import { SchemaExtractionWatchModeTrace } from '../../telemetry/extractSchema.telemetry.js';
5
5
  import { DEFAULT_WATCH_PATTERNS, startExtractSchemaWatcher } from './extractSchemaWatcher.js';
6
6
  export async function watchExtractSchema(options) {
7
7
  const { extractOptions, output } = options;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/actions/schema/watchExtractSchema.ts"],"sourcesContent":["import {getCliTelemetry, type Output} from '@sanity/cli-core'\nimport mean from 'lodash-es/mean.js'\nimport once from 'lodash-es/once.js'\n\nimport {SchemaExtractionWatchModeTrace} from '../../telemetry/extractSchema.telemetry.js'\nimport {DEFAULT_WATCH_PATTERNS, startExtractSchemaWatcher} from './extractSchemaWatcher.js'\nimport {type ExtractOptions} from './getExtractOptions.js'\n\ninterface WatchExtractSchemaOptions {\n extractOptions: ExtractOptions\n output: Output\n}\n\nexport async function watchExtractSchema(\n options: WatchExtractSchemaOptions,\n): Promise<{close: () => Promise<void>}> {\n const {extractOptions, output} = options\n\n // Keep the start time + some simple stats for extractions as they happen\n const startTime = Date.now()\n const stats: {failedCount: number; successfulDurations: number[]} = {\n failedCount: 0,\n successfulDurations: [],\n }\n\n const watchPatterns = [...DEFAULT_WATCH_PATTERNS, ...extractOptions.watchPatterns]\n\n const trace = getCliTelemetry().trace(SchemaExtractionWatchModeTrace)\n trace.start()\n\n // Print watch mode header and patterns at the very beginning\n output.log('Schema extraction watch mode')\n output.log('')\n output.log('Watching for changes in:')\n for (const pattern of watchPatterns) {\n output.log(` - ${pattern}`)\n }\n output.log('')\n\n output.log('Running initial extraction...')\n\n // Start the watcher (includes initial extraction)\n const {close} = await startExtractSchemaWatcher({\n extractOptions,\n onExtraction: ({duration, success}) => {\n if (success) {\n stats.successfulDurations.push(duration)\n } else {\n stats.failedCount++\n }\n },\n output,\n watchPatterns,\n })\n\n trace.log({\n enforceRequiredFields: extractOptions.enforceRequiredFields,\n schemaFormat: extractOptions.format,\n step: 'started',\n })\n\n output.log('')\n output.log('Watching for changes... (Ctrl+C to stop)')\n\n /**\n * Cleanup function that logs telemetry and stops the watcher.\n * Wrapped in once() to prevent multiple calls.\n */\n const cleanup = once(async () => {\n trace.log({\n averageExtractionDuration: mean(stats.successfulDurations) || 0,\n extractionFailedCount: stats.failedCount,\n extractionSuccessfulCount: stats.successfulDurations.length,\n step: 'stopped',\n watcherDuration: Date.now() - startTime,\n })\n trace.complete()\n\n output.log('')\n output.log('Stopping watch mode...')\n await close()\n })\n\n // Return cleanup function for programmatic usage and testing\n // The CLI framework will handle SIGINT/SIGTERM\n return {close: cleanup}\n}\n"],"names":["getCliTelemetry","mean","once","SchemaExtractionWatchModeTrace","DEFAULT_WATCH_PATTERNS","startExtractSchemaWatcher","watchExtractSchema","options","extractOptions","output","startTime","Date","now","stats","failedCount","successfulDurations","watchPatterns","trace","start","log","pattern","close","onExtraction","duration","success","push","enforceRequiredFields","schemaFormat","format","step","cleanup","averageExtractionDuration","extractionFailedCount","extractionSuccessfulCount","length","watcherDuration","complete"],"mappings":"AAAA,SAAQA,eAAe,QAAoB,mBAAkB;AAC7D,OAAOC,UAAU,oBAAmB;AACpC,OAAOC,UAAU,oBAAmB;AAEpC,SAAQC,8BAA8B,QAAO,6CAA4C;AACzF,SAAQC,sBAAsB,EAAEC,yBAAyB,QAAO,4BAA2B;AAQ3F,OAAO,eAAeC,mBACpBC,OAAkC;IAElC,MAAM,EAACC,cAAc,EAAEC,MAAM,EAAC,GAAGF;IAEjC,yEAAyE;IACzE,MAAMG,YAAYC,KAAKC,GAAG;IAC1B,MAAMC,QAA8D;QAClEC,aAAa;QACbC,qBAAqB,EAAE;IACzB;IAEA,MAAMC,gBAAgB;WAAIZ;WAA2BI,eAAeQ,aAAa;KAAC;IAElF,MAAMC,QAAQjB,kBAAkBiB,KAAK,CAACd;IACtCc,MAAMC,KAAK;IAEX,6DAA6D;IAC7DT,OAAOU,GAAG,CAAC;IACXV,OAAOU,GAAG,CAAC;IACXV,OAAOU,GAAG,CAAC;IACX,KAAK,MAAMC,WAAWJ,cAAe;QACnCP,OAAOU,GAAG,CAAC,CAAC,IAAI,EAAEC,SAAS;IAC7B;IACAX,OAAOU,GAAG,CAAC;IAEXV,OAAOU,GAAG,CAAC;IAEX,kDAAkD;IAClD,MAAM,EAACE,KAAK,EAAC,GAAG,MAAMhB,0BAA0B;QAC9CG;QACAc,cAAc,CAAC,EAACC,QAAQ,EAAEC,OAAO,EAAC;YAChC,IAAIA,SAAS;gBACXX,MAAME,mBAAmB,CAACU,IAAI,CAACF;YACjC,OAAO;gBACLV,MAAMC,WAAW;YACnB;QACF;QACAL;QACAO;IACF;IAEAC,MAAME,GAAG,CAAC;QACRO,uBAAuBlB,eAAekB,qBAAqB;QAC3DC,cAAcnB,eAAeoB,MAAM;QACnCC,MAAM;IACR;IAEApB,OAAOU,GAAG,CAAC;IACXV,OAAOU,GAAG,CAAC;IAEX;;;GAGC,GACD,MAAMW,UAAU5B,KAAK;QACnBe,MAAME,GAAG,CAAC;YACRY,2BAA2B9B,KAAKY,MAAME,mBAAmB,KAAK;YAC9DiB,uBAAuBnB,MAAMC,WAAW;YACxCmB,2BAA2BpB,MAAME,mBAAmB,CAACmB,MAAM;YAC3DL,MAAM;YACNM,iBAAiBxB,KAAKC,GAAG,KAAKF;QAChC;QACAO,MAAMmB,QAAQ;QAEd3B,OAAOU,GAAG,CAAC;QACXV,OAAOU,GAAG,CAAC;QACX,MAAME;IACR;IAEA,6DAA6D;IAC7D,+CAA+C;IAC/C,OAAO;QAACA,OAAOS;IAAO;AACxB"}
1
+ {"version":3,"sources":["../../../src/actions/schema/watchExtractSchema.ts"],"sourcesContent":["import {\n type ExtractOptions,\n SchemaExtractionWatchModeTrace,\n} from '@sanity/cli-build/_internal/extract'\nimport {getCliTelemetry, type Output} from '@sanity/cli-core'\nimport mean from 'lodash-es/mean.js'\nimport once from 'lodash-es/once.js'\n\nimport {DEFAULT_WATCH_PATTERNS, startExtractSchemaWatcher} from './extractSchemaWatcher.js'\n\ninterface WatchExtractSchemaOptions {\n extractOptions: ExtractOptions\n output: Output\n}\n\nexport async function watchExtractSchema(\n options: WatchExtractSchemaOptions,\n): Promise<{close: () => Promise<void>}> {\n const {extractOptions, output} = options\n\n // Keep the start time + some simple stats for extractions as they happen\n const startTime = Date.now()\n const stats: {failedCount: number; successfulDurations: number[]} = {\n failedCount: 0,\n successfulDurations: [],\n }\n\n const watchPatterns = [...DEFAULT_WATCH_PATTERNS, ...extractOptions.watchPatterns]\n\n const trace = getCliTelemetry().trace(SchemaExtractionWatchModeTrace)\n trace.start()\n\n // Print watch mode header and patterns at the very beginning\n output.log('Schema extraction watch mode')\n output.log('')\n output.log('Watching for changes in:')\n for (const pattern of watchPatterns) {\n output.log(` - ${pattern}`)\n }\n output.log('')\n\n output.log('Running initial extraction...')\n\n // Start the watcher (includes initial extraction)\n const {close} = await startExtractSchemaWatcher({\n extractOptions,\n onExtraction: ({duration, success}) => {\n if (success) {\n stats.successfulDurations.push(duration)\n } else {\n stats.failedCount++\n }\n },\n output,\n watchPatterns,\n })\n\n trace.log({\n enforceRequiredFields: extractOptions.enforceRequiredFields,\n schemaFormat: extractOptions.format,\n step: 'started',\n })\n\n output.log('')\n output.log('Watching for changes... (Ctrl+C to stop)')\n\n /**\n * Cleanup function that logs telemetry and stops the watcher.\n * Wrapped in once() to prevent multiple calls.\n */\n const cleanup = once(async () => {\n trace.log({\n averageExtractionDuration: mean(stats.successfulDurations) || 0,\n extractionFailedCount: stats.failedCount,\n extractionSuccessfulCount: stats.successfulDurations.length,\n step: 'stopped',\n watcherDuration: Date.now() - startTime,\n })\n trace.complete()\n\n output.log('')\n output.log('Stopping watch mode...')\n await close()\n })\n\n // Return cleanup function for programmatic usage and testing\n // The CLI framework will handle SIGINT/SIGTERM\n return {close: cleanup}\n}\n"],"names":["SchemaExtractionWatchModeTrace","getCliTelemetry","mean","once","DEFAULT_WATCH_PATTERNS","startExtractSchemaWatcher","watchExtractSchema","options","extractOptions","output","startTime","Date","now","stats","failedCount","successfulDurations","watchPatterns","trace","start","log","pattern","close","onExtraction","duration","success","push","enforceRequiredFields","schemaFormat","format","step","cleanup","averageExtractionDuration","extractionFailedCount","extractionSuccessfulCount","length","watcherDuration","complete"],"mappings":"AAAA,SAEEA,8BAA8B,QACzB,sCAAqC;AAC5C,SAAQC,eAAe,QAAoB,mBAAkB;AAC7D,OAAOC,UAAU,oBAAmB;AACpC,OAAOC,UAAU,oBAAmB;AAEpC,SAAQC,sBAAsB,EAAEC,yBAAyB,QAAO,4BAA2B;AAO3F,OAAO,eAAeC,mBACpBC,OAAkC;IAElC,MAAM,EAACC,cAAc,EAAEC,MAAM,EAAC,GAAGF;IAEjC,yEAAyE;IACzE,MAAMG,YAAYC,KAAKC,GAAG;IAC1B,MAAMC,QAA8D;QAClEC,aAAa;QACbC,qBAAqB,EAAE;IACzB;IAEA,MAAMC,gBAAgB;WAAIZ;WAA2BI,eAAeQ,aAAa;KAAC;IAElF,MAAMC,QAAQhB,kBAAkBgB,KAAK,CAACjB;IACtCiB,MAAMC,KAAK;IAEX,6DAA6D;IAC7DT,OAAOU,GAAG,CAAC;IACXV,OAAOU,GAAG,CAAC;IACXV,OAAOU,GAAG,CAAC;IACX,KAAK,MAAMC,WAAWJ,cAAe;QACnCP,OAAOU,GAAG,CAAC,CAAC,IAAI,EAAEC,SAAS;IAC7B;IACAX,OAAOU,GAAG,CAAC;IAEXV,OAAOU,GAAG,CAAC;IAEX,kDAAkD;IAClD,MAAM,EAACE,KAAK,EAAC,GAAG,MAAMhB,0BAA0B;QAC9CG;QACAc,cAAc,CAAC,EAACC,QAAQ,EAAEC,OAAO,EAAC;YAChC,IAAIA,SAAS;gBACXX,MAAME,mBAAmB,CAACU,IAAI,CAACF;YACjC,OAAO;gBACLV,MAAMC,WAAW;YACnB;QACF;QACAL;QACAO;IACF;IAEAC,MAAME,GAAG,CAAC;QACRO,uBAAuBlB,eAAekB,qBAAqB;QAC3DC,cAAcnB,eAAeoB,MAAM;QACnCC,MAAM;IACR;IAEApB,OAAOU,GAAG,CAAC;IACXV,OAAOU,GAAG,CAAC;IAEX;;;GAGC,GACD,MAAMW,UAAU3B,KAAK;QACnBc,MAAME,GAAG,CAAC;YACRY,2BAA2B7B,KAAKW,MAAME,mBAAmB,KAAK;YAC9DiB,uBAAuBnB,MAAMC,WAAW;YACxCmB,2BAA2BpB,MAAME,mBAAmB,CAACmB,MAAM;YAC3DL,MAAM;YACNM,iBAAiBxB,KAAKC,GAAG,KAAKF;QAChC;QACAO,MAAMmB,QAAQ;QAEd3B,OAAOU,GAAG,CAAC;QACXV,OAAOU,GAAG,CAAC;QACX,MAAME;IACR;IAEA,6DAA6D;IAC7D,+CAA+C;IAC/C,OAAO;QAACA,OAAOS;IAAO;AACxB"}
@@ -0,0 +1,54 @@
1
+ import { subdebug } from '@sanity/cli-core';
2
+ import { execa } from 'execa';
3
+ import { SKILLS_BIN_PATH } from './setupSkills.js';
4
+ const debug = subdebug('skills:state');
5
+ /**
6
+ * Runs the bundled `skills list -g --json` and returns the set of agent
7
+ * display names that have `skillName` installed globally.
8
+ *
9
+ * Any failure (spawn, parse, timeout, non-zero exit) is debug-logged and
10
+ * resolved with an empty set. Callers should treat that as "treat all agents
11
+ * as not installed" — re-installing is idempotent, so over-installing is
12
+ * safer than skipping based on a flaky probe.
13
+ */ export async function readSkillState(opts) {
14
+ const empty = {
15
+ installedAgentDisplayNames: new Set()
16
+ };
17
+ let stdout;
18
+ try {
19
+ const result = await execa(process.execPath, [
20
+ SKILLS_BIN_PATH,
21
+ 'list',
22
+ '-g',
23
+ '--json'
24
+ ], {
25
+ stdio: 'pipe',
26
+ timeout: 10_000
27
+ });
28
+ stdout = result.stdout;
29
+ } catch (error) {
30
+ debug('skills list failed: %O', error);
31
+ return empty;
32
+ }
33
+ let parsed;
34
+ try {
35
+ parsed = JSON.parse(stdout);
36
+ } catch (error) {
37
+ debug('Failed to parse skills list JSON: %O', error);
38
+ return empty;
39
+ }
40
+ if (!Array.isArray(parsed)) {
41
+ debug('Unexpected skills list JSON shape (not an array)');
42
+ return empty;
43
+ }
44
+ const match = parsed.find((entry)=>entry?.name === opts.skillName);
45
+ if (!match || !Array.isArray(match.agents)) {
46
+ return empty;
47
+ }
48
+ const displayNames = match.agents.filter((a)=>typeof a === 'string');
49
+ return {
50
+ installedAgentDisplayNames: new Set(displayNames)
51
+ };
52
+ }
53
+
54
+ //# sourceMappingURL=readSkillState.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/actions/skills/readSkillState.ts"],"sourcesContent":["import {subdebug} from '@sanity/cli-core'\nimport {execa} from 'execa'\n\nimport {SKILLS_BIN_PATH} from './setupSkills.js'\n\nconst debug = subdebug('skills:state')\n\ninterface ReadSkillStateOptions {\n /** Name of the skill to look up (matches the `name` field in `skills list --json`). */\n skillName: string\n}\n\ninterface SkillState {\n /** Display names of agents that have this skill installed globally. */\n installedAgentDisplayNames: Set<string>\n}\n\ninterface SkillListEntry {\n agents?: unknown\n name?: unknown\n}\n\n/**\n * Runs the bundled `skills list -g --json` and returns the set of agent\n * display names that have `skillName` installed globally.\n *\n * Any failure (spawn, parse, timeout, non-zero exit) is debug-logged and\n * resolved with an empty set. Callers should treat that as \"treat all agents\n * as not installed\" — re-installing is idempotent, so over-installing is\n * safer than skipping based on a flaky probe.\n */\nexport async function readSkillState(opts: ReadSkillStateOptions): Promise<SkillState> {\n const empty: SkillState = {installedAgentDisplayNames: new Set()}\n\n let stdout: string\n try {\n const result = await execa(process.execPath, [SKILLS_BIN_PATH, 'list', '-g', '--json'], {\n stdio: 'pipe',\n timeout: 10_000,\n })\n stdout = result.stdout\n } catch (error) {\n debug('skills list failed: %O', error)\n return empty\n }\n\n let parsed: unknown\n try {\n parsed = JSON.parse(stdout)\n } catch (error) {\n debug('Failed to parse skills list JSON: %O', error)\n return empty\n }\n\n if (!Array.isArray(parsed)) {\n debug('Unexpected skills list JSON shape (not an array)')\n return empty\n }\n\n const match = (parsed as SkillListEntry[]).find((entry) => entry?.name === opts.skillName)\n if (!match || !Array.isArray(match.agents)) {\n return empty\n }\n\n const displayNames = match.agents.filter((a): a is string => typeof a === 'string')\n return {installedAgentDisplayNames: new Set(displayNames)}\n}\n"],"names":["subdebug","execa","SKILLS_BIN_PATH","debug","readSkillState","opts","empty","installedAgentDisplayNames","Set","stdout","result","process","execPath","stdio","timeout","error","parsed","JSON","parse","Array","isArray","match","find","entry","name","skillName","agents","displayNames","filter","a"],"mappings":"AAAA,SAAQA,QAAQ,QAAO,mBAAkB;AACzC,SAAQC,KAAK,QAAO,QAAO;AAE3B,SAAQC,eAAe,QAAO,mBAAkB;AAEhD,MAAMC,QAAQH,SAAS;AAiBvB;;;;;;;;CAQC,GACD,OAAO,eAAeI,eAAeC,IAA2B;IAC9D,MAAMC,QAAoB;QAACC,4BAA4B,IAAIC;IAAK;IAEhE,IAAIC;IACJ,IAAI;QACF,MAAMC,SAAS,MAAMT,MAAMU,QAAQC,QAAQ,EAAE;YAACV;YAAiB;YAAQ;YAAM;SAAS,EAAE;YACtFW,OAAO;YACPC,SAAS;QACX;QACAL,SAASC,OAAOD,MAAM;IACxB,EAAE,OAAOM,OAAO;QACdZ,MAAM,0BAA0BY;QAChC,OAAOT;IACT;IAEA,IAAIU;IACJ,IAAI;QACFA,SAASC,KAAKC,KAAK,CAACT;IACtB,EAAE,OAAOM,OAAO;QACdZ,MAAM,wCAAwCY;QAC9C,OAAOT;IACT;IAEA,IAAI,CAACa,MAAMC,OAAO,CAACJ,SAAS;QAC1Bb,MAAM;QACN,OAAOG;IACT;IAEA,MAAMe,QAAQ,AAACL,OAA4BM,IAAI,CAAC,CAACC,QAAUA,OAAOC,SAASnB,KAAKoB,SAAS;IACzF,IAAI,CAACJ,SAAS,CAACF,MAAMC,OAAO,CAACC,MAAMK,MAAM,GAAG;QAC1C,OAAOpB;IACT;IAEA,MAAMqB,eAAeN,MAAMK,MAAM,CAACE,MAAM,CAAC,CAACC,IAAmB,OAAOA,MAAM;IAC1E,OAAO;QAACtB,4BAA4B,IAAIC,IAAImB;IAAa;AAC3D"}
@@ -0,0 +1,73 @@
1
+ import { fileURLToPath } from 'node:url';
2
+ import { ux } from '@oclif/core';
3
+ import { subdebug } from '@sanity/cli-core';
4
+ import { logSymbols } from '@sanity/cli-core/ux';
5
+ import { execa } from 'execa';
6
+ import { getErrorMessage, toError } from '../../util/getErrorMessage.js';
7
+ const skillsDebug = subdebug('skills:setup');
8
+ /** Source repo for the bundled `skills` CLI. See https://www.sanity.io/docs/ai/skills. */ export const SANITY_SKILLS_REPO = 'sanity-io/agent-toolkit';
9
+ /** Name of the skill we install — must match the entry in the source repo. */ export const SANITY_SKILL_NAME = 'sanity-best-practices';
10
+ /**
11
+ * Absolute path to the bundled `skills` CLI bin. Resolved once at module load
12
+ * via `import.meta.resolve` so we run the version pinned in our package.json
13
+ * instead of paying the `npx -y` registry lookup at runtime.
14
+ */ export const SKILLS_BIN_PATH = fileURLToPath(import.meta.resolve('skills/bin/cli.mjs', import.meta.url));
15
+ /**
16
+ * Runs the bundled `skills add` globally for the given agents. Failures are
17
+ * surfaced as warnings and never throw — skills install is best-effort and
18
+ * must not abort `sanity init`.
19
+ */ export async function setupSkills(options) {
20
+ const uniqueAgents = [
21
+ ...new Set(options.agents)
22
+ ];
23
+ if (uniqueAgents.length === 0) {
24
+ skillsDebug('No agents passed — skipping skills install');
25
+ return {
26
+ installedAgents: [],
27
+ skipped: true
28
+ };
29
+ }
30
+ const args = [
31
+ SKILLS_BIN_PATH,
32
+ 'add',
33
+ SANITY_SKILLS_REPO,
34
+ '--skill',
35
+ SANITY_SKILL_NAME,
36
+ '-g',
37
+ ...uniqueAgents.flatMap((agent)=>[
38
+ '-a',
39
+ agent
40
+ ]),
41
+ '-y'
42
+ ];
43
+ skillsDebug('Running: %s %s', process.execPath, args.join(' '));
44
+ try {
45
+ const result = await execa(process.execPath, args, {
46
+ stdio: 'pipe',
47
+ timeout: 90_000
48
+ });
49
+ skillsDebug('skills stdout: %s', result.stdout);
50
+ skillsDebug('skills stderr: %s', result.stderr);
51
+ ux.stdout(`${logSymbols.success} Installed Sanity agent skills for ${uniqueAgents.join(', ')}`);
52
+ return {
53
+ installedAgents: uniqueAgents,
54
+ skipped: false
55
+ };
56
+ } catch (error) {
57
+ skillsDebug('Error installing skills %O', error);
58
+ const err = toError(error);
59
+ ux.warn(`Could not install Sanity agent skills: ${getErrorMessage(error)}`);
60
+ if (error && typeof error === 'object') {
61
+ const { stderr, stdout } = error;
62
+ if (stdout) ux.warn(stdout);
63
+ if (stderr) ux.warn(stderr);
64
+ }
65
+ return {
66
+ error: err,
67
+ installedAgents: [],
68
+ skipped: false
69
+ };
70
+ }
71
+ }
72
+
73
+ //# sourceMappingURL=setupSkills.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/actions/skills/setupSkills.ts"],"sourcesContent":["import {fileURLToPath} from 'node:url'\n\nimport {ux} from '@oclif/core'\nimport {subdebug} from '@sanity/cli-core'\nimport {logSymbols} from '@sanity/cli-core/ux'\nimport {execa} from 'execa'\n\nimport {getErrorMessage, toError} from '../../util/getErrorMessage.js'\n\nconst skillsDebug = subdebug('skills:setup')\n\n/** Source repo for the bundled `skills` CLI. See https://www.sanity.io/docs/ai/skills. */\nexport const SANITY_SKILLS_REPO = 'sanity-io/agent-toolkit'\n\n/** Name of the skill we install — must match the entry in the source repo. */\nexport const SANITY_SKILL_NAME = 'sanity-best-practices'\n\n/**\n * Absolute path to the bundled `skills` CLI bin. Resolved once at module load\n * via `import.meta.resolve` so we run the version pinned in our package.json\n * instead of paying the `npx -y` registry lookup at runtime.\n */\nexport const SKILLS_BIN_PATH = fileURLToPath(\n import.meta.resolve('skills/bin/cli.mjs', import.meta.url),\n)\n\ninterface SetupSkillsOptions {\n /** Skills-CLI agent IDs (e.g. 'cursor', 'claude-code') to install for. */\n agents: string[]\n}\n\ninterface SetupSkillsResult {\n /** Deduplicated `--agent` values passed to `skills add`. */\n installedAgents: string[]\n skipped: boolean\n\n error?: Error\n}\n\n/**\n * Runs the bundled `skills add` globally for the given agents. Failures are\n * surfaced as warnings and never throw — skills install is best-effort and\n * must not abort `sanity init`.\n */\nexport async function setupSkills(options: SetupSkillsOptions): Promise<SetupSkillsResult> {\n const uniqueAgents = [...new Set(options.agents)]\n\n if (uniqueAgents.length === 0) {\n skillsDebug('No agents passed — skipping skills install')\n return {installedAgents: [], skipped: true}\n }\n\n const args = [\n SKILLS_BIN_PATH,\n 'add',\n SANITY_SKILLS_REPO,\n '--skill',\n SANITY_SKILL_NAME,\n '-g',\n ...uniqueAgents.flatMap((agent) => ['-a', agent]),\n '-y',\n ]\n\n skillsDebug('Running: %s %s', process.execPath, args.join(' '))\n\n try {\n const result = await execa(process.execPath, args, {stdio: 'pipe', timeout: 90_000})\n skillsDebug('skills stdout: %s', result.stdout)\n skillsDebug('skills stderr: %s', result.stderr)\n ux.stdout(`${logSymbols.success} Installed Sanity agent skills for ${uniqueAgents.join(', ')}`)\n return {installedAgents: uniqueAgents, skipped: false}\n } catch (error) {\n skillsDebug('Error installing skills %O', error)\n const err = toError(error)\n ux.warn(`Could not install Sanity agent skills: ${getErrorMessage(error)}`)\n if (error && typeof error === 'object') {\n const {stderr, stdout} = error as {stderr?: string; stdout?: string}\n if (stdout) ux.warn(stdout)\n if (stderr) ux.warn(stderr)\n }\n return {error: err, installedAgents: [], skipped: false}\n }\n}\n"],"names":["fileURLToPath","ux","subdebug","logSymbols","execa","getErrorMessage","toError","skillsDebug","SANITY_SKILLS_REPO","SANITY_SKILL_NAME","SKILLS_BIN_PATH","resolve","url","setupSkills","options","uniqueAgents","Set","agents","length","installedAgents","skipped","args","flatMap","agent","process","execPath","join","result","stdio","timeout","stdout","stderr","success","error","err","warn"],"mappings":"AAAA,SAAQA,aAAa,QAAO,WAAU;AAEtC,SAAQC,EAAE,QAAO,cAAa;AAC9B,SAAQC,QAAQ,QAAO,mBAAkB;AACzC,SAAQC,UAAU,QAAO,sBAAqB;AAC9C,SAAQC,KAAK,QAAO,QAAO;AAE3B,SAAQC,eAAe,EAAEC,OAAO,QAAO,gCAA+B;AAEtE,MAAMC,cAAcL,SAAS;AAE7B,wFAAwF,GACxF,OAAO,MAAMM,qBAAqB,0BAAyB;AAE3D,4EAA4E,GAC5E,OAAO,MAAMC,oBAAoB,wBAAuB;AAExD;;;;CAIC,GACD,OAAO,MAAMC,kBAAkBV,cAC7B,YAAYW,OAAO,CAAC,sBAAsB,YAAYC,GAAG,GAC1D;AAeD;;;;CAIC,GACD,OAAO,eAAeC,YAAYC,OAA2B;IAC3D,MAAMC,eAAe;WAAI,IAAIC,IAAIF,QAAQG,MAAM;KAAE;IAEjD,IAAIF,aAAaG,MAAM,KAAK,GAAG;QAC7BX,YAAY;QACZ,OAAO;YAACY,iBAAiB,EAAE;YAAEC,SAAS;QAAI;IAC5C;IAEA,MAAMC,OAAO;QACXX;QACA;QACAF;QACA;QACAC;QACA;WACGM,aAAaO,OAAO,CAAC,CAACC,QAAU;gBAAC;gBAAMA;aAAM;QAChD;KACD;IAEDhB,YAAY,kBAAkBiB,QAAQC,QAAQ,EAAEJ,KAAKK,IAAI,CAAC;IAE1D,IAAI;QACF,MAAMC,SAAS,MAAMvB,MAAMoB,QAAQC,QAAQ,EAAEJ,MAAM;YAACO,OAAO;YAAQC,SAAS;QAAM;QAClFtB,YAAY,qBAAqBoB,OAAOG,MAAM;QAC9CvB,YAAY,qBAAqBoB,OAAOI,MAAM;QAC9C9B,GAAG6B,MAAM,CAAC,GAAG3B,WAAW6B,OAAO,CAAC,mCAAmC,EAAEjB,aAAaW,IAAI,CAAC,OAAO;QAC9F,OAAO;YAACP,iBAAiBJ;YAAcK,SAAS;QAAK;IACvD,EAAE,OAAOa,OAAO;QACd1B,YAAY,8BAA8B0B;QAC1C,MAAMC,MAAM5B,QAAQ2B;QACpBhC,GAAGkC,IAAI,CAAC,CAAC,uCAAuC,EAAE9B,gBAAgB4B,QAAQ;QAC1E,IAAIA,SAAS,OAAOA,UAAU,UAAU;YACtC,MAAM,EAACF,MAAM,EAAED,MAAM,EAAC,GAAGG;YACzB,IAAIH,QAAQ7B,GAAGkC,IAAI,CAACL;YACpB,IAAIC,QAAQ9B,GAAGkC,IAAI,CAACJ;QACtB;QACA,OAAO;YAACE,OAAOC;YAAKf,iBAAiB,EAAE;YAAEC,SAAS;QAAK;IACzD;AACF"}
@@ -1,7 +1,6 @@
1
1
  import { Args, Flags } from '@oclif/core';
2
2
  import { SanityCommand } from '@sanity/cli-core';
3
3
  import { buildApp } from '../actions/build/buildApp.js';
4
- import { buildDebug } from '../actions/build/buildDebug.js';
5
4
  import { buildStudio } from '../actions/build/buildStudio.js';
6
5
  import { shouldAutoUpdate } from '../actions/build/shouldAutoUpdate.js';
7
6
  import { determineIsApp } from '../util/determineIsApp.js';
@@ -52,27 +51,15 @@ export class BuildCommand extends SanityCommand {
52
51
  flags,
53
52
  output
54
53
  });
55
- if (isApp) {
56
- buildDebug(`Building app`);
57
- await buildApp({
58
- autoUpdatesEnabled,
59
- cliConfig,
60
- flags,
61
- outDir: this.args.outputDir,
62
- output,
63
- workDir
64
- });
65
- } else {
66
- buildDebug(`Building studio`);
67
- await buildStudio({
68
- autoUpdatesEnabled,
69
- cliConfig,
70
- flags,
71
- outDir: this.args.outputDir,
72
- output,
73
- workDir
74
- });
75
- }
54
+ const buildFunc = isApp ? buildApp : buildStudio;
55
+ await buildFunc({
56
+ autoUpdatesEnabled,
57
+ cliConfig,
58
+ flags,
59
+ outDir: this.args.outputDir,
60
+ output,
61
+ workDir
62
+ });
76
63
  }
77
64
  }
78
65
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/commands/build.ts"],"sourcesContent":["import {Args, Flags} from '@oclif/core'\nimport {SanityCommand} from '@sanity/cli-core'\n\nimport {buildApp} from '../actions/build/buildApp.js'\nimport {buildDebug} from '../actions/build/buildDebug.js'\nimport {buildStudio} from '../actions/build/buildStudio.js'\nimport {shouldAutoUpdate} from '../actions/build/shouldAutoUpdate.js'\nimport {determineIsApp} from '../util/determineIsApp.js'\n\nexport class BuildCommand extends SanityCommand<typeof BuildCommand> {\n static override args = {\n outputDir: Args.directory({description: 'Output directory'}),\n }\n\n static override description = 'Build Sanity Studio into a static bundle'\n\n static override examples = [\n '<%= config.bin %> <%= command.id %>',\n '<%= config.bin %> <%= command.id %> --no-minify --source-maps',\n ]\n\n static override flags = {\n 'auto-updates': Flags.boolean({\n allowNo: true,\n description: 'Enable/disable auto updates of studio versions',\n }),\n minify: Flags.boolean({\n allowNo: true,\n default: true,\n description: 'Enable/disable minifying of built bundles',\n }),\n 'source-maps': Flags.boolean({\n allowNo: true,\n default: false,\n description: 'Enable source maps for built bundles (increases size of bundle)',\n }),\n stats: Flags.boolean({\n default: false,\n description: 'Show stats about the built bundles',\n }),\n yes: Flags.boolean({\n char: 'y',\n default: false,\n description:\n 'Unattended mode, answers \"yes\" to any \"yes/no\" prompt and otherwise uses defaults',\n }),\n }\n\n public async run(): Promise<void> {\n const cliConfig = await this.getCliConfig()\n\n const {flags} = await this.parse(BuildCommand)\n\n const isApp = determineIsApp(cliConfig)\n\n const workDir = (await this.getProjectRoot()).directory\n\n const output = this.output\n\n const autoUpdatesEnabled = shouldAutoUpdate({cliConfig, flags, output})\n\n if (isApp) {\n buildDebug(`Building app`)\n await buildApp({\n autoUpdatesEnabled,\n cliConfig,\n flags,\n outDir: this.args.outputDir,\n output,\n workDir,\n })\n } else {\n buildDebug(`Building studio`)\n await buildStudio({\n autoUpdatesEnabled,\n cliConfig,\n flags,\n outDir: this.args.outputDir,\n output,\n workDir,\n })\n }\n }\n}\n"],"names":["Args","Flags","SanityCommand","buildApp","buildDebug","buildStudio","shouldAutoUpdate","determineIsApp","BuildCommand","args","outputDir","directory","description","examples","flags","boolean","allowNo","minify","default","stats","yes","char","run","cliConfig","getCliConfig","parse","isApp","workDir","getProjectRoot","output","autoUpdatesEnabled","outDir"],"mappings":"AAAA,SAAQA,IAAI,EAAEC,KAAK,QAAO,cAAa;AACvC,SAAQC,aAAa,QAAO,mBAAkB;AAE9C,SAAQC,QAAQ,QAAO,+BAA8B;AACrD,SAAQC,UAAU,QAAO,iCAAgC;AACzD,SAAQC,WAAW,QAAO,kCAAiC;AAC3D,SAAQC,gBAAgB,QAAO,uCAAsC;AACrE,SAAQC,cAAc,QAAO,4BAA2B;AAExD,OAAO,MAAMC,qBAAqBN;IAChC,OAAgBO,OAAO;QACrBC,WAAWV,KAAKW,SAAS,CAAC;YAACC,aAAa;QAAkB;IAC5D,EAAC;IAED,OAAgBA,cAAc,2CAA0C;IAExE,OAAgBC,WAAW;QACzB;QACA;KACD,CAAA;IAED,OAAgBC,QAAQ;QACtB,gBAAgBb,MAAMc,OAAO,CAAC;YAC5BC,SAAS;YACTJ,aAAa;QACf;QACAK,QAAQhB,MAAMc,OAAO,CAAC;YACpBC,SAAS;YACTE,SAAS;YACTN,aAAa;QACf;QACA,eAAeX,MAAMc,OAAO,CAAC;YAC3BC,SAAS;YACTE,SAAS;YACTN,aAAa;QACf;QACAO,OAAOlB,MAAMc,OAAO,CAAC;YACnBG,SAAS;YACTN,aAAa;QACf;QACAQ,KAAKnB,MAAMc,OAAO,CAAC;YACjBM,MAAM;YACNH,SAAS;YACTN,aACE;QACJ;IACF,EAAC;IAED,MAAaU,MAAqB;QAChC,MAAMC,YAAY,MAAM,IAAI,CAACC,YAAY;QAEzC,MAAM,EAACV,KAAK,EAAC,GAAG,MAAM,IAAI,CAACW,KAAK,CAACjB;QAEjC,MAAMkB,QAAQnB,eAAegB;QAE7B,MAAMI,UAAU,AAAC,CAAA,MAAM,IAAI,CAACC,cAAc,EAAC,EAAGjB,SAAS;QAEvD,MAAMkB,SAAS,IAAI,CAACA,MAAM;QAE1B,MAAMC,qBAAqBxB,iBAAiB;YAACiB;YAAWT;YAAOe;QAAM;QAErE,IAAIH,OAAO;YACTtB,WAAW,CAAC,YAAY,CAAC;YACzB,MAAMD,SAAS;gBACb2B;gBACAP;gBACAT;gBACAiB,QAAQ,IAAI,CAACtB,IAAI,CAACC,SAAS;gBAC3BmB;gBACAF;YACF;QACF,OAAO;YACLvB,WAAW,CAAC,eAAe,CAAC;YAC5B,MAAMC,YAAY;gBAChByB;gBACAP;gBACAT;gBACAiB,QAAQ,IAAI,CAACtB,IAAI,CAACC,SAAS;gBAC3BmB;gBACAF;YACF;QACF;IACF;AACF"}
1
+ {"version":3,"sources":["../../src/commands/build.ts"],"sourcesContent":["import {Args, Flags} from '@oclif/core'\nimport {SanityCommand} from '@sanity/cli-core'\n\nimport {buildApp} from '../actions/build/buildApp.js'\nimport {buildStudio} from '../actions/build/buildStudio.js'\nimport {shouldAutoUpdate} from '../actions/build/shouldAutoUpdate.js'\nimport {determineIsApp} from '../util/determineIsApp.js'\n\nexport class BuildCommand extends SanityCommand<typeof BuildCommand> {\n static override args = {\n outputDir: Args.directory({description: 'Output directory'}),\n }\n\n static override description = 'Build Sanity Studio into a static bundle'\n\n static override examples = [\n '<%= config.bin %> <%= command.id %>',\n '<%= config.bin %> <%= command.id %> --no-minify --source-maps',\n ]\n\n static override flags = {\n 'auto-updates': Flags.boolean({\n allowNo: true,\n description: 'Enable/disable auto updates of studio versions',\n }),\n minify: Flags.boolean({\n allowNo: true,\n default: true,\n description: 'Enable/disable minifying of built bundles',\n }),\n 'source-maps': Flags.boolean({\n allowNo: true,\n default: false,\n description: 'Enable source maps for built bundles (increases size of bundle)',\n }),\n stats: Flags.boolean({\n default: false,\n description: 'Show stats about the built bundles',\n }),\n yes: Flags.boolean({\n char: 'y',\n default: false,\n description:\n 'Unattended mode, answers \"yes\" to any \"yes/no\" prompt and otherwise uses defaults',\n }),\n }\n\n public async run(): Promise<void> {\n const cliConfig = await this.getCliConfig()\n\n const {flags} = await this.parse(BuildCommand)\n\n const isApp = determineIsApp(cliConfig)\n\n const workDir = (await this.getProjectRoot()).directory\n\n const output = this.output\n\n const autoUpdatesEnabled = shouldAutoUpdate({cliConfig, flags, output})\n\n const buildFunc = isApp ? buildApp : buildStudio\n await buildFunc({\n autoUpdatesEnabled,\n cliConfig,\n flags,\n outDir: this.args.outputDir,\n output,\n workDir,\n })\n }\n}\n"],"names":["Args","Flags","SanityCommand","buildApp","buildStudio","shouldAutoUpdate","determineIsApp","BuildCommand","args","outputDir","directory","description","examples","flags","boolean","allowNo","minify","default","stats","yes","char","run","cliConfig","getCliConfig","parse","isApp","workDir","getProjectRoot","output","autoUpdatesEnabled","buildFunc","outDir"],"mappings":"AAAA,SAAQA,IAAI,EAAEC,KAAK,QAAO,cAAa;AACvC,SAAQC,aAAa,QAAO,mBAAkB;AAE9C,SAAQC,QAAQ,QAAO,+BAA8B;AACrD,SAAQC,WAAW,QAAO,kCAAiC;AAC3D,SAAQC,gBAAgB,QAAO,uCAAsC;AACrE,SAAQC,cAAc,QAAO,4BAA2B;AAExD,OAAO,MAAMC,qBAAqBL;IAChC,OAAgBM,OAAO;QACrBC,WAAWT,KAAKU,SAAS,CAAC;YAACC,aAAa;QAAkB;IAC5D,EAAC;IAED,OAAgBA,cAAc,2CAA0C;IAExE,OAAgBC,WAAW;QACzB;QACA;KACD,CAAA;IAED,OAAgBC,QAAQ;QACtB,gBAAgBZ,MAAMa,OAAO,CAAC;YAC5BC,SAAS;YACTJ,aAAa;QACf;QACAK,QAAQf,MAAMa,OAAO,CAAC;YACpBC,SAAS;YACTE,SAAS;YACTN,aAAa;QACf;QACA,eAAeV,MAAMa,OAAO,CAAC;YAC3BC,SAAS;YACTE,SAAS;YACTN,aAAa;QACf;QACAO,OAAOjB,MAAMa,OAAO,CAAC;YACnBG,SAAS;YACTN,aAAa;QACf;QACAQ,KAAKlB,MAAMa,OAAO,CAAC;YACjBM,MAAM;YACNH,SAAS;YACTN,aACE;QACJ;IACF,EAAC;IAED,MAAaU,MAAqB;QAChC,MAAMC,YAAY,MAAM,IAAI,CAACC,YAAY;QAEzC,MAAM,EAACV,KAAK,EAAC,GAAG,MAAM,IAAI,CAACW,KAAK,CAACjB;QAEjC,MAAMkB,QAAQnB,eAAegB;QAE7B,MAAMI,UAAU,AAAC,CAAA,MAAM,IAAI,CAACC,cAAc,EAAC,EAAGjB,SAAS;QAEvD,MAAMkB,SAAS,IAAI,CAACA,MAAM;QAE1B,MAAMC,qBAAqBxB,iBAAiB;YAACiB;YAAWT;YAAOe;QAAM;QAErE,MAAME,YAAYL,QAAQtB,WAAWC;QACrC,MAAM0B,UAAU;YACdD;YACAP;YACAT;YACAkB,QAAQ,IAAI,CAACvB,IAAI,CAACC,SAAS;YAC3BmB;YACAF;QACF;IACF;AACF"}
@@ -115,9 +115,9 @@ export class Add extends SanityCommand {
115
115
  'red',
116
116
  'underline'
117
117
  ], 'HIGHLY')} recommend NOT allowing credentials
118
- on origins containing wildcards. If you are logged in to a studio, people will
119
- be able to send requests ${styleText('underline', 'on your behalf')} to read and modify
120
- data, from any matching origin. Please tread carefully!
118
+ on origins containing wildcards. If you are logged in to a Sanity studio or an app built with
119
+ the Sanity App SDK, people will be able to send requests ${styleText('underline', 'on your behalf')}
120
+ to read and modify data, from any matching origin. Please tread carefully!
121
121
  `);
122
122
  } else {
123
123
  this.log(oneline`
@@ -125,8 +125,8 @@ export class Add extends SanityCommand {
125
125
  Should this origin be allowed to send requests using authentication tokens or
126
126
  session cookies? Be aware that any script on this origin will be able to send
127
127
  requests ${styleText('underline', 'on your behalf')} to read and modify data if you
128
- are logged in to a Sanity studio. If this origin hosts a studio, you will need
129
- this, otherwise you should probably answer "No" (n).
128
+ are logged in to a Sanity studio or app. If this origin hosts a studio or an app built with
129
+ the Sanity App SDK, you will need this, otherwise you should probably answer "No" (n).
130
130
  `);
131
131
  }
132
132
  this.log('');