@sanity/cli-build 0.1.0 → 0.2.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.
- package/LICENSE +21 -0
- package/dist/_exports/_internal/build.d.ts +2418 -0
- package/dist/_exports/_internal/build.js +10 -0
- package/dist/_exports/_internal/build.js.map +1 -0
- package/dist/_exports/_internal/extract.d.ts +120 -0
- package/dist/_exports/_internal/extract.js +9 -0
- package/dist/_exports/_internal/extract.js.map +1 -0
- package/dist/actions/build/buildDebug.js +4 -0
- package/dist/actions/build/buildDebug.js.map +1 -0
- package/dist/actions/build/buildVendorDependencies.js +149 -0
- package/dist/actions/build/buildVendorDependencies.js.map +1 -0
- package/dist/actions/build/checkStudioDependencyVersions.js +155 -0
- package/dist/actions/build/checkStudioDependencyVersions.js.map +1 -0
- package/dist/actions/build/createExternalFromImportMap.js +11 -0
- package/dist/actions/build/createExternalFromImportMap.js.map +1 -0
- package/dist/actions/build/decorateIndexWithAutoGeneratedWarning.js +13 -0
- package/dist/actions/build/decorateIndexWithAutoGeneratedWarning.js.map +1 -0
- package/dist/actions/build/decorateIndexWithBridgeScript.js +17 -0
- package/dist/actions/build/decorateIndexWithBridgeScript.js.map +1 -0
- package/dist/actions/build/decorateIndexWithStagingScript.js +16 -0
- package/dist/actions/build/decorateIndexWithStagingScript.js.map +1 -0
- package/dist/actions/build/getEntryModule.js +46 -0
- package/dist/actions/build/getEntryModule.js.map +1 -0
- package/dist/actions/build/getPossibleDocumentComponentLocations.js +11 -0
- package/dist/actions/build/getPossibleDocumentComponentLocations.js.map +1 -0
- package/dist/actions/build/getViteConfig.js +204 -0
- package/dist/actions/build/getViteConfig.js.map +1 -0
- package/dist/actions/build/normalizeBasePath.js +9 -0
- package/dist/actions/build/normalizeBasePath.js.map +1 -0
- package/dist/actions/build/renderDocument.js +50 -0
- package/dist/actions/build/renderDocument.js.map +1 -0
- package/dist/actions/build/renderDocument.worker.js +9 -0
- package/dist/actions/build/renderDocument.worker.js.map +1 -0
- package/dist/actions/build/renderDocumentWorker/addTimestampImportMapScriptToHtml.js +79 -0
- package/dist/actions/build/renderDocumentWorker/addTimestampImportMapScriptToHtml.js.map +1 -0
- package/dist/actions/build/renderDocumentWorker/components/BasicDocument.js +61 -0
- package/dist/actions/build/renderDocumentWorker/components/BasicDocument.js.map +1 -0
- package/dist/actions/build/renderDocumentWorker/components/DefaultDocument.js +165 -0
- package/dist/actions/build/renderDocumentWorker/components/DefaultDocument.js.map +1 -0
- package/dist/actions/build/renderDocumentWorker/components/Favicons.js +28 -0
- package/dist/actions/build/renderDocumentWorker/components/Favicons.js.map +1 -0
- package/dist/actions/build/renderDocumentWorker/components/GlobalErrorHandler.js +178 -0
- package/dist/actions/build/renderDocumentWorker/components/GlobalErrorHandler.js.map +1 -0
- package/dist/actions/build/renderDocumentWorker/components/NoJavascript.js +51 -0
- package/dist/actions/build/renderDocumentWorker/components/NoJavascript.js.map +1 -0
- package/dist/actions/build/renderDocumentWorker/getDocumentComponent.js +41 -0
- package/dist/actions/build/renderDocumentWorker/getDocumentComponent.js.map +1 -0
- package/dist/actions/build/renderDocumentWorker/getDocumentHtml.js +55 -0
- package/dist/actions/build/renderDocumentWorker/getDocumentHtml.js.map +1 -0
- package/dist/actions/build/renderDocumentWorker/renderDocumentWorker.js +31 -0
- package/dist/actions/build/renderDocumentWorker/renderDocumentWorker.js.map +1 -0
- package/dist/actions/build/renderDocumentWorker/tryLoadDocumentComponent.js +30 -0
- package/dist/actions/build/renderDocumentWorker/tryLoadDocumentComponent.js.map +1 -0
- package/dist/actions/build/renderDocumentWorker/types.js +5 -0
- package/dist/actions/build/renderDocumentWorker/types.js.map +1 -0
- package/dist/actions/build/vite/plugin-sanity-build-entries.js +67 -0
- package/dist/actions/build/vite/plugin-sanity-build-entries.js.map +1 -0
- package/dist/actions/build/vite/plugin-sanity-favicons.js +72 -0
- package/dist/actions/build/vite/plugin-sanity-favicons.js.map +1 -0
- package/dist/actions/build/vite/plugin-sanity-runtime-rewrite.js +18 -0
- package/dist/actions/build/vite/plugin-sanity-runtime-rewrite.js.map +1 -0
- package/dist/actions/build/writeSanityRuntime.js +66 -0
- package/dist/actions/build/writeSanityRuntime.js.map +1 -0
- package/dist/actions/schema/extractSanitySchema.worker.js +32 -0
- package/dist/actions/schema/extractSanitySchema.worker.js.map +1 -0
- package/dist/actions/schema/formatSchemaValidation.js +78 -0
- package/dist/actions/schema/formatSchemaValidation.js.map +1 -0
- package/dist/actions/schema/getExtractOptions.js +23 -0
- package/dist/actions/schema/getExtractOptions.js.map +1 -0
- package/dist/actions/schema/matchSchemaPattern.js +21 -0
- package/dist/actions/schema/matchSchemaPattern.js.map +1 -0
- package/dist/actions/schema/runSchemaExtraction.js +39 -0
- package/dist/actions/schema/runSchemaExtraction.js.map +1 -0
- package/dist/actions/schema/types.js +9 -0
- package/dist/actions/schema/types.js.map +1 -0
- package/dist/actions/schema/utils/SchemaExtractionError.js +10 -0
- package/dist/actions/schema/utils/SchemaExtractionError.js.map +1 -0
- package/dist/actions/schema/utils/extractValidationFromSchemaError.js +12 -0
- package/dist/actions/schema/utils/extractValidationFromSchemaError.js.map +1 -0
- package/dist/actions/schema/vite/plugin-schema-extraction.js +201 -0
- package/dist/actions/schema/vite/plugin-schema-extraction.js.map +1 -0
- package/dist/constants.js +8 -0
- package/dist/constants.js.map +1 -0
- package/dist/telemetry/build.telemetry.js +13 -0
- package/dist/telemetry/build.telemetry.js.map +1 -0
- package/dist/telemetry/extractSchema.telemetry.js +18 -0
- package/dist/telemetry/extractSchema.telemetry.js.map +1 -0
- package/package.json +58 -29
- package/dist/_exports/_internal.d.ts +0 -45
- package/dist/_exports/_internal.js +0 -5
- package/dist/_exports/_internal.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/actions/build/renderDocumentWorker/tryLoadDocumentComponent.ts"],"sourcesContent":["import fs from 'node:fs'\n\nimport {doImport} from '@sanity/cli-core'\n\nimport {buildDebug} from '../buildDebug.js'\nimport {getPossibleDocumentComponentLocations} from '../getPossibleDocumentComponentLocations.js'\n\n/**\n * @internal\n */\nexport async function tryLoadDocumentComponent(studioRootPath: string) {\n const locations = getPossibleDocumentComponentLocations(studioRootPath)\n\n for (const componentPath of locations) {\n buildDebug('Trying to load document component from %s', componentPath)\n try {\n const component = await doImport(componentPath)\n\n return {\n component,\n modified: Math.floor(fs.statSync(componentPath)?.mtimeMs),\n path: componentPath,\n }\n } catch (err) {\n // Allow \"not found\" errors\n if (err.code !== 'ERR_MODULE_NOT_FOUND') {\n buildDebug('Failed to load document component: %s', err.message)\n throw err\n }\n\n buildDebug('Document component not found at %s', componentPath)\n }\n }\n\n return null\n}\n"],"names":["fs","doImport","buildDebug","getPossibleDocumentComponentLocations","tryLoadDocumentComponent","studioRootPath","locations","componentPath","component","modified","Math","floor","statSync","mtimeMs","path","err","code","message"],"mappings":"AAAA,OAAOA,QAAQ,UAAS;AAExB,SAAQC,QAAQ,QAAO,mBAAkB;AAEzC,SAAQC,UAAU,QAAO,mBAAkB;AAC3C,SAAQC,qCAAqC,QAAO,8CAA6C;AAEjG;;CAEC,GACD,OAAO,eAAeC,yBAAyBC,cAAsB;IACnE,MAAMC,YAAYH,sCAAsCE;IAExD,KAAK,MAAME,iBAAiBD,UAAW;QACrCJ,WAAW,6CAA6CK;QACxD,IAAI;YACF,MAAMC,YAAY,MAAMP,SAASM;YAEjC,OAAO;gBACLC;gBACAC,UAAUC,KAAKC,KAAK,CAACX,GAAGY,QAAQ,CAACL,gBAAgBM;gBACjDC,MAAMP;YACR;QACF,EAAE,OAAOQ,KAAK;YACZ,2BAA2B;YAC3B,IAAIA,IAAIC,IAAI,KAAK,wBAAwB;gBACvCd,WAAW,yCAAyCa,IAAIE,OAAO;gBAC/D,MAAMF;YACR;YAEAb,WAAW,sCAAsCK;QACnD;IACF;IAEA,OAAO;AACT"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/actions/build/renderDocumentWorker/types.ts"],"sourcesContent":["/**\n * @internal\n */\nexport interface DocumentProps {\n basePath: string\n\n css?: string[]\n entryPath?: string\n title?: string\n}\n"],"names":[],"mappings":"AAAA;;CAEC,GACD,WAMC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { decorateIndexWithBridgeScript } from '../decorateIndexWithBridgeScript.js';
|
|
2
|
+
import { decorateIndexWithStagingScript } from '../decorateIndexWithStagingScript.js';
|
|
3
|
+
import { renderDocument } from '../renderDocument.js';
|
|
4
|
+
const entryChunkId = '.sanity/runtime/app.js';
|
|
5
|
+
export function sanityBuildEntries(options) {
|
|
6
|
+
const { autoUpdatesCssUrls, basePath, cwd, importMap, isApp } = options;
|
|
7
|
+
return {
|
|
8
|
+
apply: 'build',
|
|
9
|
+
name: 'sanity/server/build-entries',
|
|
10
|
+
buildStart () {
|
|
11
|
+
this.emitFile({
|
|
12
|
+
id: entryChunkId,
|
|
13
|
+
name: 'sanity',
|
|
14
|
+
type: 'chunk'
|
|
15
|
+
});
|
|
16
|
+
},
|
|
17
|
+
async generateBundle (_options, outputBundle) {
|
|
18
|
+
const bundle = outputBundle;
|
|
19
|
+
const entryFile = Object.values(bundle).find((file)=>file.type === 'chunk' && file.name === 'sanity' && file.facadeModuleId?.endsWith(entryChunkId));
|
|
20
|
+
if (!entryFile) {
|
|
21
|
+
throw new Error(`Failed to find entry file in bundle (${entryChunkId})`);
|
|
22
|
+
}
|
|
23
|
+
if (entryFile.type !== 'chunk') {
|
|
24
|
+
throw new Error('Entry file is not a chunk');
|
|
25
|
+
}
|
|
26
|
+
const entryFileName = entryFile.fileName;
|
|
27
|
+
const entryPath = [
|
|
28
|
+
basePath.replace(/\/+$/, ''),
|
|
29
|
+
entryFileName
|
|
30
|
+
].join('/');
|
|
31
|
+
let css = [];
|
|
32
|
+
if (entryFile.viteMetadata?.importedCss) {
|
|
33
|
+
// Check all the top-level imports of the entryPoint to see if they have
|
|
34
|
+
// static CSS assets that need loading
|
|
35
|
+
css = [
|
|
36
|
+
...entryFile.viteMetadata.importedCss
|
|
37
|
+
];
|
|
38
|
+
for (const key of entryFile.imports){
|
|
39
|
+
// Traverse all CSS assets that isn't loaded by the runtime and
|
|
40
|
+
// need <link> tags in the HTML template
|
|
41
|
+
const entry = bundle[key];
|
|
42
|
+
const importedCss = entry && entry.type === 'chunk' ? entry.viteMetadata.importedCss : undefined;
|
|
43
|
+
if (importedCss) {
|
|
44
|
+
css.push(...importedCss);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
this.emitFile({
|
|
49
|
+
fileName: 'index.html',
|
|
50
|
+
source: decorateIndexWithStagingScript(decorateIndexWithBridgeScript(await renderDocument({
|
|
51
|
+
autoUpdatesCssUrls,
|
|
52
|
+
importMap,
|
|
53
|
+
isApp,
|
|
54
|
+
props: {
|
|
55
|
+
basePath,
|
|
56
|
+
css,
|
|
57
|
+
entryPath
|
|
58
|
+
},
|
|
59
|
+
studioRootPath: cwd
|
|
60
|
+
}))),
|
|
61
|
+
type: 'asset'
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
//# sourceMappingURL=plugin-sanity-build-entries.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/actions/build/vite/plugin-sanity-build-entries.ts"],"sourcesContent":["import {type ChunkMetadata, type Plugin} from 'vite'\n\nimport {decorateIndexWithBridgeScript} from '../decorateIndexWithBridgeScript.js'\nimport {decorateIndexWithStagingScript} from '../decorateIndexWithStagingScript.js'\nimport {renderDocument} from '../renderDocument.js'\n\ninterface ViteOutputBundle {\n [fileName: string]: ViteRenderedAsset | ViteRenderedChunk\n}\n\ninterface ViteRenderedAsset {\n type: 'asset'\n}\n\ninterface ViteRenderedChunk {\n code: string\n facadeModuleId: string | null\n fileName: string\n imports: string[]\n isEntry: boolean\n name: string\n type: 'chunk'\n viteMetadata: ChunkMetadata\n}\n\nconst entryChunkId = '.sanity/runtime/app.js'\n\nexport function sanityBuildEntries(options: {\n autoUpdatesCssUrls?: string[]\n basePath: string\n cwd: string\n importMap?: {imports?: Record<string, string>}\n isApp?: boolean\n}): Plugin {\n const {autoUpdatesCssUrls, basePath, cwd, importMap, isApp} = options\n\n return {\n apply: 'build',\n name: 'sanity/server/build-entries',\n\n buildStart() {\n this.emitFile({\n id: entryChunkId,\n name: 'sanity',\n type: 'chunk',\n })\n },\n\n async generateBundle(_options, outputBundle) {\n const bundle = outputBundle as unknown as ViteOutputBundle\n const entryFile = Object.values(bundle).find(\n (file) =>\n file.type === 'chunk' &&\n file.name === 'sanity' &&\n file.facadeModuleId?.endsWith(entryChunkId),\n )\n\n if (!entryFile) {\n throw new Error(`Failed to find entry file in bundle (${entryChunkId})`)\n }\n\n if (entryFile.type !== 'chunk') {\n throw new Error('Entry file is not a chunk')\n }\n\n const entryFileName = entryFile.fileName\n const entryPath = [basePath.replace(/\\/+$/, ''), entryFileName].join('/')\n\n let css: string[] = []\n if (entryFile.viteMetadata?.importedCss) {\n // Check all the top-level imports of the entryPoint to see if they have\n // static CSS assets that need loading\n css = [...entryFile.viteMetadata.importedCss]\n for (const key of entryFile.imports) {\n // Traverse all CSS assets that isn't loaded by the runtime and\n // need <link> tags in the HTML template\n const entry = bundle[key]\n const importedCss =\n entry && entry.type === 'chunk' ? entry.viteMetadata.importedCss : undefined\n\n if (importedCss) {\n css.push(...importedCss)\n }\n }\n }\n\n this.emitFile({\n fileName: 'index.html',\n source: decorateIndexWithStagingScript(\n decorateIndexWithBridgeScript(\n await renderDocument({\n autoUpdatesCssUrls,\n importMap,\n isApp,\n props: {\n basePath,\n css,\n entryPath,\n },\n studioRootPath: cwd,\n }),\n ),\n ),\n type: 'asset',\n })\n },\n }\n}\n"],"names":["decorateIndexWithBridgeScript","decorateIndexWithStagingScript","renderDocument","entryChunkId","sanityBuildEntries","options","autoUpdatesCssUrls","basePath","cwd","importMap","isApp","apply","name","buildStart","emitFile","id","type","generateBundle","_options","outputBundle","bundle","entryFile","Object","values","find","file","facadeModuleId","endsWith","Error","entryFileName","fileName","entryPath","replace","join","css","viteMetadata","importedCss","key","imports","entry","undefined","push","source","props","studioRootPath"],"mappings":"AAEA,SAAQA,6BAA6B,QAAO,sCAAqC;AACjF,SAAQC,8BAA8B,QAAO,uCAAsC;AACnF,SAAQC,cAAc,QAAO,uBAAsB;AAqBnD,MAAMC,eAAe;AAErB,OAAO,SAASC,mBAAmBC,OAMlC;IACC,MAAM,EAACC,kBAAkB,EAAEC,QAAQ,EAAEC,GAAG,EAAEC,SAAS,EAAEC,KAAK,EAAC,GAAGL;IAE9D,OAAO;QACLM,OAAO;QACPC,MAAM;QAENC;YACE,IAAI,CAACC,QAAQ,CAAC;gBACZC,IAAIZ;gBACJS,MAAM;gBACNI,MAAM;YACR;QACF;QAEA,MAAMC,gBAAeC,QAAQ,EAAEC,YAAY;YACzC,MAAMC,SAASD;YACf,MAAME,YAAYC,OAAOC,MAAM,CAACH,QAAQI,IAAI,CAC1C,CAACC,OACCA,KAAKT,IAAI,KAAK,WACdS,KAAKb,IAAI,KAAK,YACda,KAAKC,cAAc,EAAEC,SAASxB;YAGlC,IAAI,CAACkB,WAAW;gBACd,MAAM,IAAIO,MAAM,CAAC,qCAAqC,EAAEzB,aAAa,CAAC,CAAC;YACzE;YAEA,IAAIkB,UAAUL,IAAI,KAAK,SAAS;gBAC9B,MAAM,IAAIY,MAAM;YAClB;YAEA,MAAMC,gBAAgBR,UAAUS,QAAQ;YACxC,MAAMC,YAAY;gBAACxB,SAASyB,OAAO,CAAC,QAAQ;gBAAKH;aAAc,CAACI,IAAI,CAAC;YAErE,IAAIC,MAAgB,EAAE;YACtB,IAAIb,UAAUc,YAAY,EAAEC,aAAa;gBACvC,wEAAwE;gBACxE,sCAAsC;gBACtCF,MAAM;uBAAIb,UAAUc,YAAY,CAACC,WAAW;iBAAC;gBAC7C,KAAK,MAAMC,OAAOhB,UAAUiB,OAAO,CAAE;oBACnC,+DAA+D;oBAC/D,wCAAwC;oBACxC,MAAMC,QAAQnB,MAAM,CAACiB,IAAI;oBACzB,MAAMD,cACJG,SAASA,MAAMvB,IAAI,KAAK,UAAUuB,MAAMJ,YAAY,CAACC,WAAW,GAAGI;oBAErE,IAAIJ,aAAa;wBACfF,IAAIO,IAAI,IAAIL;oBACd;gBACF;YACF;YAEA,IAAI,CAACtB,QAAQ,CAAC;gBACZgB,UAAU;gBACVY,QAAQzC,+BACND,8BACE,MAAME,eAAe;oBACnBI;oBACAG;oBACAC;oBACAiC,OAAO;wBACLpC;wBACA2B;wBACAH;oBACF;oBACAa,gBAAgBpC;gBAClB;gBAGJQ,MAAM;YACR;QACF;IACF;AACF"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { generateWebManifest } from '../generateWebManifest.js';
|
|
4
|
+
const mimeTypes = {
|
|
5
|
+
'.ico': 'image/x-icon',
|
|
6
|
+
'.png': 'image/png',
|
|
7
|
+
'.svg': 'image/svg+xml'
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Fallback favicons plugin for Sanity.
|
|
11
|
+
*
|
|
12
|
+
* If a favicon is not found in the static folder, this plugin will serve the default
|
|
13
|
+
* Sanity favicons from the npm bundle. If a custom `favicon.ico` is found in the static
|
|
14
|
+
* folder, it will also be served for a root `/favicon.ico` request.
|
|
15
|
+
*
|
|
16
|
+
* @param options - Options for the plugin
|
|
17
|
+
* @returns A Vite plugin
|
|
18
|
+
* @internal
|
|
19
|
+
*/ export function sanityFaviconsPlugin({ customFaviconsPath, defaultFaviconsPath, staticUrlPath }) {
|
|
20
|
+
const cache = {};
|
|
21
|
+
async function getFavicons() {
|
|
22
|
+
if (cache.favicons) {
|
|
23
|
+
return cache.favicons;
|
|
24
|
+
}
|
|
25
|
+
cache.favicons = await fs.readdir(defaultFaviconsPath);
|
|
26
|
+
return cache.favicons;
|
|
27
|
+
}
|
|
28
|
+
async function hasCustomFavicon(fileName) {
|
|
29
|
+
try {
|
|
30
|
+
await fs.access(path.join(customFaviconsPath, fileName));
|
|
31
|
+
return true;
|
|
32
|
+
} catch {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
apply: 'serve',
|
|
38
|
+
configureServer (viteDevServer) {
|
|
39
|
+
const webManifest = JSON.stringify(generateWebManifest(staticUrlPath), null, 2);
|
|
40
|
+
const webManifestPath = `${staticUrlPath}/manifest.webmanifest`;
|
|
41
|
+
viteDevServer.middlewares.use(async (req, res, next)=>{
|
|
42
|
+
if (req.url?.endsWith(webManifestPath)) {
|
|
43
|
+
res.writeHead(200, 'OK', {
|
|
44
|
+
'content-type': 'application/manifest+json'
|
|
45
|
+
});
|
|
46
|
+
res.write(webManifest);
|
|
47
|
+
res.end();
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const parsedUrl = typeof req === 'object' && req !== null && '_parsedUrl' in req && req._parsedUrl instanceof URL ? req._parsedUrl : new URL(req.url || '/', 'http://localhost:3333');
|
|
51
|
+
const pathName = parsedUrl.pathname || '';
|
|
52
|
+
const fileName = path.basename(pathName || '');
|
|
53
|
+
const icons = await getFavicons();
|
|
54
|
+
const isIconRequest = pathName.startsWith('/favicon.ico') || icons.includes(fileName) && pathName.includes(staticUrlPath);
|
|
55
|
+
if (!isIconRequest) {
|
|
56
|
+
next();
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const faviconPath = await hasCustomFavicon(fileName) ? path.join(customFaviconsPath, fileName) : path.join(defaultFaviconsPath, fileName);
|
|
60
|
+
const mimeType = mimeTypes[path.extname(fileName)] || 'application/octet-stream';
|
|
61
|
+
res.writeHead(200, 'OK', {
|
|
62
|
+
'content-type': mimeType
|
|
63
|
+
});
|
|
64
|
+
res.write(await fs.readFile(faviconPath));
|
|
65
|
+
res.end();
|
|
66
|
+
});
|
|
67
|
+
},
|
|
68
|
+
name: 'sanity/server/sanity-favicons'
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
//# sourceMappingURL=plugin-sanity-favicons.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/actions/build/vite/plugin-sanity-favicons.ts"],"sourcesContent":["import fs from 'node:fs/promises'\nimport path from 'node:path'\n\nimport {type Plugin} from 'vite'\n\nimport {generateWebManifest} from '../generateWebManifest.js'\n\nconst mimeTypes: Record<string, string | undefined> = {\n '.ico': 'image/x-icon',\n '.png': 'image/png',\n '.svg': 'image/svg+xml',\n}\n\n/**\n * Fallback favicons plugin for Sanity.\n *\n * If a favicon is not found in the static folder, this plugin will serve the default\n * Sanity favicons from the npm bundle. If a custom `favicon.ico` is found in the static\n * folder, it will also be served for a root `/favicon.ico` request.\n *\n * @param options - Options for the plugin\n * @returns A Vite plugin\n * @internal\n */\nexport function sanityFaviconsPlugin({\n customFaviconsPath,\n defaultFaviconsPath,\n staticUrlPath,\n}: {\n customFaviconsPath: string\n defaultFaviconsPath: string\n staticUrlPath: string\n}): Plugin {\n const cache: {favicons?: string[]} = {}\n\n async function getFavicons(): Promise<string[]> {\n if (cache.favicons) {\n return cache.favicons\n }\n\n cache.favicons = await fs.readdir(defaultFaviconsPath)\n return cache.favicons\n }\n\n async function hasCustomFavicon(fileName: string): Promise<boolean> {\n try {\n await fs.access(path.join(customFaviconsPath, fileName))\n return true\n } catch {\n return false\n }\n }\n\n return {\n apply: 'serve',\n configureServer(viteDevServer) {\n const webManifest = JSON.stringify(generateWebManifest(staticUrlPath), null, 2)\n const webManifestPath = `${staticUrlPath}/manifest.webmanifest`\n\n viteDevServer.middlewares.use(async (req, res, next) => {\n if (req.url?.endsWith(webManifestPath)) {\n res.writeHead(200, 'OK', {'content-type': 'application/manifest+json'})\n res.write(webManifest)\n res.end()\n return\n }\n\n const parsedUrl =\n typeof req === 'object' &&\n req !== null &&\n '_parsedUrl' in req &&\n req._parsedUrl instanceof URL\n ? req._parsedUrl\n : new URL(req.url || '/', 'http://localhost:3333')\n\n const pathName = parsedUrl.pathname || ''\n const fileName = path.basename(pathName || '')\n const icons = await getFavicons()\n const isIconRequest =\n pathName.startsWith('/favicon.ico') ||\n (icons.includes(fileName) && pathName.includes(staticUrlPath))\n\n if (!isIconRequest) {\n next()\n return\n }\n\n const faviconPath = (await hasCustomFavicon(fileName))\n ? path.join(customFaviconsPath, fileName)\n : path.join(defaultFaviconsPath, fileName)\n\n const mimeType = mimeTypes[path.extname(fileName)] || 'application/octet-stream'\n res.writeHead(200, 'OK', {'content-type': mimeType})\n res.write(await fs.readFile(faviconPath))\n res.end()\n })\n },\n name: 'sanity/server/sanity-favicons',\n }\n}\n"],"names":["fs","path","generateWebManifest","mimeTypes","sanityFaviconsPlugin","customFaviconsPath","defaultFaviconsPath","staticUrlPath","cache","getFavicons","favicons","readdir","hasCustomFavicon","fileName","access","join","apply","configureServer","viteDevServer","webManifest","JSON","stringify","webManifestPath","middlewares","use","req","res","next","url","endsWith","writeHead","write","end","parsedUrl","_parsedUrl","URL","pathName","pathname","basename","icons","isIconRequest","startsWith","includes","faviconPath","mimeType","extname","readFile","name"],"mappings":"AAAA,OAAOA,QAAQ,mBAAkB;AACjC,OAAOC,UAAU,YAAW;AAI5B,SAAQC,mBAAmB,QAAO,4BAA2B;AAE7D,MAAMC,YAAgD;IACpD,QAAQ;IACR,QAAQ;IACR,QAAQ;AACV;AAEA;;;;;;;;;;CAUC,GACD,OAAO,SAASC,qBAAqB,EACnCC,kBAAkB,EAClBC,mBAAmB,EACnBC,aAAa,EAKd;IACC,MAAMC,QAA+B,CAAC;IAEtC,eAAeC;QACb,IAAID,MAAME,QAAQ,EAAE;YAClB,OAAOF,MAAME,QAAQ;QACvB;QAEAF,MAAME,QAAQ,GAAG,MAAMV,GAAGW,OAAO,CAACL;QAClC,OAAOE,MAAME,QAAQ;IACvB;IAEA,eAAeE,iBAAiBC,QAAgB;QAC9C,IAAI;YACF,MAAMb,GAAGc,MAAM,CAACb,KAAKc,IAAI,CAACV,oBAAoBQ;YAC9C,OAAO;QACT,EAAE,OAAM;YACN,OAAO;QACT;IACF;IAEA,OAAO;QACLG,OAAO;QACPC,iBAAgBC,aAAa;YAC3B,MAAMC,cAAcC,KAAKC,SAAS,CAACnB,oBAAoBK,gBAAgB,MAAM;YAC7E,MAAMe,kBAAkB,GAAGf,cAAc,qBAAqB,CAAC;YAE/DW,cAAcK,WAAW,CAACC,GAAG,CAAC,OAAOC,KAAKC,KAAKC;gBAC7C,IAAIF,IAAIG,GAAG,EAAEC,SAASP,kBAAkB;oBACtCI,IAAII,SAAS,CAAC,KAAK,MAAM;wBAAC,gBAAgB;oBAA2B;oBACrEJ,IAAIK,KAAK,CAACZ;oBACVO,IAAIM,GAAG;oBACP;gBACF;gBAEA,MAAMC,YACJ,OAAOR,QAAQ,YACfA,QAAQ,QACR,gBAAgBA,OAChBA,IAAIS,UAAU,YAAYC,MACtBV,IAAIS,UAAU,GACd,IAAIC,IAAIV,IAAIG,GAAG,IAAI,KAAK;gBAE9B,MAAMQ,WAAWH,UAAUI,QAAQ,IAAI;gBACvC,MAAMxB,WAAWZ,KAAKqC,QAAQ,CAACF,YAAY;gBAC3C,MAAMG,QAAQ,MAAM9B;gBACpB,MAAM+B,gBACJJ,SAASK,UAAU,CAAC,mBACnBF,MAAMG,QAAQ,CAAC7B,aAAauB,SAASM,QAAQ,CAACnC;gBAEjD,IAAI,CAACiC,eAAe;oBAClBb;oBACA;gBACF;gBAEA,MAAMgB,cAAc,AAAC,MAAM/B,iBAAiBC,YACxCZ,KAAKc,IAAI,CAACV,oBAAoBQ,YAC9BZ,KAAKc,IAAI,CAACT,qBAAqBO;gBAEnC,MAAM+B,WAAWzC,SAAS,CAACF,KAAK4C,OAAO,CAAChC,UAAU,IAAI;gBACtDa,IAAII,SAAS,CAAC,KAAK,MAAM;oBAAC,gBAAgBc;gBAAQ;gBAClDlB,IAAIK,KAAK,CAAC,MAAM/B,GAAG8C,QAAQ,CAACH;gBAC5BjB,IAAIM,GAAG;YACT;QACF;QACAe,MAAM;IACR;AACF"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export function sanityRuntimeRewritePlugin() {
|
|
2
|
+
return {
|
|
3
|
+
apply: 'serve',
|
|
4
|
+
configureServer (viteDevServer) {
|
|
5
|
+
return ()=>{
|
|
6
|
+
viteDevServer.middlewares.use((req, res, next)=>{
|
|
7
|
+
if (req.url === '/index.html') {
|
|
8
|
+
req.url = '/.sanity/runtime/index.html';
|
|
9
|
+
}
|
|
10
|
+
next();
|
|
11
|
+
});
|
|
12
|
+
};
|
|
13
|
+
},
|
|
14
|
+
name: 'sanity/server/sanity-runtime-rewrite'
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
//# sourceMappingURL=plugin-sanity-runtime-rewrite.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/actions/build/vite/plugin-sanity-runtime-rewrite.ts"],"sourcesContent":["import {type Plugin} from 'vite'\n\nexport function sanityRuntimeRewritePlugin(): Plugin {\n return {\n apply: 'serve',\n configureServer(viteDevServer) {\n return () => {\n viteDevServer.middlewares.use((req, res, next) => {\n if (req.url === '/index.html') {\n req.url = '/.sanity/runtime/index.html'\n }\n\n next()\n })\n }\n },\n name: 'sanity/server/sanity-runtime-rewrite',\n }\n}\n"],"names":["sanityRuntimeRewritePlugin","apply","configureServer","viteDevServer","middlewares","use","req","res","next","url","name"],"mappings":"AAEA,OAAO,SAASA;IACd,OAAO;QACLC,OAAO;QACPC,iBAAgBC,aAAa;YAC3B,OAAO;gBACLA,cAAcC,WAAW,CAACC,GAAG,CAAC,CAACC,KAAKC,KAAKC;oBACvC,IAAIF,IAAIG,GAAG,KAAK,eAAe;wBAC7BH,IAAIG,GAAG,GAAG;oBACZ;oBAEAD;gBACF;YACF;QACF;QACAE,MAAM;IACR;AACF"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { tryFindStudioConfigPath } from '@sanity/cli-core';
|
|
4
|
+
import { watch as chokidarWatch } from 'chokidar';
|
|
5
|
+
import { buildDebug } from './buildDebug.js';
|
|
6
|
+
import { decorateIndexWithAutoGeneratedWarning } from './decorateIndexWithAutoGeneratedWarning.js';
|
|
7
|
+
import { decorateIndexWithBridgeScript } from './decorateIndexWithBridgeScript.js';
|
|
8
|
+
import { decorateIndexWithStagingScript } from './decorateIndexWithStagingScript.js';
|
|
9
|
+
import { getEntryModule } from './getEntryModule.js';
|
|
10
|
+
import { getPossibleDocumentComponentLocations } from './getPossibleDocumentComponentLocations.js';
|
|
11
|
+
import { renderDocument } from './renderDocument.js';
|
|
12
|
+
/**
|
|
13
|
+
* Generates the `.sanity/runtime` directory, and optionally watches for custom
|
|
14
|
+
* document files, rebuilding when they change
|
|
15
|
+
*
|
|
16
|
+
* @param options - Current working directory (Sanity root dir), and whether or not to watch
|
|
17
|
+
* @returns A watcher instance if watch is enabled, undefined otherwise
|
|
18
|
+
* @internal
|
|
19
|
+
*/ export async function writeSanityRuntime(options) {
|
|
20
|
+
const { appTitle, basePath, cwd, entry, isApp, reactStrictMode, watch } = options;
|
|
21
|
+
const runtimeDir = path.join(cwd, '.sanity', 'runtime');
|
|
22
|
+
buildDebug('Making runtime directory');
|
|
23
|
+
await fs.mkdir(runtimeDir, {
|
|
24
|
+
recursive: true
|
|
25
|
+
});
|
|
26
|
+
async function renderAndWriteDocument() {
|
|
27
|
+
buildDebug('Rendering document template');
|
|
28
|
+
const indexHtml = decorateIndexWithStagingScript(decorateIndexWithBridgeScript(decorateIndexWithAutoGeneratedWarning(await renderDocument({
|
|
29
|
+
isApp,
|
|
30
|
+
props: {
|
|
31
|
+
basePath: basePath || '/',
|
|
32
|
+
entryPath: `/${toForwardSlashes(path.relative(cwd, path.join(runtimeDir, 'app.js')))}`,
|
|
33
|
+
title: appTitle
|
|
34
|
+
},
|
|
35
|
+
studioRootPath: cwd
|
|
36
|
+
}))));
|
|
37
|
+
buildDebug('Writing index.html to runtime directory');
|
|
38
|
+
await fs.writeFile(path.join(runtimeDir, 'index.html'), indexHtml);
|
|
39
|
+
}
|
|
40
|
+
let watcher;
|
|
41
|
+
if (watch) {
|
|
42
|
+
watcher = chokidarWatch(getPossibleDocumentComponentLocations(cwd)).on('all', ()=>renderAndWriteDocument());
|
|
43
|
+
}
|
|
44
|
+
await renderAndWriteDocument();
|
|
45
|
+
buildDebug('Writing app.js to runtime directory');
|
|
46
|
+
let relativeConfigLocation = null;
|
|
47
|
+
if (!isApp) {
|
|
48
|
+
const studioConfigPath = await tryFindStudioConfigPath(cwd);
|
|
49
|
+
relativeConfigLocation = studioConfigPath ? toForwardSlashes(path.relative(runtimeDir, studioConfigPath)) : null;
|
|
50
|
+
}
|
|
51
|
+
const relativeEntry = toForwardSlashes(path.relative(runtimeDir, path.resolve(cwd, entry || './src/App')));
|
|
52
|
+
const appJsContent = getEntryModule({
|
|
53
|
+
basePath,
|
|
54
|
+
entry: relativeEntry,
|
|
55
|
+
isApp,
|
|
56
|
+
reactStrictMode,
|
|
57
|
+
relativeConfigLocation
|
|
58
|
+
});
|
|
59
|
+
await fs.writeFile(path.join(runtimeDir, 'app.js'), appJsContent);
|
|
60
|
+
return watcher;
|
|
61
|
+
}
|
|
62
|
+
function toForwardSlashes(filePath) {
|
|
63
|
+
return filePath.replaceAll('\\', '/');
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
//# sourceMappingURL=writeSanityRuntime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/build/writeSanityRuntime.ts"],"sourcesContent":["import fs from 'node:fs/promises'\nimport path from 'node:path'\n\nimport {tryFindStudioConfigPath} from '@sanity/cli-core'\nimport {watch as chokidarWatch, type FSWatcher} from 'chokidar'\n\nimport {buildDebug} from './buildDebug.js'\nimport {decorateIndexWithAutoGeneratedWarning} from './decorateIndexWithAutoGeneratedWarning.js'\nimport {decorateIndexWithBridgeScript} from './decorateIndexWithBridgeScript.js'\nimport {decorateIndexWithStagingScript} from './decorateIndexWithStagingScript.js'\nimport {getEntryModule} from './getEntryModule.js'\nimport {getPossibleDocumentComponentLocations} from './getPossibleDocumentComponentLocations.js'\nimport {renderDocument} from './renderDocument.js'\n\ninterface RuntimeOptions {\n cwd: string\n reactStrictMode: boolean\n watch: boolean\n\n appTitle?: string\n basePath?: string\n entry?: string\n isApp?: boolean\n}\n\n/**\n * Generates the `.sanity/runtime` directory, and optionally watches for custom\n * document files, rebuilding when they change\n *\n * @param options - Current working directory (Sanity root dir), and whether or not to watch\n * @returns A watcher instance if watch is enabled, undefined otherwise\n * @internal\n */\nexport async function writeSanityRuntime(options: RuntimeOptions): Promise<FSWatcher | undefined> {\n const {appTitle, basePath, cwd, entry, isApp, reactStrictMode, watch} = options\n const runtimeDir = path.join(cwd, '.sanity', 'runtime')\n\n buildDebug('Making runtime directory')\n await fs.mkdir(runtimeDir, {recursive: true})\n\n async function renderAndWriteDocument() {\n buildDebug('Rendering document template')\n const indexHtml = decorateIndexWithStagingScript(\n decorateIndexWithBridgeScript(\n decorateIndexWithAutoGeneratedWarning(\n await renderDocument({\n isApp,\n props: {\n basePath: basePath || '/',\n entryPath: `/${toForwardSlashes(path.relative(cwd, path.join(runtimeDir, 'app.js')))}`,\n title: appTitle,\n },\n studioRootPath: cwd,\n }),\n ),\n ),\n )\n\n buildDebug('Writing index.html to runtime directory')\n await fs.writeFile(path.join(runtimeDir, 'index.html'), indexHtml)\n }\n\n let watcher: FSWatcher | undefined\n\n if (watch) {\n watcher = chokidarWatch(getPossibleDocumentComponentLocations(cwd)).on('all', () =>\n renderAndWriteDocument(),\n )\n }\n\n await renderAndWriteDocument()\n\n buildDebug('Writing app.js to runtime directory')\n let relativeConfigLocation: string | null = null\n if (!isApp) {\n const studioConfigPath = await tryFindStudioConfigPath(cwd)\n relativeConfigLocation = studioConfigPath\n ? toForwardSlashes(path.relative(runtimeDir, studioConfigPath))\n : null\n }\n\n const relativeEntry = toForwardSlashes(\n path.relative(runtimeDir, path.resolve(cwd, entry || './src/App')),\n )\n const appJsContent = getEntryModule({\n basePath,\n entry: relativeEntry,\n isApp,\n reactStrictMode,\n relativeConfigLocation,\n })\n await fs.writeFile(path.join(runtimeDir, 'app.js'), appJsContent)\n\n return watcher\n}\n\nfunction toForwardSlashes(filePath: string): string {\n return filePath.replaceAll('\\\\', '/')\n}\n"],"names":["fs","path","tryFindStudioConfigPath","watch","chokidarWatch","buildDebug","decorateIndexWithAutoGeneratedWarning","decorateIndexWithBridgeScript","decorateIndexWithStagingScript","getEntryModule","getPossibleDocumentComponentLocations","renderDocument","writeSanityRuntime","options","appTitle","basePath","cwd","entry","isApp","reactStrictMode","runtimeDir","join","mkdir","recursive","renderAndWriteDocument","indexHtml","props","entryPath","toForwardSlashes","relative","title","studioRootPath","writeFile","watcher","on","relativeConfigLocation","studioConfigPath","relativeEntry","resolve","appJsContent","filePath","replaceAll"],"mappings":"AAAA,OAAOA,QAAQ,mBAAkB;AACjC,OAAOC,UAAU,YAAW;AAE5B,SAAQC,uBAAuB,QAAO,mBAAkB;AACxD,SAAQC,SAASC,aAAa,QAAuB,WAAU;AAE/D,SAAQC,UAAU,QAAO,kBAAiB;AAC1C,SAAQC,qCAAqC,QAAO,6CAA4C;AAChG,SAAQC,6BAA6B,QAAO,qCAAoC;AAChF,SAAQC,8BAA8B,QAAO,sCAAqC;AAClF,SAAQC,cAAc,QAAO,sBAAqB;AAClD,SAAQC,qCAAqC,QAAO,6CAA4C;AAChG,SAAQC,cAAc,QAAO,sBAAqB;AAalD;;;;;;;CAOC,GACD,OAAO,eAAeC,mBAAmBC,OAAuB;IAC9D,MAAM,EAACC,QAAQ,EAAEC,QAAQ,EAAEC,GAAG,EAAEC,KAAK,EAAEC,KAAK,EAAEC,eAAe,EAAEhB,KAAK,EAAC,GAAGU;IACxE,MAAMO,aAAanB,KAAKoB,IAAI,CAACL,KAAK,WAAW;IAE7CX,WAAW;IACX,MAAML,GAAGsB,KAAK,CAACF,YAAY;QAACG,WAAW;IAAI;IAE3C,eAAeC;QACbnB,WAAW;QACX,MAAMoB,YAAYjB,+BAChBD,8BACED,sCACE,MAAMK,eAAe;YACnBO;YACAQ,OAAO;gBACLX,UAAUA,YAAY;gBACtBY,WAAW,CAAC,CAAC,EAAEC,iBAAiB3B,KAAK4B,QAAQ,CAACb,KAAKf,KAAKoB,IAAI,CAACD,YAAY,aAAa;gBACtFU,OAAOhB;YACT;YACAiB,gBAAgBf;QAClB;QAKNX,WAAW;QACX,MAAML,GAAGgC,SAAS,CAAC/B,KAAKoB,IAAI,CAACD,YAAY,eAAeK;IAC1D;IAEA,IAAIQ;IAEJ,IAAI9B,OAAO;QACT8B,UAAU7B,cAAcM,sCAAsCM,MAAMkB,EAAE,CAAC,OAAO,IAC5EV;IAEJ;IAEA,MAAMA;IAENnB,WAAW;IACX,IAAI8B,yBAAwC;IAC5C,IAAI,CAACjB,OAAO;QACV,MAAMkB,mBAAmB,MAAMlC,wBAAwBc;QACvDmB,yBAAyBC,mBACrBR,iBAAiB3B,KAAK4B,QAAQ,CAACT,YAAYgB,qBAC3C;IACN;IAEA,MAAMC,gBAAgBT,iBACpB3B,KAAK4B,QAAQ,CAACT,YAAYnB,KAAKqC,OAAO,CAACtB,KAAKC,SAAS;IAEvD,MAAMsB,eAAe9B,eAAe;QAClCM;QACAE,OAAOoB;QACPnB;QACAC;QACAgB;IACF;IACA,MAAMnC,GAAGgC,SAAS,CAAC/B,KAAKoB,IAAI,CAACD,YAAY,WAAWmB;IAEpD,OAAON;AACT;AAEA,SAASL,iBAAiBY,QAAgB;IACxC,OAAOA,SAASC,UAAU,CAAC,MAAM;AACnC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { isMainThread, parentPort, workerData } from 'node:worker_threads';
|
|
2
|
+
import { getStudioWorkspaces, getWorkspace } from '@sanity/cli-core';
|
|
3
|
+
import { extractSchema } from '@sanity/schema/_internal';
|
|
4
|
+
import { extractSchemaWorkerData } from './types.js';
|
|
5
|
+
import { extractValidationFromSchemaError } from './utils/extractValidationFromSchemaError.js';
|
|
6
|
+
if (isMainThread || !parentPort) {
|
|
7
|
+
throw new Error('Should only be run in a worker!');
|
|
8
|
+
}
|
|
9
|
+
const { configPath, enforceRequiredFields, workDir, workspaceName } = extractSchemaWorkerData.parse(workerData);
|
|
10
|
+
try {
|
|
11
|
+
const workspaces = await getStudioWorkspaces(configPath);
|
|
12
|
+
if (workspaces.length === 0) {
|
|
13
|
+
throw new Error('Failed to resolve configuration');
|
|
14
|
+
}
|
|
15
|
+
const workspace = getWorkspace(workspaces, workspaceName);
|
|
16
|
+
const schema = extractSchema(workspace.schema, {
|
|
17
|
+
enforceRequiredFields
|
|
18
|
+
});
|
|
19
|
+
parentPort.postMessage({
|
|
20
|
+
schema,
|
|
21
|
+
type: 'success'
|
|
22
|
+
});
|
|
23
|
+
} catch (error) {
|
|
24
|
+
const validation = await extractValidationFromSchemaError(error, workDir);
|
|
25
|
+
parentPort.postMessage({
|
|
26
|
+
error: error instanceof Error ? error.message : String(error),
|
|
27
|
+
type: 'error',
|
|
28
|
+
validation
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
//# sourceMappingURL=extractSanitySchema.worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/schema/extractSanitySchema.worker.ts"],"sourcesContent":["import {isMainThread, parentPort, workerData} from 'node:worker_threads'\n\nimport {getStudioWorkspaces, getWorkspace} from '@sanity/cli-core'\nimport {extractSchema} from '@sanity/schema/_internal'\n\nimport {extractSchemaWorkerData} 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, enforceRequiredFields, workDir, workspaceName} =\n extractSchemaWorkerData.parse(workerData)\n\ntry {\n const workspaces = await getStudioWorkspaces(configPath)\n if (workspaces.length === 0) {\n throw new Error('Failed to resolve configuration')\n }\n\n const workspace = getWorkspace(workspaces, workspaceName)\n const schema = extractSchema(workspace.schema, {\n enforceRequiredFields,\n })\n\n parentPort.postMessage({\n schema,\n type: 'success',\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","getWorkspace","extractSchema","extractSchemaWorkerData","extractValidationFromSchemaError","Error","configPath","enforceRequiredFields","workDir","workspaceName","parse","workspaces","length","workspace","schema","postMessage","type","error","validation","message","String"],"mappings":"AAAA,SAAQA,YAAY,EAAEC,UAAU,EAAEC,UAAU,QAAO,sBAAqB;AAExE,SAAQC,mBAAmB,EAAEC,YAAY,QAAO,mBAAkB;AAClE,SAAQC,aAAa,QAAO,2BAA0B;AAEtD,SAAQC,uBAAuB,QAAO,aAAY;AAClD,SAAQC,gCAAgC,QAAO,8CAA6C;AAE5F,IAAIP,gBAAgB,CAACC,YAAY;IAC/B,MAAM,IAAIO,MAAM;AAClB;AAEA,MAAM,EAACC,UAAU,EAAEC,qBAAqB,EAAEC,OAAO,EAAEC,aAAa,EAAC,GAC/DN,wBAAwBO,KAAK,CAACX;AAEhC,IAAI;IACF,MAAMY,aAAa,MAAMX,oBAAoBM;IAC7C,IAAIK,WAAWC,MAAM,KAAK,GAAG;QAC3B,MAAM,IAAIP,MAAM;IAClB;IAEA,MAAMQ,YAAYZ,aAAaU,YAAYF;IAC3C,MAAMK,SAASZ,cAAcW,UAAUC,MAAM,EAAE;QAC7CP;IACF;IAEAT,WAAWiB,WAAW,CAAC;QACrBD;QACAE,MAAM;IACR;AACF,EAAE,OAAOC,OAAO;IACd,MAAMC,aAAa,MAAMd,iCAAiCa,OAAOT;IACjEV,WAAWiB,WAAW,CAAC;QACrBE,OAAOA,iBAAiBZ,QAAQY,MAAME,OAAO,GAAGC,OAAOH;QACvDD,MAAM;QACNE;IACF;AACF"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { isatty } from 'node:tty';
|
|
2
|
+
import { styleText } from 'node:util';
|
|
3
|
+
import { logSymbols } from '@sanity/cli-core/ux';
|
|
4
|
+
import { generateHelpUrl } from '@sanity/generate-help-url';
|
|
5
|
+
const isTty = isatty(1);
|
|
6
|
+
const headers = {
|
|
7
|
+
error: isTty ? styleText([
|
|
8
|
+
'bold',
|
|
9
|
+
'bgRed',
|
|
10
|
+
'black'
|
|
11
|
+
], ' ERROR ') : styleText('red', '[ERROR]'),
|
|
12
|
+
warning: isTty ? styleText([
|
|
13
|
+
'bold',
|
|
14
|
+
'bgYellow',
|
|
15
|
+
'black'
|
|
16
|
+
], ' WARN ') : styleText('yellow', '[WARN]')
|
|
17
|
+
};
|
|
18
|
+
const severityValues = {
|
|
19
|
+
error: 0,
|
|
20
|
+
warning: 1
|
|
21
|
+
};
|
|
22
|
+
function formatPath(pathSegments) {
|
|
23
|
+
const format = ([curr, ...next], mode = 'object')=>{
|
|
24
|
+
if (!curr) return '';
|
|
25
|
+
if (curr.kind === 'property') return format(next, curr.name === 'of' ? 'array' : 'object');
|
|
26
|
+
const name = curr.name || `<anonymous_${curr.type}>`;
|
|
27
|
+
return `${mode === 'array' ? `[${name}]` : `.${name}`}${format(next)}`;
|
|
28
|
+
};
|
|
29
|
+
return format(pathSegments.slice(1)).slice(1) // removes the top-level type and leading `.`
|
|
30
|
+
;
|
|
31
|
+
}
|
|
32
|
+
export function getAggregatedSeverity(groupOrGroups) {
|
|
33
|
+
const groups = Array.isArray(groupOrGroups) ? groupOrGroups : [
|
|
34
|
+
groupOrGroups
|
|
35
|
+
];
|
|
36
|
+
return groups.flatMap((group)=>group.problems.map((problem)=>problem.severity)).includes('error') ? 'error' : 'warning';
|
|
37
|
+
}
|
|
38
|
+
export function formatSchemaValidation(validation) {
|
|
39
|
+
let unnamedTopLevelTypeCount = 0;
|
|
40
|
+
const validationByTypeMap = {};
|
|
41
|
+
for (const group of validation){
|
|
42
|
+
const [firstSegment] = group.path;
|
|
43
|
+
if (!firstSegment) continue;
|
|
44
|
+
if (firstSegment.kind !== 'type') continue;
|
|
45
|
+
const topLevelType = firstSegment.name || `<unnamed_${firstSegment.type}_type_${unnamedTopLevelTypeCount++}>`;
|
|
46
|
+
if (!validationByTypeMap[topLevelType]) {
|
|
47
|
+
validationByTypeMap[topLevelType] = [];
|
|
48
|
+
}
|
|
49
|
+
validationByTypeMap[topLevelType].push(group);
|
|
50
|
+
}
|
|
51
|
+
const validationByType = Object.entries(validationByTypeMap);
|
|
52
|
+
const formatted = validationByType.toSorted((a, b)=>{
|
|
53
|
+
const [aType, aGroups] = a;
|
|
54
|
+
const [bType, bGroups] = b;
|
|
55
|
+
const aValue = severityValues[getAggregatedSeverity(aGroups)];
|
|
56
|
+
const bValue = severityValues[getAggregatedSeverity(bGroups)];
|
|
57
|
+
if (aValue === bValue) return aType.localeCompare(bType, 'en-US');
|
|
58
|
+
return aValue - bValue;
|
|
59
|
+
}).map(([topLevelType, groups])=>{
|
|
60
|
+
const formattedTopLevelType = isTty ? styleText([
|
|
61
|
+
'bgWhite',
|
|
62
|
+
'black'
|
|
63
|
+
], ` ${topLevelType} `) : `[${topLevelType}]`;
|
|
64
|
+
const header = `${headers[getAggregatedSeverity(groups)]} ${formattedTopLevelType}`;
|
|
65
|
+
const body = groups.toSorted((a, b)=>severityValues[getAggregatedSeverity(a)] - severityValues[getAggregatedSeverity(b)]).map((group)=>{
|
|
66
|
+
const formattedPath = ` ${styleText('bold', formatPath(group.path) || '(root)')}`;
|
|
67
|
+
const formattedMessages = group.problems.toSorted((a, b)=>severityValues[a.severity] - severityValues[b.severity]).map(({ helpId, message, severity })=>{
|
|
68
|
+
const help = helpId ? `\n See ${generateHelpUrl(helpId)}` : '';
|
|
69
|
+
return ` ${logSymbols[severity]} ${message}${help}`;
|
|
70
|
+
}).join('\n');
|
|
71
|
+
return `${formattedPath}\n${formattedMessages}`;
|
|
72
|
+
}).join('\n');
|
|
73
|
+
return `${header}\n${body}`;
|
|
74
|
+
}).join('\n\n');
|
|
75
|
+
return formatted;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
//# sourceMappingURL=formatSchemaValidation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/schema/formatSchemaValidation.ts"],"sourcesContent":["import {isatty} from 'node:tty'\nimport {styleText} from 'node:util'\n\nimport {logSymbols} from '@sanity/cli-core/ux'\nimport {generateHelpUrl} from '@sanity/generate-help-url'\nimport {type SchemaValidationProblemGroup, type SchemaValidationProblemPath} from '@sanity/types'\n\nconst isTty = isatty(1)\n\nconst headers = {\n error: isTty ? styleText(['bold', 'bgRed', 'black'], ' ERROR ') : styleText('red', '[ERROR]'),\n warning: isTty\n ? styleText(['bold', 'bgYellow', 'black'], ' WARN ')\n : styleText('yellow', '[WARN]'),\n}\n\nconst severityValues = {error: 0, warning: 1}\n\nfunction formatPath(pathSegments: SchemaValidationProblemPath) {\n const format = (\n [curr, ...next]: SchemaValidationProblemPath,\n mode: 'array' | 'object' = 'object',\n ): string => {\n if (!curr) return ''\n if (curr.kind === 'property') return format(next, curr.name === 'of' ? 'array' : 'object')\n\n const name = curr.name || `<anonymous_${curr.type}>`\n return `${mode === 'array' ? `[${name}]` : `.${name}`}${format(next)}`\n }\n\n return format(pathSegments.slice(1)).slice(1) // removes the top-level type and leading `.`\n}\n\nexport function getAggregatedSeverity(\n groupOrGroups: SchemaValidationProblemGroup | SchemaValidationProblemGroup[],\n): 'error' | 'warning' {\n const groups = Array.isArray(groupOrGroups) ? groupOrGroups : [groupOrGroups]\n return groups\n .flatMap((group) => group.problems.map((problem) => problem.severity))\n .includes('error')\n ? 'error'\n : 'warning'\n}\n\nexport function formatSchemaValidation(validation: SchemaValidationProblemGroup[]): string {\n let unnamedTopLevelTypeCount = 0\n const validationByTypeMap: Record<string, SchemaValidationProblemGroup[]> = {}\n\n for (const group of validation) {\n const [firstSegment] = group.path\n if (!firstSegment) continue\n if (firstSegment.kind !== 'type') continue\n\n const topLevelType =\n firstSegment.name || `<unnamed_${firstSegment.type}_type_${unnamedTopLevelTypeCount++}>`\n\n if (!validationByTypeMap[topLevelType]) {\n validationByTypeMap[topLevelType] = []\n }\n\n validationByTypeMap[topLevelType].push(group)\n }\n\n const validationByType = Object.entries(validationByTypeMap)\n\n const formatted = validationByType\n .toSorted((a, b) => {\n const [aType, aGroups] = a\n const [bType, bGroups] = b\n const aValue = severityValues[getAggregatedSeverity(aGroups)]\n const bValue = severityValues[getAggregatedSeverity(bGroups)]\n if (aValue === bValue) return aType.localeCompare(bType, 'en-US')\n return aValue - bValue\n })\n .map(([topLevelType, groups]) => {\n const formattedTopLevelType = isTty\n ? styleText(['bgWhite', 'black'], ` ${topLevelType} `)\n : `[${topLevelType}]`\n\n const header = `${headers[getAggregatedSeverity(groups)]} ${formattedTopLevelType}`\n const body = groups\n .toSorted(\n (a, b) =>\n severityValues[getAggregatedSeverity(a)] - severityValues[getAggregatedSeverity(b)],\n )\n .map((group) => {\n const formattedPath = ` ${styleText('bold', formatPath(group.path) || '(root)')}`\n const formattedMessages = group.problems\n .toSorted((a, b) => severityValues[a.severity] - severityValues[b.severity])\n .map(({helpId, message, severity}) => {\n const help = helpId ? `\\n See ${generateHelpUrl(helpId)}` : ''\n return ` ${logSymbols[severity]} ${message}${help}`\n })\n .join('\\n')\n\n return `${formattedPath}\\n${formattedMessages}`\n })\n .join('\\n')\n\n return `${header}\\n${body}`\n })\n .join('\\n\\n')\n\n return formatted\n}\n"],"names":["isatty","styleText","logSymbols","generateHelpUrl","isTty","headers","error","warning","severityValues","formatPath","pathSegments","format","curr","next","mode","kind","name","type","slice","getAggregatedSeverity","groupOrGroups","groups","Array","isArray","flatMap","group","problems","map","problem","severity","includes","formatSchemaValidation","validation","unnamedTopLevelTypeCount","validationByTypeMap","firstSegment","path","topLevelType","push","validationByType","Object","entries","formatted","toSorted","a","b","aType","aGroups","bType","bGroups","aValue","bValue","localeCompare","formattedTopLevelType","header","body","formattedPath","formattedMessages","helpId","message","help","join"],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { existsSync, statSync } from 'node:fs';
|
|
2
|
+
import { extname, join, resolve } from 'node:path';
|
|
3
|
+
export function getExtractOptions(options) {
|
|
4
|
+
const { enforceRequiredFields, format, path: pathFlag, projectRoot, watchPatterns, workspace } = options;
|
|
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: enforceRequiredFields ?? false,
|
|
16
|
+
format: format ?? 'groq-type-nodes',
|
|
17
|
+
outputPath,
|
|
18
|
+
watchPatterns: watchPatterns ?? [],
|
|
19
|
+
workspace
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
//# sourceMappingURL=getExtractOptions.js.map
|
|
@@ -0,0 +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 ProjectRootResult} from '@sanity/cli-core'\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 GetExtractOptions {\n enforceRequiredFields: boolean | undefined\n format: string | undefined\n path: string | undefined\n projectRoot: ProjectRootResult\n watchPatterns: string[] | undefined\n workspace: string | undefined\n}\n\nexport function getExtractOptions(options: GetExtractOptions): ExtractOptions {\n const {\n enforceRequiredFields,\n format,\n path: pathFlag,\n projectRoot,\n watchPatterns,\n workspace,\n } = options\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: enforceRequiredFields ?? false,\n format: format ?? 'groq-type-nodes',\n outputPath,\n watchPatterns: watchPatterns ?? [],\n workspace,\n }\n}\n"],"names":["existsSync","statSync","extname","join","resolve","getExtractOptions","options","enforceRequiredFields","format","path","pathFlag","projectRoot","watchPatterns","workspace","outputPath","resolved","directory","isExistingDirectory","isDirectory","configPath"],"mappings":"AAAA,SAAQA,UAAU,EAAEC,QAAQ,QAAO,UAAS;AAC5C,SAAQC,OAAO,EAAEC,IAAI,EAAEC,OAAO,QAAO,YAAW;AAsBhD,OAAO,SAASC,kBAAkBC,OAA0B;IAC1D,MAAM,EACJC,qBAAqB,EACrBC,MAAM,EACNC,MAAMC,QAAQ,EACdC,WAAW,EACXC,aAAa,EACbC,SAAS,EACV,GAAGP;IACJ,IAAIQ;IACJ,IAAIJ,UAAU;QACZ,MAAMK,WAAWX,QAAQD,KAAKQ,YAAYK,SAAS,EAAEN;QACrD,MAAMO,sBAAsBjB,WAAWe,aAAad,SAASc,UAAUG,WAAW;QAElFJ,aACEG,uBAAuB,CAACf,QAAQa,YAAYZ,KAAKY,UAAU,iBAAiBA;IAChF,OAAO;QACLD,aAAaV,QAAQD,KAAKQ,YAAYK,SAAS,EAAE;IACnD;IAEA,OAAO;QACLG,YAAYR,YAAYF,IAAI;QAC5BF,uBAAuBA,yBAAyB;QAChDC,QAAQA,UAAU;QAClBM;QACAF,eAAeA,iBAAiB,EAAE;QAClCC;IACF;AACF"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { isAbsolute, relative } from 'node:path';
|
|
2
|
+
import picomatch from 'picomatch';
|
|
3
|
+
/**
|
|
4
|
+
* Creates a pattern matcher function for schema watch patterns.
|
|
5
|
+
* Normalizes file paths to forward slashes and makes them relative before matching.
|
|
6
|
+
*
|
|
7
|
+
* @param patterns - Array of glob patterns to match against
|
|
8
|
+
* @returns Function that takes a file path and workDir, returns true if file matches any pattern
|
|
9
|
+
* @internal
|
|
10
|
+
*/ export function createSchemaPatternMatcher(patterns) {
|
|
11
|
+
const matcher = picomatch(patterns);
|
|
12
|
+
return {
|
|
13
|
+
isMatch: (filePath, workDir)=>{
|
|
14
|
+
const relativePath = isAbsolute(filePath) ? relative(workDir, filePath) : filePath;
|
|
15
|
+
const normalizedPath = relativePath.replaceAll('\\', '/');
|
|
16
|
+
return matcher(normalizedPath);
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
//# sourceMappingURL=matchSchemaPattern.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/schema/matchSchemaPattern.ts"],"sourcesContent":["import {isAbsolute, relative} from 'node:path'\n\nimport picomatch from 'picomatch'\n\n/**\n * Creates a pattern matcher function for schema watch patterns.\n * Normalizes file paths to forward slashes and makes them relative before matching.\n *\n * @param patterns - Array of glob patterns to match against\n * @returns Function that takes a file path and workDir, returns true if file matches any pattern\n * @internal\n */\nexport function createSchemaPatternMatcher(patterns: string[]): {\n isMatch: (filePath: string, workDir: string) => boolean\n} {\n const matcher = picomatch(patterns)\n\n return {\n isMatch: (filePath: string, workDir: string): boolean => {\n const relativePath = isAbsolute(filePath) ? relative(workDir, filePath) : filePath\n const normalizedPath = relativePath.replaceAll('\\\\', '/')\n return matcher(normalizedPath)\n },\n }\n}\n"],"names":["isAbsolute","relative","picomatch","createSchemaPatternMatcher","patterns","matcher","isMatch","filePath","workDir","relativePath","normalizedPath","replaceAll"],"mappings":"AAAA,SAAQA,UAAU,EAAEC,QAAQ,QAAO,YAAW;AAE9C,OAAOC,eAAe,YAAW;AAEjC;;;;;;;CAOC,GACD,OAAO,SAASC,2BAA2BC,QAAkB;IAG3D,MAAMC,UAAUH,UAAUE;IAE1B,OAAO;QACLE,SAAS,CAACC,UAAkBC;YAC1B,MAAMC,eAAeT,WAAWO,YAAYN,SAASO,SAASD,YAAYA;YAC1E,MAAMG,iBAAiBD,aAAaE,UAAU,CAAC,MAAM;YACrD,OAAON,QAAQK;QACjB;IACF;AACF"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { mkdir, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { dirname } from 'node:path';
|
|
3
|
+
import { studioWorkerTask } from '@sanity/cli-core';
|
|
4
|
+
import { SchemaExtractionError } from './utils/SchemaExtractionError.js';
|
|
5
|
+
/**
|
|
6
|
+
* Core schema extraction logic.
|
|
7
|
+
* Performs the extraction via worker and writes to file.
|
|
8
|
+
* Throws SchemaExtractionError on failure.
|
|
9
|
+
*/ export async function runSchemaExtraction(extractOptions) {
|
|
10
|
+
const { configPath, enforceRequiredFields, format, outputPath, workspace } = extractOptions;
|
|
11
|
+
if (format !== 'groq-type-nodes') {
|
|
12
|
+
throw new Error(`Unsupported format: "${format}"`);
|
|
13
|
+
}
|
|
14
|
+
const workDir = dirname(configPath);
|
|
15
|
+
const outputDir = dirname(outputPath);
|
|
16
|
+
const result = await studioWorkerTask(new URL('extractSanitySchema.worker.js', import.meta.url), {
|
|
17
|
+
name: 'extractSanitySchema',
|
|
18
|
+
studioRootPath: workDir,
|
|
19
|
+
workerData: {
|
|
20
|
+
configPath,
|
|
21
|
+
enforceRequiredFields,
|
|
22
|
+
workDir,
|
|
23
|
+
workspaceName: workspace
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
if (result.type === 'error') {
|
|
27
|
+
throw new SchemaExtractionError(result.error, result.validation);
|
|
28
|
+
}
|
|
29
|
+
const schema = result.schema;
|
|
30
|
+
// Ensure output directory exists
|
|
31
|
+
await mkdir(outputDir, {
|
|
32
|
+
recursive: true
|
|
33
|
+
});
|
|
34
|
+
// Write schema to file
|
|
35
|
+
await writeFile(outputPath, `${JSON.stringify(schema, null, 2)}\n`);
|
|
36
|
+
return schema;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
//# sourceMappingURL=runSchemaExtraction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/schema/runSchemaExtraction.ts"],"sourcesContent":["import {mkdir, writeFile} from 'node:fs/promises'\nimport {dirname} from 'node:path'\n\nimport {studioWorkerTask} from '@sanity/cli-core'\nimport {type extractSchema as extractSchemaInternal} from '@sanity/schema/_internal'\n\nimport {type ExtractOptions} from './getExtractOptions.js'\nimport {type ExtractSchemaWorkerData, type ExtractSchemaWorkerError} from './types.js'\nimport {SchemaExtractionError} from './utils/SchemaExtractionError.js'\n\ninterface ExtractSchemaWorkerResult {\n schema: ReturnType<typeof extractSchemaInternal>\n type: 'success'\n}\n\ntype ExtractSchemaWorkerMessage = ExtractSchemaWorkerError | ExtractSchemaWorkerResult\n\n/**\n * Core schema extraction logic.\n * Performs the extraction via worker and writes to file.\n * Throws SchemaExtractionError on failure.\n */\nexport async function runSchemaExtraction(\n extractOptions: Omit<ExtractOptions, 'watchPatterns'>,\n): Promise<ReturnType<typeof extractSchemaInternal>> {\n const {configPath, enforceRequiredFields, format, outputPath, workspace} = extractOptions\n\n if (format !== 'groq-type-nodes') {\n throw new Error(`Unsupported format: \"${format}\"`)\n }\n\n const workDir = dirname(configPath)\n const outputDir = dirname(outputPath)\n\n const result = await studioWorkerTask<ExtractSchemaWorkerMessage>(\n new URL('extractSanitySchema.worker.js', import.meta.url),\n {\n name: 'extractSanitySchema',\n studioRootPath: workDir,\n workerData: {\n configPath,\n enforceRequiredFields,\n workDir,\n workspaceName: workspace,\n } satisfies ExtractSchemaWorkerData,\n },\n )\n\n if (result.type === 'error') {\n throw new SchemaExtractionError(result.error, result.validation)\n }\n\n const schema = result.schema\n\n // Ensure output directory exists\n await mkdir(outputDir, {recursive: true})\n\n // Write schema to file\n await writeFile(outputPath, `${JSON.stringify(schema, null, 2)}\\n`)\n\n return schema\n}\n"],"names":["mkdir","writeFile","dirname","studioWorkerTask","SchemaExtractionError","runSchemaExtraction","extractOptions","configPath","enforceRequiredFields","format","outputPath","workspace","Error","workDir","outputDir","result","URL","url","name","studioRootPath","workerData","workspaceName","type","error","validation","schema","recursive","JSON","stringify"],"mappings":"AAAA,SAAQA,KAAK,EAAEC,SAAS,QAAO,mBAAkB;AACjD,SAAQC,OAAO,QAAO,YAAW;AAEjC,SAAQC,gBAAgB,QAAO,mBAAkB;AAKjD,SAAQC,qBAAqB,QAAO,mCAAkC;AAStE;;;;CAIC,GACD,OAAO,eAAeC,oBACpBC,cAAqD;IAErD,MAAM,EAACC,UAAU,EAAEC,qBAAqB,EAAEC,MAAM,EAAEC,UAAU,EAAEC,SAAS,EAAC,GAAGL;IAE3E,IAAIG,WAAW,mBAAmB;QAChC,MAAM,IAAIG,MAAM,CAAC,qBAAqB,EAAEH,OAAO,CAAC,CAAC;IACnD;IAEA,MAAMI,UAAUX,QAAQK;IACxB,MAAMO,YAAYZ,QAAQQ;IAE1B,MAAMK,SAAS,MAAMZ,iBACnB,IAAIa,IAAI,iCAAiC,YAAYC,GAAG,GACxD;QACEC,MAAM;QACNC,gBAAgBN;QAChBO,YAAY;YACVb;YACAC;YACAK;YACAQ,eAAeV;QACjB;IACF;IAGF,IAAII,OAAOO,IAAI,KAAK,SAAS;QAC3B,MAAM,IAAIlB,sBAAsBW,OAAOQ,KAAK,EAAER,OAAOS,UAAU;IACjE;IAEA,MAAMC,SAASV,OAAOU,MAAM;IAE5B,iCAAiC;IACjC,MAAMzB,MAAMc,WAAW;QAACY,WAAW;IAAI;IAEvC,uBAAuB;IACvB,MAAMzB,UAAUS,YAAY,GAAGiB,KAAKC,SAAS,CAACH,QAAQ,MAAM,GAAG,EAAE,CAAC;IAElE,OAAOA;AACT"}
|
|
@@ -0,0 +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/** @internal */\nexport interface ExtractSchemaWorkerError {\n error: string\n type: 'error'\n\n validation?: SchemaValidationProblemGroup[]\n}\n"],"names":["z","extractSchemaWorkerData","object","configPath","string","enforceRequiredFields","boolean","workDir","workspaceName","optional"],"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/actions/schema/utils/SchemaExtractionError.ts"],"sourcesContent":["import {type SchemaValidationProblemGroup} from '@sanity/types'\n\nexport class SchemaExtractionError extends Error {\n validation?: SchemaValidationProblemGroup[]\n\n constructor(message: string, validation?: SchemaValidationProblemGroup[]) {\n super(message)\n this.name = 'SchemaExtractionError'\n this.validation = validation\n }\n}\n"],"names":["SchemaExtractionError","Error","validation","message","name"],"mappings":"AAEA,OAAO,MAAMA,8BAA8BC;IACzCC,WAA2C;IAE3C,YAAYC,OAAe,EAAED,UAA2C,CAAE;QACxE,KAAK,CAACC;QACN,IAAI,CAACC,IAAI,GAAG;QACZ,IAAI,CAACF,UAAU,GAAGA;IACpB;AACF"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { resolveLocalPackage } from '@sanity/cli-core';
|
|
2
|
+
/**
|
|
3
|
+
* Extracts validation problem groups from a SchemaError.
|
|
4
|
+
*/ export async function extractValidationFromSchemaError(error, workDir) {
|
|
5
|
+
const { SchemaError } = await resolveLocalPackage('sanity', workDir);
|
|
6
|
+
if (error instanceof SchemaError) {
|
|
7
|
+
return error.schema._validation;
|
|
8
|
+
}
|
|
9
|
+
return undefined;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
//# sourceMappingURL=extractValidationFromSchemaError.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/actions/schema/utils/extractValidationFromSchemaError.ts"],"sourcesContent":["import {resolveLocalPackage} from '@sanity/cli-core'\nimport {type SchemaValidationProblemGroup} from '@sanity/types'\n\n/**\n * Extracts validation problem groups from a SchemaError.\n */\nexport async function extractValidationFromSchemaError(\n error: unknown,\n workDir: string,\n): Promise<SchemaValidationProblemGroup[] | undefined> {\n const {SchemaError} = await resolveLocalPackage<typeof import('sanity')>('sanity', workDir)\n\n if (error instanceof SchemaError) {\n return error.schema._validation\n }\n\n return undefined\n}\n"],"names":["resolveLocalPackage","extractValidationFromSchemaError","error","workDir","SchemaError","schema","_validation","undefined"],"mappings":"AAAA,SAAQA,mBAAmB,QAAO,mBAAkB;AAGpD;;CAEC,GACD,OAAO,eAAeC,iCACpBC,KAAc,EACdC,OAAe;IAEf,MAAM,EAACC,WAAW,EAAC,GAAG,MAAMJ,oBAA6C,UAAUG;IAEnF,IAAID,iBAAiBE,aAAa;QAChC,OAAOF,MAAMG,MAAM,CAACC,WAAW;IACjC;IAEA,OAAOC;AACT"}
|