@sanity/cli 8.21.0 → 8.22.1

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 (80) hide show
  1. package/README.md +106 -47
  2. package/codemods/dashboard.js +111 -0
  3. package/dist/actions/build/buildApp.js +1 -1
  4. package/dist/actions/build/buildApp.js.map +1 -1
  5. package/dist/actions/build/buildStudio.js +1 -1
  6. package/dist/actions/build/buildStudio.js.map +1 -1
  7. package/dist/actions/codemods/dashboard.js +113 -0
  8. package/dist/actions/codemods/dashboard.js.map +1 -0
  9. package/dist/actions/codemods/index.js +2 -0
  10. package/dist/actions/codemods/index.js.map +1 -1
  11. package/dist/actions/codemods/types.js.map +1 -1
  12. package/dist/actions/deploy/deployApp.js +13 -6
  13. package/dist/actions/deploy/deployApp.js.map +1 -1
  14. package/dist/actions/deploy/deployChecks.js +12 -7
  15. package/dist/actions/deploy/deployChecks.js.map +1 -1
  16. package/dist/actions/deploy/deployRunner.js +14 -8
  17. package/dist/actions/deploy/deployRunner.js.map +1 -1
  18. package/dist/actions/deploy/deployStudio.js +39 -4
  19. package/dist/actions/deploy/deployStudio.js.map +1 -1
  20. package/dist/actions/deploy/deployStudioSchemasAndManifestsWorker.js +6 -15
  21. package/dist/actions/deploy/deployStudioSchemasAndManifestsWorker.js.map +1 -1
  22. package/dist/actions/deploy/resolveDeployTarget.js +7 -6
  23. package/dist/actions/deploy/resolveDeployTarget.js.map +1 -1
  24. package/dist/actions/init/project/promptForAppTemplateSetup.js +22 -0
  25. package/dist/actions/init/project/promptForAppTemplateSetup.js.map +1 -1
  26. package/dist/actions/schema/deploySchemas.js.map +1 -1
  27. package/dist/actions/schema/extractSchemaWatcher.js +69 -14
  28. package/dist/actions/schema/extractSchemaWatcher.js.map +1 -1
  29. package/dist/actions/schema/listSchemas.js +2 -3
  30. package/dist/actions/schema/listSchemas.js.map +1 -1
  31. package/dist/actions/schema/updateWorkspaceSchema.js.map +1 -1
  32. package/dist/actions/typegen/generateResourceTypes.js +11 -8
  33. package/dist/actions/typegen/generateResourceTypes.js.map +1 -1
  34. package/dist/actions/typegen/watchResourceTypes.js +208 -0
  35. package/dist/actions/typegen/watchResourceTypes.js.map +1 -0
  36. package/dist/actions/undeploy/runUndeploy.js +14 -8
  37. package/dist/actions/undeploy/runUndeploy.js.map +1 -1
  38. package/dist/commands/codemod.js +15 -4
  39. package/dist/commands/codemod.js.map +1 -1
  40. package/dist/commands/context/get.js +3 -8
  41. package/dist/commands/context/get.js.map +1 -1
  42. package/dist/commands/context/imports/download.js +3 -8
  43. package/dist/commands/context/imports/download.js.map +1 -1
  44. package/dist/commands/context/imports/get.js +3 -8
  45. package/dist/commands/context/imports/get.js.map +1 -1
  46. package/dist/commands/context/imports/list.js +3 -8
  47. package/dist/commands/context/imports/list.js.map +1 -1
  48. package/dist/commands/context/jobs/get.js +8 -8
  49. package/dist/commands/context/jobs/get.js.map +1 -1
  50. package/dist/commands/context/list.js +2 -6
  51. package/dist/commands/context/list.js.map +1 -1
  52. package/dist/commands/deploy.js +1 -0
  53. package/dist/commands/deploy.js.map +1 -1
  54. package/dist/commands/doctor.js +2 -1
  55. package/dist/commands/doctor.js.map +1 -1
  56. package/dist/commands/openapi/list.js +2 -4
  57. package/dist/commands/openapi/list.js.map +1 -1
  58. package/dist/commands/projects/create.js +3 -6
  59. package/dist/commands/projects/create.js.map +1 -1
  60. package/dist/commands/schemas/list.js +1 -3
  61. package/dist/commands/schemas/list.js.map +1 -1
  62. package/dist/commands/tokens/create.js +2 -5
  63. package/dist/commands/tokens/create.js.map +1 -1
  64. package/dist/commands/tokens/list.js +2 -6
  65. package/dist/commands/tokens/list.js.map +1 -1
  66. package/dist/commands/tokens/rotate.js +2 -5
  67. package/dist/commands/tokens/rotate.js.map +1 -1
  68. package/dist/commands/typegen/generate.js +83 -45
  69. package/dist/commands/typegen/generate.js.map +1 -1
  70. package/dist/commands/undeploy.js +1 -0
  71. package/dist/commands/undeploy.js.map +1 -1
  72. package/dist/commands/whoami.js +5 -11
  73. package/dist/commands/whoami.js.map +1 -1
  74. package/dist/exports/invokeSanityCli/index.js +26 -6
  75. package/dist/exports/invokeSanityCli/index.js.map +1 -1
  76. package/dist/generated/apiRoutes.js +11 -26
  77. package/dist/generated/apiRoutes.js.map +1 -1
  78. package/dist/telemetry/init.telemetry.js.map +1 -1
  79. package/oclif.manifest.json +2340 -2311
  80. package/package.json +6 -5
