diff --git a/.github/renovate.json b/.github/renovate.json index 47aed6e6a7c..a6f4e615c36 100644 --- a/.github/renovate.json +++ b/.github/renovate.json @@ -30,6 +30,12 @@ "pinDigest", "replacement", "rollback" + ], + "matchPackageNames": [ + "!@portabletext/editor", + "!@sanity/client", + "!@sanity/tsdoc", + "!@sanity/ui" ] }, { diff --git a/dev/.bin/sanity b/dev/.bin/sanity index ba62a21bce5..e15d000943f 100755 --- a/dev/.bin/sanity +++ b/dev/.bin/sanity @@ -4,6 +4,7 @@ const path = require('path') require('esbuild-register/dist/node').register({ target: `node${process.version.slice(1)}`, + supported: {'dynamic-import': true}, jsx: 'automatic', }) diff --git a/dev/depcheck-test/package.json b/dev/depcheck-test/package.json index df298b605cd..b942dc18422 100644 --- a/dev/depcheck-test/package.json +++ b/dev/depcheck-test/package.json @@ -1,6 +1,6 @@ { "name": "depcheck-test", - "version": "3.66.1", + "version": "3.67.1", "private": true, "license": "MIT", "author": "Sanity.io " diff --git a/dev/design-studio/package.json b/dev/design-studio/package.json index a981011325c..d8a2b4bb216 100644 --- a/dev/design-studio/package.json +++ b/dev/design-studio/package.json @@ -1,6 +1,6 @@ { "name": "design-studio", - "version": "3.66.1", + "version": "3.67.1", "private": true, "description": "Sanity Design Studio", "keywords": [ @@ -31,8 +31,8 @@ "start": "../.bin/sanity start --port 4000" }, "dependencies": { - "@sanity/icons": "^3.5.0", - "@sanity/ui": "^2.9.1", + "@sanity/icons": "^3.5.2", + "@sanity/ui": "^2.10.9", "react": "^18.3.1", "react-dom": "^18.3.1", "sanity": "workspace:*", diff --git a/dev/embedded-studio/package.json b/dev/embedded-studio/package.json index 2d992bea955..effd0eb95f9 100644 --- a/dev/embedded-studio/package.json +++ b/dev/embedded-studio/package.json @@ -1,6 +1,6 @@ { "name": "embedded-studio", - "version": "3.66.1", + "version": "3.67.1", "private": true, "scripts": { "build": "tsc && vite build && sanity manifest extract", @@ -8,17 +8,17 @@ "preview": "vite preview" }, "dependencies": { - "@sanity/ui": "^2.9.1", + "@sanity/ui": "^2.10.9", "react": "^18.3.1", "react-dom": "^18.3.1", "sanity": "workspace:*", "styled-components": "^6.1.0" }, "devDependencies": { - "@types/react": "^18.3.13", - "@types/react-dom": "^18.3.1", + "@types/react": "^18.3.14", + "@types/react-dom": "^18.3.3", "@vitejs/plugin-react": "^4.3.4", "typescript": "5.7.2", - "vite": "^4.5.5" + "vite": "^5.4.11" } } diff --git a/dev/page-building-studio/package.json b/dev/page-building-studio/package.json index 3ca143dfa5c..b018beb29e1 100644 --- a/dev/page-building-studio/package.json +++ b/dev/page-building-studio/package.json @@ -1,6 +1,6 @@ { "name": "sanity-page-building-studio", - "version": "3.66.1", + "version": "3.67.1", "private": true, "license": "MIT", "author": "Sanity.io ", @@ -13,9 +13,9 @@ }, "dependencies": { "@sanity/vision": "workspace:*", - "babel-plugin-react-compiler": "19.0.0-beta-df7b47d-20241124", + "babel-plugin-react-compiler": "19.0.0-beta-37ed2a7-20241206", "react": "^18.2.0", - "react-compiler-runtime": "19.0.0-beta-df7b47d-20241124", + "react-compiler-runtime": "19.0.0-beta-37ed2a7-20241206", "react-dom": "^18.2.0", "react-icons": "^5.2.1", "sanity": "workspace:*", diff --git a/dev/starter-next-studio/package.json b/dev/starter-next-studio/package.json index e53e4721c2c..f65f636ffb2 100644 --- a/dev/starter-next-studio/package.json +++ b/dev/starter-next-studio/package.json @@ -1,6 +1,6 @@ { "name": "sanity-starter-next-studio", - "version": "3.66.1", + "version": "3.67.1", "private": true, "license": "MIT", "author": "Sanity.io ", diff --git a/dev/starter-studio/package.json b/dev/starter-studio/package.json index 1bbe84e9066..675d2dd148f 100644 --- a/dev/starter-studio/package.json +++ b/dev/starter-studio/package.json @@ -1,6 +1,6 @@ { "name": "sanity-starter-studio", - "version": "3.66.1", + "version": "3.67.1", "private": true, "license": "MIT", "author": "Sanity.io ", @@ -12,9 +12,9 @@ "start": "../.bin/sanity start --port 3337" }, "dependencies": { - "babel-plugin-react-compiler": "19.0.0-beta-df7b47d-20241124", + "babel-plugin-react-compiler": "19.0.0-beta-37ed2a7-20241206", "react": "^18.3.1", - "react-compiler-runtime": "19.0.0-beta-df7b47d-20241124", + "react-compiler-runtime": "19.0.0-beta-37ed2a7-20241206", "react-dom": "^18.3.1", "sanity": "workspace:*", "styled-components": "^6.1.0" diff --git a/dev/strict-studio/package.json b/dev/strict-studio/package.json index 6efbc3eb3d4..917a28bfef4 100644 --- a/dev/strict-studio/package.json +++ b/dev/strict-studio/package.json @@ -1,6 +1,6 @@ { "name": "sanity-strict-studio", - "version": "3.66.1", + "version": "3.67.1", "private": true, "license": "MIT", "author": "Sanity.io ", diff --git a/dev/studio-e2e-testing/package.json b/dev/studio-e2e-testing/package.json index f74bcb00c60..7d0072b6c80 100644 --- a/dev/studio-e2e-testing/package.json +++ b/dev/studio-e2e-testing/package.json @@ -1,6 +1,6 @@ { "name": "studio-e2e-testing", - "version": "3.66.1", + "version": "3.67.1", "private": true, "keywords": [ "sanity" @@ -15,15 +15,17 @@ "start": "sanity preview --port 3339" }, "dependencies": { + "@sanity/color-input": "^4.0.1", "@sanity/google-maps-input": "^4.0.0", - "@sanity/icons": "^3.5.0", - "@sanity/ui": "^2.9.1", - "@sanity/vision": "3.66.1", - "babel-plugin-react-compiler": "19.0.0-beta-df7b47d-20241124", + "@sanity/icons": "^3.5.2", + "@sanity/ui": "^2.10.9", + "@sanity/vision": "3.67.1", + "babel-plugin-react-compiler": "19.0.0-beta-37ed2a7-20241206", "react": "^18.3.1", - "react-compiler-runtime": "19.0.0-beta-df7b47d-20241124", + "react-compiler-runtime": "19.0.0-beta-37ed2a7-20241206", "react-dom": "^18.3.1", "sanity": "workspace:*", + "sanity-plugin-markdown": "^5.0.0", "sanity-plugin-media": "^2.3.1", "sanity-plugin-mux-input": "^2.2.1", "sanity-test-studio": "workspace:*", diff --git a/dev/studio-e2e-testing/sanity.config.ts b/dev/studio-e2e-testing/sanity.config.ts index 5a9c830981f..58f20ebbb03 100644 --- a/dev/studio-e2e-testing/sanity.config.ts +++ b/dev/studio-e2e-testing/sanity.config.ts @@ -1,8 +1,10 @@ +import {colorInput} from '@sanity/color-input' import {googleMapsInput} from '@sanity/google-maps-input' import {BookIcon} from '@sanity/icons' import {visionTool} from '@sanity/vision' import {defineConfig} from 'sanity' import {structureTool} from 'sanity/structure' +import {markdownSchema} from 'sanity-plugin-markdown' import {media} from 'sanity-plugin-media' import {muxInput} from 'sanity-plugin-mux-input' import {imageAssetSource} from 'sanity-test-studio/assetSources' @@ -87,12 +89,14 @@ export default defineConfig({ lng: -74.1180863, }, }), + colorInput(), visionTool({ defaultApiVersion: '2022-08-08', }), // eslint-disable-next-line camelcase muxInput({mp4_support: 'standard'}), media(), + markdownSchema(), ], beta: { treeArrayEditing: { diff --git a/dev/test-create-integration-studio/package.json b/dev/test-create-integration-studio/package.json index 806866684ba..18f3ff34eef 100644 --- a/dev/test-create-integration-studio/package.json +++ b/dev/test-create-integration-studio/package.json @@ -1,6 +1,6 @@ { "name": "test-create-integration-studio", - "version": "3.66.1", + "version": "3.67.1", "private": true, "license": "MIT", "author": "Sanity.io ", diff --git a/dev/test-create-integration-studio/sanity.config.ts b/dev/test-create-integration-studio/sanity.config.ts index 146861de727..1731cef7e21 100644 --- a/dev/test-create-integration-studio/sanity.config.ts +++ b/dev/test-create-integration-studio/sanity.config.ts @@ -5,18 +5,51 @@ import {structureTool} from 'sanity/structure' import {schemaTypes} from './schema' -export default defineConfig({ +const baseConfig = defineConfig({ plugins: [structureTool(), codeInput()], - title: 'Strict', - name: 'default', projectId: 'ppsg7ml5', dataset: 'test', schema: {types: schemaTypes}, +}) - beta: { - create: { - startInCreateEnabled: true, - fallbackStudioOrigin: 'create-integration-test.sanity.studio', +export default defineConfig([ + { + ...baseConfig, + title: 'Fallback origin', + name: 'fallback', + basePath: '/fallback', + beta: { + create: { + fallbackStudioOrigin: 'create-integration-test.sanity.studio', + }, }, }, -}) + { + ...baseConfig, + title: 'No fallback origin', + name: 'no-fallback', + basePath: '/no-fallback', + }, + { + ...baseConfig, + title: 'Invalid fallback origin', + name: 'invalid-fallback', + basePath: '/invalid-fallback', + beta: { + create: { + fallbackStudioOrigin: 'does-not-exist', + }, + }, + }, + { + ...baseConfig, + title: 'Opt out', + name: 'opt-out', + basePath: '/opt-out', + beta: { + create: { + startInCreateEnabled: false, + }, + }, + }, +]) diff --git a/dev/test-create-integration-studio/schema.ts b/dev/test-create-integration-studio/schema.ts index b5bb34ee379..b1a5c8140d8 100644 --- a/dev/test-create-integration-studio/schema.ts +++ b/dev/test-create-integration-studio/schema.ts @@ -24,6 +24,30 @@ export const schemaTypes = [ sanityCreate: {exclude: true}, }, }), + defineType({ + type: 'document', + name: 'has-initial-values', + fields: [ + defineField({ + name: 'title', + title: 'Documents with initial values are disabled for Create', + type: 'string', + initialValue: () => + new Promise((resolve) => { + setTimeout(() => { + resolve('Delayed initial value') + }, 5000) + }), + }), + defineField({ + name: 'description', + title: + 'When any value resolves, the Start in Create button disappears. This is not perfect, but "good enough" for now.', + type: 'string', + initialValue: 'Initial value', + }), + ], + }), defineType({ title: 'Documentation Article', name: 'create-test-article', @@ -40,7 +64,7 @@ export const schemaTypes = [ }), defineField({ name: 'description', - title: 'Description', + title: 'Description – with initial value – Create excluded', type: 'text', rows: 3, description: 'Lede and page summary.', diff --git a/dev/test-next-studio/package.json b/dev/test-next-studio/package.json index f5eddf7f0e5..9f3ec2c327f 100644 --- a/dev/test-next-studio/package.json +++ b/dev/test-next-studio/package.json @@ -1,6 +1,6 @@ { "name": "sanity-test-next-studio", - "version": "3.66.1", + "version": "3.67.1", "private": true, "license": "MIT", "author": "Sanity.io ", @@ -12,8 +12,8 @@ }, "dependencies": { "@sanity/vision": "workspace:*", - "babel-plugin-react-compiler": "19.0.0-beta-df7b47d-20241124", - "next": "15.0.3", + "babel-plugin-react-compiler": "19.0.0-beta-37ed2a7-20241206", + "next": "15.0.4", "react": "rc", "react-dom": "rc", "react-is": "rc", diff --git a/dev/test-studio/package.json b/dev/test-studio/package.json index 68d792d2b9e..b1c7d0987a0 100644 --- a/dev/test-studio/package.json +++ b/dev/test-studio/package.json @@ -1,6 +1,6 @@ { "name": "sanity-test-studio", - "version": "3.66.1", + "version": "3.67.1", "private": true, "license": "MIT", "author": "Sanity.io ", @@ -16,14 +16,15 @@ "workshop:dev": "node -r esbuild-register scripts/workshop/dev.ts" }, "dependencies": { - "@portabletext/editor": "^1.13.0", + "@portabletext/editor": "^1.15.3", "@portabletext/react": "^3.0.0", "@sanity/assist": "^3.0.2", - "@sanity/block-tools": "3.66.1", + "@sanity/block-tools": "3.67.1", "@sanity/client": "^6.24.1", "@sanity/color": "^3.0.0", + "@sanity/color-input": "^4.0.1", "@sanity/google-maps-input": "^4.0.0", - "@sanity/icons": "^3.5.0", + "@sanity/icons": "^3.5.2", "@sanity/image-url": "^1.0.2", "@sanity/locale-ko-kr": "^1.0.1", "@sanity/locale-nb-no": "^1.0.1", @@ -34,37 +35,38 @@ "@sanity/migrate": "workspace:*", "@sanity/preview-url-secret": "^2.0.0", "@sanity/react-loader": "^1.10.27", - "@sanity/tsdoc": "1.0.142", + "@sanity/tsdoc": "1.0.150", "@sanity/types": "workspace:*", - "@sanity/ui": "^2.9.1", + "@sanity/ui": "^2.10.9", "@sanity/ui-workshop": "^1.0.0", "@sanity/util": "workspace:*", "@sanity/uuid": "^3.0.1", "@sanity/vision": "workspace:*", - "@sanity/visual-editing": "2.10.4", + "@sanity/visual-editing": "2.10.6", "@turf/helpers": "^6.0.1", "@turf/points-within-polygon": "^5.1.5", "@vercel/stega": "0.1.2", "chokidar": "^3.5.3", - "globby": "^10.0.0", + "globby": "^11.1.0", "history": "^5.3.0", "lodash": "^4.17.21", "qs": "^6.10.2", "react": "^18.3.1", - "react-compiler-runtime": "19.0.0-beta-df7b47d-20241124", + "react-compiler-runtime": "19.0.0-beta-37ed2a7-20241206", "react-dom": "^18.3.1", "react-refractor": "^2.1.6", "refractor": "^3.6.0", "rxjs": "^7.8.0", "sanity": "workspace:*", "sanity-plugin-hotspot-array": "^2.0.0", + "sanity-plugin-markdown": "^5.0.0", "sanity-plugin-media": "^2.3.1", "sanity-plugin-mux-input": "^2.2.1", "styled-components": "^6.1.11" }, "devDependencies": { - "babel-plugin-react-compiler": "19.0.0-beta-df7b47d-20241124", + "babel-plugin-react-compiler": "19.0.0-beta-37ed2a7-20241206", "chokidar": "^3.6.0", - "vite": "^4.5.5" + "vite": "^5.4.11" } } diff --git a/dev/test-studio/sanity.config.ts b/dev/test-studio/sanity.config.ts index 694d11d5f24..6c4559ed9d7 100644 --- a/dev/test-studio/sanity.config.ts +++ b/dev/test-studio/sanity.config.ts @@ -1,4 +1,5 @@ import {assist} from '@sanity/assist' +import {colorInput} from '@sanity/color-input' import {googleMapsInput} from '@sanity/google-maps-input' import {BookIcon} from '@sanity/icons' import {koKRLocale} from '@sanity/locale-ko-kr' @@ -14,6 +15,7 @@ import {defineConfig, definePlugin, type WorkspaceOptions} from 'sanity' import {presentationTool} from 'sanity/presentation' import {structureTool} from 'sanity/structure' import {imageHotspotArrayPlugin} from 'sanity-plugin-hotspot-array' +import {markdownSchema} from 'sanity-plugin-markdown' import {media} from 'sanity-plugin-media' import {muxInput} from 'sanity-plugin-mux-input' @@ -76,7 +78,9 @@ const sharedSettings = definePlugin({ enabled: true, }, }, - + search: { + strategy: 'groq2024', + }, document: { actions: documentActions, inspectors: (prev, ctx) => { @@ -127,6 +131,7 @@ const sharedSettings = definePlugin({ lng: -74.1180863, }, }), + colorInput(), workshopTool({ collections: [ {name: 'sanity', title: 'sanity'}, @@ -144,6 +149,7 @@ const sharedSettings = definePlugin({ errorReportingTestPlugin(), tsdoc(), media(), + markdownSchema(), ], }) diff --git a/dev/test-studio/schema/externalPlugins/markdown.ts b/dev/test-studio/schema/externalPlugins/markdown.ts index f77a8fbec88..10df9867d38 100644 --- a/dev/test-studio/schema/externalPlugins/markdown.ts +++ b/dev/test-studio/schema/externalPlugins/markdown.ts @@ -10,10 +10,10 @@ export default defineType({ name: 'title', title: 'Title', }, - // { - // type: 'markdown', - // name: 'markdown', - // title: 'Markdown', - // }, + { + type: 'markdown', + name: 'markdown', + title: 'Markdown', + }, ], }) diff --git a/dev/test-studio/schema/plugins/color.tsx b/dev/test-studio/schema/plugins/color.tsx index 69f6109cdbd..9d72f9ac838 100644 --- a/dev/test-studio/schema/plugins/color.tsx +++ b/dev/test-studio/schema/plugins/color.tsx @@ -50,69 +50,87 @@ export default defineType({ title: 'Title', type: 'string', }, - // { - // name: 'testColor1', - // title: 'Color to be used in preview', - // description: 'A color input', - // type: 'color', - // }, - // { - // name: 'testColor2', - // title: 'Color with no alpha', - // description: 'A color input with no alpha', - // type: 'color', - // options: { - // disableAlpha: true, - // }, - // }, - // { - // name: 'colorList', - // title: 'List of colors', - // description: 'An array of colors with the built in color preview', - // type: 'array', - // of: [ - // { - // type: 'color', - // }, - // ], - // }, - // { - // name: 'readOnlyColor', - // title: 'Read-only color', - // description: 'Color input in readOnly mode', - // readOnly: true, - // type: 'color', - // }, - // { - // name: 'colorGrid', - // title: 'Grid of colors', - // description: 'An grid of colors with the built in color preview', - // type: 'array', - // options: { - // layout: 'grid', - // }, - // of: [ - // { - // type: 'color', - // }, - // ], - // }, - // { - // name: 'objectWithObjectWithColors', - // title: 'Object with object with colors', - // type: 'object', - // fields: [ - // { - // name: 'objectWithColors', - // title: 'Object with colors', - // type: 'object', - // fields: [ - // {name: 'primaryColor', title: 'Primary color', type: 'color'}, - // {name: 'secondaryColor', title: 'Secondary color', type: 'color'}, - // {name: 'extraColor', title: 'Extra color', type: 'color'}, - // ], - // }, - // ], - // }, + { + name: 'testColor1', + title: 'Color to be used in preview', + description: 'A color input', + type: 'color', + }, + { + name: 'testColor2', + title: 'Color with no alpha', + description: 'A color input with no alpha', + type: 'color', + options: { + disableAlpha: true, + }, + }, + { + name: 'testColor3', + title: 'Color with presets', + description: 'A color input with a list of preset colors', + type: 'color', + options: { + colorList: [ + '#FF6900', + {hex: '#FCB900'}, + {r: 123, g: 220, b: 181}, + {r: 0, g: 208, b: 132, a: 0.5}, + {h: 203, s: 95, l: 77, a: 1}, + {h: 202, s: 95, l: 46, a: 0.5}, + {h: 345, s: 43, v: 97}, + {h: 344, s: 91, v: 92, a: 0.5}, + ], + }, + }, + { + name: 'colorList', + title: 'List of colors', + description: 'An array of colors with the built in color preview', + type: 'array', + of: [ + { + type: 'color', + }, + ], + }, + { + name: 'readOnlyColor', + title: 'Read-only color', + description: 'Color input in readOnly mode', + readOnly: true, + type: 'color', + }, + { + name: 'colorGrid', + title: 'Grid of colors', + description: 'An grid of colors with the built in color preview', + type: 'array', + options: { + layout: 'grid', + }, + of: [ + { + type: 'color', + }, + ], + }, + { + name: 'objectWithObjectWithColors', + title: 'Object with object with colors', + type: 'object', + fields: [ + { + name: 'objectWithColors', + title: 'Object with colors', + type: 'object', + fields: [ + {name: 'primaryColor', title: 'Primary color', type: 'color'}, + {name: 'secondaryColor', title: 'Secondary color', type: 'color'}, + {name: 'extraColor', title: 'Extra color', type: 'color'}, + ], + }, + ], + }, ], }) diff --git a/examples/blog-studio/package.json b/examples/blog-studio/package.json index a25e6e838f7..46c5dc92c66 100644 --- a/examples/blog-studio/package.json +++ b/examples/blog-studio/package.json @@ -1,6 +1,6 @@ { "name": "blog-studio", - "version": "3.66.1", + "version": "3.67.1", "private": true, "description": "Content studio running with schema from the blog init template", "keywords": [ diff --git a/examples/clean-studio/package.json b/examples/clean-studio/package.json index 3fb746a88ef..6e77add793a 100644 --- a/examples/clean-studio/package.json +++ b/examples/clean-studio/package.json @@ -1,6 +1,6 @@ { "name": "clean-studio", - "version": "3.66.1", + "version": "3.67.1", "private": true, "description": "Content studio running with schema from the clean template", "keywords": [ diff --git a/examples/ecommerce-studio/package.json b/examples/ecommerce-studio/package.json index 0efa590b9e4..c1cea776bd7 100644 --- a/examples/ecommerce-studio/package.json +++ b/examples/ecommerce-studio/package.json @@ -1,6 +1,6 @@ { "name": "ecommerce-studio", - "version": "3.66.1", + "version": "3.67.1", "private": true, "description": "", "keywords": [ @@ -29,8 +29,8 @@ "start": "sanity dev --port 3337" }, "dependencies": { - "@sanity/cli": "3.66.1", - "@sanity/ui": "^2.9.1", + "@sanity/cli": "3.67.1", + "@sanity/ui": "^2.10.9", "react": "^18.3.1", "react-barcode": "^1.4.1", "react-dom": "^18.3.1", diff --git a/examples/movies-studio/package.json b/examples/movies-studio/package.json index 1b4031d18a6..1931c0d2a49 100644 --- a/examples/movies-studio/package.json +++ b/examples/movies-studio/package.json @@ -1,6 +1,6 @@ { "name": "movies-studio", - "version": "3.66.1", + "version": "3.67.1", "private": true, "description": "Content studio running with schema from the moviedb init template", "keywords": [ diff --git a/lerna.json b/lerna.json index e1d95cc4ed2..df78b0f9bbb 100644 --- a/lerna.json +++ b/lerna.json @@ -12,5 +12,5 @@ "packages/groq", "packages/sanity" ], - "version": "3.66.1" + "version": "3.67.1" } diff --git a/package.json b/package.json index 3128c4cff47..6552b43b26a 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "dev:starter-studio": "pnpm --filter sanity-starter-studio dev", "dev:strict-studio": "pnpm --filter sanity-strict-studio dev", "dev:test-studio": "pnpm --filter sanity-test-studio dev", + "dev:test-create-studio": "pnpm --filter test-create-integration-studio dev", "dev:test-studio-production-profiling": "REACT_PRODUCTION_PROFILING=true turbo run start --filter=sanity-test-studio", "dev:next-studio": "pnpm --filter sanity-test-next-studio dev", "dev:turbo-studio": "pnpm dev:next-studio --turbo", @@ -101,7 +102,7 @@ "prettier": "@sanity/prettier-config", "devDependencies": { "@google-cloud/storage": "^7.11.0", - "@playwright/test": "1.44.1", + "@playwright/test": "1.49.1", "@repo/dev-aliases": "workspace:*", "@repo/package.config": "workspace:*", "@repo/test-config": "workspace:*", @@ -110,11 +111,11 @@ "@sanity/eslint-config-i18n": "1.0.0", "@sanity/eslint-config-studio": "^4.0.0", "@sanity/mutate": "^0.11.1", - "@sanity/pkg-utils": "6.11.14", + "@sanity/pkg-utils": "6.12.0", "@sanity/prettier-config": "^1.0.3", "@sanity/test": "0.0.1-alpha.1", - "@sanity/tsdoc": "1.0.142", - "@sanity/ui": "^2.9.1", + "@sanity/tsdoc": "1.0.150", + "@sanity/ui": "^2.10.9", "@sanity/uuid": "^3.0.2", "@types/glob": "^7.2.0", "@types/lodash": "^4.17.7", @@ -124,7 +125,7 @@ "@types/yargs": "^17.0.7", "@typescript-eslint/eslint-plugin": "^7.18.0", "@typescript-eslint/parser": "^7.18.0", - "@vitejs/plugin-react": "^4.3.3", + "@vitejs/plugin-react": "^4.3.4", "cac": "^6.7.12", "chalk": "^4.1.2", "depcheck": "^1.4.7", @@ -141,15 +142,15 @@ "eslint-plugin-import": "^2.30.0", "eslint-plugin-prettier": "^5.2.1", "eslint-plugin-react": "^7.36.1", - "eslint-plugin-react-compiler": "19.0.0-beta-df7b47d-20241124", + "eslint-plugin-react-compiler": "19.0.0-beta-37ed2a7-20241206", "eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-simple-import-sort": "^12.1.1", "eslint-plugin-tsdoc": "^0.3.0", "eslint-plugin-unicorn": "^52.0.0", "eslint-plugin-unused-imports": "^3.2.0", "execa": "^2.0.0", - "glob": "^7.2.0", - "globby": "^10.0.0", + "glob": "^11.0.0", + "globby": "^11.1.0", "husky": "^9.0.11", "js-yaml": "^4.1.0", "lerna": "^8.1.9", @@ -160,13 +161,13 @@ "ora": "^8.0.1", "prettier": "^3.3.3", "read-package-up": "^11.0.0", - "rimraf": "^3.0.2", + "rimraf": "^5.0.10", "rxjs": "^7.8.1", "sanity": "workspace:*", "semver": "^7.3.5", "turbo": "^2.3.0", "typescript": "5.7.2", - "vite": "^4.5.3", + "vite": "^5.4.11", "vite-tsconfig-paths": "^4.3.2", "vitest": "^2.1.1", "yargs": "^17.3.0" diff --git a/packages/@repo/dev-aliases/package.json b/packages/@repo/dev-aliases/package.json index a1f53f6b483..408c9293f85 100644 --- a/packages/@repo/dev-aliases/package.json +++ b/packages/@repo/dev-aliases/package.json @@ -1,6 +1,6 @@ { "name": "@repo/dev-aliases", - "version": "3.66.1", + "version": "3.67.1", "private": true, "description": "Dev aliases for the sanity monorepo", "type": "module", diff --git a/packages/@repo/package.bundle/package.json b/packages/@repo/package.bundle/package.json index 9b87c1318cd..a8a8b883387 100644 --- a/packages/@repo/package.bundle/package.json +++ b/packages/@repo/package.bundle/package.json @@ -1,6 +1,6 @@ { "name": "@repo/package.bundle", - "version": "3.66.1", + "version": "3.67.1", "private": true, "description": "Shared package bundle configuration", "main": "./src/package.bundle.ts", diff --git a/packages/@repo/package.config/package.json b/packages/@repo/package.config/package.json index 929bb455ca1..07d9e2c62b0 100644 --- a/packages/@repo/package.config/package.json +++ b/packages/@repo/package.config/package.json @@ -1,6 +1,6 @@ { "name": "@repo/package.config", - "version": "3.66.1", + "version": "3.67.1", "private": true, "description": "Shared @sanity/pkg-utils configuration", "main": "./src/package.config.ts", diff --git a/packages/@repo/test-config/package.json b/packages/@repo/test-config/package.json index b7d77671fac..f9ce1de02c2 100644 --- a/packages/@repo/test-config/package.json +++ b/packages/@repo/test-config/package.json @@ -1,6 +1,6 @@ { "name": "@repo/test-config", - "version": "3.66.1", + "version": "3.67.1", "private": true, "description": "Test (as in unit test) config shared across packages in the sanity monorepo", "type": "module", diff --git a/packages/@repo/test-exports/package.json b/packages/@repo/test-exports/package.json index 6e4ba8e7e9f..bb60638debd 100644 --- a/packages/@repo/test-exports/package.json +++ b/packages/@repo/test-exports/package.json @@ -1,6 +1,6 @@ { "name": "@repo/test-exports", - "version": "3.66.1", + "version": "3.67.1", "private": true, "description": "Ensures that all the monorepo packages that are published works in native node ESM and CJS runtimes", "exports": { diff --git a/packages/@repo/tsconfig/package.json b/packages/@repo/tsconfig/package.json index 783f909263b..236524b4ada 100644 --- a/packages/@repo/tsconfig/package.json +++ b/packages/@repo/tsconfig/package.json @@ -1,5 +1,5 @@ { "name": "@repo/tsconfig", - "version": "3.66.1", + "version": "3.67.1", "private": true } diff --git a/packages/@sanity/block-tools/package.json b/packages/@sanity/block-tools/package.json index b242be56e10..779a6b725d2 100644 --- a/packages/@sanity/block-tools/package.json +++ b/packages/@sanity/block-tools/package.json @@ -1,6 +1,6 @@ { "name": "@sanity/block-tools", - "version": "3.66.1", + "version": "3.67.1", "description": "Can format HTML, Slate JSON or Sanity block array into any other format.", "keywords": [ "sanity", @@ -49,7 +49,7 @@ "watch": "pkg-utils watch" }, "dependencies": { - "@sanity/types": "3.66.1", + "@sanity/types": "3.67.1", "@types/react": "^18.3.5", "get-random-values-esm": "1.0.2", "lodash": "^4.17.21" @@ -57,7 +57,7 @@ "devDependencies": { "@repo/package.config": "workspace:*", "@repo/test-config": "workspace:*", - "@sanity/schema": "3.66.1", + "@sanity/schema": "3.67.1", "@types/jsdom": "^20.0.0", "@types/lodash": "^4.17.7", "@vercel/stega": "0.1.2", diff --git a/packages/@sanity/cli/package.config.ts b/packages/@sanity/cli/package.config.ts index 37812df9b61..633b99a7fdd 100644 --- a/packages/@sanity/cli/package.config.ts +++ b/packages/@sanity/cli/package.config.ts @@ -1,11 +1,11 @@ /* eslint-disable no-sync */ import fs from 'node:fs' +import {isBuiltin} from 'node:module' import path from 'node:path' import baseConfig from '@repo/package.config' import {nodeResolve} from '@rollup/plugin-node-resolve' import {defineConfig} from '@sanity/pkg-utils' -import isBuiltin from 'is-builtin-module' const workersDir = path.join(__dirname, 'src', 'workers') @@ -17,13 +17,6 @@ const workerNames = fs export default defineConfig({ ...baseConfig, - // This is a workaround for an issue where the `readable-stream` package imports - // from `string_decoder/` instead of `string_decoder` (note the trailing slash), - // which _should_ tell rollup not to use the built-in `string_decoder` module, - // which it unfortunately does not. Hoping we can get rid of this hack soon: - // https://github.com/rollup/plugins/issues/1211 - // https://github.com/sindresorhus/is-builtin-module/issues/7 - // https://github.com/sindresorhus/builtin-modules/pull/17 rollup: { plugins: (plugins) => [ ...plugins.filter((plugin) => plugin.name !== 'node-resolve'), @@ -31,7 +24,7 @@ export default defineConfig({ browser: false, extensions: ['.cjs', '.mjs', '.js', '.jsx', '.json', '.node'], preferBuiltins: false, - resolveOnly: (moduleName) => moduleName === 'string_decoder' || !isBuiltin(moduleName), + resolveOnly: (moduleName) => !isBuiltin(moduleName), }), ], }, diff --git a/packages/@sanity/cli/package.json b/packages/@sanity/cli/package.json index fa7f19ccd97..0c7c284edfb 100644 --- a/packages/@sanity/cli/package.json +++ b/packages/@sanity/cli/package.json @@ -1,6 +1,6 @@ { "name": "@sanity/cli", - "version": "3.66.1", + "version": "3.67.1", "description": "Sanity CLI tool for managing Sanity installations, managing plugins, schemas and datasets", "keywords": [ "sanity", @@ -58,16 +58,16 @@ "dependencies": { "@babel/traverse": "^7.23.5", "@sanity/client": "^6.24.1", - "@sanity/codegen": "3.66.1", + "@sanity/codegen": "3.67.1", "@sanity/telemetry": "^0.7.7", - "@sanity/util": "3.66.1", + "@sanity/util": "3.67.1", "chalk": "^4.1.2", "debug": "^4.3.4", "decompress": "^4.2.0", "esbuild": "0.21.5", "esbuild-register": "^3.5.0", "get-it": "^8.6.5", - "groq-js": "^1.14.1", + "groq-js": "^1.14.2", "pkg-dir": "^5.0.0", "prettier": "^3.3.0", "semver": "^7.3.5", @@ -92,7 +92,6 @@ "@types/lodash": "^4.17.7", "@types/minimist": "^1.2.5", "@types/node": "^22.10.0", - "@types/rimraf": "^3.0.2", "@types/semver": "^7.5.6", "@types/semver-compare": "^1.0.1", "@types/tar": "^6.1.3", @@ -111,7 +110,6 @@ "get-latest-version": "^5.0.0", "git-user-info": "^2.0.3", "inquirer": "^6.0.0", - "is-builtin-module": "^3.2.0", "is-installed-globally": "^0.4.0", "leven": "^3.1.0", "lodash": "^4.17.21", @@ -124,11 +122,11 @@ "promise-props-recursive": "^2.0.2", "recast": "^0.23.9", "resolve-from": "^5.0.0", - "rimraf": "^3.0.2", + "rimraf": "^5.0.10", "semver": "^7.3.5", "semver-compare": "^1.0.0", "tar": "^6.1.11", - "vite": "^4.5.3", + "vite": "^5.4.11", "vitest": "^2.1.1", "which": "^2.0.2", "xdg-basedir": "^4.0.0" diff --git a/packages/@sanity/cli/src/actions/init-project/bootstrapLocalTemplate.ts b/packages/@sanity/cli/src/actions/init-project/bootstrapLocalTemplate.ts index 1029ef80d63..a635d5c792d 100644 --- a/packages/@sanity/cli/src/actions/init-project/bootstrapLocalTemplate.ts +++ b/packages/@sanity/cli/src/actions/init-project/bootstrapLocalTemplate.ts @@ -138,8 +138,8 @@ export async function bootstrapLocalTemplate( writeFileIfNotExists(`sanity.cli.${codeExt}`, cliConfig), writeFileIfNotExists('package.json', packageManifest), writeFileIfNotExists( - '.eslintrc', - `${JSON.stringify({extends: '@sanity/eslint-config-studio'}, null, 2)}\n`, + 'eslint.config.mjs', + `import studio from '@sanity/eslint-config-studio'\n\nexport default [...studio]\n`, ), ]) diff --git a/packages/@sanity/cli/src/actions/init-project/bootstrapRemoteTemplate.ts b/packages/@sanity/cli/src/actions/init-project/bootstrapRemoteTemplate.ts index efa32999057..7eca8f489ca 100644 --- a/packages/@sanity/cli/src/actions/init-project/bootstrapRemoteTemplate.ts +++ b/packages/@sanity/cli/src/actions/init-project/bootstrapRemoteTemplate.ts @@ -1,6 +1,9 @@ import {mkdir} from 'node:fs/promises' import {join} from 'node:path' +import {type Framework, frameworks} from '@vercel/frameworks' +import {detectFrameworkRecord, LocalFileSystemDetector} from '@vercel/fs-detectors' + import {debug} from '../../debug' import {type CliCommandContext} from '../../types' import { @@ -9,7 +12,6 @@ import { downloadAndExtractRepo, generateSanityApiReadToken, getMonoRepo, - isNextJsTemplate, type RepoInfo, tryApplyPackageName, validateRemoteTemplate, @@ -56,12 +58,16 @@ export async function bootstrapRemoteTemplate( const readToken = needsReadToken ? await generateSanityApiReadToken('API Read Token', variables.projectId, apiClient) : undefined - const isNext = await isNextJsTemplate(outputPath) - const envName = isNext ? '.env.local' : '.env' - for (const folder of packages ?? ['']) { - const path = join(outputPath, folder) - await applyEnvVariables(path, {...variables, readToken}, envName) + for (const pkg of packages ?? ['']) { + const packagePath = join(outputPath, pkg) + const packageFramework: Framework | null = await detectFrameworkRecord({ + fs: new LocalFileSystemDetector(packagePath), + frameworkList: frameworks as readonly Framework[], + }) + // Next.js uses `.env.local` for local environment variables + const envName = packageFramework?.slug === 'nextjs' ? '.env.local' : '.env' + await applyEnvVariables(packagePath, {...variables, readToken}, envName) } debug('Setting package name to %s', packageName) diff --git a/packages/@sanity/cli/src/actions/init-project/git.ts b/packages/@sanity/cli/src/actions/init-project/git.ts index 6c8093f23fe..a48928099b9 100644 --- a/packages/@sanity/cli/src/actions/init-project/git.ts +++ b/packages/@sanity/cli/src/actions/init-project/git.ts @@ -1,7 +1,7 @@ import {execFileSync, execSync, type ExecSyncOptions} from 'node:child_process' import path from 'node:path' -import rimraf from 'rimraf' +import {rimrafSync} from 'rimraf' const defaultCommitMessage = 'feat: bootstrap sanity studio' @@ -29,7 +29,7 @@ export function tryGitInit(rootDir: string, commitMessage?: string): boolean { } catch (e) { if (didInit) { try { - rimraf.sync(path.join(rootDir, '.git')) + rimrafSync(path.join(rootDir, '.git')) } catch (_) { // intentional noop } diff --git a/packages/@sanity/cli/src/actions/init-project/initProject.ts b/packages/@sanity/cli/src/actions/init-project/initProject.ts index 0b4bbb3ca09..4a5324c882f 100644 --- a/packages/@sanity/cli/src/actions/init-project/initProject.ts +++ b/packages/@sanity/cli/src/actions/init-project/initProject.ts @@ -12,7 +12,6 @@ import pFilter from 'p-filter' import resolveFrom from 'resolve-from' import semver from 'semver' import {evaluate, patch} from 'silver-fleece' -import which from 'which' import {CLIInitStepCompleted} from '../../__telemetry__/init.telemetry' import {type InitFlags} from '../../commands/init/initCommand' @@ -121,7 +120,8 @@ export default async function initSanity( const cliFlags = args.extOptions const unattended = cliFlags.y || cliFlags.yes const print = unattended ? noop : output.print - const warn = (msg: string) => output.warn(chalk.yellow.bgBlack(msg)) + const success = output.success + const warn = output.warn const intendedPlan = cliFlags['project-plan'] const intendedCoupon = cliFlags.coupon @@ -258,25 +258,17 @@ export default async function initSanity( if (hasToken) { trace.log({step: 'login', alreadyLoggedIn: true}) const user = await getUserData(apiClient) - print('') - print( - `${chalk.gray(" 👤 You're logged in as %s using %s")}`, - user.name, - getProviderName(user.provider), - ) - print('') + success('You are logged in as %s using %s', user.email, getProviderName(user.provider)) } else if (!unattended) { trace.log({step: 'login'}) await getOrCreateUser() } - let introMessage = "Let's get you started with a new project" + let introMessage = 'Fetching existing projects' if (cliFlags.quickstart) { - introMessage = "Let's get you started with remote Sanity project" - } else if (remoteTemplateInfo) { - introMessage = "Let's get you started with a remote Sanity template" + introMessage = "Eject your existing project's Sanity configuration" } - print(` ➡️ ${chalk.gray(introMessage)}`) + success(introMessage) print('') const flags = await prepareFlags() @@ -289,7 +281,8 @@ export default async function initSanity( // If user doesn't want to output any template code if (bareOutput) { - print(`\n${chalk.green('Success!')} Below are your project details:\n`) + success('Below are your project details') + print('') print(`Project ID: ${chalk.cyan(projectId)}`) print(`Dataset: ${chalk.cyan(datasetName)}`) print( @@ -659,13 +652,11 @@ export default async function initSanity( context, }) - if (await hasGlobalCli()) { - print('') - print('If you want to delete the imported data, use') - print(` ${chalk.cyan(`sanity dataset delete ${datasetName}`)}`) - print('and create a new clean dataset with') - print(` ${chalk.cyan(`sanity dataset create `)}\n`) - } + print('') + print('If you want to delete the imported data, use') + print(` ${chalk.cyan(`npx sanity dataset delete ${datasetName}`)}`) + print('and create a new clean dataset with') + print(` ${chalk.cyan(`npx sanity dataset create `)}\n`) } const devCommandMap: Record = { @@ -687,12 +678,10 @@ export default async function initSanity( print(`Then: ${chalk.cyan(devCommand)} - to run Sanity Studio\n`) } - if (await hasGlobalCli()) { - print(`Other helpful commands`) - print(`sanity docs - to open the documentation in a browser`) - print(`sanity manage - to open the project settings in a browser`) - print(`sanity help - to explore the CLI manual`) - } + print(`Other helpful commands`) + print(`npx sanity docs - to open the documentation in a browser`) + print(`npx sanity manage - to open the project settings in a browser`) + print(`npx sanity help - to explore the CLI manual`) const sendInvite = isFirstProject && @@ -717,16 +706,13 @@ export default async function initSanity( trace.complete() async function getOrCreateUser() { - print(`We can't find any auth credentials in your Sanity config`) - print('- log in or create a new account\n') + warn('No authentication credentials found in your Sanity config') + print('') // Provide login options (`sanity login`) const {extOptions, ...otherArgs} = args const loginArgs: CliCommandArguments = {...otherArgs, extOptions: {}} await login(loginArgs, {...context, telemetry: trace.newContext('login')}) - - print("Good stuff, you're now authenticated. You'll need a project to keep your") - print('datasets and collaborators safe and snug.') } async function getProjectDetails(): Promise<{ @@ -880,7 +866,7 @@ export default async function initSanity( })) const selected = await prompt.single({ - message: 'Select project to use', + message: 'Create a new project or select an existing one', type: 'list', choices: [ {value: 'new', name: 'Create new project'}, @@ -1059,20 +1045,20 @@ export default async function initSanity( type: 'list', choices: [ { - value: 'moviedb', - name: 'Movie project (schema + sample data)', - }, - { - value: 'shopify', - name: 'E-commerce (Shopify)', + value: 'clean', + name: 'Clean project with no predefined schema types', }, { value: 'blog', name: 'Blog (schema)', }, { - value: 'clean', - name: 'Clean project with no predefined schema types', + value: 'shopify', + name: 'E-commerce (Shopify)', + }, + { + value: 'moviedb', + name: 'Movie project (schema + sample data)', }, ], }) @@ -1560,12 +1546,3 @@ function getImportCommand( !isCommandGroup(cmd) && cmd.name === 'import' && cmd.group === 'dataset', ) } - -async function hasGlobalCli(): Promise { - try { - const globalCliPath = await which('sanity') - return Boolean(globalCliPath) - } catch (err) { - return false - } -} diff --git a/packages/@sanity/cli/src/actions/login/login.ts b/packages/@sanity/cli/src/actions/login/login.ts index 736bcab7eef..2f194a708a9 100644 --- a/packages/@sanity/cli/src/actions/login/login.ts +++ b/packages/@sanity/cli/src/actions/login/login.ts @@ -2,7 +2,6 @@ import http, {type Server} from 'node:http' import os from 'node:os' import {type SanityClient} from '@sanity/client' -import chalk from 'chalk' import open from 'open' import {debug as debugIt} from '../../debug' @@ -146,7 +145,7 @@ export async function login( }) } - output.print(chalk.green('Login successful')) + output.success('Login successful') trace.complete() } @@ -335,7 +334,7 @@ async function promptProviders( const provider = await prompt.single({ type: 'list', - message: 'Login type', + message: 'Please log in or create a new account', choices: providers.map((choice) => choice.title), }) diff --git a/packages/@sanity/cli/src/commands/logout/logoutCommand.ts b/packages/@sanity/cli/src/commands/logout/logoutCommand.ts index 21bf43ca657..e57b41de177 100644 --- a/packages/@sanity/cli/src/commands/logout/logoutCommand.ts +++ b/packages/@sanity/cli/src/commands/logout/logoutCommand.ts @@ -45,7 +45,7 @@ const logoutCommand: CliCommandDefinition = { // Clear cached telemetry consent cfg.delete(TELEMETRY_CONSENT_CONFIG_KEY) - output.print(chalk.green('Logged out')) + output.success('Logged out') }, } diff --git a/packages/@sanity/cli/src/outputters/cliOutputter.ts b/packages/@sanity/cli/src/outputters/cliOutputter.ts index ad399f909bd..08738f36099 100644 --- a/packages/@sanity/cli/src/outputters/cliOutputter.ts +++ b/packages/@sanity/cli/src/outputters/cliOutputter.ts @@ -2,6 +2,10 @@ import chalk from 'chalk' import ora, {type Options, type Ora} from 'ora' +const SYMBOL_CHECK = chalk.green('✓') +const SYMBOL_WARN = chalk.yellow('⚠') +const SYMBOL_FAIL = chalk.red('✗') + let isFirstClear = true export default { @@ -9,15 +13,19 @@ export default { console.log(...args) }, + success(...args: unknown[]): void { + console.log(`${SYMBOL_CHECK} ${args.join(' ')}`) + }, + warn(...args: unknown[]): void { - console.warn(...args) + console.warn(`${SYMBOL_WARN} ${args.join(' ')}`) }, error(...args: unknown[]): void { if (args[0] instanceof Error) { - console.error(chalk.red(args[0].stack)) + console.error(`${SYMBOL_FAIL} ${chalk.red(args[0].stack)}`) } else { - console.error(...args) + console.error(`${SYMBOL_FAIL} ${args.join(' ')}`) } }, @@ -28,7 +36,12 @@ export default { isFirstClear = false }, - spinner(options: Options | string): Ora { - return ora(options) + spinner(options: Options): Ora { + const spinner = ora({...options, spinner: 'dots'}) + // Override the default status methods to use custom symbols instead of emojis + spinner.succeed = (text?: string) => spinner.stopAndPersist({text, symbol: SYMBOL_CHECK}) + spinner.warn = (text?: string) => spinner.stopAndPersist({text, symbol: SYMBOL_WARN}) + spinner.fail = (text?: string) => spinner.stopAndPersist({text, symbol: SYMBOL_FAIL}) + return spinner }, } diff --git a/packages/@sanity/cli/src/studioDependencies.ts b/packages/@sanity/cli/src/studioDependencies.ts index 0adcfce5c5a..4c37da4e6b8 100644 --- a/packages/@sanity/cli/src/studioDependencies.ts +++ b/packages/@sanity/cli/src/studioDependencies.ts @@ -18,7 +18,7 @@ export const studioDependencies = { '@sanity/eslint-config-studio': 'latest', // When using typescript, we'll want the these types too, so might as well install them '@types/react': '^18.0.25', - 'eslint': '^8.6.0', + 'eslint': '^9.9.0', 'prettier': '^3.0.2', 'typescript': '^5.1.6', // Peer dependency of eslint-config-studio (implicitly) }, diff --git a/packages/@sanity/cli/src/types.ts b/packages/@sanity/cli/src/types.ts index 8c419805f8a..33b2c04f9f9 100644 --- a/packages/@sanity/cli/src/types.ts +++ b/packages/@sanity/cli/src/types.ts @@ -150,6 +150,7 @@ export interface CommandRunnerOptions { export interface CliOutputter { print: (...args: unknown[]) => void + success: (...args: unknown[]) => void warn: (...args: unknown[]) => void error: (...args: unknown[]) => void clear: () => void diff --git a/packages/@sanity/cli/src/util/generateCommandsDocumentation.ts b/packages/@sanity/cli/src/util/generateCommandsDocumentation.ts index 9f9b1665f1d..cd85d59066d 100644 --- a/packages/@sanity/cli/src/util/generateCommandsDocumentation.ts +++ b/packages/@sanity/cli/src/util/generateCommandsDocumentation.ts @@ -22,12 +22,15 @@ export function generateCommandsDocumentation( const prefix = group === 'default' ? '' : ` ${group}` const rows = [ - `usage: sanity${prefix} [--default] [-v|--version] [-d|--debug] [-h|--help] []`, + `usage: npx sanity${prefix} [--default] [-v|--version] [-d|--debug] [-h|--help] []`, '', 'Commands:', ] .concat(commands.map((cmd) => ` ${padEnd(cmd.name, cmdLength + 1)} ${cmd.description}`)) - .concat(['', `See 'sanity help${prefix} ' for specific information on a subcommand.`]) + .concat([ + '', + `See 'npx sanity help${prefix} ' for specific information on a subcommand.`, + ]) return rows.join('\n') } @@ -43,14 +46,14 @@ export function generateCommandDocumentation( if (!command) { throw new Error( subCommand - ? `"${subCommand}" is not a subcommand of "${group}". See 'sanity help ${group}'` + ? `"${subCommand}" is not a subcommand of "${group}". See 'npx sanity help ${group}'` : getNoSuchCommandText(group || command), ) } const cmdParts = [group || command.name, subCommand].filter(Boolean).join(' ') return [ - `usage: sanity ${cmdParts} ${command.signature}`, + `usage: npx sanity ${cmdParts} ${command.signature}`, '', ` ${command.description}`, '', diff --git a/packages/@sanity/cli/src/util/getCliConfig.ts b/packages/@sanity/cli/src/util/getCliConfig.ts index 5a518069f7d..575472a4a08 100644 --- a/packages/@sanity/cli/src/util/getCliConfig.ts +++ b/packages/@sanity/cli/src/util/getCliConfig.ts @@ -42,7 +42,7 @@ export async function getCliConfig( const {unregister} = __DEV__ ? {unregister: () => undefined} - : require('esbuild-register/dist/node').register() + : require('esbuild-register/dist/node').register({supported: {'dynamic-import': true}}) try { const v3Config = getSanityCliConfig(cwd) diff --git a/packages/@sanity/cli/src/util/remoteTemplate.ts b/packages/@sanity/cli/src/util/remoteTemplate.ts index 53e987fccc6..fbfc184e3f8 100644 --- a/packages/@sanity/cli/src/util/remoteTemplate.ts +++ b/packages/@sanity/cli/src/util/remoteTemplate.ts @@ -410,16 +410,6 @@ export async function validateRemoteTemplate( } } -export async function isNextJsTemplate(root: string): Promise { - try { - const packageJson = await readFile(join(root, 'package.json'), 'utf8') - const pkg = JSON.parse(packageJson) - return !!(pkg.dependencies?.next || pkg.devDependencies?.next) - } catch { - return false - } -} - export async function checkNeedsReadToken(root: string): Promise { try { const templatePath = await Promise.any( diff --git a/packages/@sanity/cli/test/dev.test.ts b/packages/@sanity/cli/test/dev.test.ts index f5768883bf4..0db05ea5ee1 100644 --- a/packages/@sanity/cli/test/dev.test.ts +++ b/packages/@sanity/cli/test/dev.test.ts @@ -12,13 +12,19 @@ describeCliTest('CLI: `sanity dev`', () => { describe.each(studioVersions)('%s', (version) => { test('start', async () => { const testRunArgs = getTestRunArgs(version) - const expectedFiles = ['static/favicon.ico', 'favicon.ico', 'static/favicon.svg'] + const basePath = '/config-base-path' + const expectedFiles = [ + '/favicon.ico', + `${basePath}/static/favicon.ico`, + `${basePath}/static/favicon.svg`, + ] const {html: startHtml, fileHashes} = await testServerCommand({ command: 'dev', port: testRunArgs.port, args: ['--port', `${testRunArgs.port}`], cwd: path.join(studiosPath, version), + basePath, expectedTitle: 'Sanity Studio', expectedFiles, }) @@ -29,11 +35,12 @@ describeCliTest('CLI: `sanity dev`', () => { expect(fileHashes.get(file)).not.toBe(null) } - if (fileHashes.has('static/favicon.svg')) { - const faviconHash = createHash('sha256') + // Check that the custom favicon is used if present, not the default one + if (fileHashes.has(`${basePath}/static/favicon.svg`)) { + const customFaviconHash = createHash('sha256') .update(await readFile(path.join(studiosPath, version, 'static', 'favicon.svg'))) .digest('hex') - expect(fileHashes.get('static/favicon.svg')).toBe(faviconHash) + expect(fileHashes.get(`${basePath}/static/favicon.svg`)).toBe(customFaviconHash) } }) @@ -42,6 +49,7 @@ describeCliTest('CLI: `sanity dev`', () => { const {html: startHtml} = await testServerCommand({ command: 'dev', port: testRunArgs.port - 1, + basePath: '/config-base-path', args: ['--port', `${testRunArgs.port - 1}`], cwd: path.join(studiosPath, `${version}-custom-document`), expectedTitle: 'Sanity Studio w/ custom document', @@ -58,6 +66,7 @@ describeCliTest('CLI: `sanity dev`', () => { const {html: startHtml} = await testServerCommand({ command: 'dev', port: testRunArgs.port - 2, + basePath: '/config-base-path', args: ['--port', `${testRunArgs.port - 2}`], env: {SANITY_ACTIVE_ENV: 'production'}, cwd: path.join(studiosPath, `${version}-custom-document`), diff --git a/packages/@sanity/cli/test/preview.test.ts b/packages/@sanity/cli/test/preview.test.ts index 2b276128a97..d6b62919eaf 100644 --- a/packages/@sanity/cli/test/preview.test.ts +++ b/packages/@sanity/cli/test/preview.test.ts @@ -12,6 +12,7 @@ describeCliTest('CLI: `sanity preview`', () => { const {html: previewHtml, stderr} = await testServerCommand({ command: 'preview', args: ['--port', '3330', '../../static'], + basePath: '/', port: 3330, cwd: path.join(studiosPath, 'v3'), expectedTitle: 'Sanity Static', @@ -24,6 +25,7 @@ describeCliTest('CLI: `sanity preview`', () => { const {html: previewHtml, stdout} = await testServerCommand({ command: 'preview', args: ['--port', '3456', '../../static-basepath'], + basePath: '/some-base-path', port: 3456, cwd: path.join(studiosPath, 'v3'), expectedTitle: 'Sanity Static, Base Pathed', @@ -39,6 +41,7 @@ describeCliTest('CLI: `sanity preview`', () => { const {html: previewHtml} = await testServerCommand({ command: 'preview', args: ['--port', '3457', '../../static-root-basepath'], + basePath: '/', port: 3457, cwd: path.join(studiosPath, 'v3'), expectedTitle: 'Sanity Static', @@ -50,6 +53,7 @@ describeCliTest('CLI: `sanity preview`', () => { const {html: previewHtml} = await testServerCommand({ command: 'start', args: ['--port', '3331', '../../static'], + basePath: '/', port: 3331, cwd: path.join(studiosPath, 'v3'), expectedTitle: 'Sanity Static', diff --git a/packages/@sanity/cli/test/shared/devServer.ts b/packages/@sanity/cli/test/shared/devServer.ts index 3237563a278..90e2e1a906b 100644 --- a/packages/@sanity/cli/test/shared/devServer.ts +++ b/packages/@sanity/cli/test/shared/devServer.ts @@ -9,6 +9,7 @@ export async function testServerCommand({ port, cwd, env, + basePath, expectedTitle, expectedFiles = [], args, @@ -16,6 +17,7 @@ export async function testServerCommand({ command: 'preview' | 'dev' | 'start' port: number cwd: string + basePath: string expectedTitle: string expectedFiles?: string[] env?: Record @@ -77,7 +79,7 @@ export async function testServerCommand({ let res: ResponseData try { res = await Promise.race([ - request(`http://localhost:${port}/`), + request(`http://localhost:${port}${basePath.replace(/\/$/, '')}/`), new Promise((_, rejectTimeout) => setTimeout(rejectTimeout, 500, new Error('Timed out trying to connect')), ), @@ -97,7 +99,7 @@ export async function testServerCommand({ for (const file of expectedFiles) { fileHashes.set( file, - await request(`http://localhost:${port}/${file}`) + await request(`http://localhost:${port}${file}`) .then(({body, statusCode}) => statusCode === 200 ? createHash('sha256').update(body).digest('hex') : null, ) diff --git a/packages/@sanity/cli/test/test-template/package.json b/packages/@sanity/cli/test/test-template/package.json index 56373316f3d..7fdbd0c9c4b 100644 --- a/packages/@sanity/cli/test/test-template/package.json +++ b/packages/@sanity/cli/test/test-template/package.json @@ -14,7 +14,7 @@ }, "dependencies": { "@sanity/assist": "^3.0.8", - "@sanity/icons": "^3.5.0", + "@sanity/icons": "^3.5.2", "@sanity/image-url": "^1.0.2", "@sanity/preview-url-secret": "^2.0.0", "@sanity/vision": "^3.62.0", diff --git a/packages/@sanity/codegen/.depcheckrc.json b/packages/@sanity/codegen/.depcheckrc.json index 35f1b4badf9..85f2a752c57 100644 --- a/packages/@sanity/codegen/.depcheckrc.json +++ b/packages/@sanity/codegen/.depcheckrc.json @@ -1,3 +1,3 @@ { - "ignores": ["@repo/tsconfig", "@sanity/pkg-utils"] + "ignores": ["@repo/tsconfig", "@sanity/pkg-utils", "rimraf"] } diff --git a/packages/@sanity/codegen/package.json b/packages/@sanity/codegen/package.json index 86d73a9dbac..b87d9b8c52c 100644 --- a/packages/@sanity/codegen/package.json +++ b/packages/@sanity/codegen/package.json @@ -1,6 +1,6 @@ { "name": "@sanity/codegen", - "version": "3.66.1", + "version": "3.67.1", "description": "Codegen toolkit for Sanity.io", "keywords": [ "sanity", @@ -59,9 +59,9 @@ "@babel/traverse": "^7.23.5", "@babel/types": "^7.23.9", "debug": "^4.3.4", - "globby": "^10.0.0", + "globby": "^11.1.0", "groq": "workspace:*", - "groq-js": "^1.14.1", + "groq-js": "^1.14.2", "json5": "^2.2.3", "tsconfig-paths": "^4.2.0", "zod": "^3.22.4" @@ -74,7 +74,7 @@ "@types/babel__register": "^7.17.3", "@types/babel__traverse": "^7.20.5", "@types/debug": "^4.1.12", - "rimraf": "^3.0.2", + "rimraf": "^5.0.10", "vitest": "^2.1.1" }, "engines": { diff --git a/packages/@sanity/diff/.depcheckrc.json b/packages/@sanity/diff/.depcheckrc.json index 35f1b4badf9..85f2a752c57 100644 --- a/packages/@sanity/diff/.depcheckrc.json +++ b/packages/@sanity/diff/.depcheckrc.json @@ -1,3 +1,3 @@ { - "ignores": ["@repo/tsconfig", "@sanity/pkg-utils"] + "ignores": ["@repo/tsconfig", "@sanity/pkg-utils", "rimraf"] } diff --git a/packages/@sanity/diff/package.json b/packages/@sanity/diff/package.json index 757c705cf50..1fc114f6732 100644 --- a/packages/@sanity/diff/package.json +++ b/packages/@sanity/diff/package.json @@ -1,6 +1,6 @@ { "name": "@sanity/diff", - "version": "3.66.1", + "version": "3.67.1", "description": "Generates diffs between documents and primitive types", "keywords": [ "sanity", @@ -51,7 +51,7 @@ }, "devDependencies": { "@repo/package.config": "workspace:*", - "rimraf": "^3.0.2" + "rimraf": "^5.0.10" }, "engines": { "node": ">=18" diff --git a/packages/@sanity/migrate/.depcheckrc.json b/packages/@sanity/migrate/.depcheckrc.json index 35f1b4badf9..85f2a752c57 100644 --- a/packages/@sanity/migrate/.depcheckrc.json +++ b/packages/@sanity/migrate/.depcheckrc.json @@ -1,3 +1,3 @@ { - "ignores": ["@repo/tsconfig", "@sanity/pkg-utils"] + "ignores": ["@repo/tsconfig", "@sanity/pkg-utils", "rimraf"] } diff --git a/packages/@sanity/migrate/package.json b/packages/@sanity/migrate/package.json index 827ec3b9bc7..ddc79049e61 100644 --- a/packages/@sanity/migrate/package.json +++ b/packages/@sanity/migrate/package.json @@ -1,6 +1,6 @@ { "name": "@sanity/migrate", - "version": "3.66.1", + "version": "3.67.1", "description": "Tooling for running data migrations on Sanity.io projects", "keywords": [ "sanity", @@ -52,12 +52,12 @@ "dependencies": { "@sanity/client": "^6.24.1", "@sanity/mutate": "^0.11.1", - "@sanity/types": "3.66.1", - "@sanity/util": "3.66.1", + "@sanity/types": "3.67.1", + "@sanity/util": "3.67.1", "arrify": "^2.0.1", "debug": "^4.3.4", "fast-fifo": "^1.3.2", - "groq-js": "^1.14.1", + "groq-js": "^1.14.2", "p-map": "^7.0.1" }, "devDependencies": { @@ -65,7 +65,7 @@ "@repo/test-config": "workspace:*", "@types/arrify": "^2.0.1", "@types/debug": "^4.1.12", - "rimraf": "^3.0.2", + "rimraf": "^5.0.10", "vitest": "^2.1.1" }, "engines": { diff --git a/packages/@sanity/mutator/.depcheckrc.json b/packages/@sanity/mutator/.depcheckrc.json index 35f1b4badf9..85f2a752c57 100644 --- a/packages/@sanity/mutator/.depcheckrc.json +++ b/packages/@sanity/mutator/.depcheckrc.json @@ -1,3 +1,3 @@ { - "ignores": ["@repo/tsconfig", "@sanity/pkg-utils"] + "ignores": ["@repo/tsconfig", "@sanity/pkg-utils", "rimraf"] } diff --git a/packages/@sanity/mutator/package.json b/packages/@sanity/mutator/package.json index c8e6b9cfd11..8d2ef7f33c8 100644 --- a/packages/@sanity/mutator/package.json +++ b/packages/@sanity/mutator/package.json @@ -1,6 +1,6 @@ { "name": "@sanity/mutator", - "version": "3.66.1", + "version": "3.67.1", "description": "A set of models to make it easier to utilize the powerful real time collaborative features of Sanity", "keywords": [ "sanity", @@ -50,7 +50,7 @@ }, "dependencies": { "@sanity/diff-match-patch": "^3.1.1", - "@sanity/types": "3.66.1", + "@sanity/types": "3.67.1", "@sanity/uuid": "^3.0.1", "debug": "^4.3.4", "lodash": "^4.17.21" @@ -60,7 +60,7 @@ "@repo/test-config": "workspace:*", "@types/debug": "^4.1.5", "@types/lodash": "^4.17.7", - "rimraf": "^3.0.2", + "rimraf": "^5.0.10", "vitest": "^2.1.1" } } diff --git a/packages/@sanity/schema/.depcheckrc.json b/packages/@sanity/schema/.depcheckrc.json index f05b0634d43..a2a2831b61e 100644 --- a/packages/@sanity/schema/.depcheckrc.json +++ b/packages/@sanity/schema/.depcheckrc.json @@ -1,3 +1,3 @@ { - "ignores": ["@repo/tsconfig", "@sanity/pkg-utils", "@types/react"] + "ignores": ["@repo/tsconfig", "@sanity/pkg-utils", "@types/react", "rimraf"] } diff --git a/packages/@sanity/schema/package.json b/packages/@sanity/schema/package.json index 4daa2c0fd57..71918760238 100644 --- a/packages/@sanity/schema/package.json +++ b/packages/@sanity/schema/package.json @@ -1,6 +1,6 @@ { "name": "@sanity/schema", - "version": "3.66.1", + "version": "3.67.1", "description": "", "keywords": [ "sanity", @@ -64,9 +64,9 @@ }, "dependencies": { "@sanity/generate-help-url": "^3.0.0", - "@sanity/types": "3.66.1", + "@sanity/types": "3.67.1", "arrify": "^1.0.1", - "groq-js": "^1.14.1", + "groq-js": "^1.14.2", "humanize-list": "^1.0.1", "leven": "^3.1.0", "lodash": "^4.17.21", @@ -75,12 +75,12 @@ "devDependencies": { "@repo/package.config": "workspace:*", "@repo/test-config": "workspace:*", - "@sanity/icons": "^3.5.0", + "@sanity/icons": "^3.5.2", "@types/arrify": "^1.0.4", "@types/lodash": "^4.17.7", "@types/object-inspect": "^1.13.0", "@types/react": "^18.3.12", - "rimraf": "^3.0.2", + "rimraf": "^5.0.10", "vitest": "^2.1.1" } } diff --git a/packages/@sanity/types/.depcheckrc.json b/packages/@sanity/types/.depcheckrc.json index 10cd9026ee0..2a2450b6289 100644 --- a/packages/@sanity/types/.depcheckrc.json +++ b/packages/@sanity/types/.depcheckrc.json @@ -1,3 +1,3 @@ { - "ignores": ["@repo/tsconfig", "@sanity/pkg-utils", "@sanity/types", "react"] + "ignores": ["@repo/tsconfig", "@sanity/pkg-utils", "@sanity/types", "react", "rimraf"] } diff --git a/packages/@sanity/types/package.json b/packages/@sanity/types/package.json index 6043915e0b6..278a2ce8bb3 100644 --- a/packages/@sanity/types/package.json +++ b/packages/@sanity/types/package.json @@ -1,6 +1,6 @@ { "name": "@sanity/types", - "version": "3.66.1", + "version": "3.67.1", "description": "Type definitions for common Sanity data structures", "keywords": [ "sanity", @@ -55,10 +55,10 @@ "devDependencies": { "@repo/package.config": "workspace:*", "@repo/test-config": "workspace:*", - "@sanity/insert-menu": "^1.0.16", - "@vitejs/plugin-react": "^4.3.3", + "@sanity/insert-menu": "1.0.16", + "@vitejs/plugin-react": "^4.3.4", "react": "^18.3.1", - "rimraf": "^3.0.2", + "rimraf": "^5.0.10", "vitest": "^2.1.1" } } diff --git a/packages/@sanity/types/src/schema/definition/type/slug.ts b/packages/@sanity/types/src/schema/definition/type/slug.ts index a571f79b3c1..0184909b58d 100644 --- a/packages/@sanity/types/src/schema/definition/type/slug.ts +++ b/packages/@sanity/types/src/schema/definition/type/slug.ts @@ -25,6 +25,7 @@ export interface SlugOptions extends SearchConfiguration, BaseSchemaTypeOptions maxLength?: number slugify?: SlugifierFn isUnique?: SlugIsUniqueValidator + disableArrayWarning?: boolean } /** @public */ diff --git a/packages/@sanity/types/src/search/types.ts b/packages/@sanity/types/src/search/types.ts index 6025fc16dc5..1eacc85da7d 100644 --- a/packages/@sanity/types/src/search/types.ts +++ b/packages/@sanity/types/src/search/types.ts @@ -1,7 +1,7 @@ /** * @public */ -export const searchStrategies = ['groqLegacy', 'textSearch'] as const +export const searchStrategies = ['groqLegacy', 'textSearch', 'groq2024'] as const /** * @public diff --git a/packages/@sanity/util/.depcheckrc.json b/packages/@sanity/util/.depcheckrc.json index 35f1b4badf9..85f2a752c57 100644 --- a/packages/@sanity/util/.depcheckrc.json +++ b/packages/@sanity/util/.depcheckrc.json @@ -1,3 +1,3 @@ { - "ignores": ["@repo/tsconfig", "@sanity/pkg-utils"] + "ignores": ["@repo/tsconfig", "@sanity/pkg-utils", "rimraf"] } diff --git a/packages/@sanity/util/package.json b/packages/@sanity/util/package.json index af4cd315864..63a2275005f 100644 --- a/packages/@sanity/util/package.json +++ b/packages/@sanity/util/package.json @@ -1,6 +1,6 @@ { "name": "@sanity/util", - "version": "3.66.1", + "version": "3.67.1", "description": "Utilities shared across projects of Sanity", "keywords": [ "sanity", @@ -122,7 +122,7 @@ }, "dependencies": { "@sanity/client": "^6.24.1", - "@sanity/types": "3.66.1", + "@sanity/types": "3.67.1", "get-random-values-esm": "1.0.2", "moment": "^2.30.1", "rxjs": "^7.8.1" @@ -130,7 +130,7 @@ "devDependencies": { "@repo/package.config": "workspace:*", "@repo/test-config": "workspace:*", - "rimraf": "^3.0.2", + "rimraf": "^5.0.10", "vitest": "^2.1.1" }, "engines": { diff --git a/packages/@sanity/vision/package.json b/packages/@sanity/vision/package.json index 4005917e7e6..3189db8d3cc 100644 --- a/packages/@sanity/vision/package.json +++ b/packages/@sanity/vision/package.json @@ -1,6 +1,6 @@ { "name": "@sanity/vision", - "version": "3.66.1", + "version": "3.67.1", "description": "Sanity plugin for running/debugging GROQ-queries against Sanity datasets", "keywords": [ "sanity", @@ -62,15 +62,15 @@ "@rexxars/react-json-inspector": "^8.0.1", "@rexxars/react-split-pane": "^0.1.93", "@sanity/color": "^3.0.0", - "@sanity/icons": "^3.5.0", - "@sanity/ui": "^2.9.1", + "@sanity/icons": "^3.5.2", + "@sanity/ui": "^2.10.9", "@uiw/react-codemirror": "^4.11.4", "is-hotkey-esm": "^1.0.0", "json-2-csv": "^5.5.1", "json5": "^2.2.3", "lodash": "^4.17.21", "quick-lru": "^5.1.1", - "react-compiler-runtime": "19.0.0-beta-df7b47d-20241124" + "react-compiler-runtime": "19.0.0-beta-37ed2a7-20241206" }, "devDependencies": { "@repo/package.config": "workspace:*", @@ -85,7 +85,7 @@ "@sanity/types": "workspace:*", "@sanity/util": "workspace:*", "@types/lodash": "^4.17.7", - "babel-plugin-react-compiler": "19.0.0-beta-df7b47d-20241124", + "babel-plugin-react-compiler": "19.0.0-beta-37ed2a7-20241206", "react": "^18.3.1", "sanity": "workspace:*", "styled-components": "^6.1.13" diff --git a/packages/create-sanity/package.json b/packages/create-sanity/package.json index 95f92eff74a..9e67a61e845 100644 --- a/packages/create-sanity/package.json +++ b/packages/create-sanity/package.json @@ -1,6 +1,6 @@ { "name": "create-sanity", - "version": "3.66.1", + "version": "3.67.1", "description": "Initialize a new Sanity project", "keywords": [ "sanity", @@ -26,7 +26,7 @@ "index.js" ], "dependencies": { - "@sanity/cli": "3.66.1", + "@sanity/cli": "3.67.1", "resolve-pkg": "^2.0.0" }, "engines": { diff --git a/packages/groq/package.json b/packages/groq/package.json index 5672d4aa860..96fb815fe2b 100644 --- a/packages/groq/package.json +++ b/packages/groq/package.json @@ -1,6 +1,6 @@ { "name": "groq", - "version": "3.66.1", + "version": "3.67.1", "description": "Tagged template literal for Sanity.io GROQ-queries", "keywords": [ "sanity", diff --git a/packages/sanity/package.json b/packages/sanity/package.json index 22a35c79dc3..e960f001d08 100644 --- a/packages/sanity/package.json +++ b/packages/sanity/package.json @@ -1,6 +1,6 @@ { "name": "sanity", - "version": "3.66.1", + "version": "3.67.1", "description": "Sanity is a real-time content infrastructure with a scalable, hosted backend featuring a Graph Oriented Query Language (GROQ), asset pipelines and fast edge caches", "keywords": [ "sanity", @@ -153,32 +153,32 @@ "@dnd-kit/sortable": "^7.0.1", "@dnd-kit/utilities": "^3.2.0", "@juggle/resize-observer": "^3.3.1", - "@portabletext/editor": "^1.13.0", + "@portabletext/editor": "^1.15.3", "@portabletext/react": "^3.0.0", "@rexxars/react-json-inspector": "^8.0.1", "@sanity/asset-utils": "^2.0.6", "@sanity/bifur-client": "^0.4.1", - "@sanity/block-tools": "3.66.1", - "@sanity/cli": "3.66.1", + "@sanity/block-tools": "3.67.1", + "@sanity/cli": "3.67.1", "@sanity/client": "^6.24.1", "@sanity/color": "^3.0.0", - "@sanity/diff": "3.66.1", + "@sanity/diff": "3.67.1", "@sanity/diff-match-patch": "^3.1.1", "@sanity/eventsource": "^5.0.0", - "@sanity/export": "^3.41.0", - "@sanity/icons": "^3.5.0", + "@sanity/export": "^3.41.1", + "@sanity/icons": "^3.5.2", "@sanity/image-url": "^1.0.2", - "@sanity/import": "^3.37.3", - "@sanity/insert-menu": "^1.0.16", + "@sanity/import": "^3.37.9", + "@sanity/insert-menu": "1.0.16", "@sanity/logos": "^2.1.4", - "@sanity/migrate": "3.66.1", - "@sanity/mutator": "3.66.1", + "@sanity/migrate": "3.67.1", + "@sanity/mutator": "3.67.1", "@sanity/presentation": "1.19.8-release.0", - "@sanity/schema": "3.66.1", + "@sanity/schema": "3.67.1", "@sanity/telemetry": "^0.7.7", - "@sanity/types": "3.66.1", - "@sanity/ui": "^2.9.1", - "@sanity/util": "3.66.1", + "@sanity/types": "3.67.1", + "@sanity/ui": "^2.10.9", + "@sanity/util": "3.67.1", "@sanity/uuid": "^3.0.1", "@sentry/react": "^8.33.0", "@tanstack/react-table": "^8.16.0", @@ -189,7 +189,7 @@ "@types/speakingurl": "^13.0.3", "@types/tar-stream": "^3.1.3", "@types/use-sync-external-store": "^0.0.6", - "@vitejs/plugin-react": "^4.3.3", + "@vitejs/plugin-react": "^4.3.4", "archiver": "^7.0.0", "arrify": "^1.0.1", "async-mutex": "^0.4.1", @@ -198,7 +198,6 @@ "classnames": "^2.2.5", "color2k": "^2.0.0", "configstore": "^5.0.1", - "connect-history-api-fallback": "^1.6.0", "console-table-printer": "^2.11.1", "dataloader": "^2.1.0", "date-fns": "^2.26.1", @@ -211,7 +210,7 @@ "framer-motion": "11.0.8", "get-it": "^8.6.5", "get-random-values-esm": "1.0.2", - "groq-js": "^1.14.1", + "groq-js": "^1.14.2", "history": "^5.3.0", "i18next": "^23.2.7", "import-fresh": "^3.3.0", @@ -238,19 +237,19 @@ "pretty-ms": "^7.0.1", "quick-lru": "^5.1.1", "raf": "^3.4.1", - "react-compiler-runtime": "19.0.0-beta-df7b47d-20241124", + "react-compiler-runtime": "19.0.0-beta-37ed2a7-20241206", "react-copy-to-clipboard": "^5.0.4", "react-fast-compare": "^3.2.0", "react-focus-lock": "^2.8.1", "react-i18next": "14.0.2", "react-is": "^18.2.0", "react-refractor": "^2.1.6", - "react-rx": "^4.1.7", + "react-rx": "^4.1.8", "read-pkg-up": "^7.0.1", "refractor": "^3.6.0", "resolve-from": "^5.0.0", "resolve.exports": "^2.0.2", - "rimraf": "^3.0.2", + "rimraf": "^5.0.10", "rxjs": "^7.8.0", "rxjs-exhaustmap-with-trailing": "^2.1.1", "rxjs-mergemap-array": "^0.1.0", @@ -265,19 +264,19 @@ "use-effect-event": "^1.0.2", "use-hot-module-reload": "^2.0.0", "use-sync-external-store": "^1.2.0", - "vite": "^4.5.1", + "vite": "^5.4.11", "yargs": "^17.3.0" }, "devDependencies": { - "@playwright/experimental-ct-react": "1.44.1", - "@playwright/test": "1.44.1", + "@playwright/experimental-ct-react": "1.49.1", + "@playwright/test": "1.49.1", "@repo/dev-aliases": "workspace:*", "@repo/package.config": "workspace:*", "@repo/test-config": "workspace:*", - "@sanity/codegen": "3.66.1", + "@sanity/codegen": "3.67.1", "@sanity/generate-help-url": "^3.0.0", - "@sanity/pkg-utils": "6.11.14", - "@sanity/tsdoc": "1.0.142", + "@sanity/pkg-utils": "6.12.0", + "@sanity/tsdoc": "1.0.150", "@sanity/ui-workshop": "^1.2.11", "@sentry/types": "^8.12.0", "@testing-library/jest-dom": "^6.4.8", @@ -286,7 +285,6 @@ "@types/archiver": "^6.0.2", "@types/arrify": "^1.0.4", "@types/configstore": "^5.0.1", - "@types/connect-history-api-fallback": "^1.5.2", "@types/debug": "^4.1.12", "@types/jsdom": "^20.0.0", "@types/lodash": "^4.17.7", @@ -297,17 +295,15 @@ "@types/react-dom": "^18.3.1", "@types/refractor": "^3.0.0", "@types/resolve-from": "^4.0.0", - "@types/rimraf": "^3.0.2", "@types/semver": "^6.2.3", "@types/tar-fs": "^2.0.1", "@vitejs/plugin-react": "^4.3.3", "@vvo/tzdb": "6.137.0", - "babel-plugin-react-compiler": "19.0.0-beta-df7b47d-20241124", + "babel-plugin-react-compiler": "19.0.0-beta-37ed2a7-20241206", "blob-polyfill": "^9.0.20240710", "date-fns-tz": "2.0.1", "react": "^18.3.1", "react-dom": "^18.3.1", - "rimraf": "^3.0.2", "rxjs-etc": "^10.6.2", "styled-components": "^6.1.13", "swr": "2.2.5", diff --git a/packages/sanity/playwright-ct.config.ts b/packages/sanity/playwright-ct.config.ts index 158091b1e66..ed5132af298 100644 --- a/packages/sanity/playwright-ct.config.ts +++ b/packages/sanity/playwright-ct.config.ts @@ -39,10 +39,10 @@ export default defineConfig({ ], /* Maximum time one test can run for. */ - timeout: 30 * 1000, + timeout: 60 * 1000, expect: { // Maximum time expect() should wait for the condition to be met. - timeout: 10 * 1000, + timeout: 40 * 1000, }, /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ diff --git a/packages/sanity/playwright-ct/tests/formBuilder/inputs/PortableText/Decorators.spec.tsx b/packages/sanity/playwright-ct/tests/formBuilder/inputs/PortableText/Decorators.spec.tsx index 3d735029c75..504582cc6b5 100644 --- a/packages/sanity/playwright-ct/tests/formBuilder/inputs/PortableText/Decorators.spec.tsx +++ b/packages/sanity/playwright-ct/tests/formBuilder/inputs/PortableText/Decorators.spec.tsx @@ -44,12 +44,6 @@ test.describe('Portable Text Input', () => { page, browserName, }) => { - // avoid flakiness to make sure the test has the best chance despite being slow - test.slow() - - // For now, only test in Chromium due to flakiness in Firefox and WebKit - test.skip(browserName !== 'chromium') - const { getModifierKey, getFocusedPortableTextEditor, @@ -62,7 +56,7 @@ test.describe('Portable Text Input', () => { await mount() const $portableTextInput = await getFocusedPortableTextInput('field-defaultDecorators') const $pte = await getFocusedPortableTextEditor('field-defaultDecorators') - const modifierKey = getModifierKey() + const modifierKey = getModifierKey({browserName}) for (const decorator of DEFAULT_DECORATORS) { if (decorator.hotkey) { diff --git a/packages/sanity/playwright-ct/tests/formBuilder/inputs/PortableText/Toolbar.spec.tsx b/packages/sanity/playwright-ct/tests/formBuilder/inputs/PortableText/Toolbar.spec.tsx index f8862ec0e03..73c347948ae 100644 --- a/packages/sanity/playwright-ct/tests/formBuilder/inputs/PortableText/Toolbar.spec.tsx +++ b/packages/sanity/playwright-ct/tests/formBuilder/inputs/PortableText/Toolbar.spec.tsx @@ -106,7 +106,7 @@ test.describe('Portable Text Input', () => { }) // TODO - needs rewrite to avoid flakiness - test.skip('Opening block style', () => { + test.describe('Opening block style', () => { test('on a simple editor', async ({mount, page}) => { const {getFocusedPortableTextInput} = testHelpers({page}) await mount() diff --git a/packages/sanity/playwright-ct/tests/utils/testHelpers.tsx b/packages/sanity/playwright-ct/tests/utils/testHelpers.tsx index 45bff1a1e25..d85b8cc65e5 100644 --- a/packages/sanity/playwright-ct/tests/utils/testHelpers.tsx +++ b/packages/sanity/playwright-ct/tests/utils/testHelpers.tsx @@ -13,7 +13,7 @@ export function testHelpers({page}: {page: PlaywrightTestArgs['page']}) { await $overlay.press('Space') } - await expect($overlay).not.toBeVisible({timeout: 1500}) + await expect($overlay).not.toBeVisible() } return { /** @@ -105,11 +105,20 @@ export function testHelpers({page}: {page: PlaywrightTestArgs['page']}) { * Gets the appropriate modifier key for the current platform. * @returns The modifier key name ('Meta' for macOS, 'Control' for other platforms). */ - getModifierKey: () => { - if (process.platform === 'darwin') { + getModifierKey: (options?: {browserName?: string}) => { + // There's a bug with Firefox and Chromium on macOS where it use 'Control' instead of 'Meta' inside Playwright for some reason + if ( + process.platform === 'darwin' && + options?.browserName && + ['chromium', 'firefox'].includes(options.browserName) + ) { + return 'Control' + } + // Webkit on Linux uses 'Meta' instead of 'Control' as the modifier key for some reason + if (process.platform === 'linux' && options?.browserName === 'webkit') { return 'Meta' } - return 'Control' + return 'ControlOrMeta' }, /** * Types text with a delay using `page.keyboard.type`. Default delay emulates a human typing. diff --git a/packages/sanity/src/_internal/cli/actions/backup/cleanupTmpDir.ts b/packages/sanity/src/_internal/cli/actions/backup/cleanupTmpDir.ts index f32dc4b203d..b4893245116 100644 --- a/packages/sanity/src/_internal/cli/actions/backup/cleanupTmpDir.ts +++ b/packages/sanity/src/_internal/cli/actions/backup/cleanupTmpDir.ts @@ -1,13 +1,13 @@ -import rimraf from 'rimraf' +import {rimraf} from 'rimraf' import debug from './debug' -function cleanupTmpDir(tmpDir: string): void { - rimraf(tmpDir, (err) => { - if (err) { - debug(`Error cleaning up temporary files: ${err.message}`) - } - }) +async function cleanupTmpDir(tmpDir: string): Promise { + try { + await rimraf(tmpDir) + } catch (err) { + debug(`Error cleaning up temporary files: ${err.message}`) + } } export default cleanupTmpDir diff --git a/packages/sanity/src/_internal/cli/actions/build/buildAction.ts b/packages/sanity/src/_internal/cli/actions/build/buildAction.ts index beb8e29bbc6..24e105335b5 100644 --- a/packages/sanity/src/_internal/cli/actions/build/buildAction.ts +++ b/packages/sanity/src/_internal/cli/actions/build/buildAction.ts @@ -1,11 +1,10 @@ import path from 'node:path' -import {promisify} from 'node:util' import chalk from 'chalk' import {info} from 'log-symbols' import semver from 'semver' import {noopLogger} from '@sanity/telemetry' -import rimrafCallback from 'rimraf' +import {rimraf} from 'rimraf' import type {CliCommandArguments, CliCommandContext} from '@sanity/cli' import {buildStaticFiles, ChunkModule, ChunkStats} from '../../server' @@ -18,8 +17,6 @@ import {compareStudioDependencyVersions} from '../../util/compareStudioDependenc import {getAutoUpdateImportMap} from '../../util/getAutoUpdatesImportMap' import {shouldAutoUpdate} from '../../util/shouldAutoUpdate' -const rimraf = promisify(rimrafCallback) - export interface BuildSanityStudioCommandFlags { 'yes'?: boolean 'y'?: boolean diff --git a/packages/sanity/src/_internal/cli/actions/exec/esbuild.ts b/packages/sanity/src/_internal/cli/actions/exec/esbuild.ts index 137fc5c7537..dcf4d5283e3 100644 --- a/packages/sanity/src/_internal/cli/actions/exec/esbuild.ts +++ b/packages/sanity/src/_internal/cli/actions/exec/esbuild.ts @@ -3,5 +3,6 @@ import {register} from 'esbuild-register/dist/node' if (!__DEV__) { register({ target: `node${process.version.slice(1)}`, + supported: {'dynamic-import': true}, }) } diff --git a/packages/sanity/src/_internal/cli/commands/backup/downloadBackupCommand.ts b/packages/sanity/src/_internal/cli/commands/backup/downloadBackupCommand.ts index b10d2ba77af..060c6d7e86b 100644 --- a/packages/sanity/src/_internal/cli/commands/backup/downloadBackupCommand.ts +++ b/packages/sanity/src/_internal/cli/commands/backup/downloadBackupCommand.ts @@ -189,7 +189,7 @@ const downloadBackupCommand: CliCommandDefinition = { progressSpinner.set({ step: `Cleaning up temporary files at ${chalk.cyan(`${tmpOutDir}`)}`, }) - cleanupTmpDir(tmpOutDir) + await cleanupTmpDir(tmpOutDir) progressSpinner.set({ step: `Backup download complete [${prettyMs(Date.now() - start)}]`, diff --git a/packages/sanity/src/_internal/cli/commands/migration/listMigrationsCommand.ts b/packages/sanity/src/_internal/cli/commands/migration/listMigrationsCommand.ts index 0bf8413de84..5dd5011ea2e 100644 --- a/packages/sanity/src/_internal/cli/commands/migration/listMigrationsCommand.ts +++ b/packages/sanity/src/_internal/cli/commands/migration/listMigrationsCommand.ts @@ -78,6 +78,7 @@ export async function resolveMigrations(workDir: string): Promise = { if (!__DEV__) { register({ target: `node${process.version.slice(1)}`, + supported: {'dynamic-import': true}, }) } diff --git a/packages/sanity/src/_internal/cli/server/buildStaticFiles.ts b/packages/sanity/src/_internal/cli/server/buildStaticFiles.ts index a0bcbec040f..1b500c2327e 100644 --- a/packages/sanity/src/_internal/cli/server/buildStaticFiles.ts +++ b/packages/sanity/src/_internal/cli/server/buildStaticFiles.ts @@ -4,7 +4,6 @@ import path from 'node:path' import {type ReactCompilerConfig, type UserViteConfig} from '@sanity/cli' import readPkgUp from 'read-pkg-up' -import {build} from 'vite' import {debug as serverDebug} from './debug' import {extendViteConfigWithUserConfig, finalizeViteConfig, getViteConfig} from './getViteConfig' @@ -74,7 +73,7 @@ export async function buildStaticFiles( viteConfig, extendViteConfig, ) - viteConfig = finalizeViteConfig(viteConfig) + viteConfig = await finalizeViteConfig(viteConfig) } // Copy files placed in /static to the built /static @@ -88,6 +87,7 @@ export async function buildStaticFiles( await writeFavicons(faviconBasePath, staticPath) debug('Bundling using vite') + const {build} = await import('vite') const bundle = await build(viteConfig) debug('Bundling complete') diff --git a/packages/sanity/src/_internal/cli/server/buildVendorDependencies.ts b/packages/sanity/src/_internal/cli/server/buildVendorDependencies.ts index 305650076e2..631fcf8aa5d 100644 --- a/packages/sanity/src/_internal/cli/server/buildVendorDependencies.ts +++ b/packages/sanity/src/_internal/cli/server/buildVendorDependencies.ts @@ -3,7 +3,6 @@ import path from 'node:path' import resolveFrom from 'resolve-from' import semver from 'semver' -import {build} from 'vite' import {createExternalFromImportMap} from './createExternalFromImportMap' @@ -209,6 +208,7 @@ export async function buildVendorDependencies({ // removes the `RollupWatcher` type type BuildResult = Exclude>, {close: unknown}> + const {build} = await import('vite') // Use Vite to build the packages into the output directory let buildResult = (await build({ // Define a custom cache directory so that sanity's vite cache diff --git a/packages/sanity/src/_internal/cli/server/devServer.ts b/packages/sanity/src/_internal/cli/server/devServer.ts index d3ef1ab8551..8d92e89b14b 100644 --- a/packages/sanity/src/_internal/cli/server/devServer.ts +++ b/packages/sanity/src/_internal/cli/server/devServer.ts @@ -1,6 +1,5 @@ import {type ReactCompilerConfig, type UserViteConfig} from '@sanity/cli' import chalk from 'chalk' -import {createServer} from 'vite' import {debug} from './debug' import {extendViteConfigWithUserConfig, getViteConfig} from './getViteConfig' @@ -59,6 +58,7 @@ export async function startDevServer(options: DevServerOptions): Promise const defaultFaviconsPath = path.join(path.dirname(sanityPkgPath), 'static', 'favicons') const staticPath = `${basePath}static` + const {default: viteReact} = await import('@vitejs/plugin-react') const viteConfig: InlineConfig = { // Define a custom cache directory so that sanity's vite cache // does not conflict with any potential local vite projects @@ -110,7 +109,6 @@ export async function getViteConfig(options: ViteOptions): Promise reactCompiler ? {babel: {plugins: [['babel-plugin-react-compiler', reactCompiler]]}} : {}, ), sanityFaviconsPlugin({defaultFaviconsPath, customFaviconsPath, staticUrlPath: staticPath}), - sanityDotWorkaroundPlugin(), sanityRuntimeRewritePlugin(), sanityBuildEntries({basePath, cwd, monorepo, importMap}), ], @@ -149,6 +147,7 @@ export async function getViteConfig(options: ViteOptions): Promise emptyOutDir: false, // Rely on CLI to do this rollupOptions: { + onwarn: onRollupWarn, external: createExternalFromImportMap(importMap), input: { sanity: path.join(cwd, '.sanity', 'runtime', 'app.js'), @@ -160,6 +159,32 @@ export async function getViteConfig(options: ViteOptions): Promise return viteConfig } +function onRollupWarn(warning: Rollup.RollupLog, warn: Rollup.LoggingFunction) { + if (suppressUnusedImport(warning)) { + return + } + + warn(warning) +} + +function suppressUnusedImport(warning: Rollup.RollupLog & {ids?: string[]}): boolean { + if (warning.code !== 'UNUSED_EXTERNAL_IMPORT') return false + + // Suppress: + // ``` + // "useDebugValue" is imported from external module "react"… + // ``` + if (warning.names?.includes('useDebugValue')) { + warning.names = warning.names.filter((n) => n !== 'useDebugValue') + if (warning.names.length === 0) return true + } + + // If some library does something unexpected, we suppress since it isn't actionable + if (warning.ids?.every((id) => id.includes('/node_modules/'))) return true + + return false +} + /** * Ensure Sanity entry chunk is always loaded * @@ -167,7 +192,7 @@ export async function getViteConfig(options: ViteOptions): Promise * @returns Merged configuration * @internal */ -export function finalizeViteConfig(config: InlineConfig): InlineConfig { +export async function finalizeViteConfig(config: InlineConfig): Promise { if (typeof config.build?.rollupOptions?.input !== 'object') { throw new Error( 'Vite config must contain `build.rollupOptions.input`, and it must be an object', @@ -180,6 +205,7 @@ export function finalizeViteConfig(config: InlineConfig): InlineConfig { ) } + const {mergeConfig} = await import('vite') return mergeConfig(config, { build: { rollupOptions: { @@ -211,6 +237,7 @@ export async function extendViteConfigWithUserConfig( config = await userConfig(config, env) } else if (typeof userConfig === 'object') { debug('Merging vite config using user-specified object') + const {mergeConfig} = await import('vite') config = mergeConfig(config, userConfig) } diff --git a/packages/sanity/src/_internal/cli/server/previewServer.ts b/packages/sanity/src/_internal/cli/server/previewServer.ts index 5443a52f7b4..bc5b23bf554 100644 --- a/packages/sanity/src/_internal/cli/server/previewServer.ts +++ b/packages/sanity/src/_internal/cli/server/previewServer.ts @@ -3,7 +3,7 @@ import path from 'node:path' import {type UserViteConfig} from '@sanity/cli' import chalk from 'chalk' -import {type InlineConfig, preview} from 'vite' +import {type InlineConfig} from 'vite' import {debug as serverDebug} from './debug' import {extendViteConfigWithUserConfig} from './getViteConfig' @@ -75,10 +75,11 @@ export async function startPreviewServer(options: PreviewServerOptions): Promise } debug('Creating vite server') + const {preview} = await import('vite') const server = await preview(previewConfig) const warn = server.config.logger.warn const info = server.config.logger.info - const url = server.resolvedUrls.local[0] + const url = server.resolvedUrls!.local[0] if (typeof basePath === 'undefined') { warn('Could not determine base path from index.html, using "/" as default') @@ -96,7 +97,7 @@ export async function startPreviewServer(options: PreviewServerOptions): Promise ) return { - urls: server.resolvedUrls, + urls: server.resolvedUrls!, close: () => new Promise((resolve, reject) => server.httpServer.close((err) => (err ? reject(err) : resolve())), diff --git a/packages/sanity/src/_internal/cli/server/renderDocument.ts b/packages/sanity/src/_internal/cli/server/renderDocument.ts index 3c1a3badd96..123e7b68cca 100644 --- a/packages/sanity/src/_internal/cli/server/renderDocument.ts +++ b/packages/sanity/src/_internal/cli/server/renderDocument.ts @@ -183,6 +183,7 @@ function renderDocumentFromWorkerData() { ? {unregister: () => undefined} : require('esbuild-register/dist/node').register({ target: `node${process.version.slice(1)}`, + supported: {'dynamic-import': true}, jsx: 'automatic', extensions: ['.jsx', '.ts', '.tsx', '.mjs'], }) @@ -194,6 +195,7 @@ function renderDocumentFromWorkerData() { ? {unregister: () => undefined} : require('esbuild-register/dist/node').register({ target: `node${process.version.slice(1)}`, + supported: {'dynamic-import': true}, extensions: ['.js'], jsx: 'automatic', loader: 'jsx', diff --git a/packages/sanity/src/_internal/cli/server/vite/plugin-sanity-dot-workaround.ts b/packages/sanity/src/_internal/cli/server/vite/plugin-sanity-dot-workaround.ts deleted file mode 100644 index 7783712b0bf..00000000000 --- a/packages/sanity/src/_internal/cli/server/vite/plugin-sanity-dot-workaround.ts +++ /dev/null @@ -1,43 +0,0 @@ -import fs from 'node:fs' -import path from 'node:path' - -import history from 'connect-history-api-fallback' -import {type Plugin} from 'vite' - -/** - * This is a Vite plugin for supporting locations containing `.` in their pathname. - * - * @see https://github.com/vitejs/vite/issues/2245 - */ -export function sanityDotWorkaroundPlugin(): Plugin { - return { - name: 'sanity/server/dot-workaround', - configureServer(server) { - const {root} = server.config - - return () => { - const handler = history({ - disableDotRule: true, - rewrites: [ - { - from: /\/index.html$/, - to: ({parsedUrl}) => { - const pathname = parsedUrl.pathname - - if (pathname && fs.existsSync(path.join(root, pathname))) { - return pathname - } - - return `/index.html` - }, - }, - ], - }) - - server.middlewares.use((req, res, next) => { - handler(req as any, res as any, next) - }) - } - }, - } -} diff --git a/packages/sanity/src/_internal/cli/server/vite/plugin-sanity-favicons.ts b/packages/sanity/src/_internal/cli/server/vite/plugin-sanity-favicons.ts index ef8667001d9..c4e65288b1c 100644 --- a/packages/sanity/src/_internal/cli/server/vite/plugin-sanity-favicons.ts +++ b/packages/sanity/src/_internal/cli/server/vite/plugin-sanity-favicons.ts @@ -42,9 +42,9 @@ export function sanityFaviconsPlugin({ return cache.favicons } - async function hasCustomFavicon(): Promise { + async function hasCustomFavicon(fileName: string): Promise { try { - await fs.access(path.join(customFaviconsPath, 'favicon.ico')) + await fs.access(path.join(customFaviconsPath, fileName)) return true } catch (err) { return false @@ -58,41 +58,38 @@ export function sanityFaviconsPlugin({ const webManifest = JSON.stringify(generateWebManifest(staticUrlPath), null, 2) const webManifestPath = `${staticUrlPath}/manifest.webmanifest` - return () => { - viteDevServer.middlewares.use(async (req, res, next) => { - if (req.url?.endsWith(webManifestPath)) { - res.writeHead(200, 'OK', {'content-type': 'application/manifest+json'}) - res.write(webManifest) - res.end() - return - } + viteDevServer.middlewares.use(async (req, res, next) => { + if (req.url?.endsWith(webManifestPath)) { + res.writeHead(200, 'OK', {'content-type': 'application/manifest+json'}) + res.write(webManifest) + res.end() + return + } - const parsedUrl = - ((req as any)._parsedUrl as URL) || new URL(req.url || '/', 'http://localhost:3333') + const parsedUrl = + ((req as any)._parsedUrl as URL) || new URL(req.url || '/', 'http://localhost:3333') - const pathName = parsedUrl.pathname || '' - const fileName = path.basename(pathName || '') - const icons = await getFavicons() - const isIconRequest = - pathName.startsWith('/favicon.ico') || - (icons.includes(fileName) && pathName.includes(staticUrlPath)) + const pathName = parsedUrl.pathname || '' + const fileName = path.basename(pathName || '') + const icons = await getFavicons() + const isIconRequest = + pathName.startsWith('/favicon.ico') || + (icons.includes(fileName) && pathName.includes(staticUrlPath)) - if (!isIconRequest) { - next() - return - } + if (!isIconRequest) { + next() + return + } - const faviconPath = - fileName === 'favicon.ico' && (await hasCustomFavicon()) - ? path.join(customFaviconsPath, 'favicon.ico') - : path.join(defaultFaviconsPath, fileName) + const faviconPath = (await hasCustomFavicon(fileName)) + ? path.join(customFaviconsPath, fileName) + : path.join(defaultFaviconsPath, fileName) - const mimeType = mimeTypes[path.extname(fileName)] || 'application/octet-stream' - res.writeHead(200, 'OK', {'content-type': mimeType}) - res.write(await fs.readFile(faviconPath)) - res.end() - }) - } + const mimeType = mimeTypes[path.extname(fileName)] || 'application/octet-stream' + res.writeHead(200, 'OK', {'content-type': mimeType}) + res.write(await fs.readFile(faviconPath)) + res.end() + }) }, } } diff --git a/packages/sanity/src/_internal/cli/threads/esbuild.ts b/packages/sanity/src/_internal/cli/threads/esbuild.ts index 137fc5c7537..dcf4d5283e3 100644 --- a/packages/sanity/src/_internal/cli/threads/esbuild.ts +++ b/packages/sanity/src/_internal/cli/threads/esbuild.ts @@ -3,5 +3,6 @@ import {register} from 'esbuild-register/dist/node' if (!__DEV__) { register({ target: `node${process.version.slice(1)}`, + supported: {'dynamic-import': true}, }) } diff --git a/packages/sanity/src/_internal/cli/util/mockBrowserEnvironment.ts b/packages/sanity/src/_internal/cli/util/mockBrowserEnvironment.ts index 5bbecd44420..35f22f4b26c 100644 --- a/packages/sanity/src/_internal/cli/util/mockBrowserEnvironment.ts +++ b/packages/sanity/src/_internal/cli/util/mockBrowserEnvironment.ts @@ -33,6 +33,7 @@ export function mockBrowserEnvironment(basePath: string): () => void { const {unregister: unregisterESBuild} = registerESBuild({ target: 'node18', + supported: {'dynamic-import': true}, format: 'cjs', extensions: ['.js', '.jsx', '.ts', '.tsx', '.mjs'], jsx: 'automatic', diff --git a/packages/sanity/src/_internal/cli/vitest.config.mts b/packages/sanity/src/_internal/cli/vitest.config.mts index 60aa02e5e31..984764639e1 100644 --- a/packages/sanity/src/_internal/cli/vitest.config.mts +++ b/packages/sanity/src/_internal/cli/vitest.config.mts @@ -2,7 +2,6 @@ import {defineConfig} from '@repo/test-config/vitest' import react from '@vitejs/plugin-react' export default defineConfig({ - // @ts-expect-error vite typings error plugins: [react({babel: {plugins: [['babel-plugin-react-compiler', {target: '18'}]]}})], test: { environment: 'node', diff --git a/packages/sanity/src/core/components/DefaultDocument.tsx b/packages/sanity/src/core/components/DefaultDocument.tsx index f09eb81d3c3..25bc84feb17 100644 --- a/packages/sanity/src/core/components/DefaultDocument.tsx +++ b/packages/sanity/src/core/components/DefaultDocument.tsx @@ -106,10 +106,14 @@ const globalStyles = ` /** * @hidden - * @beta */ + * @beta + */ export interface DefaultDocumentProps { entryPath: string css?: string[] + + // Currently unused, but kept for potential future use + // eslint-disable-next-line react/no-unused-prop-types basePath?: string } @@ -119,7 +123,7 @@ const EMPTY_ARRAY: never[] = [] * @hidden * @beta */ export function DefaultDocument(props: DefaultDocumentProps): ReactElement { - const {entryPath, css = EMPTY_ARRAY, basePath = '/'} = props + const {entryPath, css = EMPTY_ARRAY} = props return ( @@ -132,7 +136,7 @@ export function DefaultDocument(props: DefaultDocumentProps): ReactElement { - + Sanity Studio diff --git a/packages/sanity/src/core/components/Favicons.tsx b/packages/sanity/src/core/components/Favicons.tsx index bd0b9fddc84..d7cab685ce9 100644 --- a/packages/sanity/src/core/components/Favicons.tsx +++ b/packages/sanity/src/core/components/Favicons.tsx @@ -1,9 +1,10 @@ export interface FaviconProps { - basePath: string + /** @deprecated No longer needed/used - will be added by Vite automatically */ + basePath?: string } -export function Favicons({basePath}: FaviconProps) { - const base = `${basePath.replace(/\/+$/, '')}/static` +export function Favicons(_props: FaviconProps) { + const base = '/static' return ( <> diff --git a/packages/sanity/src/core/config/create/__tests__/startInCreateSortedActions.test.ts b/packages/sanity/src/core/config/create/__tests__/startInCreateSortedActions.test.ts deleted file mode 100644 index ccc2cecc84b..00000000000 --- a/packages/sanity/src/core/config/create/__tests__/startInCreateSortedActions.test.ts +++ /dev/null @@ -1,40 +0,0 @@ -import {describe, expect, it} from 'vitest' - -import {type DocumentActionComponent} from '../../document/actions' -import { - getStartInCreateSortedActions, - START_IN_CREATE_ACTION_NAME, -} from '../startInCreateSortedActions' - -describe('getStartInCreateSortedActions', () => { - it(`sorts "Start in Create" action first`, async () => { - const StartInCreateAction: DocumentActionComponent = () => { - return null - } - StartInCreateAction.action = START_IN_CREATE_ACTION_NAME - - const Action1: DocumentActionComponent = () => { - return null - } - const Action2: DocumentActionComponent = () => { - return null - } - - const actions = [Action1, Action2, StartInCreateAction] - const sortedActions = getStartInCreateSortedActions(actions) - expect(sortedActions).toEqual([StartInCreateAction, Action1, Action2]) - }) - - it(`leaves actions untouched when "Start in Create" actions is not present`, async () => { - const Action1: DocumentActionComponent = () => { - return null - } - const Action2: DocumentActionComponent = () => { - return null - } - - const actions = [Action1, Action2] - const sortedActions = getStartInCreateSortedActions(actions) - expect(sortedActions).toEqual([Action1, Action2]) - }) -}) diff --git a/packages/sanity/src/core/config/create/startInCreateSortedActions.ts b/packages/sanity/src/core/config/create/startInCreateSortedActions.ts deleted file mode 100644 index 0f3938722ab..00000000000 --- a/packages/sanity/src/core/config/create/startInCreateSortedActions.ts +++ /dev/null @@ -1,23 +0,0 @@ -//this file has to live here to avoid cyclic dependencies between config<->create -import {type DocumentActionComponent} from '../document' - -// The "Start in Create" action must be sorted first, so we need a sort key; the action string – -// we also don't want this string in the config interfaces, so we need the cheeky cast to smuggle it through -export const START_IN_CREATE_ACTION_NAME = - 'startInCreate' as unknown as DocumentActionComponent['action'] - -/** - * Sorts "Start in Create" action first, when present - */ -export function getStartInCreateSortedActions( - actions: DocumentActionComponent[], -): DocumentActionComponent[] { - return [...actions].sort((a, b) => { - if (a.action === START_IN_CREATE_ACTION_NAME) { - return -1 - } else if (b.action === START_IN_CREATE_ACTION_NAME) { - return 1 - } - return 0 - }) -} diff --git a/packages/sanity/src/core/config/prepareConfig.ts b/packages/sanity/src/core/config/prepareConfig.ts index 87caa731f31..a9266da29bb 100644 --- a/packages/sanity/src/core/config/prepareConfig.ts +++ b/packages/sanity/src/core/config/prepareConfig.ts @@ -50,7 +50,6 @@ import { toolsReducer, } from './configPropertyReducers' import {ConfigResolutionError} from './ConfigResolutionError' -import {getStartInCreateSortedActions} from './create/startInCreateSortedActions' import {createDefaultIcon} from './createDefaultIcon' import {documentFieldActionsReducer, initialDocumentFieldActions} from './document' import {resolveConfigProperty} from './resolveConfigProperty' @@ -501,16 +500,14 @@ function resolveSource({ config, }), document: { - actions: (partialContext) => { - const actions = resolveConfigProperty({ + actions: (partialContext) => + resolveConfigProperty({ config, context: {...context, ...partialContext}, initialValue: initialDocumentActions, propertyName: 'document.actions', reducer: documentActionsReducer, - }) - return getStartInCreateSortedActions(actions) - }, + }), badges: (partialContext) => resolveConfigProperty({ config, @@ -664,7 +661,7 @@ function resolveSource({ enabled: false, }, create: { - startInCreateEnabled: startInCreateEnabledReducer({config, initialValue: false}), + startInCreateEnabled: startInCreateEnabledReducer({config, initialValue: true}), fallbackStudioOrigin: createFallbackOriginReducer(config), }, }, diff --git a/packages/sanity/src/core/config/types.ts b/packages/sanity/src/core/config/types.ts index f9ec820c546..4af60acb82f 100644 --- a/packages/sanity/src/core/config/types.ts +++ b/packages/sanity/src/core/config/types.ts @@ -396,6 +396,8 @@ export interface PluginOptions { * - `"groqLegacy"` (default): Use client-side tokenization and schema introspection to search * using the GROQ Query API. * - `"textSearch"` (deprecated): Perform full text searching using the Text Search API. + * - `"groq2024"`: (experimental) Perform full text searching using the GROQ Query API and its + * new `text::matchQuery` function. */ strategy?: SearchStrategy diff --git a/packages/sanity/src/core/create/__tests__/createUtils.test.ts b/packages/sanity/src/core/create/__tests__/createUtils.test.ts index 4a333c826d2..b924d3c63d8 100644 --- a/packages/sanity/src/core/create/__tests__/createUtils.test.ts +++ b/packages/sanity/src/core/create/__tests__/createUtils.test.ts @@ -1,8 +1,8 @@ -import {defineType, type ObjectSchemaType} from '@sanity/types' +import {defineType, type ObjectSchemaType, type SanityDocumentLike} from '@sanity/types' import {describe, expect, it} from 'vitest' import {createSchema} from '../../schema' -import {isSanityCreateExcludedType} from '../createUtils' +import {isSanityCreateExcludedType, isSanityCreateStartCompatibleDoc} from '../createUtils' const basicDoc = defineType({ type: 'document', @@ -69,6 +69,36 @@ describe('createUtils', () => { expect(isSanityCreateExcludedType(documentType)).toEqual(false) }) }) + + describe('isSanityCreateStartCompatibleDoc', () => { + it(`should allow documents with values in underscore-prefixed fields`, () => { + const doc: SanityDocumentLike = { + _id: '123', + _type: 'yolo', + _createdAt: 'whenever', + } + expect(isSanityCreateStartCompatibleDoc(doc)).toEqual(true) + }) + + it(`should allow documents with null or undefined values in underscore-prefixed fields`, () => { + const doc: SanityDocumentLike = { + _id: '123', + _type: 'yolo', + someField: undefined, + other: null, + } + expect(isSanityCreateStartCompatibleDoc(doc)).toEqual(true) + }) + + it(`should not allow documents with values in regular fields`, () => { + expect(isSanityCreateStartCompatibleDoc({_id: '1', _type: '2', someArray: []})).toEqual(false) + expect(isSanityCreateStartCompatibleDoc({_id: '1', _type: '2', string: ''})).toEqual(false) + expect(isSanityCreateStartCompatibleDoc({_id: '1', _type: '2', number: 0})).toEqual(false) + expect(isSanityCreateStartCompatibleDoc({_id: '1', _type: '2', boolean: false})).toEqual( + false, + ) + }) + }) }) function getDocumentType(docDefs: ReturnType[], docName: string) { diff --git a/packages/sanity/src/core/create/components/CreateLearnMoreButton.tsx b/packages/sanity/src/core/create/components/CreateLearnMoreButton.tsx index c01110e95ae..d86862b810b 100644 --- a/packages/sanity/src/core/create/components/CreateLearnMoreButton.tsx +++ b/packages/sanity/src/core/create/components/CreateLearnMoreButton.tsx @@ -4,6 +4,7 @@ import {type ForwardedRef, forwardRef} from 'react' import {Button} from '../../../ui-components' import {useTranslation} from '../../i18n' import {createLocaleNamespace} from '../i18n' +import {createUserDocumentationUrl} from './constants' export const CreateLearnMoreButton = forwardRef(function CreateLearnMoreButton( props, @@ -13,7 +14,7 @@ export const CreateLearnMoreButton = forwardRef(function CreateLearnMoreButton( return (