@sanity/cli-build 7.0.1 → 7.0.2

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.
@@ -6,18 +6,66 @@ const entryChunkId = '.sanity/runtime/app.js';
6
6
  /**
7
7
  * Logical name Vite gives the single CSS asset emitted when
8
8
  * `build.cssCodeSplit` is false. `assetFileNames` can change the file written
9
- * to disk; `names` / `originalFileNames` still carry this value.
9
+ * to disk; `names` still carries this value.
10
10
  */ const CSS_BUNDLE_NAME = 'style.css';
11
11
  export function sanityBuildEntries(options) {
12
12
  const { autoUpdates, basePath, bridge = true, cwd, isApp } = options;
13
13
  // Vite's default. `configResolved` replaces this with the resolved value,
14
14
  // including a userland `vite` config that sets `build.cssCodeSplit: false`.
15
15
  let cssCodeSplit = true;
16
+ const generateBundle = {
17
+ async handler (_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
+ const css = collectStylesheets(entryFile, bundle, cssCodeSplit);
32
+ // For auto-updating studios/apps the import map combines the vendor
33
+ // chunks emitted by this very build (hashed filenames, resolved from the
34
+ // bundle) with the module-CDN imports for auto-updated packages.
35
+ const importMap = autoUpdates ? {
36
+ imports: {
37
+ ...createVendorImportMapFromBundle(bundle, autoUpdates.vendor.specifiersByChunkName, basePath),
38
+ ...autoUpdates.imports
39
+ }
40
+ } : undefined;
41
+ const html = await renderDocument({
42
+ autoUpdatesCssUrls: autoUpdates?.cssUrls,
43
+ importMap,
44
+ isApp,
45
+ props: {
46
+ basePath,
47
+ css,
48
+ entryPath
49
+ },
50
+ studioRootPath: cwd
51
+ });
52
+ this.emitFile({
53
+ fileName: 'index.html',
54
+ source: decorateIndexWithStagingScript(bridge ? decorateIndexWithBridgeScript(html) : html),
55
+ type: 'asset'
56
+ });
57
+ }
58
+ };
16
59
  return {
17
60
  apply: 'build',
18
61
  name: 'sanity/server/build-entries',
19
62
  configResolved (resolved) {
20
63
  cssCodeSplit = resolved.build.cssCodeSplit;
64
+ // `vite:css-post` emits the combined stylesheet during its own unordered
65
+ // `generateBundle`, so with `cssCodeSplit: false` this hook has to run
66
+ // after it. Default builds keep the normal order so user plugins with an
67
+ // unordered `generateBundle` (HTML minifiers, SRI) still see `index.html`.
68
+ generateBundle.order = cssCodeSplit ? undefined : 'post';
21
69
  },
22
70
  buildStart () {
23
71
  this.emitFile({
@@ -26,53 +74,7 @@ export function sanityBuildEntries(options) {
26
74
  type: 'chunk'
27
75
  });
28
76
  },
29
- // `vite:css-post` emits the combined stylesheet during its own
30
- // `generateBundle`. That hook is unordered, so this one has to run after
31
- // it (`order: 'post'`) or the asset is not in the bundle yet.
32
- generateBundle: {
33
- async handler (_options, outputBundle) {
34
- const bundle = outputBundle;
35
- const entryFile = Object.values(bundle).find((file)=>file.type === 'chunk' && file.name === 'sanity' && file.facadeModuleId?.endsWith(entryChunkId));
36
- if (!entryFile) {
37
- throw new Error(`Failed to find entry file in bundle (${entryChunkId})`);
38
- }
39
- if (entryFile.type !== 'chunk') {
40
- throw new Error('Entry file is not a chunk');
41
- }
42
- const entryFileName = entryFile.fileName;
43
- const entryPath = [
44
- basePath.replace(/\/+$/, ''),
45
- entryFileName
46
- ].join('/');
47
- const css = collectStylesheets(entryFile, bundle, cssCodeSplit);
48
- // For auto-updating studios/apps the import map combines the vendor
49
- // chunks emitted by this very build (hashed filenames, resolved from the
50
- // bundle) with the module-CDN imports for auto-updated packages.
51
- const importMap = autoUpdates ? {
52
- imports: {
53
- ...createVendorImportMapFromBundle(bundle, autoUpdates.vendor.specifiersByChunkName, basePath),
54
- ...autoUpdates.imports
55
- }
56
- } : undefined;
57
- const html = await renderDocument({
58
- autoUpdatesCssUrls: autoUpdates?.cssUrls,
59
- importMap,
60
- isApp,
61
- props: {
62
- basePath,
63
- css,
64
- entryPath
65
- },
66
- studioRootPath: cwd
67
- });
68
- this.emitFile({
69
- fileName: 'index.html',
70
- source: decorateIndexWithStagingScript(bridge ? decorateIndexWithBridgeScript(html) : html),
71
- type: 'asset'
72
- });
73
- },
74
- order: 'post'
75
- }
77
+ generateBundle
76
78
  };
77
79
  }
78
80
  /**
@@ -82,9 +84,8 @@ export function sanityBuildEntries(options) {
82
84
  * `viteMetadata.importedCss` (including the chunks the entry statically
83
85
  * imports). With `cssCodeSplit: false`, Vite emits one combined asset instead
84
86
  * and never adds it to `importedCss`. `vite:build-html` finds that asset by
85
- * its bundle name (`style.css`); mirror that, and if Rolldown omits `names` /
86
- * `originalFileNames`, link every emitted `.css` asset so the document is not
87
- * unstyled.
87
+ * its bundle name (`style.css`); mirror that. Other CSS assets (e.g. `?url`
88
+ * imports) are not stylesheets for the document and must not be linked.
88
89
  */ function collectStylesheets(entryFile, bundle, cssCodeSplit) {
89
90
  const css = collectImportedCss(entryFile, bundle);
90
91
  if (cssCodeSplit) return css;
@@ -112,29 +113,12 @@ function cssFilesFromChunk(chunk) {
112
113
  ];
113
114
  }
114
115
  function collectCombinedStylesheets(bundle) {
115
- const cssAssets = Object.values(bundle).filter((file)=>isCssAsset(file));
116
- const named = cssAssets.filter((asset)=>isCombinedCssBundle(asset));
117
- const chosen = named.length > 0 ? named : cssAssets;
118
- return chosen.flatMap((asset)=>asset.fileName ? [
119
- asset.fileName
116
+ return Object.values(bundle).flatMap((file)=>file.type === 'asset' && file.fileName && isCombinedCssBundle(file) ? [
117
+ file.fileName
120
118
  ] : []);
121
119
  }
122
- function isCssAsset(file) {
123
- return file.type === 'asset' && typeof file.fileName === 'string' && file.fileName.endsWith('.css');
124
- }
125
120
  function isCombinedCssBundle(asset) {
126
- return assetIdentifiers(asset).some((name)=>baseName(name) === CSS_BUNDLE_NAME);
127
- }
128
- function assetIdentifiers(asset) {
129
- return [
130
- asset.name,
131
- asset.originalFileName,
132
- ...asset.names ?? [],
133
- ...asset.originalFileNames ?? []
134
- ].filter((name)=>typeof name === 'string' && name.length > 0);
135
- }
136
- function baseName(fileName) {
137
- return fileName.split(/[/\\]/).pop() ?? fileName;
121
+ return asset.names ? asset.names.includes(CSS_BUNDLE_NAME) : asset.name === CSS_BUNDLE_NAME;
138
122
  }
139
123
 
140
124
  //# sourceMappingURL=plugin-sanity-build-entries.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/actions/build/vite/plugin-sanity-build-entries.ts"],"sourcesContent":["import {type ChunkMetadata, type Plugin} from 'vite'\n\nimport {type AutoUpdatesBuildConfig} from '../autoUpdates.js'\nimport {createVendorImportMapFromBundle} from '../createVendorImportMapFromBundle.js'\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 fileName?: string\n name?: string | null\n names?: string[]\n originalFileName?: string | null\n originalFileNames?: string[]\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\n /**\n * Populated by Vite when `build.cssCodeSplit` is true. Rolldown-based Vite\n * (Vite 7/8 and `rolldown-vite`) may omit it, or leave `importedCss` empty,\n * for the single stylesheet emitted when code splitting is disabled.\n */\n viteMetadata?: ChunkMetadata\n}\n\nconst entryChunkId = '.sanity/runtime/app.js'\n\n/**\n * Logical name Vite gives the single CSS asset emitted when\n * `build.cssCodeSplit` is false. `assetFileNames` can change the file written\n * to disk; `names` / `originalFileNames` still carry this value.\n */\nconst CSS_BUNDLE_NAME = 'style.css'\n\nexport function sanityBuildEntries(options: {\n autoUpdates?: AutoUpdatesBuildConfig\n basePath: string\n /**\n * Injects the core-ui bridge script into the emitted `index.html`. Defaults to\n * `true`. Workbench remotes serve themselves standalone and pass `false`.\n */\n bridge?: boolean\n cwd: string\n isApp?: boolean\n}): Plugin {\n const {autoUpdates, basePath, bridge = true, cwd, isApp} = options\n // Vite's default. `configResolved` replaces this with the resolved value,\n // including a userland `vite` config that sets `build.cssCodeSplit: false`.\n let cssCodeSplit = true\n\n return {\n apply: 'build',\n name: 'sanity/server/build-entries',\n\n configResolved(resolved) {\n cssCodeSplit = resolved.build.cssCodeSplit\n },\n\n buildStart() {\n this.emitFile({\n id: entryChunkId,\n name: 'sanity',\n type: 'chunk',\n })\n },\n\n // `vite:css-post` emits the combined stylesheet during its own\n // `generateBundle`. That hook is unordered, so this one has to run after\n // it (`order: 'post'`) or the asset is not in the bundle yet.\n generateBundle: {\n async handler(_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 const css = collectStylesheets(entryFile, bundle, cssCodeSplit)\n\n // For auto-updating studios/apps the import map combines the vendor\n // chunks emitted by this very build (hashed filenames, resolved from the\n // bundle) with the module-CDN imports for auto-updated packages.\n const importMap = autoUpdates\n ? {\n imports: {\n ...createVendorImportMapFromBundle(\n bundle,\n autoUpdates.vendor.specifiersByChunkName,\n basePath,\n ),\n ...autoUpdates.imports,\n },\n }\n : undefined\n\n const html = await renderDocument({\n autoUpdatesCssUrls: autoUpdates?.cssUrls,\n importMap,\n isApp,\n props: {\n basePath,\n css,\n entryPath,\n },\n studioRootPath: cwd,\n })\n\n this.emitFile({\n fileName: 'index.html',\n source: decorateIndexWithStagingScript(\n bridge ? decorateIndexWithBridgeScript(html) : html,\n ),\n type: 'asset',\n })\n },\n order: 'post',\n },\n }\n}\n\n/**\n * Stylesheets the document should link.\n *\n * With CSS code splitting, Vite records each chunk's styles on\n * `viteMetadata.importedCss` (including the chunks the entry statically\n * imports). With `cssCodeSplit: false`, Vite emits one combined asset instead\n * and never adds it to `importedCss`. `vite:build-html` finds that asset by\n * its bundle name (`style.css`); mirror that, and if Rolldown omits `names` /\n * `originalFileNames`, link every emitted `.css` asset so the document is not\n * unstyled.\n */\nfunction collectStylesheets(\n entryFile: ViteRenderedChunk,\n bundle: ViteOutputBundle,\n cssCodeSplit: boolean,\n): string[] {\n const css = collectImportedCss(entryFile, bundle)\n if (cssCodeSplit) return css\n\n const seen = new Set(css)\n for (const fileName of collectCombinedStylesheets(bundle)) {\n if (seen.has(fileName)) continue\n seen.add(fileName)\n css.push(fileName)\n }\n return css\n}\n\nfunction collectImportedCss(entryFile: ViteRenderedChunk, bundle: ViteOutputBundle): string[] {\n const css = cssFilesFromChunk(entryFile)\n for (const key of entryFile.imports) {\n const imported = bundle[key]\n if (imported?.type === 'chunk') css.push(...cssFilesFromChunk(imported))\n }\n return css\n}\n\nfunction cssFilesFromChunk(chunk: ViteRenderedChunk): string[] {\n const imported = chunk.viteMetadata?.importedCss\n if (!imported) return []\n return [...imported]\n}\n\nfunction collectCombinedStylesheets(bundle: ViteOutputBundle): string[] {\n const cssAssets = Object.values(bundle).filter((file) => isCssAsset(file))\n const named = cssAssets.filter((asset) => isCombinedCssBundle(asset))\n const chosen = named.length > 0 ? named : cssAssets\n return chosen.flatMap((asset) => (asset.fileName ? [asset.fileName] : []))\n}\n\nfunction isCssAsset(file: ViteRenderedAsset | ViteRenderedChunk): file is ViteRenderedAsset {\n return (\n file.type === 'asset' && typeof file.fileName === 'string' && file.fileName.endsWith('.css')\n )\n}\n\nfunction isCombinedCssBundle(asset: ViteRenderedAsset): boolean {\n return assetIdentifiers(asset).some((name) => baseName(name) === CSS_BUNDLE_NAME)\n}\n\nfunction assetIdentifiers(asset: ViteRenderedAsset): string[] {\n return [\n asset.name,\n asset.originalFileName,\n ...(asset.names ?? []),\n ...(asset.originalFileNames ?? []),\n ].filter((name): name is string => typeof name === 'string' && name.length > 0)\n}\n\nfunction baseName(fileName: string): string {\n return fileName.split(/[/\\\\]/).pop() ?? fileName\n}\n"],"names":["createVendorImportMapFromBundle","decorateIndexWithBridgeScript","decorateIndexWithStagingScript","renderDocument","entryChunkId","CSS_BUNDLE_NAME","sanityBuildEntries","options","autoUpdates","basePath","bridge","cwd","isApp","cssCodeSplit","apply","name","configResolved","resolved","build","buildStart","emitFile","id","type","generateBundle","handler","_options","outputBundle","bundle","entryFile","Object","values","find","file","facadeModuleId","endsWith","Error","entryFileName","fileName","entryPath","replace","join","css","collectStylesheets","importMap","imports","vendor","specifiersByChunkName","undefined","html","autoUpdatesCssUrls","cssUrls","props","studioRootPath","source","order","collectImportedCss","seen","Set","collectCombinedStylesheets","has","add","push","cssFilesFromChunk","key","imported","chunk","viteMetadata","importedCss","cssAssets","filter","isCssAsset","named","asset","isCombinedCssBundle","chosen","length","flatMap","assetIdentifiers","some","baseName","originalFileName","names","originalFileNames","split","pop"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../src/actions/build/vite/plugin-sanity-build-entries.ts"],"sourcesContent":["import {type ChunkMetadata, type Plugin} from 'vite'\n\nimport {type AutoUpdatesBuildConfig} from '../autoUpdates.js'\nimport {createVendorImportMapFromBundle} from '../createVendorImportMapFromBundle.js'\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 fileName?: string\n name?: string | null\n names?: string[]\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\n /**\n * Populated by Vite when `build.cssCodeSplit` is true. Rolldown-based Vite\n * (Vite 7/8 and `rolldown-vite`) may omit it, or leave `importedCss` empty,\n * for the single stylesheet emitted when code splitting is disabled.\n */\n viteMetadata?: ChunkMetadata\n}\n\nconst entryChunkId = '.sanity/runtime/app.js'\n\n/**\n * Logical name Vite gives the single CSS asset emitted when\n * `build.cssCodeSplit` is false. `assetFileNames` can change the file written\n * to disk; `names` still carries this value.\n */\nconst CSS_BUNDLE_NAME = 'style.css'\n\nexport function sanityBuildEntries(options: {\n autoUpdates?: AutoUpdatesBuildConfig\n basePath: string\n /**\n * Injects the core-ui bridge script into the emitted `index.html`. Defaults to\n * `true`. Workbench remotes serve themselves standalone and pass `false`.\n */\n bridge?: boolean\n cwd: string\n isApp?: boolean\n}): Plugin {\n const {autoUpdates, basePath, bridge = true, cwd, isApp} = options\n // Vite's default. `configResolved` replaces this with the resolved value,\n // including a userland `vite` config that sets `build.cssCodeSplit: false`.\n let cssCodeSplit = true\n\n const generateBundle: Extract<Plugin['generateBundle'], {handler: unknown}> = {\n async handler(_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 const css = collectStylesheets(entryFile, bundle, cssCodeSplit)\n\n // For auto-updating studios/apps the import map combines the vendor\n // chunks emitted by this very build (hashed filenames, resolved from the\n // bundle) with the module-CDN imports for auto-updated packages.\n const importMap = autoUpdates\n ? {\n imports: {\n ...createVendorImportMapFromBundle(\n bundle,\n autoUpdates.vendor.specifiersByChunkName,\n basePath,\n ),\n ...autoUpdates.imports,\n },\n }\n : undefined\n\n const html = await renderDocument({\n autoUpdatesCssUrls: autoUpdates?.cssUrls,\n importMap,\n isApp,\n props: {\n basePath,\n css,\n entryPath,\n },\n studioRootPath: cwd,\n })\n\n this.emitFile({\n fileName: 'index.html',\n source: decorateIndexWithStagingScript(bridge ? decorateIndexWithBridgeScript(html) : html),\n type: 'asset',\n })\n },\n }\n\n return {\n apply: 'build',\n name: 'sanity/server/build-entries',\n\n configResolved(resolved) {\n cssCodeSplit = resolved.build.cssCodeSplit\n // `vite:css-post` emits the combined stylesheet during its own unordered\n // `generateBundle`, so with `cssCodeSplit: false` this hook has to run\n // after it. Default builds keep the normal order so user plugins with an\n // unordered `generateBundle` (HTML minifiers, SRI) still see `index.html`.\n generateBundle.order = cssCodeSplit ? undefined : 'post'\n },\n\n buildStart() {\n this.emitFile({\n id: entryChunkId,\n name: 'sanity',\n type: 'chunk',\n })\n },\n\n generateBundle,\n }\n}\n\n/**\n * Stylesheets the document should link.\n *\n * With CSS code splitting, Vite records each chunk's styles on\n * `viteMetadata.importedCss` (including the chunks the entry statically\n * imports). With `cssCodeSplit: false`, Vite emits one combined asset instead\n * and never adds it to `importedCss`. `vite:build-html` finds that asset by\n * its bundle name (`style.css`); mirror that. Other CSS assets (e.g. `?url`\n * imports) are not stylesheets for the document and must not be linked.\n */\nfunction collectStylesheets(\n entryFile: ViteRenderedChunk,\n bundle: ViteOutputBundle,\n cssCodeSplit: boolean,\n): string[] {\n const css = collectImportedCss(entryFile, bundle)\n if (cssCodeSplit) return css\n\n const seen = new Set(css)\n for (const fileName of collectCombinedStylesheets(bundle)) {\n if (seen.has(fileName)) continue\n seen.add(fileName)\n css.push(fileName)\n }\n return css\n}\n\nfunction collectImportedCss(entryFile: ViteRenderedChunk, bundle: ViteOutputBundle): string[] {\n const css = cssFilesFromChunk(entryFile)\n for (const key of entryFile.imports) {\n const imported = bundle[key]\n if (imported?.type === 'chunk') css.push(...cssFilesFromChunk(imported))\n }\n return css\n}\n\nfunction cssFilesFromChunk(chunk: ViteRenderedChunk): string[] {\n const imported = chunk.viteMetadata?.importedCss\n if (!imported) return []\n return [...imported]\n}\n\nfunction collectCombinedStylesheets(bundle: ViteOutputBundle): string[] {\n return Object.values(bundle).flatMap((file) =>\n file.type === 'asset' && file.fileName && isCombinedCssBundle(file) ? [file.fileName] : [],\n )\n}\n\nfunction isCombinedCssBundle(asset: ViteRenderedAsset): boolean {\n return asset.names ? asset.names.includes(CSS_BUNDLE_NAME) : asset.name === CSS_BUNDLE_NAME\n}\n"],"names":["createVendorImportMapFromBundle","decorateIndexWithBridgeScript","decorateIndexWithStagingScript","renderDocument","entryChunkId","CSS_BUNDLE_NAME","sanityBuildEntries","options","autoUpdates","basePath","bridge","cwd","isApp","cssCodeSplit","generateBundle","handler","_options","outputBundle","bundle","entryFile","Object","values","find","file","type","name","facadeModuleId","endsWith","Error","entryFileName","fileName","entryPath","replace","join","css","collectStylesheets","importMap","imports","vendor","specifiersByChunkName","undefined","html","autoUpdatesCssUrls","cssUrls","props","studioRootPath","emitFile","source","apply","configResolved","resolved","build","order","buildStart","id","collectImportedCss","seen","Set","collectCombinedStylesheets","has","add","push","cssFilesFromChunk","key","imported","chunk","viteMetadata","importedCss","flatMap","isCombinedCssBundle","asset","names","includes"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanity/cli-build",
3
- "version": "7.0.1",
3
+ "version": "7.0.2",
4
4
  "description": "Internal Sanity package for building studios and apps",
5
5
  "keywords": [
6
6
  "cli",
@@ -52,12 +52,12 @@
52
52
  "dependencies": {
53
53
  "@oclif/core": "^4.11.14",
54
54
  "@rolldown/plugin-babel": "^0.2.4",
55
- "@sanity/cli-core": "^3.11.1",
55
+ "@sanity/cli-core": "^3.12.0",
56
56
  "@sanity/generate-help-url": "^4.0.0",
57
57
  "@sanity/schema": "^6.17.0",
58
58
  "@sanity/telemetry": "^1.1.0",
59
59
  "@sanity/types": "^6.17.0",
60
- "@sanity/workbench-cli": "^2.13.0",
60
+ "@sanity/workbench-cli": "^2.14.0",
61
61
  "@vitejs/plugin-react": "^6.1.2",
62
62
  "chokidar": "^5.0.0",
63
63
  "cjs-module-lexer": "^2.2.1",
@@ -79,7 +79,7 @@
79
79
  "@eslint/compat": "^2.1.0",
80
80
  "@repo/package.config": "0.0.1",
81
81
  "@repo/tsconfig": "3.70.0",
82
- "@sanity/cli-test": "21.0.1",
82
+ "@sanity/cli-test": "22.0.0",
83
83
  "@sanity/eslint-config-cli": "^1.1.3",
84
84
  "@sanity/pkg-utils": "^12.3.4",
85
85
  "@sanity/ui": "^4.3.1",