sanity 3.77.3-server-side-schemas.15 → 3.77.3-server-side-schemas.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/lib/_chunks-cjs/_internal.js +427 -142
  2. package/lib/_chunks-cjs/_internal.js.map +1 -1
  3. package/lib/_chunks-cjs/buildAction.js +2 -2
  4. package/lib/_chunks-cjs/buildAction.js.map +1 -1
  5. package/lib/_chunks-cjs/deleteSchemaAction.js +13 -7
  6. package/lib/_chunks-cjs/deleteSchemaAction.js.map +1 -1
  7. package/lib/_chunks-cjs/deployAction.js +3 -3
  8. package/lib/_chunks-cjs/deployAction.js.map +1 -1
  9. package/lib/_chunks-cjs/devAction.js +2 -2
  10. package/lib/_chunks-cjs/devAction.js.map +1 -1
  11. package/lib/_chunks-cjs/version.js +1 -1
  12. package/lib/_chunks-es/version.mjs +1 -1
  13. package/lib/_legacy/version.esm.js +1 -1
  14. package/lib/index.d.mts +3 -3
  15. package/lib/index.d.ts +3 -3
  16. package/lib/structure.d.mts +1 -1
  17. package/lib/structure.d.ts +1 -1
  18. package/package.json +10 -10
  19. package/src/_internal/cli/actions/manifest/extractManifestAction.ts +3 -3
  20. package/src/_internal/cli/actions/schema/deleteSchemaAction.ts +24 -9
  21. package/src/_internal/cli/actions/schema/schemaListAction.ts +28 -10
  22. package/src/_internal/cli/actions/schema/storeSchemasAction.ts +63 -22
  23. package/src/_internal/cli/commands/app/deployCommand.ts +2 -0
  24. package/src/_internal/cli/commands/index.ts +12 -4
  25. package/src/_internal/cli/commands/schema/deleteSchemaCommand.ts +1 -1
  26. package/src/_internal/cli/commands/schema/schemaListCommand.ts +1 -1
  27. package/src/_internal/cli/commands/schema/storeSchemaCommand.ts +6 -5
  28. package/lib/_chunks-cjs/extractManifestAction.js +0 -99
  29. package/lib/_chunks-cjs/extractManifestAction.js.map +0 -1
  30. package/lib/_chunks-cjs/storeSchemasAction.js +0 -147
  31. package/lib/_chunks-cjs/storeSchemasAction.js.map +0 -1
  32. package/lib/_chunks-cjs/timing.js +0 -22
  33. package/lib/_chunks-cjs/timing.js.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sanity",
3
- "version": "3.77.3-server-side-schemas.15+9ffaf1fe9f",
3
+ "version": "3.77.3-server-side-schemas.20+98354d9a54",
4
4
  "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",
5
5
  "keywords": [
6
6
  "sanity",
@@ -160,11 +160,11 @@
160
160
  "@rexxars/react-json-inspector": "^9.0.1",
161
161
  "@sanity/asset-utils": "^2.0.6",
162
162
  "@sanity/bifur-client": "^0.4.1",
163
- "@sanity/cli": "3.77.3-server-side-schemas.15+9ffaf1fe9f",
163
+ "@sanity/cli": "3.77.3-server-side-schemas.20+98354d9a54",
164
164
  "@sanity/client": "^6.28.1",
165
165
  "@sanity/color": "^3.0.0",
166
166
  "@sanity/comlink": "^3.0.1",
167
- "@sanity/diff": "3.77.3-server-side-schemas.15+9ffaf1fe9f",
167
+ "@sanity/diff": "3.77.3-server-side-schemas.20+98354d9a54",
168
168
  "@sanity/diff-match-patch": "^3.1.1",
169
169
  "@sanity/diff-patch": "^5.0.0",
170
170
  "@sanity/eventsource": "^5.0.0",
@@ -174,15 +174,15 @@
174
174
  "@sanity/import": "^3.37.9",
175
175
  "@sanity/insert-menu": "^1.1.3",
176
176
  "@sanity/logos": "^2.1.13",
177
- "@sanity/migrate": "3.77.3-server-side-schemas.15+9ffaf1fe9f",
178
- "@sanity/mutator": "3.77.3-server-side-schemas.15+9ffaf1fe9f",
177
+ "@sanity/migrate": "3.77.3-server-side-schemas.20+98354d9a54",
178
+ "@sanity/mutator": "3.77.3-server-side-schemas.20+98354d9a54",
179
179
  "@sanity/presentation-comlink": "^1.0.8",
180
180
  "@sanity/preview-url-secret": "^2.1.4",
181
- "@sanity/schema": "3.77.3-server-side-schemas.15+9ffaf1fe9f",
181
+ "@sanity/schema": "3.77.3-server-side-schemas.20+98354d9a54",
182
182
  "@sanity/telemetry": "^0.7.7",
183
- "@sanity/types": "3.77.3-server-side-schemas.15+9ffaf1fe9f",
183
+ "@sanity/types": "3.77.3-server-side-schemas.20+98354d9a54",
184
184
  "@sanity/ui": "^2.14.3",
185
- "@sanity/util": "3.77.3-server-side-schemas.15+9ffaf1fe9f",
185
+ "@sanity/util": "3.77.3-server-side-schemas.20+98354d9a54",
186
186
  "@sanity/uuid": "^3.0.2",
187
187
  "@sentry/react": "^8.33.0",
188
188
  "@tanstack/react-table": "^8.16.0",
@@ -280,7 +280,7 @@
280
280
  "@repo/dev-aliases": "3.77.2",
281
281
  "@repo/package.config": "3.77.2",
282
282
  "@repo/test-config": "3.77.2",
283
- "@sanity/codegen": "3.77.3-server-side-schemas.15+9ffaf1fe9f",
283
+ "@sanity/codegen": "3.77.3-server-side-schemas.20+98354d9a54",
284
284
  "@sanity/generate-help-url": "^3.0.0",
285
285
  "@sanity/pkg-utils": "6.13.4",
286
286
  "@sanity/tsdoc": "1.0.169",
@@ -325,5 +325,5 @@
325
325
  "engines": {
326
326
  "node": ">=18"
327
327
  },
328
- "gitHead": "9ffaf1fe9f0b8eecb91741bc04a8ebdd13190ec7"
328
+ "gitHead": "98354d9a54e0adbedd489c794db794cd8e220df4"
329
329
  }
