@sanity/cli 8.22.1 → 8.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +313 -0
- package/dist/actions/codemods/dashboard.js +136 -8
- package/dist/actions/codemods/dashboard.js.map +1 -1
- package/dist/actions/codemods/types.js.map +1 -1
- package/dist/actions/context/watchJob.js +9 -3
- package/dist/actions/context/watchJob.js.map +1 -1
- package/dist/actions/deploy/blueprintManaged.js +59 -0
- package/dist/actions/deploy/blueprintManaged.js.map +1 -0
- package/dist/actions/deploy/deployApp.js +117 -1
- package/dist/actions/deploy/deployApp.js.map +1 -1
- package/dist/actions/deploy/deployRunner.js.map +1 -1
- package/dist/actions/deploy/deployStudio.js +6 -31
- package/dist/actions/deploy/deployStudio.js.map +1 -1
- package/dist/actions/exec/runScript.worker.js +6 -2
- package/dist/actions/exec/runScript.worker.js.map +1 -1
- package/dist/actions/init/bootstrapLocalTemplate.js +35 -11
- package/dist/actions/init/bootstrapLocalTemplate.js.map +1 -1
- package/dist/actions/init/createMediaLibraryCliConfig.js +12 -0
- package/dist/actions/init/createMediaLibraryCliConfig.js.map +1 -0
- package/dist/actions/init/determineMediaLibraryTemplate.js +14 -0
- package/dist/actions/init/determineMediaLibraryTemplate.js.map +1 -0
- package/dist/actions/init/initAction.js +35 -6
- package/dist/actions/init/initAction.js.map +1 -1
- package/dist/actions/init/initApp.js +81 -6
- package/dist/actions/init/initApp.js.map +1 -1
- package/dist/actions/init/offerAspectPull.js +81 -0
- package/dist/actions/init/offerAspectPull.js.map +1 -0
- package/dist/actions/init/project/getOrCreateDataset.js +8 -5
- package/dist/actions/init/project/getOrCreateDataset.js.map +1 -1
- package/dist/actions/init/project/getOrCreateProject.js +7 -5
- package/dist/actions/init/project/getOrCreateProject.js.map +1 -1
- package/dist/actions/init/project/getProjectDetails.js +25 -2
- package/dist/actions/init/project/getProjectDetails.js.map +1 -1
- package/dist/actions/init/project/promptUserForOrganization.js +6 -4
- package/dist/actions/init/project/promptUserForOrganization.js.map +1 -1
- package/dist/actions/init/templates/index.js +3 -0
- package/dist/actions/init/templates/index.js.map +1 -1
- package/dist/actions/init/templates/mediaLibraryConfig.js +51 -0
- package/dist/actions/init/templates/mediaLibraryConfig.js.map +1 -0
- package/dist/actions/media/aspectName.js +8 -0
- package/dist/actions/media/aspectName.js.map +1 -0
- package/dist/actions/media/aspectSync/contract.js +163 -0
- package/dist/actions/media/aspectSync/contract.js.map +1 -0
- package/dist/actions/media/aspectSync/syncAspects.js +115 -0
- package/dist/actions/media/aspectSync/syncAspects.js.map +1 -0
- package/dist/actions/media/cliConfigFields.js +192 -0
- package/dist/actions/media/cliConfigFields.js.map +1 -0
- package/dist/actions/media/pullAspects.js +225 -0
- package/dist/actions/media/pullAspects.js.map +1 -0
- package/dist/actions/media/resolveMediaLibraryId.js +83 -0
- package/dist/actions/media/resolveMediaLibraryId.js.map +1 -0
- package/dist/commands/codemod.js +1 -0
- package/dist/commands/codemod.js.map +1 -1
- package/dist/commands/context/build.js +2 -2
- package/dist/commands/context/build.js.map +1 -1
- package/dist/commands/context/entries/get.js +83 -0
- package/dist/commands/context/entries/get.js.map +1 -0
- package/dist/commands/context/entries/list.js +82 -0
- package/dist/commands/context/entries/list.js.map +1 -0
- package/dist/commands/context/entries/rebuild.js +95 -0
- package/dist/commands/context/entries/rebuild.js.map +1 -0
- package/dist/commands/context/issues/apply.js +86 -0
- package/dist/commands/context/issues/apply.js.map +1 -0
- package/dist/commands/context/issues/dismiss.js +52 -0
- package/dist/commands/context/issues/dismiss.js.map +1 -0
- package/dist/commands/context/issues/get.js +105 -0
- package/dist/commands/context/issues/get.js.map +1 -0
- package/dist/commands/context/issues/list.js +128 -0
- package/dist/commands/context/issues/list.js.map +1 -0
- package/dist/commands/context/issues/reopen.js +53 -0
- package/dist/commands/context/issues/reopen.js.map +1 -0
- package/dist/commands/context/issues/resolve.js +137 -0
- package/dist/commands/context/issues/resolve.js.map +1 -0
- package/dist/commands/context/jobs/get.js +2 -2
- package/dist/commands/context/jobs/get.js.map +1 -1
- package/dist/commands/context/query.js +92 -0
- package/dist/commands/context/query.js.map +1 -0
- package/dist/commands/deploy.js +13 -0
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/media/prune-aspect-data.js +170 -0
- package/dist/commands/media/prune-aspect-data.js.map +1 -0
- package/dist/commands/media/pull-aspects.js +309 -0
- package/dist/commands/media/pull-aspects.js.map +1 -0
- package/dist/exports/invokeSanityCli/commandPolicies/mcpPolicy.js +17 -0
- package/dist/exports/invokeSanityCli/commandPolicies/mcpPolicy.js.map +1 -1
- package/dist/services/context.js +96 -3
- package/dist/services/context.js.map +1 -1
- package/dist/services/mediaLibraries.js +175 -8
- package/dist/services/mediaLibraries.js.map +1 -1
- package/dist/util/searchChoices.js +52 -0
- package/dist/util/searchChoices.js.map +1 -0
- package/oclif.manifest.json +2134 -1445
- package/package.json +9 -8
- package/templates/media-library-config/README.md +52 -0
- package/templates/media-library-config/eslint.config.txt +52 -0
- package/templates/media-library-config/src/fields/caption.tsx +29 -0
- package/templates/media-library-config/src/fields/notes.tsx +54 -0
- package/templates/shopify/.gitignore +0 -26
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sanity/cli",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.24.0",
|
|
4
4
|
"description": "Sanity CLI tool for managing Sanity projects and organizations",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -63,8 +63,8 @@
|
|
|
63
63
|
"@oclif/plugin-help": "^6.2.53",
|
|
64
64
|
"@oclif/plugin-not-found": "^3.2.88",
|
|
65
65
|
"@sanity/blueprints": "^0.28.0",
|
|
66
|
-
"@sanity/cli-build": "^7.0.
|
|
67
|
-
"@sanity/cli-core": "^3.
|
|
66
|
+
"@sanity/cli-build": "^7.0.2",
|
|
67
|
+
"@sanity/cli-core": "^3.13.0",
|
|
68
68
|
"@sanity/client": "^8.9.0",
|
|
69
69
|
"@sanity/codegen": "^8.2.0",
|
|
70
70
|
"@sanity/descriptors": "^1.3.0",
|
|
@@ -73,20 +73,20 @@
|
|
|
73
73
|
"@sanity/id-utils": "^1.1.0",
|
|
74
74
|
"@sanity/import": "^7.0.4",
|
|
75
75
|
"@sanity/migrate": "^8.0.5",
|
|
76
|
-
"@sanity/runtime-cli": "17.
|
|
76
|
+
"@sanity/runtime-cli": "^17.16.0",
|
|
77
77
|
"@sanity/schema": "^6.17.0",
|
|
78
78
|
"@sanity/schema-descriptor-utils": "^1.3.3",
|
|
79
79
|
"@sanity/telemetry": "^1.1.0",
|
|
80
80
|
"@sanity/template-validator": "^3.1.1",
|
|
81
81
|
"@sanity/types": "^6.17.0",
|
|
82
|
-
"@sanity/workbench-cli": "^2.
|
|
82
|
+
"@sanity/workbench-cli": "^2.14.0",
|
|
83
83
|
"@sanity/worker-channels": "^2.0.0",
|
|
84
84
|
"@sanity/workflow-cli": "0.36.0",
|
|
85
85
|
"@sanity/workflow-engine": "0.36.0",
|
|
86
86
|
"@vercel/frameworks": "3.29.0",
|
|
87
87
|
"chokidar": "^5.0.0",
|
|
88
88
|
"console-table-printer": "^2.15.0",
|
|
89
|
-
"eventsource": "^5.1.
|
|
89
|
+
"eventsource": "^5.1.3",
|
|
90
90
|
"execa": "^10.0.1",
|
|
91
91
|
"form-data": "^4.0.5",
|
|
92
92
|
"get-latest-version": "^6.0.1",
|
|
@@ -126,9 +126,10 @@
|
|
|
126
126
|
},
|
|
127
127
|
"devDependencies": {
|
|
128
128
|
"@eslint/compat": "^2.1.0",
|
|
129
|
+
"@oxc-project/types": "0.152.0",
|
|
129
130
|
"@repo/package.config": "0.0.1",
|
|
130
131
|
"@repo/tsconfig": "3.70.0",
|
|
131
|
-
"@sanity/cli-test": "
|
|
132
|
+
"@sanity/cli-test": "23.0.0",
|
|
132
133
|
"@sanity/eslint-config-cli": "1.1.3",
|
|
133
134
|
"@sanity/pkg-utils": "^12.3.4",
|
|
134
135
|
"@swc/cli": "^0.8.1",
|
|
@@ -137,7 +138,7 @@
|
|
|
137
138
|
"@types/jsdom": "^28.0.3",
|
|
138
139
|
"@types/lodash-es": "^4.17.12",
|
|
139
140
|
"@types/minimist": "^1.2.5",
|
|
140
|
-
"@types/node": "^22.20.
|
|
141
|
+
"@types/node": "^22.20.5",
|
|
141
142
|
"@types/picomatch": "^4.0.3",
|
|
142
143
|
"@types/semver": "^7.7.1",
|
|
143
144
|
"@types/tar-stream": "^3.1.4",
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Media Library config app
|
|
2
|
+
|
|
3
|
+
A **Media Library config app**: it defines custom fields (aspects) for your
|
|
4
|
+
organization's Sanity Media Library. It has no UI of its own — the CLI
|
|
5
|
+
bundles the field modules in `src/fields/` into a remote that the Media
|
|
6
|
+
Library loads to drive asset metadata editing.
|
|
7
|
+
|
|
8
|
+
## Commands
|
|
9
|
+
|
|
10
|
+
- `npm run dev` starts the dev server and prints a Sanity Dashboard URL.
|
|
11
|
+
Open it, sign in, and go to the Media Library — the fields defined here
|
|
12
|
+
appear on assets, served live from your machine.
|
|
13
|
+
- `npm run build` builds the config for production.
|
|
14
|
+
- `npm run deploy` deploys the config to your organization.
|
|
15
|
+
|
|
16
|
+
## Defining fields
|
|
17
|
+
|
|
18
|
+
Each field lives in `src/fields/<name>.tsx` as a default-exported
|
|
19
|
+
`defineField(...)` — the same API as Sanity Studio — and is registered in
|
|
20
|
+
`sanity.cli.ts` under `fields`. Two examples are included:
|
|
21
|
+
|
|
22
|
+
- `caption` — a plain field rendered by the Media Library's standard
|
|
23
|
+
controls, with validation and an initial value.
|
|
24
|
+
- `notes` — a field with a custom input component (`components.input`).
|
|
25
|
+
|
|
26
|
+
The `name` of a field must match its entry in `sanity.cli.ts`: it becomes
|
|
27
|
+
the key the field's data is stored under on assets.
|
|
28
|
+
|
|
29
|
+
## Custom input components
|
|
30
|
+
|
|
31
|
+
Custom inputs render as **islands**: isolated React roots using this app's
|
|
32
|
+
own bundled `react`, `@sanity/ui`, and `sanity` copies — no version coupling
|
|
33
|
+
with the Media Library itself. The rules that keep an input working inside
|
|
34
|
+
an island are documented in `src/fields/notes.tsx`; the supported `sanity`
|
|
35
|
+
import surface is enforced at lint time by the override in
|
|
36
|
+
`eslint.config.mjs`. An import outside that surface has no provider inside
|
|
37
|
+
the island and fails at runtime.
|
|
38
|
+
|
|
39
|
+
## Validation and initial values
|
|
40
|
+
|
|
41
|
+
Validation rules and `initialValue` resolvers are config code executed by
|
|
42
|
+
the Media Library. `initialValue` runs when a new asset is uploaded;
|
|
43
|
+
resolver functions receive `(params, context)` where `context` carries the
|
|
44
|
+
uploaded asset document and its instance document (e.g. image metadata).
|
|
45
|
+
|
|
46
|
+
## Field modules must be loadable under plain Node.js
|
|
47
|
+
|
|
48
|
+
Field definitions are evaluated outside the browser when the config is
|
|
49
|
+
synchronized. Browser-only libraries that touch `window` at import time must
|
|
50
|
+
be loaded lazily from a component module
|
|
51
|
+
(`lazy(() => import('./MapInput'))`), never imported at the top of a field
|
|
52
|
+
module.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import studio from '@sanity/eslint-config-studio'
|
|
2
|
+
import tseslint from 'typescript-eslint'
|
|
3
|
+
|
|
4
|
+
export default [
|
|
5
|
+
...studio,
|
|
6
|
+
{
|
|
7
|
+
files: ['src/fields/**'],
|
|
8
|
+
// Flat config does not merge plugin registrations across config objects,
|
|
9
|
+
// so the plugin must be declared here even though the studio config also
|
|
10
|
+
// registers it (same module instance, so no redefinition conflict).
|
|
11
|
+
plugins: {'@typescript-eslint': tseslint.plugin},
|
|
12
|
+
rules: {
|
|
13
|
+
// The supported `sanity` surface for Media Library field modules.
|
|
14
|
+
// Custom inputs render in an isolated island root: imports outside
|
|
15
|
+
// this list have no provider there and fail at runtime with the
|
|
16
|
+
// field-failure card. Type-only imports are erased at build time and
|
|
17
|
+
// always safe.
|
|
18
|
+
'@typescript-eslint/no-restricted-imports': [
|
|
19
|
+
'error',
|
|
20
|
+
{
|
|
21
|
+
paths: [
|
|
22
|
+
{
|
|
23
|
+
name: 'sanity',
|
|
24
|
+
allowImportNames: [
|
|
25
|
+
'defineField',
|
|
26
|
+
'defineArrayMember',
|
|
27
|
+
'defineType',
|
|
28
|
+
'set',
|
|
29
|
+
'unset',
|
|
30
|
+
'setIfMissing',
|
|
31
|
+
'useFormValue',
|
|
32
|
+
'useGetFormValue',
|
|
33
|
+
'useCurrentLocale',
|
|
34
|
+
'useDateTimeFormat',
|
|
35
|
+
],
|
|
36
|
+
allowTypeImports: true,
|
|
37
|
+
message:
|
|
38
|
+
'Not part of the supported Media Library field surface. Custom inputs render in an isolated island: this import has no provider there and will show the field-failure card at runtime. Call onChange with plain patches (set/unset), never PatchEvent.',
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
patterns: [
|
|
42
|
+
{
|
|
43
|
+
group: ['sanity/*'],
|
|
44
|
+
message:
|
|
45
|
+
'Subpath imports from `sanity` are internals, not part of the supported Media Library field surface.',
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
]
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import {defineField} from 'sanity'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A plain field: no custom input component, so the Media Library renders it
|
|
5
|
+
* with its standard aspect-form controls. Start here — most fields never
|
|
6
|
+
* need a custom component. The definition uses the same `defineField` API as
|
|
7
|
+
* Sanity Studio; validation rules and initial values run in the Media
|
|
8
|
+
* Library's own runtime.
|
|
9
|
+
*/
|
|
10
|
+
export default defineField({
|
|
11
|
+
name: 'caption',
|
|
12
|
+
title: 'Caption',
|
|
13
|
+
type: 'object',
|
|
14
|
+
fields: [
|
|
15
|
+
defineField({
|
|
16
|
+
name: 'text',
|
|
17
|
+
title: 'Text',
|
|
18
|
+
type: 'string',
|
|
19
|
+
validation: (Rule) => Rule.required().error('A caption is required'),
|
|
20
|
+
}),
|
|
21
|
+
defineField({
|
|
22
|
+
name: 'language',
|
|
23
|
+
title: 'Language',
|
|
24
|
+
type: 'string',
|
|
25
|
+
options: {list: ['en', 'de', 'no']},
|
|
26
|
+
initialValue: 'en',
|
|
27
|
+
}),
|
|
28
|
+
],
|
|
29
|
+
})
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import {Stack, Text, TextArea} from '@sanity/ui'
|
|
2
|
+
import type {ChangeEvent, Ref} from 'react'
|
|
3
|
+
import {type InputProps, defineField, set, unset} from 'sanity'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* A custom input component. It renders as an *island*: an isolated React
|
|
7
|
+
* root using this app's own bundled `react` and `@sanity/ui` copies, so
|
|
8
|
+
* there is no version coupling with the Media Library host.
|
|
9
|
+
*
|
|
10
|
+
* Rules that keep an input working inside the island:
|
|
11
|
+
*
|
|
12
|
+
* - Call `onChange` with plain patches (`set(...)` / `unset()`), never
|
|
13
|
+
* `PatchEvent.from(...)` — patches cross the island boundary as plain
|
|
14
|
+
* data, and a PatchEvent instance from this bundle's `sanity` copy fails
|
|
15
|
+
* the host's checks.
|
|
16
|
+
* - Wire `elementProps.id` and `elementProps.ref` onto the focusable
|
|
17
|
+
* control, so host-driven focus (validation links, presence) reaches it.
|
|
18
|
+
* - Only import the supported `sanity` surface (enforced by the override in
|
|
19
|
+
* `eslint.config.mjs`); other exports have no provider inside the island
|
|
20
|
+
* and fail at runtime with the field-failure card.
|
|
21
|
+
* - Keep the module loadable under plain Node.js (field definitions are
|
|
22
|
+
* evaluated outside the browser when the config is synchronized):
|
|
23
|
+
* browser-only libraries must be imported lazily from a component module.
|
|
24
|
+
*/
|
|
25
|
+
function NotesInput(props: InputProps) {
|
|
26
|
+
const {value, onChange, elementProps} = props
|
|
27
|
+
const text = typeof value === 'string' ? value : ''
|
|
28
|
+
|
|
29
|
+
return (
|
|
30
|
+
<Stack space={2}>
|
|
31
|
+
<TextArea
|
|
32
|
+
id={elementProps?.id}
|
|
33
|
+
ref={elementProps?.ref as Ref<HTMLTextAreaElement>}
|
|
34
|
+
value={text}
|
|
35
|
+
rows={4}
|
|
36
|
+
placeholder="Add notes..."
|
|
37
|
+
onChange={(event: ChangeEvent<HTMLTextAreaElement>) => {
|
|
38
|
+
const next = event.currentTarget.value
|
|
39
|
+
onChange(next ? set(next) : unset())
|
|
40
|
+
}}
|
|
41
|
+
/>
|
|
42
|
+
<Text size={1} muted>
|
|
43
|
+
{text.length} characters
|
|
44
|
+
</Text>
|
|
45
|
+
</Stack>
|
|
46
|
+
)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export default defineField({
|
|
50
|
+
name: 'notes',
|
|
51
|
+
title: 'Notes',
|
|
52
|
+
type: 'text',
|
|
53
|
+
components: {input: NotesInput},
|
|
54
|
+
})
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
|
2
|
-
|
|
3
|
-
# Dependencies
|
|
4
|
-
/node_modules
|
|
5
|
-
/.pnp
|
|
6
|
-
.pnp.js
|
|
7
|
-
|
|
8
|
-
# Compiled Sanity Studio
|
|
9
|
-
/dist
|
|
10
|
-
|
|
11
|
-
# Temporary Sanity runtime, generated by the CLI on every dev server start
|
|
12
|
-
/.sanity
|
|
13
|
-
|
|
14
|
-
# Logs
|
|
15
|
-
/logs
|
|
16
|
-
*.log
|
|
17
|
-
|
|
18
|
-
# Coverage directory used by testing tools
|
|
19
|
-
/coverage
|
|
20
|
-
|
|
21
|
-
# Misc
|
|
22
|
-
.DS_Store
|
|
23
|
-
*.pem
|
|
24
|
-
|
|
25
|
-
# Typescript
|
|
26
|
-
*.tsbuildinfo
|