package/README.md CHANGED
@@ -139,6 +139,7 @@ Code for sanity cli
139
139
  - [`sanity users invite [EMAIL]`](#sanity-users-invite-email)
140
140
  - [`sanity users list`](#sanity-users-list)
141
141
  - [`sanity versions`](#sanity-versions)
142
+ - [`sanity whoami`](#sanity-whoami)
142
143
  - [`sanity workflows abort INSTANCEID`](#sanity-workflows-abort-instanceid)
143
144
  - [`sanity workflows blueprint generate`](#sanity-workflows-blueprint-generate)
144
145
  - [`sanity workflows definition delete NAME`](#sanity-workflows-definition-delete-name)
@@ -1070,8 +1071,8 @@ USAGE
1070
1071
  ARGUMENTS
1071
1072
  KNOWLEDGEBASEID Knowledge base ID
1072
1073
 
1073
- FLAGS
1074
- --json Output the knowledge base in JSON format
1074
+ GLOBAL FLAGS
1075
+ --json Format output as json.
1075
1076
 
1076
1077
  DESCRIPTION
1077
1078
  Get details of a knowledge base
@@ -1171,8 +1172,8 @@ ARGUMENTS
1171
1172
  KNOWLEDGEBASEID Knowledge base ID
1172
1173
  IMPORTID Import ID
1173
1174
 
1174
- FLAGS
1175
- --json Output the download URL in JSON format
1175
+ GLOBAL FLAGS
1176
+ --json Format output as json.
1176
1177
 
1177
1178
  DESCRIPTION
1178
1179
  Get a short-lived signed URL for the original uploaded bytes of a file import
@@ -1195,8 +1196,8 @@ ARGUMENTS
1195
1196
  KNOWLEDGEBASEID Knowledge base ID
1196
1197
  IMPORTID Import ID
1197
1198
 
1198
- FLAGS
1199
- --json Output the import in JSON format
1199
+ GLOBAL FLAGS
1200
+ --json Format output as json.
1200
1201
 
1201
1202
  DESCRIPTION
1202
1203
  Get details of an import
@@ -1222,8 +1223,8 @@ USAGE
1222
1223
  ARGUMENTS
1223
1224
  KNOWLEDGEBASEID Knowledge base ID
1224
1225
 
1225
- FLAGS
1226
- --json Output imports in JSON format
1226
+ GLOBAL FLAGS
1227
+ --json Format output as json.
1227
1228
 
1228
1229
  DESCRIPTION
1229
1230
  List imports for a knowledge base
@@ -1251,9 +1252,11 @@ ARGUMENTS
1251
1252
  JOBID Job ID
1252
1253
 
1253
1254
  FLAGS
1254
- --json Output the job in JSON format
1255
1255
  --watch Poll until the job reaches a terminal state
1256
1256
 
1257
+ GLOBAL FLAGS
1258
+ --json Format output as json.
1259
+
1257
1260
  DESCRIPTION
1258
1261
  Get the status of a knowledge base job
1259
1262
 
@@ -1273,10 +1276,10 @@ List knowledge bases in an organization
1273
1276
 
1274
1277
  ```
1275
1278
  USAGE
1276
- $ sanity context list [--organization <id>] [--json]
1279
+ $ sanity context list [--json] [--organization <id>]
1277
1280
 
1278
- FLAGS
1279
- --json Output knowledge bases in JSON format
1281
+ GLOBAL FLAGS
1282
+ --json Format output as json.
1280
1283
 
1281
1284
  OVERRIDE FLAGS
1282
1285
  --organization=<id> Organization to list knowledge bases for (overrides CLI configuration)
@@ -2009,8 +2012,8 @@ Builds and deploys Sanity Studio or application to Sanity hosting
2009
2012
 
2010
2013
  ```
2011
2014
  USAGE
2012
- $ sanity deploy [SOURCEDIR] [--auto-updates] [--build] [--create | --external | --url <value>] [--dry-run]
2013
- [-j] [--minify] [--schema-required] [--source-maps] [--title <value>] [--verbose] [-y]
2015
+ $ sanity deploy [SOURCEDIR] [-j] [--auto-updates] [--build] [--create | --external | --url <value>]
2016
+ [--dry-run] [--minify] [--schema-required] [--source-maps] [--title <value>] [--verbose] [-y]
2014
2017
 
2015
2018
  ARGUMENTS
2016
2019
  [SOURCEDIR] Source directory
@@ -3574,8 +3577,10 @@ USAGE
3574
3577
  $ sanity openapi list [--json] [-w]
3575
3578
 
3576
3579
  FLAGS
3577
- -w, --web Open HTTP Reference in web browser
3578
- --json Output JSON
3580
+ -w, --web Open HTTP Reference in web browser
3581
+
3582
+ GLOBAL FLAGS
3583
+ --json Format output as json.
3579
3584
 
3580
3585
  DESCRIPTION
3581
3586
  List all available OpenAPI specifications
@@ -3752,7 +3757,7 @@ Create a new Sanity project
3752
3757
 
3753
3758
  ```
3754
3759
  USAGE
3755
- $ sanity projects create [PROJECTNAME] [--dataset <value>] [--dataset-visibility private|public] [--json]
3760
+ $ sanity projects create [PROJECTNAME] [--json] [--dataset <value>] [--dataset-visibility private|public]
3756
3761
  [--organization <slug|id>] [-y]
3757
3762
 
3758
3763
  ARGUMENTS
@@ -3764,9 +3769,11 @@ FLAGS
3764
3769
  --dataset=<value> Create a dataset. Prompts for visibility unless specified or --yes used
3765
3770
  --dataset-visibility=<option> Dataset visibility: public or private
3766
3771
  <options: private|public>
3767
- --json Output in JSON format
3768
3772
  --organization=<slug|id> Organization to create the project in
3769
3773
 
3774
+ GLOBAL FLAGS
3775
+ --json Format output as json.
3776
+
3770
3777
  DESCRIPTION
3771
3778
  Create a new Sanity project
3772
3779
 
@@ -3950,11 +3957,13 @@ List all schemas in the current dataset.
3950
3957
 
3951
3958
  ```
3952
3959
  USAGE
3953
- $ sanity schemas list [--id <schema_id>] [--json]
3960
+ $ sanity schemas list [--json] [--id <schema_id>]
3954
3961
 
3955
3962
  FLAGS
3956
3963
  --id=<schema_id> Fetch a single schema by id
3957
- --json Get schema as json
3964
+
3965
+ GLOBAL FLAGS
3966
+ --json Format output as json.
3958
3967
 
3959
3968
  DESCRIPTION
3960
3969
  List all schemas in the current dataset.
@@ -4093,37 +4102,48 @@ EXAMPLES
4093
4102
 
4094
4103
  ## `sanity tokens create [LABEL]`
4095
4104
 
4096
- Create a new API token for the project
4105
+ Create a new API token with access to an organization and its projects
4097
4106
 
4098
4107
  ```
4099
4108
  USAGE
4100
- $ sanity tokens create [LABEL] [-p <id>] [--expires-at 2027-01-01] [--json] [--role viewer] [-y]
4109
+ $ sanity tokens create [LABEL] [--json] [-p <id>] [--organization <id>] [--expires-at 2027-01-01] [--grant
4110
+ context=editor...] [--role viewer] [-y]
4101
4111
 
4102
4112
  ARGUMENTS
4103
4113
  [LABEL] Label for the new token
4104
4114
 
4105
4115
  FLAGS
4106
- -y, --yes Skip prompts and use defaults (unattended mode)
4107
- --expires-at=2027-01-01 Date or timestamp the token expires (ISO 8601; tokens never expire by default)
4108
- --json Output as JSON
4109
- --role=viewer Role to assign to the token (defaults to viewer in unattended mode)
4116
+ -y, --yes Skip prompts and use defaults (unattended mode)
4117
+ --expires-at=2027-01-01 Date or timestamp the token expires (ISO 8601; tokens never expire by default)
4118
+ --grant=context=editor... Access to grant, as <permission>[=<role>] or project:<projectId>=<role>[,<role>].
4119
+ Permissions: context, blueprints, media-library, canvas, sdk-apps, access,
4120
+ deploy-studios. Repeatable
4121
+ --role=viewer Role to assign on the project (defaults to viewer in unattended mode)
4110
4122
 
4111
4123
  OVERRIDE FLAGS
4112
- -p, --project-id=<id> Project ID to create token in (overrides CLI configuration)
4124
+ -p, --project-id=<id> Project ID to create token in (overrides CLI configuration)
4125
+ --organization=<id> Organization to create an organization token in (overrides CLI configuration)
4126
+
4127
+ GLOBAL FLAGS
4128
+ --json Format output as json.
4113
4129
 
4114
4130
  DESCRIPTION
4115
- Create a new API token for the project
4131
+ Create a new API token with access to an organization and its projects
4116
4132
 
4117
4133
  EXAMPLES
4118
- Create a token with a label
4134
+ Create a token, choosing its access interactively
4119
4135
 
4120
4136
  $ sanity tokens create "My API Token"
4121
4137
 
4122
- Create a token with editor role
4138
+ Create an organization token with Context, Blueprints and project access
4139
+
4140
+ $ sanity tokens create "CI Token" --grant context=developer --grant blueprints --grant project:abc123=editor
4123
4141
 
4124
- $ sanity tokens create "My API Token" --role=editor
4142
+ Create a project token with editor role
4143
+
4144
+ $ sanity tokens create "My Token" --project-id abc123 --role=editor
4125
4145
 
4126
- Create a token in unattended mode
4146
+ Create a project token in unattended mode
4127
4147
 
4128
4148
  $ sanity tokens create "CI Token" --role=editor --yes
4129
4149
 
@@ -4134,33 +4154,38 @@ EXAMPLES
4134
4154
  Output token information as JSON
4135
4155
 
4136
4156
  $ sanity tokens create "API Token" --json
4137
-
4138
- Create a token for a specific project
4139
-
4140
- $ sanity tokens create "My Token" --project-id abc123 --role=editor
4141
4157
  ```
4142
4158
 
4143
4159
  ## `sanity tokens delete [TOKENID]`
4144
4160
 
4145
- Delete an API token from the project
4161
+ Delete an API token from a project or organization
4146
4162
 
4147
4163
  ```
4148
4164
  USAGE
4149
- $ sanity tokens delete [TOKENID] [-p <id>] [-y]
4165
+ $ sanity tokens delete [TOKENID] [--organization <id> | -p <id>] [-y]
4150
4166
 
4151
4167
  ARGUMENTS
4152
4168
  [TOKENID] Token ID to delete (will prompt if not provided)
4153
4169
 
4154
4170
  FLAGS
4155
- -y, --yes Skip confirmation prompt (unattended mode)
4171
+ -y, --yes Skip confirmation prompt (unattended mode)
4172
+ --organization=<id> Delete a token managed by this organization
4156
4173
 
4157
4174
  OVERRIDE FLAGS
4158
4175
  -p, --project-id=<id> Project ID to delete token from (overrides CLI configuration)
4159
4176
 
4160
4177
  DESCRIPTION
4161
- Delete an API token from the project
4178
+ Delete an API token from a project or organization
4162
4179
 
4163
4180
  EXAMPLES
4181
+ Interactively select and delete an organization token
4182
+
4183
+ $ sanity tokens delete --organization org123
4184
+
4185
+ Delete an organization token without confirmation
4186
+
4187
+ $ sanity tokens delete silJ2lFmK6dONB --organization org123 --yes
4188
+
4164
4189
  Interactively select and delete a token
4165
4190
 
4166
4191
  $ sanity tokens delete
@@ -4180,22 +4205,29 @@ EXAMPLES
4180
4205
 
4181
4206
  ## `sanity tokens list`
4182
4207
 
4183
- List API tokens for the project
4208
+ List API tokens for a project or organization
4184
4209
 
4185
4210
  ```
4186
4211
  USAGE
4187
- $ sanity tokens list [-p <id>] [--json]
4212
+ $ sanity tokens list [--json] [--organization <id> | -p <id>]
4188
4213
 
4189
4214
  FLAGS
4190
- --json Output tokens in JSON format
4215
+ --organization=<id> List tokens managed by this organization
4191
4216
 
4192
4217
  OVERRIDE FLAGS
4193
4218
  -p, --project-id=<id> Project ID to list tokens for (overrides CLI configuration)
4194
4219
 
4220
+ GLOBAL FLAGS
4221
+ --json Format output as json.
4222
+
4195
4223
  DESCRIPTION
4196
- List API tokens for the project
4224
+ List API tokens for a project or organization
4197
4225
 
4198
4226
  EXAMPLES
4227
+ List tokens managed by an organization
4228
+
4229
+ $ sanity tokens list --organization org123
4230
+
4199
4231
  List tokens for the project
4200
4232
 
4201
4233
  $ sanity tokens list
@@ -4219,7 +4251,9 @@ USAGE
4219
4251
 
4220
4252
  FLAGS
4221
4253
  -t, --token=<token> Token to rotate (prefer standard input to keep it out of shell history)
4222
- --json Output as JSON
4254
+
4255
+ GLOBAL FLAGS
4256
+ --json Format output as json.
4223
4257
 
4224
4258
  DESCRIPTION
4225
4259
  Rotate an API token, replacing its secret with a new one
@@ -4275,7 +4309,8 @@ DESCRIPTION
4275
4309
  - The `sanity schema extract` command is a prerequisite for extracting your Sanity Studio schema into a `schema.json`
4276
4310
  file, which is then used by the `sanity typegen generate` command to generate type definitions.
4277
4311
  - To generate types for several datasets, list them in `typegen.resources` in `sanity.cli.ts` (beta). Each resource
4278
- uses its own `schema` file, or the schema bound to its dataset when `schema` is omitted.
4312
+ uses its own `schema` file, or the schema bound to its dataset when `schema` is omitted. With `--watch`, a schema
4313
+ bound to a dataset is fetched once, when the watcher starts. Restart it after deploying a schema.
4279
4314
 
4280
4315
  EXAMPLES
4281
4316
  Generate TypeScript type definitions from a Sanity Studio schema extracted using the `sanity schema extract`
@@ -4290,7 +4325,7 @@ Removes the deployed Sanity Studio/App from Sanity hosting
4290
4325
 
4291
4326
  ```
4292
4327
  USAGE
4293
- $ sanity undeploy [APPID] [--dry-run] [-j] [-y]
4328
+ $ sanity undeploy [APPID] [-j] [--dry-run] [-y]
4294
4329
 
4295
4330
  ARGUMENTS
4296
4331
  [APPID] ID of the application to undeploy. Overrides `deployment.appId` in sanity.cli.ts
@@ -4414,6 +4449,30 @@ EXAMPLES
4414
4449
  $ sanity versions
4415
4450
  ```
4416
4451
 
4452
+ ## `sanity whoami`
4453
+
4454
+ Show the user or API token the CLI is authenticated as
4455
+
4456
+ ```
4457
+ USAGE
4458
+ $ sanity whoami [--json]
4459
+
4460
+ GLOBAL FLAGS
4461
+ --json Format output as json.
4462
+
4463
+ DESCRIPTION
4464
+ Show the user or API token the CLI is authenticated as
4465
+
4466
+ EXAMPLES
4467
+ Show the currently authenticated user
4468
+
4469
+ $ sanity whoami
4470
+
4471
+ Output the current user as JSON, for scripts and agents
4472
+
4473
+ $ sanity whoami --json
4474
+ ```
4475
+
4417
4476
  ## `sanity workflows abort INSTANCEID`
4418
4477
 
4419
4478
  Abort an in-flight workflow instance — a hard stop: pending effects are cancelled, stage guards removed, and the instance is marked terminal where it stands.
@@ -0,0 +1,111 @@
1
+ // @ts-check
2
+ /* eslint-disable unicorn/no-array-callback-reference, unicorn/no-array-method-this-argument */
3
+ const APP_VALUE_KEYS = new Set(['organizationId', 'slug', 'title'])
4
+
5
+ function keyName(property) {
6
+ return property.key?.name ?? property.key?.value
7
+ }
8
+
9
+ function importedName(specifier) {
10
+ return specifier.type === 'ImportSpecifier' && specifier.imported.name
11
+ }
12
+
13
+ function findConfigObject(j, root) {
14
+ const defineCall = root.find(j.CallExpression, {callee: {name: 'defineCliConfig'}}).paths()[0]
15
+ const configArg = defineCall?.node.arguments[0]
16
+ if (configArg?.type === 'ObjectExpression') {
17
+ return configArg
18
+ }
19
+
20
+ const defaultExport = root.find(j.ExportDefaultDeclaration).paths()[0]?.node.declaration
21
+ return defaultExport?.type === 'ObjectExpression' ? defaultExport : undefined
22
+ }
23
+
24
+ function addDefineApplicationImport(j, root) {
25
+ const cliImport = root
26
+ .find(j.ImportDeclaration, {source: {value: 'sanity/cli'}})
27
+ .filter((path) => path.node.importKind !== 'type')
28
+ .paths()[0]
29
+
30
+ if (!cliImport) {
31
+ root
32
+ .get()
33
+ .node.program.body.unshift(
34
+ j.importDeclaration(
35
+ [j.importSpecifier(j.identifier('defineApplication'))],
36
+ j.stringLiteral('sanity/cli'),
37
+ ),
38
+ )
39
+ return
40
+ }
41
+
42
+ const specifiers = cliImport.node.specifiers
43
+ if (specifiers.some((specifier) => importedName(specifier) === 'defineApplication')) {
44
+ return
45
+ }
46
+
47
+ const index = specifiers.findIndex((specifier) => importedName(specifier) > 'defineApplication')
48
+ specifiers.splice(
49
+ index === -1 ? specifiers.length : index,
50
+ 0,
51
+ j.importSpecifier(j.identifier('defineApplication')),
52
+ )
53
+ }
54
+
55
+ function dashboard(fileInfo, api, options) {
56
+ const {organizationId, slug, title} = options
57
+ if (!organizationId || !slug || !title) {
58
+ throw new Error(
59
+ 'Missing organizationId, slug or title. Run this codemod with `sanity codemod dashboard`.',
60
+ )
61
+ }
62
+
63
+ const j = api.jscodeshift
64
+ const root = j(fileInfo.source)
65
+
66
+ const config = findConfigObject(j, root)
67
+ if (!config) {
68
+ throw new Error(
69
+ 'Could not find the CLI config. Expected `export default defineCliConfig({...})`.',
70
+ )
71
+ }
72
+
73
+ const values = [
74
+ ['title', title],
75
+ ['slug', slug],
76
+ ['organizationId', organizationId],
77
+ ].map(([key, value]) => j.objectProperty(j.identifier(key), j.stringLiteral(value)))
78
+
79
+ const appProperty = config.properties.find((property) => keyName(property) === 'app')
80
+ if (appProperty) {
81
+ if (appProperty.value.type !== 'ObjectExpression') {
82
+ throw new Error('`app` must be an object literal to be wrapped in `defineApplication`.')
83
+ }
84
+
85
+ const rest = appProperty.value.properties.filter(
86
+ (property) => !APP_VALUE_KEYS.has(keyName(property)),
87
+ )
88
+ appProperty.value = j.callExpression(j.identifier('defineApplication'), [
89
+ j.objectExpression([...values, ...rest]),
90
+ ])
91
+ } else {
92
+ // Keep `app` next to `api`, matching the shape `sanity init` scaffolds
93
+ const apiIndex = config.properties.findIndex((property) => keyName(property) === 'api')
94
+ config.properties.splice(
95
+ apiIndex + 1,
96
+ 0,
97
+ j.objectProperty(
98
+ j.identifier('app'),
99
+ j.callExpression(j.identifier('defineApplication'), [j.objectExpression(values)]),
100
+ ),
101
+ )
102
+ }
103
+
104
+ addDefineApplicationImport(j, root)
105
+
106
+ return root.toSource({objectCurlySpacing: false, quote: 'single', trailingComma: true})
107
+ }
108
+
109
+ // jscodeshift reads the parser from a named export, not a property on the default export
110
+ export const parser = 'tsx'
111
+ export default dashboard
@@ -27,7 +27,7 @@ import { preReleaseEventListenerFactory } from './eventListenerFactory.js';
27
27
  } : undefined;
28
28
  const isWorkbench = !!workbench || !!workbenchConfig;
29
29
  const appId = getAppId(cliConfig);
30
- await internalBuildApp({
30
+ return internalBuildApp({
31
31
  appId,
32
32
  appTitle: app?.title,
33
33
  autoUpdatesEnabled: options.autoUpdatesEnabled,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/actions/build/buildApp.ts"],"sourcesContent":["import {\n compareDependencyVersions,\n buildApp as internalBuildApp,\n} from '@sanity/cli-build/_internal/build'\nimport {\n buildAppId,\n resolveAppEntry,\n resolveWorkbenchApp,\n resolveWorkbenchConfig,\n} from '@sanity/workbench-cli/build'\n\nimport {getAppId} from '../../util/appId.js'\nimport {warnAboutMissingAppId} from '../../util/warnAboutMissingAppId.js'\nimport {determineBasePath} from './determineBasePath.js'\nimport {preReleaseEventListenerFactory} from './eventListenerFactory.js'\nimport {type BuildOptions} from './types.js'\n\n/**\n * Build the Sanity app.\n *\n * @internal\n */\nexport async function buildApp(options: BuildOptions): Promise<void> {\n const {cliConfig, flags, outDir, output, workDir} = options\n\n const app = cliConfig && 'app' in cliConfig ? cliConfig.app : undefined\n // `views`/`webWorkers` live on the branded `defineApplication` result, not the\n // legacy `app` config object — resolve the workbench capability to read them. A\n // config is not an app: it resolves separately and only expands its `fields`.\n const workbench = resolveWorkbenchApp(cliConfig)\n const workbenchConfig = resolveWorkbenchConfig(cliConfig)\n const exposes = workbench\n ? {views: workbench.views, webWorkers: workbench.webWorkers}\n : workbenchConfig\n ? {config: {appType: workbenchConfig.appType, fields: workbenchConfig.fields}}\n : undefined\n const isWorkbench = !!workbench || !!workbenchConfig\n\n const appId = getAppId(cliConfig)\n\n await internalBuildApp({\n appId,\n appTitle: app?.title,\n autoUpdatesEnabled: options.autoUpdatesEnabled,\n checkAppId: () => {\n // Warn if auto updates enabled but no appId configured.\n // Skip when called from deploy, since deploy handles appId itself\n // (prompts the user and tells them to add it to config).\n if (!appId && !options.calledFromDeploy) {\n warnAboutMissingAppId({appType: 'app', output})\n }\n },\n compareDependencyVersions: (packages) => compareDependencyVersions(packages, workDir, {appId}),\n determineBasePath: () => determineBasePath(cliConfig, 'app', output),\n entry: resolveAppEntry(app),\n exposes,\n isWorkbenchApp: isWorkbench,\n minify: flags.minify,\n outDir,\n output,\n reactCompiler: cliConfig && 'reactCompiler' in cliConfig ? cliConfig.reactCompiler : undefined,\n schemaExtraction: cliConfig?.schemaExtraction,\n sourceMap: Boolean(flags['source-maps']),\n stats: flags.stats,\n unattendedMode: flags.yes,\n vite: cliConfig.vite,\n // Shared with deploy: it passes the resolved application id (minted by the\n // API on a first deploy) to inline; a plain build has none, so it hashes the shape.\n workbenchAppId: workbench\n ? (options.applicationId ?? (await buildAppId(workbench)))\n : undefined,\n workDir,\n\n eventListener: preReleaseEventListenerFactory(output),\n })\n}\n"],"names":["compareDependencyVersions","buildApp","internalBuildApp","buildAppId","resolveAppEntry","resolveWorkbenchApp","resolveWorkbenchConfig","getAppId","warnAboutMissingAppId","determineBasePath","preReleaseEventListenerFactory","options","cliConfig","flags","outDir","output","workDir","app","undefined","workbench","workbenchConfig","exposes","views","webWorkers","config","appType","fields","isWorkbench","appId","appTitle","title","autoUpdatesEnabled","checkAppId","calledFromDeploy","packages","entry","isWorkbenchApp","minify","reactCompiler","schemaExtraction","sourceMap","Boolean","stats","unattendedMode","yes","vite","workbenchAppId","applicationId","eventListener"],"mappings":"AAAA,SACEA,yBAAyB,EACzBC,YAAYC,gBAAgB,QACvB,oCAAmC;AAC1C,SACEC,UAAU,EACVC,eAAe,EACfC,mBAAmB,EACnBC,sBAAsB,QACjB,8BAA6B;AAEpC,SAAQC,QAAQ,QAAO,sBAAqB;AAC5C,SAAQC,qBAAqB,QAAO,sCAAqC;AACzE,SAAQC,iBAAiB,QAAO,yBAAwB;AACxD,SAAQC,8BAA8B,QAAO,4BAA2B;AAGxE;;;;CAIC,GACD,OAAO,eAAeT,SAASU,OAAqB;IAClD,MAAM,EAACC,SAAS,EAAEC,KAAK,EAAEC,MAAM,EAAEC,MAAM,EAAEC,OAAO,EAAC,GAAGL;IAEpD,MAAMM,MAAML,aAAa,SAASA,YAAYA,UAAUK,GAAG,GAAGC;IAC9D,+EAA+E;IAC/E,gFAAgF;IAChF,8EAA8E;IAC9E,MAAMC,YAAYd,oBAAoBO;IACtC,MAAMQ,kBAAkBd,uBAAuBM;IAC/C,MAAMS,UAAUF,YACZ;QAACG,OAAOH,UAAUG,KAAK;QAAEC,YAAYJ,UAAUI,UAAU;IAAA,IACzDH,kBACE;QAACI,QAAQ;YAACC,SAASL,gBAAgBK,OAAO;YAAEC,QAAQN,gBAAgBM,MAAM;QAAA;IAAC,IAC3ER;IACN,MAAMS,cAAc,CAAC,CAACR,aAAa,CAAC,CAACC;IAErC,MAAMQ,QAAQrB,SAASK;IAEvB,MAAMV,iBAAiB;QACrB0B;QACAC,UAAUZ,KAAKa;QACfC,oBAAoBpB,QAAQoB,kBAAkB;QAC9CC,YAAY;YACV,wDAAwD;YACxD,kEAAkE;YAClE,yDAAyD;YACzD,IAAI,CAACJ,SAAS,CAACjB,QAAQsB,gBAAgB,EAAE;gBACvCzB,sBAAsB;oBAACiB,SAAS;oBAAOV;gBAAM;YAC/C;QACF;QACAf,2BAA2B,CAACkC,WAAalC,0BAA0BkC,UAAUlB,SAAS;gBAACY;YAAK;QAC5FnB,mBAAmB,IAAMA,kBAAkBG,WAAW,OAAOG;QAC7DoB,OAAO/B,gBAAgBa;QACvBI;QACAe,gBAAgBT;QAChBU,QAAQxB,MAAMwB,MAAM;QACpBvB;QACAC;QACAuB,eAAe1B,aAAa,mBAAmBA,YAAYA,UAAU0B,aAAa,GAAGpB;QACrFqB,kBAAkB3B,WAAW2B;QAC7BC,WAAWC,QAAQ5B,KAAK,CAAC,cAAc;QACvC6B,OAAO7B,MAAM6B,KAAK;QAClBC,gBAAgB9B,MAAM+B,GAAG;QACzBC,MAAMjC,UAAUiC,IAAI;QACpB,2EAA2E;QAC3E,oFAAoF;QACpFC,gBAAgB3B,YACXR,QAAQoC,aAAa,IAAK,MAAM5C,WAAWgB,aAC5CD;QACJF;QAEAgC,eAAetC,+BAA+BK;IAChD;AACF"}
1
+ {"version":3,"sources":["../../../src/actions/build/buildApp.ts"],"sourcesContent":["import {\n compareDependencyVersions,\n buildApp as internalBuildApp,\n} from '@sanity/cli-build/_internal/build'\nimport {\n buildAppId,\n resolveAppEntry,\n resolveWorkbenchApp,\n resolveWorkbenchConfig,\n} from '@sanity/workbench-cli/build'\n\nimport {getAppId} from '../../util/appId.js'\nimport {warnAboutMissingAppId} from '../../util/warnAboutMissingAppId.js'\nimport {determineBasePath} from './determineBasePath.js'\nimport {preReleaseEventListenerFactory} from './eventListenerFactory.js'\nimport {type BuildOptions} from './types.js'\n\n/**\n * Build the Sanity app.\n *\n * @internal\n */\nexport async function buildApp(\n options: BuildOptions,\n): Promise<{mfManifest: Record<string, unknown> | undefined}> {\n const {cliConfig, flags, outDir, output, workDir} = options\n\n const app = cliConfig && 'app' in cliConfig ? cliConfig.app : undefined\n // `views`/`webWorkers` live on the branded `defineApplication` result, not the\n // legacy `app` config object — resolve the workbench capability to read them. A\n // config is not an app: it resolves separately and only expands its `fields`.\n const workbench = resolveWorkbenchApp(cliConfig)\n const workbenchConfig = resolveWorkbenchConfig(cliConfig)\n const exposes = workbench\n ? {views: workbench.views, webWorkers: workbench.webWorkers}\n : workbenchConfig\n ? {config: {appType: workbenchConfig.appType, fields: workbenchConfig.fields}}\n : undefined\n const isWorkbench = !!workbench || !!workbenchConfig\n\n const appId = getAppId(cliConfig)\n\n return internalBuildApp({\n appId,\n appTitle: app?.title,\n autoUpdatesEnabled: options.autoUpdatesEnabled,\n checkAppId: () => {\n // Warn if auto updates enabled but no appId configured.\n // Skip when called from deploy, since deploy handles appId itself\n // (prompts the user and tells them to add it to config).\n if (!appId && !options.calledFromDeploy) {\n warnAboutMissingAppId({appType: 'app', output})\n }\n },\n compareDependencyVersions: (packages) => compareDependencyVersions(packages, workDir, {appId}),\n determineBasePath: () => determineBasePath(cliConfig, 'app', output),\n entry: resolveAppEntry(app),\n exposes,\n isWorkbenchApp: isWorkbench,\n minify: flags.minify,\n outDir,\n output,\n reactCompiler: cliConfig && 'reactCompiler' in cliConfig ? cliConfig.reactCompiler : undefined,\n schemaExtraction: cliConfig?.schemaExtraction,\n sourceMap: Boolean(flags['source-maps']),\n stats: flags.stats,\n unattendedMode: flags.yes,\n vite: cliConfig.vite,\n // Shared with deploy: it passes the resolved application id (minted by the\n // API on a first deploy) to inline; a plain build has none, so it hashes the shape.\n workbenchAppId: workbench\n ? (options.applicationId ?? (await buildAppId(workbench)))\n : undefined,\n workDir,\n\n eventListener: preReleaseEventListenerFactory(output),\n })\n}\n"],"names":["compareDependencyVersions","buildApp","internalBuildApp","buildAppId","resolveAppEntry","resolveWorkbenchApp","resolveWorkbenchConfig","getAppId","warnAboutMissingAppId","determineBasePath","preReleaseEventListenerFactory","options","cliConfig","flags","outDir","output","workDir","app","undefined","workbench","workbenchConfig","exposes","views","webWorkers","config","appType","fields","isWorkbench","appId","appTitle","title","autoUpdatesEnabled","checkAppId","calledFromDeploy","packages","entry","isWorkbenchApp","minify","reactCompiler","schemaExtraction","sourceMap","Boolean","stats","unattendedMode","yes","vite","workbenchAppId","applicationId","eventListener"],"mappings":"AAAA,SACEA,yBAAyB,EACzBC,YAAYC,gBAAgB,QACvB,oCAAmC;AAC1C,SACEC,UAAU,EACVC,eAAe,EACfC,mBAAmB,EACnBC,sBAAsB,QACjB,8BAA6B;AAEpC,SAAQC,QAAQ,QAAO,sBAAqB;AAC5C,SAAQC,qBAAqB,QAAO,sCAAqC;AACzE,SAAQC,iBAAiB,QAAO,yBAAwB;AACxD,SAAQC,8BAA8B,QAAO,4BAA2B;AAGxE;;;;CAIC,GACD,OAAO,eAAeT,SACpBU,OAAqB;IAErB,MAAM,EAACC,SAAS,EAAEC,KAAK,EAAEC,MAAM,EAAEC,MAAM,EAAEC,OAAO,EAAC,GAAGL;IAEpD,MAAMM,MAAML,aAAa,SAASA,YAAYA,UAAUK,GAAG,GAAGC;IAC9D,+EAA+E;IAC/E,gFAAgF;IAChF,8EAA8E;IAC9E,MAAMC,YAAYd,oBAAoBO;IACtC,MAAMQ,kBAAkBd,uBAAuBM;IAC/C,MAAMS,UAAUF,YACZ;QAACG,OAAOH,UAAUG,KAAK;QAAEC,YAAYJ,UAAUI,UAAU;IAAA,IACzDH,kBACE;QAACI,QAAQ;YAACC,SAASL,gBAAgBK,OAAO;YAAEC,QAAQN,gBAAgBM,MAAM;QAAA;IAAC,IAC3ER;IACN,MAAMS,cAAc,CAAC,CAACR,aAAa,CAAC,CAACC;IAErC,MAAMQ,QAAQrB,SAASK;IAEvB,OAAOV,iBAAiB;QACtB0B;QACAC,UAAUZ,KAAKa;QACfC,oBAAoBpB,QAAQoB,kBAAkB;QAC9CC,YAAY;YACV,wDAAwD;YACxD,kEAAkE;YAClE,yDAAyD;YACzD,IAAI,CAACJ,SAAS,CAACjB,QAAQsB,gBAAgB,EAAE;gBACvCzB,sBAAsB;oBAACiB,SAAS;oBAAOV;gBAAM;YAC/C;QACF;QACAf,2BAA2B,CAACkC,WAAalC,0BAA0BkC,UAAUlB,SAAS;gBAACY;YAAK;QAC5FnB,mBAAmB,IAAMA,kBAAkBG,WAAW,OAAOG;QAC7DoB,OAAO/B,gBAAgBa;QACvBI;QACAe,gBAAgBT;QAChBU,QAAQxB,MAAMwB,MAAM;QACpBvB;QACAC;QACAuB,eAAe1B,aAAa,mBAAmBA,YAAYA,UAAU0B,aAAa,GAAGpB;QACrFqB,kBAAkB3B,WAAW2B;QAC7BC,WAAWC,QAAQ5B,KAAK,CAAC,cAAc;QACvC6B,OAAO7B,MAAM6B,KAAK;QAClBC,gBAAgB9B,MAAM+B,GAAG;QACzBC,MAAMjC,UAAUiC,IAAI;QACpB,2EAA2E;QAC3E,oFAAoF;QACpFC,gBAAgB3B,YACXR,QAAQoC,aAAa,IAAK,MAAM5C,WAAWgB,aAC5CD;QACJF;QAEAgC,eAAetC,+BAA+BK;IAChD;AACF"}
@@ -26,7 +26,7 @@ import { checkDependenciesEventListenerFactory, preReleaseEventListenerFactory }
26
26
  const appId = getAppId(cliConfig);
27
27
  let cleanOutputDirSpinner;
28
28
  let buildSpinner;
29
- await internalBuildStudio({
29
+ return internalBuildStudio({
30
30
  appId,
31
31
  autoUpdatesEnabled: options.autoUpdatesEnabled,
32
32
  checkAppId: ()=>{
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/actions/build/buildStudio.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {\n compareDependencyVersions,\n buildStudio as internalBuildStudio,\n} from '@sanity/cli-build/_internal/build'\nimport {exitCodes} from '@sanity/cli-core'\nimport {confirm, logSymbols, select, spinner} from '@sanity/cli-core/ux'\nimport {buildAppId, resolveWorkbenchApp} from '@sanity/workbench-cli/build'\n\nimport {getAppId} from '../../util/appId.js'\nimport {determineIsApp} from '../../util/determineIsApp.js'\nimport {getPackageManagerChoice} from '../../util/packageManager/packageManagerChoice.js'\nimport {upgradePackages} from '../../util/packageManager/upgradePackages.js'\nimport {warnAboutMissingAppId} from '../../util/warnAboutMissingAppId.js'\nimport {determineBasePath} from './determineBasePath.js'\nimport {\n checkDependenciesEventListenerFactory,\n preReleaseEventListenerFactory,\n} from './eventListenerFactory.js'\nimport {type BuildOptions} from './types.js'\n\n/**\n * Build the Sanity Studio.\n *\n * @internal\n */\nexport async function buildStudio(options: BuildOptions): Promise<void> {\n const {calledFromDeploy, cliConfig, flags, outDir, output, workDir} = options\n\n // `views`/`webWorkers` live on the branded `defineApplication` result — resolve\n // the workbench capability so it's gated on the brand, like the app build.\n const workbench = resolveWorkbenchApp(cliConfig)\n const exposes = workbench ? {views: workbench.views, webWorkers: workbench.webWorkers} : undefined\n\n const appId = getAppId(cliConfig)\n\n let cleanOutputDirSpinner: ReturnType<typeof spinner> | undefined\n let buildSpinner: ReturnType<typeof spinner> | undefined\n\n await internalBuildStudio({\n appId,\n autoUpdatesEnabled: options.autoUpdatesEnabled,\n checkAppId: () => {\n // Warn if auto updates enabled but no appId configured.\n // Skip when called from deploy, since deploy handles appId itself\n // (prompts the user and tells them to add it to config).\n if (!appId && !calledFromDeploy) {\n warnAboutMissingAppId({appType: 'studio', output, projectId: cliConfig?.api?.projectId})\n }\n },\n compareDependencyVersions: (packages) => compareDependencyVersions(packages, workDir, {appId}),\n determineBasePath: () => determineBasePath(cliConfig, 'studio', output),\n exposes,\n isApp: determineIsApp(cliConfig),\n isWorkbenchApp: !!workbench,\n minify: Boolean(flags.minify),\n outDir,\n output,\n reactCompiler: cliConfig.reactCompiler,\n schemaExtraction: cliConfig.schemaExtraction,\n sourceMap: Boolean(flags['source-maps']),\n stats: flags.stats,\n unattendedMode: Boolean(flags.yes),\n vite: cliConfig.vite,\n // Shared with deploy: it passes the resolved application id (minted by the\n // API on a first deploy) to inline; a plain build has none, so it hashes the shape.\n workbenchAppId: workbench\n ? (options.applicationId ?? (await buildAppId(workbench)))\n : undefined,\n workDir,\n\n eventListener: {\n ...preReleaseEventListenerFactory(output),\n\n ...checkDependenciesEventListenerFactory(output),\n\n onBuildEnd({message}) {\n if (buildSpinner) {\n buildSpinner.text = message\n buildSpinner.succeed()\n }\n },\n onBuildFail({message}) {\n if (buildSpinner) {\n buildSpinner.fail()\n }\n\n output.error(message, {exit: exitCodes.RUNTIME_ERROR})\n },\n onBuildStart({message}) {\n if (!buildSpinner) {\n buildSpinner = spinner(message).start()\n }\n },\n onCleanOutputDirEnd({message}) {\n if (cleanOutputDirSpinner) {\n cleanOutputDirSpinner.text = message\n cleanOutputDirSpinner.succeed()\n }\n },\n onCleanOutputDirStart({message}) {\n if (!cleanOutputDirSpinner) {\n cleanOutputDirSpinner = spinner(message).start()\n }\n },\n async onInteractiveNonDefaultOutputDir({message}: {message: string}) {\n const shouldClean = await confirm({\n default: true,\n message,\n })\n return {shouldClean}\n },\n async onVersionMismatchInInteractiveAutoUpdate({mismatched, versionMismatchWarning}) {\n const choice = await select({\n choices: [\n {\n name: `Upgrade local versions (recommended). You will need to run the build command again`,\n value: 'upgrade',\n },\n {\n name: `Upgrade and proceed with build`,\n value: 'upgrade-and-proceed',\n },\n {\n name: `Continue anyway`,\n value: 'continue',\n },\n {name: 'Cancel', value: 'cancel'},\n ],\n default: 'upgrade',\n message: styleText(\n 'yellow',\n `${logSymbols.warning} ${versionMismatchWarning}\\n\\nDo you want to upgrade local versions before deploying?`,\n ),\n })\n\n if (choice === 'cancel') {\n output.error('Declined to continue with build', {exit: exitCodes.RUNTIME_ERROR})\n return {stopBuild: true}\n }\n\n if (choice === 'upgrade' || choice === 'upgrade-and-proceed') {\n await upgradePackages(\n {\n packageManager: (await getPackageManagerChoice(workDir, {interactive: false})).chosen,\n packages: mismatched.map((res) => [res.pkg, res.remote]),\n },\n {output, workDir},\n )\n\n return {stopBuild: choice === 'upgrade'}\n }\n\n return {stopBuild: false}\n },\n onVersionMismatchInNonInteractiveAutoUpdate({versionMismatchWarning}) {\n output.warn(versionMismatchWarning)\n },\n },\n })\n}\n"],"names":["styleText","compareDependencyVersions","buildStudio","internalBuildStudio","exitCodes","confirm","logSymbols","select","spinner","buildAppId","resolveWorkbenchApp","getAppId","determineIsApp","getPackageManagerChoice","upgradePackages","warnAboutMissingAppId","determineBasePath","checkDependenciesEventListenerFactory","preReleaseEventListenerFactory","options","calledFromDeploy","cliConfig","flags","outDir","output","workDir","workbench","exposes","views","webWorkers","undefined","appId","cleanOutputDirSpinner","buildSpinner","autoUpdatesEnabled","checkAppId","appType","projectId","api","packages","isApp","isWorkbenchApp","minify","Boolean","reactCompiler","schemaExtraction","sourceMap","stats","unattendedMode","yes","vite","workbenchAppId","applicationId","eventListener","onBuildEnd","message","text","succeed","onBuildFail","fail","error","exit","RUNTIME_ERROR","onBuildStart","start","onCleanOutputDirEnd","onCleanOutputDirStart","onInteractiveNonDefaultOutputDir","shouldClean","default","onVersionMismatchInInteractiveAutoUpdate","mismatched","versionMismatchWarning","choice","choices","name","value","warning","stopBuild","packageManager","interactive","chosen","map","res","pkg","remote","onVersionMismatchInNonInteractiveAutoUpdate","warn"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/actions/build/buildStudio.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {\n compareDependencyVersions,\n buildStudio as internalBuildStudio,\n} from '@sanity/cli-build/_internal/build'\nimport {exitCodes} from '@sanity/cli-core'\nimport {confirm, logSymbols, select, spinner} from '@sanity/cli-core/ux'\nimport {buildAppId, resolveWorkbenchApp} from '@sanity/workbench-cli/build'\n\nimport {getAppId} from '../../util/appId.js'\nimport {determineIsApp} from '../../util/determineIsApp.js'\nimport {getPackageManagerChoice} from '../../util/packageManager/packageManagerChoice.js'\nimport {upgradePackages} from '../../util/packageManager/upgradePackages.js'\nimport {warnAboutMissingAppId} from '../../util/warnAboutMissingAppId.js'\nimport {determineBasePath} from './determineBasePath.js'\nimport {\n checkDependenciesEventListenerFactory,\n preReleaseEventListenerFactory,\n} from './eventListenerFactory.js'\nimport {type BuildOptions} from './types.js'\n\n/**\n * Build the Sanity Studio.\n *\n * @internal\n */\nexport async function buildStudio(\n options: BuildOptions,\n): Promise<{mfManifest: Record<string, unknown> | undefined}> {\n const {calledFromDeploy, cliConfig, flags, outDir, output, workDir} = options\n\n // `views`/`webWorkers` live on the branded `defineApplication` result — resolve\n // the workbench capability so it's gated on the brand, like the app build.\n const workbench = resolveWorkbenchApp(cliConfig)\n const exposes = workbench ? {views: workbench.views, webWorkers: workbench.webWorkers} : undefined\n\n const appId = getAppId(cliConfig)\n\n let cleanOutputDirSpinner: ReturnType<typeof spinner> | undefined\n let buildSpinner: ReturnType<typeof spinner> | undefined\n\n return internalBuildStudio({\n appId,\n autoUpdatesEnabled: options.autoUpdatesEnabled,\n checkAppId: () => {\n // Warn if auto updates enabled but no appId configured.\n // Skip when called from deploy, since deploy handles appId itself\n // (prompts the user and tells them to add it to config).\n if (!appId && !calledFromDeploy) {\n warnAboutMissingAppId({appType: 'studio', output, projectId: cliConfig?.api?.projectId})\n }\n },\n compareDependencyVersions: (packages) => compareDependencyVersions(packages, workDir, {appId}),\n determineBasePath: () => determineBasePath(cliConfig, 'studio', output),\n exposes,\n isApp: determineIsApp(cliConfig),\n isWorkbenchApp: !!workbench,\n minify: Boolean(flags.minify),\n outDir,\n output,\n reactCompiler: cliConfig.reactCompiler,\n schemaExtraction: cliConfig.schemaExtraction,\n sourceMap: Boolean(flags['source-maps']),\n stats: flags.stats,\n unattendedMode: Boolean(flags.yes),\n vite: cliConfig.vite,\n // Shared with deploy: it passes the resolved application id (minted by the\n // API on a first deploy) to inline; a plain build has none, so it hashes the shape.\n workbenchAppId: workbench\n ? (options.applicationId ?? (await buildAppId(workbench)))\n : undefined,\n workDir,\n\n eventListener: {\n ...preReleaseEventListenerFactory(output),\n\n ...checkDependenciesEventListenerFactory(output),\n\n onBuildEnd({message}) {\n if (buildSpinner) {\n buildSpinner.text = message\n buildSpinner.succeed()\n }\n },\n onBuildFail({message}) {\n if (buildSpinner) {\n buildSpinner.fail()\n }\n\n output.error(message, {exit: exitCodes.RUNTIME_ERROR})\n },\n onBuildStart({message}) {\n if (!buildSpinner) {\n buildSpinner = spinner(message).start()\n }\n },\n onCleanOutputDirEnd({message}) {\n if (cleanOutputDirSpinner) {\n cleanOutputDirSpinner.text = message\n cleanOutputDirSpinner.succeed()\n }\n },\n onCleanOutputDirStart({message}) {\n if (!cleanOutputDirSpinner) {\n cleanOutputDirSpinner = spinner(message).start()\n }\n },\n async onInteractiveNonDefaultOutputDir({message}: {message: string}) {\n const shouldClean = await confirm({\n default: true,\n message,\n })\n return {shouldClean}\n },\n async onVersionMismatchInInteractiveAutoUpdate({mismatched, versionMismatchWarning}) {\n const choice = await select({\n choices: [\n {\n name: `Upgrade local versions (recommended). You will need to run the build command again`,\n value: 'upgrade',\n },\n {\n name: `Upgrade and proceed with build`,\n value: 'upgrade-and-proceed',\n },\n {\n name: `Continue anyway`,\n value: 'continue',\n },\n {name: 'Cancel', value: 'cancel'},\n ],\n default: 'upgrade',\n message: styleText(\n 'yellow',\n `${logSymbols.warning} ${versionMismatchWarning}\\n\\nDo you want to upgrade local versions before deploying?`,\n ),\n })\n\n if (choice === 'cancel') {\n output.error('Declined to continue with build', {exit: exitCodes.RUNTIME_ERROR})\n return {stopBuild: true}\n }\n\n if (choice === 'upgrade' || choice === 'upgrade-and-proceed') {\n await upgradePackages(\n {\n packageManager: (await getPackageManagerChoice(workDir, {interactive: false})).chosen,\n packages: mismatched.map((res) => [res.pkg, res.remote]),\n },\n {output, workDir},\n )\n\n return {stopBuild: choice === 'upgrade'}\n }\n\n return {stopBuild: false}\n },\n onVersionMismatchInNonInteractiveAutoUpdate({versionMismatchWarning}) {\n output.warn(versionMismatchWarning)\n },\n },\n })\n}\n"],"names":["styleText","compareDependencyVersions","buildStudio","internalBuildStudio","exitCodes","confirm","logSymbols","select","spinner","buildAppId","resolveWorkbenchApp","getAppId","determineIsApp","getPackageManagerChoice","upgradePackages","warnAboutMissingAppId","determineBasePath","checkDependenciesEventListenerFactory","preReleaseEventListenerFactory","options","calledFromDeploy","cliConfig","flags","outDir","output","workDir","workbench","exposes","views","webWorkers","undefined","appId","cleanOutputDirSpinner","buildSpinner","autoUpdatesEnabled","checkAppId","appType","projectId","api","packages","isApp","isWorkbenchApp","minify","Boolean","reactCompiler","schemaExtraction","sourceMap","stats","unattendedMode","yes","vite","workbenchAppId","applicationId","eventListener","onBuildEnd","message","text","succeed","onBuildFail","fail","error","exit","RUNTIME_ERROR","onBuildStart","start","onCleanOutputDirEnd","onCleanOutputDirStart","onInteractiveNonDefaultOutputDir","shouldClean","default","onVersionMismatchInInteractiveAutoUpdate","mismatched","versionMismatchWarning","choice","choices","name","value","warning","stopBuild","packageManager","interactive","chosen","map","res","pkg","remote","onVersionMismatchInNonInteractiveAutoUpdate","warn"],"mappings":"AAAA,SAAQA,SAAS,QAAO,YAAW;AAEnC,SACEC,yBAAyB,EACzBC,eAAeC,mBAAmB,QAC7B,oCAAmC;AAC1C,SAAQC,SAAS,QAAO,mBAAkB;AAC1C,SAAQC,OAAO,EAAEC,UAAU,EAAEC,MAAM,EAAEC,OAAO,QAAO,sBAAqB;AACxE,SAAQC,UAAU,EAAEC,mBAAmB,QAAO,8BAA6B;AAE3E,SAAQC,QAAQ,QAAO,sBAAqB;AAC5C,SAAQC,cAAc,QAAO,+BAA8B;AAC3D,SAAQC,uBAAuB,QAAO,oDAAmD;AACzF,SAAQC,eAAe,QAAO,+CAA8C;AAC5E,SAAQC,qBAAqB,QAAO,sCAAqC;AACzE,SAAQC,iBAAiB,QAAO,yBAAwB;AACxD,SACEC,qCAAqC,EACrCC,8BAA8B,QACzB,4BAA2B;AAGlC;;;;CAIC,GACD,OAAO,eAAehB,YACpBiB,OAAqB;IAErB,MAAM,EAACC,gBAAgB,EAAEC,SAAS,EAAEC,KAAK,EAAEC,MAAM,EAAEC,MAAM,EAAEC,OAAO,EAAC,GAAGN;IAEtE,gFAAgF;IAChF,2EAA2E;IAC3E,MAAMO,YAAYhB,oBAAoBW;IACtC,MAAMM,UAAUD,YAAY;QAACE,OAAOF,UAAUE,KAAK;QAAEC,YAAYH,UAAUG,UAAU;IAAA,IAAIC;IAEzF,MAAMC,QAAQpB,SAASU;IAEvB,IAAIW;IACJ,IAAIC;IAEJ,OAAO9B,oBAAoB;QACzB4B;QACAG,oBAAoBf,QAAQe,kBAAkB;QAC9CC,YAAY;YACV,wDAAwD;YACxD,kEAAkE;YAClE,yDAAyD;YACzD,IAAI,CAACJ,SAAS,CAACX,kBAAkB;gBAC/BL,sBAAsB;oBAACqB,SAAS;oBAAUZ;oBAAQa,WAAWhB,WAAWiB,KAAKD;gBAAS;YACxF;QACF;QACApC,2BAA2B,CAACsC,WAAatC,0BAA0BsC,UAAUd,SAAS;gBAACM;YAAK;QAC5Ff,mBAAmB,IAAMA,kBAAkBK,WAAW,UAAUG;QAChEG;QACAa,OAAO5B,eAAeS;QACtBoB,gBAAgB,CAAC,CAACf;QAClBgB,QAAQC,QAAQrB,MAAMoB,MAAM;QAC5BnB;QACAC;QACAoB,eAAevB,UAAUuB,aAAa;QACtCC,kBAAkBxB,UAAUwB,gBAAgB;QAC5CC,WAAWH,QAAQrB,KAAK,CAAC,cAAc;QACvCyB,OAAOzB,MAAMyB,KAAK;QAClBC,gBAAgBL,QAAQrB,MAAM2B,GAAG;QACjCC,MAAM7B,UAAU6B,IAAI;QACpB,2EAA2E;QAC3E,oFAAoF;QACpFC,gBAAgBzB,YACXP,QAAQiC,aAAa,IAAK,MAAM3C,WAAWiB,aAC5CI;QACJL;QAEA4B,eAAe;YACb,GAAGnC,+BAA+BM,OAAO;YAEzC,GAAGP,sCAAsCO,OAAO;YAEhD8B,YAAW,EAACC,OAAO,EAAC;gBAClB,IAAItB,cAAc;oBAChBA,aAAauB,IAAI,GAAGD;oBACpBtB,aAAawB,OAAO;gBACtB;YACF;YACAC,aAAY,EAACH,OAAO,EAAC;gBACnB,IAAItB,cAAc;oBAChBA,aAAa0B,IAAI;gBACnB;gBAEAnC,OAAOoC,KAAK,CAACL,SAAS;oBAACM,MAAMzD,UAAU0D,aAAa;gBAAA;YACtD;YACAC,cAAa,EAACR,OAAO,EAAC;gBACpB,IAAI,CAACtB,cAAc;oBACjBA,eAAezB,QAAQ+C,SAASS,KAAK;gBACvC;YACF;YACAC,qBAAoB,EAACV,OAAO,EAAC;gBAC3B,IAAIvB,uBAAuB;oBACzBA,sBAAsBwB,IAAI,GAAGD;oBAC7BvB,sBAAsByB,OAAO;gBAC/B;YACF;YACAS,uBAAsB,EAACX,OAAO,EAAC;gBAC7B,IAAI,CAACvB,uBAAuB;oBAC1BA,wBAAwBxB,QAAQ+C,SAASS,KAAK;gBAChD;YACF;YACA,MAAMG,kCAAiC,EAACZ,OAAO,EAAoB;gBACjE,MAAMa,cAAc,MAAM/D,QAAQ;oBAChCgE,SAAS;oBACTd;gBACF;gBACA,OAAO;oBAACa;gBAAW;YACrB;YACA,MAAME,0CAAyC,EAACC,UAAU,EAAEC,sBAAsB,EAAC;gBACjF,MAAMC,SAAS,MAAMlE,OAAO;oBAC1BmE,SAAS;wBACP;4BACEC,MAAM,CAAC,kFAAkF,CAAC;4BAC1FC,OAAO;wBACT;wBACA;4BACED,MAAM,CAAC,8BAA8B,CAAC;4BACtCC,OAAO;wBACT;wBACA;4BACED,MAAM,CAAC,eAAe,CAAC;4BACvBC,OAAO;wBACT;wBACA;4BAACD,MAAM;4BAAUC,OAAO;wBAAQ;qBACjC;oBACDP,SAAS;oBACTd,SAASvD,UACP,UACA,GAAGM,WAAWuE,OAAO,CAAC,CAAC,EAAEL,uBAAuB,2DAA2D,CAAC;gBAEhH;gBAEA,IAAIC,WAAW,UAAU;oBACvBjD,OAAOoC,KAAK,CAAC,mCAAmC;wBAACC,MAAMzD,UAAU0D,aAAa;oBAAA;oBAC9E,OAAO;wBAACgB,WAAW;oBAAI;gBACzB;gBAEA,IAAIL,WAAW,aAAaA,WAAW,uBAAuB;oBAC5D,MAAM3D,gBACJ;wBACEiE,gBAAgB,AAAC,CAAA,MAAMlE,wBAAwBY,SAAS;4BAACuD,aAAa;wBAAK,EAAC,EAAGC,MAAM;wBACrF1C,UAAUgC,WAAWW,GAAG,CAAC,CAACC,MAAQ;gCAACA,IAAIC,GAAG;gCAAED,IAAIE,MAAM;6BAAC;oBACzD,GACA;wBAAC7D;wBAAQC;oBAAO;oBAGlB,OAAO;wBAACqD,WAAWL,WAAW;oBAAS;gBACzC;gBAEA,OAAO;oBAACK,WAAW;gBAAK;YAC1B;YACAQ,6CAA4C,EAACd,sBAAsB,EAAC;gBAClEhD,OAAO+D,IAAI,CAACf;YACd;QACF;IACF;AACF"}
@@ -0,0 +1,113 @@
1
+ import { findPathForFiles, getCliConfig, getLocalPackageVersion, getStudioConfig, isWorkbenchApp, tryFindStudioConfigPath } from '@sanity/cli-core';
2
+ import { input, select } from '@sanity/cli-core/ux';
3
+ import { toAppSlug } from '@sanity/workbench-cli/init';
4
+ import { lt } from 'semver';
5
+ import { getOrganizationGrants, listOrganizations } from '../../services/organizations.js';
6
+ import { getProjectById } from '../../services/projects.js';
7
+ import { getManageUrl } from '../projects/getManageUrl.js';
8
+ // The first `sanity` release whose `sanity/cli` exports `defineApplication`
9
+ const MIN_SANITY_VERSION = '6.12.0';
10
+ const purpose = 'Move an existing Studio or SDK app onto the Dashboard';
11
+ const description = `
12
+ Rewrites sanity.cli.ts (or .js) so the next \`sanity dev\` and \`sanity deploy\` run the project
13
+ as a new Dashboard application. Asks for the application's title and slug, and looks up the
14
+ organization from the project.
15
+
16
+ from: app: {organizationId: 'oAbc', entry: './src/App.tsx'}
17
+ to: app: defineApplication({title: 'Acme', slug: 'acme', organizationId: 'oAbc', entry: './src/App.tsx'})
18
+
19
+ The existing deployment is left alone. Remove \`deployment.appId\` before deploying, or the
20
+ Dashboard build replaces the existing application.
21
+ `.trim();
22
+ export const dashboard = {
23
+ description,
24
+ filename: 'dashboard.js',
25
+ prepare: async ({ output, workDir })=>{
26
+ const config = await getCliConfig(workDir);
27
+ if (isWorkbenchApp(config.app)) {
28
+ throw new Error('This project is already a Dashboard application.');
29
+ }
30
+ const projectId = config.api?.projectId;
31
+ let organizationId = config.app?.organizationId;
32
+ // Deploy creates the application with both IDs, and the API rejects a project outside the
33
+ // organization, so a project's organization is the only valid choice
34
+ if (!organizationId && projectId) {
35
+ organizationId = (await getProjectById(projectId)).organizationId ?? undefined;
36
+ if (!organizationId) {
37
+ throw new Error(`Project ${projectId} isn't in an organization, and a Dashboard application needs one. Move the project into an organization at ${getManageUrl(projectId)}, then run this again.`);
38
+ }
39
+ }
40
+ if (!organizationId) {
41
+ const choices = await Promise.all((await listOrganizations()).map(async ({ id, name })=>{
42
+ // Grants can 401 for implicit memberships; treat any failure as no access
43
+ const grants = await getOrganizationGrants(id).catch(()=>null);
44
+ const canDeploy = (grants?.['sanity.sdk.applications'] ?? []).some((resource)=>resource.grants.some((grant)=>grant.name === 'deploy'));
45
+ return {
46
+ disabled: canDeploy ? false : 'Insufficient permissions',
47
+ name: `${name} [${id}]`,
48
+ value: id
49
+ };
50
+ }));
51
+ if (!choices.some((choice)=>choice.disabled === false)) {
52
+ throw new Error("You can't deploy applications in any of your organizations. Ask an organization administrator for access, then run this again.");
53
+ }
54
+ organizationId = await select({
55
+ choices,
56
+ message: 'Organization that owns the application:'
57
+ });
58
+ }
59
+ let suggestedTitle = config.app?.title;
60
+ if (!suggestedTitle && await tryFindStudioConfigPath(workDir)) {
61
+ const studioConfig = await getStudioConfig(workDir, {
62
+ resolvePlugins: false
63
+ });
64
+ suggestedTitle = Array.isArray(studioConfig) ? undefined : studioConfig.title;
65
+ }
66
+ const title = await input({
67
+ default: suggestedTitle,
68
+ message: 'Application title:',
69
+ validate: (value)=>value.trim() ? true : 'Enter a title for the application.'
70
+ });
71
+ // A studio titled after its host would otherwise suggest the one slug that's rejected
72
+ const suggestedSlug = toAppSlug(title) ?? undefined;
73
+ const slug = await input({
74
+ default: suggestedSlug === config.studioHost ? undefined : suggestedSlug,
75
+ message: 'Application slug (the hostname it deploys to):',
76
+ validate: (value)=>{
77
+ if (toAppSlug(value) !== value) {
78
+ return 'Use lowercase letters, numbers and hyphens, starting with a letter.';
79
+ }
80
+ if (value === config.studioHost) {
81
+ return `"${value}" is your Studio's hostname (studioHost), so the deploy would fail. Choose a different slug.`;
82
+ }
83
+ return true;
84
+ }
85
+ });
86
+ // `app.id` is the deprecated spelling and deploy still honours it
87
+ const appIdKey = config.deployment?.appId ? 'deployment.appId' : config.app?.id && 'app.id';
88
+ if (appIdKey) {
89
+ output.warn(`Remove \`${appIdKey}\` from your CLI config before you deploy. It points at your existing application, and deploying with it in place replaces that application with the Dashboard build.`);
90
+ }
91
+ const sanityVersion = await getLocalPackageVersion('sanity', workDir);
92
+ if (sanityVersion && lt(sanityVersion, MIN_SANITY_VERSION)) {
93
+ output.warn(`This project uses sanity ${sanityVersion}, and \`defineApplication\` needs ${MIN_SANITY_VERSION} or later. Upgrade sanity before you run \`sanity dev\` or \`sanity deploy\`.`);
94
+ }
95
+ // getCliConfig has already checked there is exactly one
96
+ const cliConfigPaths = await findPathForFiles(workDir, [
97
+ 'sanity.cli.ts',
98
+ 'sanity.cli.js'
99
+ ]);
100
+ const paths = cliConfigPaths.filter((path)=>path.exists).map((path)=>path.path);
101
+ return {
102
+ options: {
103
+ organizationId,
104
+ slug,
105
+ title: title.trim()
106
+ },
107
+ paths
108
+ };
109
+ },
110
+ purpose
111
+ };
112
+
113
+ //# sourceMappingURL=dashboard.js.map