@@ -33,7 +33,7 @@ const EXTRACT_FAILURE_MESSAGE =
33
33
  "↳ Couldn't extract manifest file. Sanity Create will not be available for the studio.\n" +
34
34
  ` Disable this message with ${FEATURE_ENABLED_ENV_NAME}=false`
35
35
 
36
- interface ExtractFlags {
36
+ export interface ExtractManifestFlags {
37
37
  path?: string
38
38
  }
39
39
 
@@ -42,7 +42,7 @@ interface ExtractFlags {
42
42
  * @returns `undefined` if extract succeeded - caught error if it failed
43
43
  */
44
44
  export async function extractManifestSafe(
45
- args: CliCommandArguments<ExtractFlags>,
45
+ args: CliCommandArguments<ExtractManifestFlags>,
46
46
  context: CliCommandContext,
47
47
  ): Promise<Error | undefined> {
48
48
  if (!EXTRACT_MANIFEST_ENABLED) {
@@ -61,7 +61,7 @@ export async function extractManifestSafe(
61
61
  }
62
62
 
63
63
  async function extractManifest(
64
- args: CliCommandArguments<ExtractFlags>,
64
+ args: CliCommandArguments<ExtractManifestFlags>,
65
65
  context: CliCommandContext,
66
66
  ): Promise<void> {
67
67
  const {output, workDir} = context
@@ -2,22 +2,30 @@ import {type CliCommandArguments, type CliCommandContext} from '@sanity/cli'
2
2
  import chalk from 'chalk'
3
3
 
4
4
  import {type ManifestWorkspaceFile} from '../../../manifest/manifestTypes'
5
- import {getManifestPath, readManifest, throwIfProjectIdMismatch} from './storeSchemasAction'
5
+ import {
6
+ getManifestPath,
7
+ readManifest,
8
+ SCHEMA_STORE_ENABLED,
9
+ throwIfProjectIdMismatch,
10
+ } from './storeSchemasAction'
6
11
 
7
12
  export interface DeleteSchemaFlags {
8
- ids: string
9
- path: string
10
- dataset: string
13
+ 'ids': string
14
+ 'manifest-dir': string
15
+ 'dataset': string
11
16
  }
12
17
 
13
18
  export default async function deleteSchemaAction(
14
19
  args: CliCommandArguments<DeleteSchemaFlags>,
15
20
  context: CliCommandContext,
16
21
  ): Promise<void> {
22
+ if (!SCHEMA_STORE_ENABLED) {
23
+ return
24
+ }
17
25
  const flags = args.extOptions
18
26
  if (typeof flags.dataset === 'boolean') throw new Error('Dataset is empty')
19
- if (typeof flags.ids === 'boolean') throw new Error('Ids are empty')
20
- if (typeof flags.path === 'boolean') throw new Error('Path is empty')
27
+ if (typeof flags['manifest-dir'] === 'boolean') throw new Error('Manifest directory is empty')
28
+ if (typeof flags.ids !== 'string') throw new Error('--ids is required')
21
29
 
22
30
  const {apiClient, output} = context
23
31
 
@@ -36,8 +44,9 @@ export default async function deleteSchemaAction(
36
44
  return
37
45
  }
38
46
 
39
- const manifestPath = getManifestPath(context, flags.path)
40
- const manifest = readManifest(manifestPath, output)
47
+ const manifestDir = flags['manifest-dir']
48
+ const manifestPath = getManifestPath(context, manifestDir)
49
+ const manifest = await readManifest(manifestPath, context)
41
50
 
42
51
  const results = await Promise.allSettled(
43
52
  manifest.workspaces.flatMap((workspace: ManifestWorkspaceFile) => {
@@ -59,6 +68,7 @@ export default async function deleteSchemaAction(
59
68
  .delete(schemaId.trim())
60
69
 
61
70
  if (!deletedSchema.results.length) {
71
+ output.error(`Schema ${schemaId} not found in workspace: ${workspace.name}`)
62
72
  return false
63
73
  }
64
74
 
@@ -86,5 +96,10 @@ export default async function deleteSchemaAction(
86
96
  })
87
97
  .filter(Boolean).length
88
98
 
89
- output.print(`Successfully deleted ${deletedCount} schemas`)
99
+ if (deletedCount === 0) {
100
+ output.error('No schemas were deleted')
101
+ return
102
+ }
103
+
104
+ output.success(`Successfully deleted ${deletedCount} schemas`)
90
105
  }
@@ -4,12 +4,17 @@ import chalk from 'chalk'
4
4
  import {size, sortBy, uniqBy} from 'lodash'
5
5
 
6
6
  import {type ManifestWorkspaceFile} from '../../../manifest/manifestTypes'
7
- import {getManifestPath, readManifest, throwIfProjectIdMismatch} from './storeSchemasAction'
7
+ import {
8
+ getManifestPath,
9
+ readManifest,
10
+ SCHEMA_STORE_ENABLED,
11
+ throwIfProjectIdMismatch,
12
+ } from './storeSchemasAction'
8
13
 
9
14
  export interface SchemaListFlags {
10
- json: boolean
11
- id: string
12
- path: string
15
+ 'json': boolean
16
+ 'id': string
17
+ 'manifest-dir': string
13
18
  }
14
19
 
15
20
  type PrintSchemaListArgs = {
@@ -46,11 +51,18 @@ const printSchemaList = ({
46
51
  rows.forEach((row) => output.print(printRow(row)))
47
52
  }
48
53
 
49
- export default async function fetchSchemaAction(
54
+ export default async function schemaListAction(
50
55
  args: CliCommandArguments<SchemaListFlags>,
51
56
  context: CliCommandContext,
52
57
  ): Promise<void> {
58
+ if (!SCHEMA_STORE_ENABLED) {
59
+ return
60
+ }
61
+
53
62
  const flags = args.extOptions
63
+ if (typeof flags.id === 'boolean') throw new Error('Schema ID is empty')
64
+ if (typeof flags['manifest-dir'] === 'boolean') throw new Error('Manifest directory is empty')
65
+
54
66
  const {apiClient, output} = context
55
67
  const client = apiClient({
56
68
  requireUser: true,
@@ -58,14 +70,16 @@ export default async function fetchSchemaAction(
58
70
  }).withConfig({apiVersion: 'v2024-08-01'})
59
71
 
60
72
  const projectId = client.config().projectId
73
+ const dataset = client.config().dataset
61
74
 
62
- if (!projectId) {
63
- output.error('Project ID must be defined.')
75
+ if (!projectId || !dataset) {
76
+ output.error('Project ID and dataset must be defined.')
64
77
  return
65
78
  }
66
79
 
67
- const manifestPath = getManifestPath(context, flags.path)
68
- const manifest = readManifest(manifestPath, output)
80
+ const manifestDir = flags['manifest-dir']
81
+ const manifestPath = getManifestPath(context, manifestDir)
82
+ const manifest = await readManifest(manifestPath, context)
69
83
 
70
84
  // Gather all schemas
71
85
  const results = await Promise.allSettled(
@@ -73,12 +87,16 @@ export default async function fetchSchemaAction(
73
87
  throwIfProjectIdMismatch(workspace, projectId)
74
88
  if (flags.id) {
75
89
  // Fetch a specific schema by id
76
- return await client
90
+ const schemaRes = await client
77
91
  .withConfig({
78
92
  dataset: workspace.dataset,
79
93
  projectId: workspace.projectId,
80
94
  })
81
95
  .getDocument(flags.id)
96
+ if (!schemaRes) {
97
+ throw new Error(`Schema "${flags.id}" not found in dataset "${workspace.dataset}"`)
98
+ }
99
+ return schemaRes
82
100
  }
83
101
  // Fetch all schemas
84
102
  return await client
@@ -1,16 +1,22 @@
1
- import {readFileSync} from 'node:fs'
1
+ import {readFileSync, statSync} from 'node:fs'
2
2
  import path, {join, resolve} from 'node:path'
3
3
 
4
- import {type CliCommandArguments, type CliCommandContext, type CliOutputter} from '@sanity/cli'
4
+ import {type CliCommandArguments, type CliCommandContext} from '@sanity/cli'
5
5
  import chalk from 'chalk'
6
- import {type Ora} from 'ora'
7
6
 
8
7
  import {type ManifestSchemaType, type ManifestWorkspaceFile} from '../../../manifest/manifestTypes'
9
- import {MANIFEST_FILENAME} from '../manifest/extractManifestAction'
8
+ import {
9
+ type ExtractManifestFlags,
10
+ extractManifestSafe,
11
+ MANIFEST_FILENAME,
12
+ } from '../manifest/extractManifestAction'
10
13
  import {SANITY_WORKSPACE_SCHEMA_TYPE} from './schemaListAction'
11
14
 
15
+ const FEATURE_ENABLED_ENV_NAME = 'SANITY_CLI_SCHEMA_STORE_ENABLED'
16
+ export const SCHEMA_STORE_ENABLED = process.env[FEATURE_ENABLED_ENV_NAME] === 'true'
17
+
12
18
  export interface StoreManifestSchemasFlags {
13
- 'path'?: string
19
+ 'manifest-dir'?: string
14
20
  'workspace'?: string
15
21
  'id-prefix'?: string
16
22
  'schema-required'?: boolean
@@ -28,14 +34,48 @@ export const getManifestPath = (context: CliCommandContext, customPath?: string)
28
34
  return manifestPath
29
35
  }
30
36
 
31
- export const readManifest = (readPath: string, output?: CliOutputter, spinner?: Ora) => {
37
+ /**
38
+ * Helper function to read and parse a manifest file with logging
39
+ */
40
+ const readAndParseManifest = (manifestPath: string, context: CliCommandContext) => {
41
+ const content = readFileSync(manifestPath, 'utf-8')
42
+ const stats = statSync(manifestPath)
43
+ const lastModified = stats.mtime.toISOString()
44
+ context.output.print(
45
+ chalk.gray(`↳ Read manifest from ${manifestPath} (last modified: ${lastModified})`),
46
+ )
47
+ return JSON.parse(content)
48
+ }
49
+
50
+ export const readManifest = async (readPath: string, context: CliCommandContext) => {
51
+ const manifestPath = `${readPath}/${MANIFEST_FILENAME}`
52
+
32
53
  try {
33
- return JSON.parse(readFileSync(`${readPath}/${MANIFEST_FILENAME}`, 'utf-8'))
54
+ return readAndParseManifest(manifestPath, context)
34
55
  } catch (error) {
35
- const errorMessage = `Manifest not found at ${readPath}/${MANIFEST_FILENAME}`
36
- if (spinner) spinner.fail(errorMessage)
37
- if (output) output.error(errorMessage)
38
- throw error
56
+ // Still log that we're attempting extraction
57
+ context.output.error(`Manifest not found, attempting to extract it...${manifestPath}`)
58
+
59
+ await extractManifestSafe(
60
+ {
61
+ extOptions: {path: readPath},
62
+ groupOrCommand: 'extract',
63
+ argv: [],
64
+ argsWithoutOptions: [],
65
+ extraArguments: [],
66
+ } as CliCommandArguments<ExtractManifestFlags>,
67
+ context,
68
+ )
69
+
70
+ // Try reading the manifest again after extraction
71
+ try {
72
+ return readAndParseManifest(manifestPath, context)
73
+ } catch (retryError) {
74
+ const errorMessage = `Failed to read manifest at ${manifestPath}`
75
+ // We should log the error too for consistency
76
+ context.output.error(errorMessage)
77
+ throw retryError
78
+ }
39
79
  }
40
80
  }
41
81
 
@@ -55,22 +95,25 @@ export default async function storeSchemasAction(
55
95
  args: CliCommandArguments<StoreManifestSchemasFlags>,
56
96
  context: CliCommandContext,
57
97
  ): Promise<Error | undefined> {
98
+ if (!SCHEMA_STORE_ENABLED) {
99
+ return undefined
100
+ }
101
+
58
102
  const flags = args.extOptions
59
103
 
60
104
  const schemaRequired = flags['schema-required']
61
105
  const workspaceName = flags.workspace
62
106
  const idPrefix = flags['id-prefix']
63
107
  const verbose = flags.verbose
108
+ const manifestDir = flags['manifest-dir']
64
109
 
65
- if (typeof flags.path === 'boolean') throw new Error('Path is empty')
110
+ if (typeof manifestDir === 'boolean') throw new Error('Manifest directory is empty')
66
111
  if (typeof idPrefix === 'boolean') throw new Error('Id prefix is empty')
67
112
  if (typeof workspaceName === 'boolean') throw new Error('Workspace is empty')
68
113
 
69
114
  const {output, apiClient} = context
70
115
 
71
- const spinner = output.spinner({}).start('Storing schemas')
72
-
73
- const manifestPath = getManifestPath(context, flags.path)
116
+ const manifestPath = getManifestPath(context, manifestDir)
74
117
 
75
118
  try {
76
119
  const client = apiClient({
@@ -81,7 +124,7 @@ export default async function storeSchemasAction(
81
124
  const projectId = client.config().projectId
82
125
  if (!projectId) throw new Error('Project ID is not defined')
83
126
 
84
- const manifest = readManifest(manifestPath, output, spinner)
127
+ const manifest = await readManifest(manifestPath, context)
85
128
 
86
129
  let storedCount = 0
87
130
 
@@ -103,11 +146,9 @@ export default async function storeSchemasAction(
103
146
  .createOrReplace({_type: SANITY_WORKSPACE_SCHEMA_TYPE, _id: id, workspace, schema})
104
147
  .commit()
105
148
  storedCount++
106
- spinner.text = `Stored ${storedCount} schemas so far...`
107
- if (verbose) spinner.succeed(`Schema stored for workspace '${workspace.name}'`)
108
149
  } catch (err) {
109
150
  error = err
110
- spinner.fail(
151
+ output.error(
111
152
  `Error storing schema for workspace '${workspace.name}':\n${chalk.red(`${err.message}`)}`,
112
153
  )
113
154
  if (schemaRequired) throw err
@@ -126,18 +167,18 @@ export default async function storeSchemasAction(
126
167
  (workspace: ManifestWorkspaceFile) => workspace.name === workspaceName,
127
168
  )
128
169
  if (!workspaceToSave) {
129
- spinner.fail(`Workspace ${workspaceName} not found in manifest`)
170
+ output.error(`Workspace ${workspaceName} not found in manifest`)
130
171
  throw new Error(`Workspace ${workspaceName} not found in manifest: projectID: ${projectId}`)
131
172
  }
132
173
  await saveSchema(workspaceToSave as ManifestWorkspaceFile)
133
- spinner.succeed(`Stored 1 schemas`)
174
+ output.success(`Stored 1 schemas`)
134
175
  } else {
135
176
  await Promise.all(
136
177
  manifest.workspaces.map(async (workspace: ManifestWorkspaceFile): Promise<void> => {
137
178
  await saveSchema(workspace)
138
179
  }),
139
180
  )
140
- spinner.succeed(`Stored ${storedCount}/${manifest.workspaces.length} schemas`)
181
+ output.success(`Stored ${storedCount}/${manifest.workspaces.length} schemas`)
141
182
  }
142
183
 
143
184
  if (error) throw error
@@ -5,12 +5,14 @@ import {
5
5
  } from '@sanity/cli'
6
6
 
7
7
  import {type DeployStudioActionFlags} from '../../actions/deploy/deployAction'
8
+ import {SCHEMA_STORE_ENABLED} from '../../actions/schema/storeSchemasAction'
8
9
 
9
10
  const helpText = `
10
11
  Options
11
12
  --source-maps Enable source maps for built bundles (increases size of bundle)
12
13
  --no-minify Skip minifying built JavaScript (speeds up build, increases size of bundle)
13
14
  --no-build Don't build the application prior to deploy, instead deploying the version currently in \`dist/\`
15
+ ${SCHEMA_STORE_ENABLED ? '--verbose Enable verbose logging for the schema store' : ''}
14
16
  -y, --yes Unattended mode, answers "yes" to any "yes/no" prompt and otherwise uses defaults
15
17
 
16
18
  Examples
@@ -1,5 +1,6 @@
1
1
  import {type CliCommandDefinition, type CliCommandGroupDefinition} from '@sanity/cli'
2
2
 
3
+ import {SCHEMA_STORE_ENABLED} from '../actions/schema/storeSchemasAction'
3
4
  import appGroup from './app/appGroup'
4
5
  import appBuildCommand from './app/buildCommand'
5
6
  import appDeployCommand from './app/deployCommand'
@@ -62,7 +63,8 @@ import inviteUserCommand from './users/inviteUserCommand'
62
63
  import listUsersCommand from './users/listUsersCommand'
63
64
  import usersGroup from './users/usersGroup'
64
65
 
65
- const commands: (CliCommandDefinition | CliCommandGroupDefinition)[] = [
66
+ // Base commands that are always included
67
+ const baseCommands: (CliCommandDefinition | CliCommandGroupDefinition)[] = [
66
68
  appGroup,
67
69
  appDeployCommand,
68
70
  appDevCommand,
@@ -118,12 +120,18 @@ const commands: (CliCommandDefinition | CliCommandGroupDefinition)[] = [
118
120
  validateSchemaCommand,
119
121
  extractSchemaCommand,
120
122
  previewCommand,
121
- fetchSchemaCommand,
122
- storeSchemaCommand,
123
123
  execCommand,
124
124
  manifestGroup,
125
125
  extractManifestCommand,
126
- deleteSchemaCommand,
126
+ ]
127
+
128
+ // Internal schema commands that are only included when enabled
129
+ const internalSchemaCommands = [fetchSchemaCommand, storeSchemaCommand, deleteSchemaCommand]
130
+
131
+ // Include experimental commands only when the feature flag is enabled
132
+ const commands: (CliCommandDefinition | CliCommandGroupDefinition)[] = [
133
+ ...baseCommands,
134
+ ...(SCHEMA_STORE_ENABLED ? internalSchemaCommands : []),
127
135
  ]
128
136
 
129
137
  /**
@@ -10,7 +10,7 @@ const helpText = `
10
10
  Options
11
11
  --ids <schema_id_1,schema_id_2,...> comma-separated list of schema IDs to delete
12
12
  --dataset <dataset_name> delete schemas from a specific dataset
13
- --path <path> path to the manifest file if it is not in the default location
13
+ --manifest-dir <directory> directory containing your manifest file if it's not in the default location
14
14
 
15
15
  Examples
16
16
  # Delete single schema
@@ -10,7 +10,7 @@ const helpText = `
10
10
  Options
11
11
  --json get schemas as json
12
12
  --id <schema_id> fetch a specific schema by its ID
13
- --path <path> path to your manifest file if it's not in the default location
13
+ --manifest-dir <directory> directory containing your manifest file if it's not in the default location
14
14
 
15
15
  Examples
16
16
  # Get full json schemas
@@ -2,16 +2,17 @@ import {type CliCommandArguments, type CliCommandDefinition} from '@sanity/cli'
2
2
 
3
3
  import {type StoreManifestSchemasFlags} from '../../actions/schema/storeSchemasAction'
4
4
 
5
- const description = 'Store schemas into the current dataset.'
5
+ const description = 'Store schemas into workspace datasets.'
6
6
 
7
7
  const helpText = `
8
8
  **Note**: This command is experimental and subject to change.
9
9
 
10
10
  Options:
11
- --workspace The name of the workspace to fetch the stored schema for
12
- --path If you are not using the default static file path, you can specify it here.
13
- --id-prefix you can specify a custom id prefix for the stored schemas. Useful if you want to store the schema in a different path than the default one.
14
- --verbose Enable verbose logging
11
+ --workspace <workspace_name> store schema for a specific workspace
12
+ --manifest-dir <directory> directory containing your manifest file if it's not in the default location
13
+ --id-prefix <prefix> add a prefix to the schema ID
14
+ --schema-required fail if schema file is not found
15
+ --verbose print detailed information during store
15
16
 
16
17
  Examples
17
18
  # if no options are provided all workspace schemas will be stored
@@ -1,99 +0,0 @@
1
- "use strict";
2
- var node_crypto = require("node:crypto"), fs = require("node:fs/promises"), path = require("node:path"), node_worker_threads = require("node:worker_threads"), chalk = require("chalk"), dateFns = require("date-fns"), readPkgUp = require("read-pkg-up"), timing = require("./timing.js");
3
- function _interopDefaultCompat(e) {
4
- return e && typeof e == "object" && "default" in e ? e : { default: e };
5
- }
6
- var chalk__default = /* @__PURE__ */ _interopDefaultCompat(chalk), readPkgUp__default = /* @__PURE__ */ _interopDefaultCompat(readPkgUp);
7
- const MANIFEST_FILENAME = "create-manifest.json", SCHEMA_FILENAME_SUFFIX = ".create-schema.json", TOOLS_FILENAME_SUFFIX = ".create-tools.json", FEATURE_ENABLED_ENV_NAME = "SANITY_CLI_EXTRACT_MANIFEST_ENABLED", EXTRACT_MANIFEST_ENABLED = process.env[FEATURE_ENABLED_ENV_NAME] !== "false", EXTRACT_MANIFEST_LOG_ERRORS = process.env.SANITY_CLI_EXTRACT_MANIFEST_LOG_ERRORS === "true", CREATE_TIMER = "create-manifest", EXTRACT_TASK_TIMEOUT_MS = dateFns.minutesToMilliseconds(2), EXTRACT_FAILURE_MESSAGE = `\u21B3 Couldn't extract manifest file. Sanity Create will not be available for the studio.
8
- Disable this message with ${FEATURE_ENABLED_ENV_NAME}=false`;
9
- async function extractManifestSafe(args, context) {
10
- if (EXTRACT_MANIFEST_ENABLED)
11
- try {
12
- await extractManifest(args, context);
13
- return;
14
- } catch (err) {
15
- return EXTRACT_MANIFEST_LOG_ERRORS && context.output.error(err), err;
16
- }
17
- }
18
- async function extractManifest(args, context) {
19
- const {
20
- output,
21
- workDir
22
- } = context, flags = args.extOptions, defaultOutputDir = path.resolve(path.join(workDir, "dist")), outputDir = path.resolve(defaultOutputDir), defaultStaticPath = path.join(outputDir, "static"), staticPath = flags.path ?? defaultStaticPath, path$1 = path.join(staticPath, MANIFEST_FILENAME), rootPkgPath = readPkgUp__default.default.sync({
23
- cwd: __dirname
24
- })?.path;
25
- if (!rootPkgPath)
26
- throw new Error("Could not find root directory for `sanity` package");
27
- const timer = timing.getTimer();
28
- timer.start(CREATE_TIMER);
29
- const spinner = output.spinner({}).start("Extracting manifest");
30
- try {
31
- const workspaceManifests = await getWorkspaceManifests({
32
- rootPkgPath,
33
- workDir
34
- });
35
- await fs.mkdir(staticPath, {
36
- recursive: !0
37
- });
38
- const workspaceFiles = await writeWorkspaceFiles(workspaceManifests, staticPath), manifest = {
39
- /**
40
- * Version history:
41
- * 1: Initial release.
42
- * 2: Added tools file.
43
- */
44
- version: 2,
45
- createdAt: (/* @__PURE__ */ new Date()).toISOString(),
46
- workspaces: workspaceFiles
47
- };
48
- await fs.writeFile(path$1, JSON.stringify(manifest, null, 2));
49
- const manifestDuration = timer.end(CREATE_TIMER);
50
- spinner.succeed(`Extracted manifest (${manifestDuration.toFixed()}ms)`);
51
- } catch (err) {
52
- throw spinner.fail(err.message), output.print(chalk__default.default.gray(EXTRACT_FAILURE_MESSAGE)), err;
53
- }
54
- }
55
- async function getWorkspaceManifests({
56
- rootPkgPath,
57
- workDir
58
- }) {
59
- const workerPath = path.join(path.dirname(rootPkgPath), "lib", "_internal", "cli", "threads", "extractManifest.js"), worker = new node_worker_threads.Worker(workerPath, {
60
- workerData: {
61
- workDir
62
- },
63
- // eslint-disable-next-line no-process-env
64
- env: process.env
65
- });
66
- let timeout = !1;
67
- const timeoutId = setTimeout(() => {
68
- timeout = !0, worker.terminate();
69
- }, EXTRACT_TASK_TIMEOUT_MS);
70
- try {
71
- return await new Promise((resolveWorkspaces, reject) => {
72
- const buffer = [];
73
- worker.addListener("message", (message) => buffer.push(message)), worker.addListener("exit", (exitCode) => {
74
- exitCode === 0 ? resolveWorkspaces(buffer) : timeout && reject(new Error(`Extract manifest was aborted after ${EXTRACT_TASK_TIMEOUT_MS}ms`));
75
- }), worker.addListener("error", reject);
76
- });
77
- } finally {
78
- clearTimeout(timeoutId);
79
- }
80
- }
81
- function writeWorkspaceFiles(manifestWorkspaces, staticPath) {
82
- const output = manifestWorkspaces.reduce((workspaces, workspace) => [...workspaces, writeWorkspaceFile(workspace, staticPath)], []);
83
- return Promise.all(output);
84
- }
85
- async function writeWorkspaceFile(workspace, staticPath) {
86
- const [schemaFilename, toolsFilename] = await Promise.all([createFile(staticPath, workspace.schema, SCHEMA_FILENAME_SUFFIX), createFile(staticPath, workspace.tools, TOOLS_FILENAME_SUFFIX)]);
87
- return {
88
- ...workspace,
89
- schema: schemaFilename,
90
- tools: toolsFilename
91
- };
92
- }
93
- const createFile = async (path$1, content, filenameSuffix) => {
94
- const stringifiedContent = JSON.stringify(content, null, 2), filename = `${node_crypto.createHash("sha1").update(stringifiedContent).digest("hex").slice(0, 8)}${filenameSuffix}`;
95
- return await fs.writeFile(path.join(path$1, filename), stringifiedContent), filename;
96
- };
97
- exports.MANIFEST_FILENAME = MANIFEST_FILENAME;
98
- exports.extractManifestSafe = extractManifestSafe;
99
- //# sourceMappingURL=extractManifestAction.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"extractManifestAction.js","sources":["../../src/_internal/cli/actions/manifest/extractManifestAction.ts"],"sourcesContent":["import {createHash} from 'node:crypto'\nimport {mkdir, writeFile} from 'node:fs/promises'\nimport {dirname, join, resolve} from 'node:path'\nimport {Worker} from 'node:worker_threads'\n\nimport {type CliCommandArguments, type CliCommandContext} from '@sanity/cli'\nimport chalk from 'chalk'\nimport {minutesToMilliseconds} from 'date-fns'\nimport readPkgUp from 'read-pkg-up'\n\nimport {\n type CreateManifest,\n type CreateWorkspaceManifest,\n type ManifestWorkspaceFile,\n} from '../../../manifest/manifestTypes'\nimport {type ExtractManifestWorkerData} from '../../threads/extractManifest'\nimport {getTimer} from '../../util/timing'\n\nexport const MANIFEST_FILENAME = 'create-manifest.json'\nconst SCHEMA_FILENAME_SUFFIX = '.create-schema.json'\nconst TOOLS_FILENAME_SUFFIX = '.create-tools.json'\n\n/** Escape-hatch env flags to change action behavior */\nconst FEATURE_ENABLED_ENV_NAME = 'SANITY_CLI_EXTRACT_MANIFEST_ENABLED'\nconst EXTRACT_MANIFEST_ENABLED = process.env[FEATURE_ENABLED_ENV_NAME] !== 'false'\nconst EXTRACT_MANIFEST_LOG_ERRORS = process.env.SANITY_CLI_EXTRACT_MANIFEST_LOG_ERRORS === 'true'\n\nconst CREATE_TIMER = 'create-manifest'\n\nconst EXTRACT_TASK_TIMEOUT_MS = minutesToMilliseconds(2)\n\nconst EXTRACT_FAILURE_MESSAGE =\n \"↳ Couldn't extract manifest file. Sanity Create will not be available for the studio.\\n\" +\n ` Disable this message with ${FEATURE_ENABLED_ENV_NAME}=false`\n\ninterface ExtractFlags {\n path?: string\n}\n\n/**\n * This function will never throw.\n * @returns `undefined` if extract succeeded - caught error if it failed\n */\nexport async function extractManifestSafe(\n args: CliCommandArguments<ExtractFlags>,\n context: CliCommandContext,\n): Promise<Error | undefined> {\n if (!EXTRACT_MANIFEST_ENABLED) {\n return undefined\n }\n\n try {\n await extractManifest(args, context)\n return undefined\n } catch (err) {\n if (EXTRACT_MANIFEST_LOG_ERRORS) {\n context.output.error(err)\n }\n return err\n }\n}\n\nasync function extractManifest(\n args: CliCommandArguments<ExtractFlags>,\n context: CliCommandContext,\n): Promise<void> {\n const {output, workDir} = context\n\n const flags = args.extOptions\n const defaultOutputDir = resolve(join(workDir, 'dist'))\n\n const outputDir = resolve(defaultOutputDir)\n const defaultStaticPath = join(outputDir, 'static')\n\n const staticPath = flags.path ?? defaultStaticPath\n\n const path = join(staticPath, MANIFEST_FILENAME)\n\n const rootPkgPath = readPkgUp.sync({cwd: __dirname})?.path\n if (!rootPkgPath) {\n throw new Error('Could not find root directory for `sanity` package')\n }\n\n const timer = getTimer()\n timer.start(CREATE_TIMER)\n const spinner = output.spinner({}).start('Extracting manifest')\n\n try {\n const workspaceManifests = await getWorkspaceManifests({rootPkgPath, workDir})\n await mkdir(staticPath, {recursive: true})\n\n const workspaceFiles = await writeWorkspaceFiles(workspaceManifests, staticPath)\n\n const manifest: CreateManifest = {\n /**\n * Version history:\n * 1: Initial release.\n * 2: Added tools file.\n */\n version: 2,\n createdAt: new Date().toISOString(),\n workspaces: workspaceFiles,\n }\n\n await writeFile(path, JSON.stringify(manifest, null, 2))\n const manifestDuration = timer.end(CREATE_TIMER)\n\n spinner.succeed(`Extracted manifest (${manifestDuration.toFixed()}ms)`)\n } catch (err) {\n spinner.fail(err.message)\n output.print(chalk.gray(EXTRACT_FAILURE_MESSAGE))\n throw err\n }\n}\n\nasync function getWorkspaceManifests({\n rootPkgPath,\n workDir,\n}: {\n rootPkgPath: string\n workDir: string\n}): Promise<CreateWorkspaceManifest[]> {\n const workerPath = join(\n dirname(rootPkgPath),\n 'lib',\n '_internal',\n 'cli',\n 'threads',\n 'extractManifest.js',\n )\n\n const worker = new Worker(workerPath, {\n workerData: {workDir} satisfies ExtractManifestWorkerData,\n // eslint-disable-next-line no-process-env\n env: process.env,\n })\n\n let timeout = false\n const timeoutId = setTimeout(() => {\n timeout = true\n worker.terminate()\n }, EXTRACT_TASK_TIMEOUT_MS)\n\n try {\n return await new Promise<CreateWorkspaceManifest[]>((resolveWorkspaces, reject) => {\n const buffer: CreateWorkspaceManifest[] = []\n worker.addListener('message', (message) => buffer.push(message))\n worker.addListener('exit', (exitCode) => {\n if (exitCode === 0) {\n resolveWorkspaces(buffer)\n } else if (timeout) {\n reject(new Error(`Extract manifest was aborted after ${EXTRACT_TASK_TIMEOUT_MS}ms`))\n }\n })\n worker.addListener('error', reject)\n })\n } finally {\n clearTimeout(timeoutId)\n }\n}\n\nfunction writeWorkspaceFiles(\n manifestWorkspaces: CreateWorkspaceManifest[],\n staticPath: string,\n): Promise<ManifestWorkspaceFile[]> {\n const output = manifestWorkspaces.reduce<Promise<ManifestWorkspaceFile>[]>(\n (workspaces, workspace) => {\n return [...workspaces, writeWorkspaceFile(workspace, staticPath)]\n },\n [],\n )\n return Promise.all(output)\n}\n\nasync function writeWorkspaceFile(\n workspace: CreateWorkspaceManifest,\n staticPath: string,\n): Promise<ManifestWorkspaceFile> {\n const [schemaFilename, toolsFilename] = await Promise.all([\n createFile(staticPath, workspace.schema, SCHEMA_FILENAME_SUFFIX),\n createFile(staticPath, workspace.tools, TOOLS_FILENAME_SUFFIX),\n ])\n\n return {\n ...workspace,\n schema: schemaFilename,\n tools: toolsFilename,\n }\n}\n\nconst createFile = async (path: string, content: any, filenameSuffix: string) => {\n const stringifiedContent = JSON.stringify(content, null, 2)\n const hash = createHash('sha1').update(stringifiedContent).digest('hex')\n const filename = `${hash.slice(0, 8)}${filenameSuffix}`\n\n // workspaces with identical data will overwrite each others file. This is ok, since they are identical and can be shared\n await writeFile(join(path, filename), stringifiedContent)\n\n return filename\n}\n"],"names":["MANIFEST_FILENAME","SCHEMA_FILENAME_SUFFIX","TOOLS_FILENAME_SUFFIX","FEATURE_ENABLED_ENV_NAME","EXTRACT_MANIFEST_ENABLED","process","env","EXTRACT_MANIFEST_LOG_ERRORS","SANITY_CLI_EXTRACT_MANIFEST_LOG_ERRORS","CREATE_TIMER","EXTRACT_TASK_TIMEOUT_MS","minutesToMilliseconds","EXTRACT_FAILURE_MESSAGE","extractManifestSafe","args","context","extractManifest","err","output","error","workDir","flags","extOptions","defaultOutputDir","resolve","join","outputDir","defaultStaticPath","staticPath","path","rootPkgPath","readPkgUp","sync","cwd","__dirname","Error","timer","getTimer","start","spinner","workspaceManifests","getWorkspaceManifests","mkdir","recursive","workspaceFiles","writeWorkspaceFiles","manifest","version","createdAt","Date","toISOString","workspaces","writeFile","JSON","stringify","manifestDuration","end","succeed","toFixed","fail","message","print","chalk","gray","workerPath","dirname","worker","Worker","workerData","timeout","timeoutId","setTimeout","terminate","Promise","resolveWorkspaces","reject","buffer","addListener","push","exitCode","clearTimeout","manifestWorkspaces","reduce","workspace","writeWorkspaceFile","all","schemaFilename","toolsFilename","createFile","schema","tools","content","filenameSuffix","stringifiedContent","filename","createHash","update","digest","slice"],"mappings":"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"}