@sanity/cli 6.0.0-alpha.20 → 6.0.0-alpha.21

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 (227) hide show
  1. package/README.md +405 -225
  2. package/dist/actions/auth/authServer.js +13 -11
  3. package/dist/actions/auth/authServer.js.map +1 -1
  4. package/dist/actions/auth/login/getProvider.js +43 -39
  5. package/dist/actions/auth/login/getProvider.js.map +1 -1
  6. package/dist/actions/auth/login/getSSOProvider.js +25 -19
  7. package/dist/actions/auth/login/getSSOProvider.js.map +1 -1
  8. package/dist/actions/auth/login/login.js +12 -33
  9. package/dist/actions/auth/login/login.js.map +1 -1
  10. package/dist/actions/auth/types.js.map +1 -1
  11. package/dist/actions/codemods/reactIconsV3.js +2 -2
  12. package/dist/actions/codemods/reactIconsV3.js.map +1 -1
  13. package/dist/actions/debug/formatters.js +22 -0
  14. package/dist/actions/debug/formatters.js.map +1 -0
  15. package/dist/actions/dev/getDashboardAppUrl.js +3 -3
  16. package/dist/actions/dev/getDashboardAppUrl.js.map +1 -1
  17. package/dist/actions/documents/validateDocuments.worker.js +2 -2
  18. package/dist/actions/documents/validateDocuments.worker.js.map +1 -1
  19. package/dist/actions/documents/validation/reporters/prettyReporter/formatDocumentValidation.js +1 -1
  20. package/dist/actions/documents/validation/reporters/prettyReporter/formatDocumentValidation.js.map +1 -1
  21. package/dist/actions/documents/validation/reporters/prettyReporter/tree.js +108 -0
  22. package/dist/actions/documents/validation/reporters/prettyReporter/tree.js.map +1 -0
  23. package/dist/actions/graphql/SchemaError.js +4 -26
  24. package/dist/actions/graphql/SchemaError.js.map +1 -1
  25. package/dist/actions/graphql/extractFromSanitySchema.js +3 -4
  26. package/dist/actions/graphql/extractFromSanitySchema.js.map +1 -1
  27. package/dist/actions/graphql/extractGraphQLAPIs.js +150 -0
  28. package/dist/actions/graphql/extractGraphQLAPIs.js.map +1 -0
  29. package/dist/actions/graphql/extractGraphQLAPIs.worker.js +12 -0
  30. package/dist/actions/graphql/extractGraphQLAPIs.worker.js.map +1 -0
  31. package/dist/actions/graphql/gen1/index.js +5 -5
  32. package/dist/actions/graphql/gen1/index.js.map +1 -1
  33. package/dist/actions/graphql/gen2/index.js +6 -6
  34. package/dist/actions/graphql/gen2/index.js.map +1 -1
  35. package/dist/actions/graphql/gen3/generateTypeQueries.js +2 -3
  36. package/dist/actions/graphql/gen3/generateTypeQueries.js.map +1 -1
  37. package/dist/actions/graphql/gen3/index.js +6 -7
  38. package/dist/actions/graphql/gen3/index.js.map +1 -1
  39. package/dist/actions/graphql/getGraphQLAPIs.js +12 -35
  40. package/dist/actions/graphql/getGraphQLAPIs.js.map +1 -1
  41. package/dist/actions/graphql/getGraphQLAPIs.worker.js +75 -106
  42. package/dist/actions/graphql/getGraphQLAPIs.worker.js.map +1 -1
  43. package/dist/actions/graphql/helpers.js +13 -0
  44. package/dist/actions/graphql/helpers.js.map +1 -1
  45. package/dist/actions/graphql/resolveGraphQLApisFromWorkspaces.js +187 -0
  46. package/dist/actions/graphql/resolveGraphQLApisFromWorkspaces.js.map +1 -0
  47. package/dist/actions/graphql/types.js +1 -1
  48. package/dist/actions/graphql/types.js.map +1 -1
  49. package/dist/actions/init/bootstrapLocalTemplate.js +2 -1
  50. package/dist/actions/init/bootstrapLocalTemplate.js.map +1 -1
  51. package/dist/actions/init/bootstrapRemoteTemplate.js +6 -5
  52. package/dist/actions/init/bootstrapRemoteTemplate.js.map +1 -1
  53. package/dist/actions/init/createPackageManifest.js +5 -0
  54. package/dist/actions/init/createPackageManifest.js.map +1 -1
  55. package/dist/actions/init/templates/appQuickstart.js +2 -1
  56. package/dist/actions/init/templates/appQuickstart.js.map +1 -1
  57. package/dist/actions/init/templates/appSanityUi.js +2 -1
  58. package/dist/actions/init/templates/appSanityUi.js.map +1 -1
  59. package/dist/actions/init/types.js.map +1 -1
  60. package/dist/actions/media/importMedia.js +1 -2
  61. package/dist/actions/media/importMedia.js.map +1 -1
  62. package/dist/actions/projects/getManageUrl.js +1 -2
  63. package/dist/actions/projects/getManageUrl.js.map +1 -1
  64. package/dist/actions/schema/validateSchema.worker.js +1 -3
  65. package/dist/actions/schema/validateSchema.worker.js.map +1 -1
  66. package/dist/actions/telemetry/isTrueish.js +10 -0
  67. package/dist/actions/telemetry/isTrueish.js.map +1 -0
  68. package/dist/actions/telemetry/resolveConsent.js +2 -1
  69. package/dist/actions/telemetry/resolveConsent.js.map +1 -1
  70. package/dist/actions/telemetry/setConsent.js +2 -1
  71. package/dist/actions/telemetry/setConsent.js.map +1 -1
  72. package/dist/actions/versions/findSanityModulesVersions.js +1 -2
  73. package/dist/actions/versions/findSanityModulesVersions.js.map +1 -1
  74. package/dist/commands/backup/disable.js +21 -1
  75. package/dist/commands/backup/disable.js.map +1 -1
  76. package/dist/commands/backup/download.js +18 -4
  77. package/dist/commands/backup/download.js.map +1 -1
  78. package/dist/commands/backup/enable.js +21 -1
  79. package/dist/commands/backup/enable.js.map +1 -1
  80. package/dist/commands/backup/list.js +15 -1
  81. package/dist/commands/backup/list.js.map +1 -1
  82. package/dist/commands/cors/add.js +19 -1
  83. package/dist/commands/cors/add.js.map +1 -1
  84. package/dist/commands/cors/delete.js +21 -1
  85. package/dist/commands/cors/delete.js.map +1 -1
  86. package/dist/commands/cors/list.js +21 -1
  87. package/dist/commands/cors/list.js.map +1 -1
  88. package/dist/commands/dataset/alias/create.js +4 -2
  89. package/dist/commands/dataset/alias/create.js.map +1 -1
  90. package/dist/commands/dataset/alias/delete.js +4 -2
  91. package/dist/commands/dataset/alias/delete.js.map +1 -1
  92. package/dist/commands/dataset/alias/link.js +4 -2
  93. package/dist/commands/dataset/alias/link.js.map +1 -1
  94. package/dist/commands/dataset/alias/unlink.js +4 -2
  95. package/dist/commands/dataset/alias/unlink.js.map +1 -1
  96. package/dist/commands/dataset/copy.js +4 -2
  97. package/dist/commands/dataset/copy.js.map +1 -1
  98. package/dist/commands/dataset/create.js +4 -2
  99. package/dist/commands/dataset/create.js.map +1 -1
  100. package/dist/commands/dataset/delete.js +4 -2
  101. package/dist/commands/dataset/delete.js.map +1 -1
  102. package/dist/commands/dataset/embeddings/disable.js +4 -2
  103. package/dist/commands/dataset/embeddings/disable.js.map +1 -1
  104. package/dist/commands/dataset/embeddings/enable.js +6 -4
  105. package/dist/commands/dataset/embeddings/enable.js.map +1 -1
  106. package/dist/commands/dataset/embeddings/status.js +4 -2
  107. package/dist/commands/dataset/embeddings/status.js.map +1 -1
  108. package/dist/commands/dataset/export.js +7 -11
  109. package/dist/commands/dataset/export.js.map +1 -1
  110. package/dist/commands/dataset/list.js +4 -2
  111. package/dist/commands/dataset/list.js.map +1 -1
  112. package/dist/commands/dataset/visibility/get.js +4 -2
  113. package/dist/commands/dataset/visibility/get.js.map +1 -1
  114. package/dist/commands/dataset/visibility/set.js +4 -2
  115. package/dist/commands/dataset/visibility/set.js.map +1 -1
  116. package/dist/commands/debug.js +2 -1
  117. package/dist/commands/debug.js.map +1 -1
  118. package/dist/commands/documents/create.js +15 -5
  119. package/dist/commands/documents/create.js.map +1 -1
  120. package/dist/commands/documents/delete.js +17 -6
  121. package/dist/commands/documents/delete.js.map +1 -1
  122. package/dist/commands/documents/get.js +15 -6
  123. package/dist/commands/documents/get.js.map +1 -1
  124. package/dist/commands/documents/query.js +24 -12
  125. package/dist/commands/documents/query.js.map +1 -1
  126. package/dist/commands/documents/validate.js +29 -9
  127. package/dist/commands/documents/validate.js.map +1 -1
  128. package/dist/commands/graphql/deploy.js +55 -28
  129. package/dist/commands/graphql/deploy.js.map +1 -1
  130. package/dist/commands/graphql/list.js +14 -1
  131. package/dist/commands/graphql/list.js.map +1 -1
  132. package/dist/commands/graphql/undeploy.js +36 -14
  133. package/dist/commands/graphql/undeploy.js.map +1 -1
  134. package/dist/commands/hook/attempt.js +21 -1
  135. package/dist/commands/hook/attempt.js.map +1 -1
  136. package/dist/commands/hook/create.js +22 -2
  137. package/dist/commands/hook/create.js.map +1 -1
  138. package/dist/commands/hook/delete.js +21 -1
  139. package/dist/commands/hook/delete.js.map +1 -1
  140. package/dist/commands/hook/list.js +21 -1
  141. package/dist/commands/hook/list.js.map +1 -1
  142. package/dist/commands/hook/logs.js +19 -1
  143. package/dist/commands/hook/logs.js.map +1 -1
  144. package/dist/commands/init.js +13 -6
  145. package/dist/commands/init.js.map +1 -1
  146. package/dist/commands/login.js +13 -6
  147. package/dist/commands/login.js.map +1 -1
  148. package/dist/commands/logout.js +8 -6
  149. package/dist/commands/logout.js.map +1 -1
  150. package/dist/commands/media/create-aspect.js +3 -3
  151. package/dist/commands/media/create-aspect.js.map +1 -1
  152. package/dist/commands/media/delete-aspect.js +8 -1
  153. package/dist/commands/media/delete-aspect.js.map +1 -1
  154. package/dist/commands/media/deploy-aspect.js +20 -3
  155. package/dist/commands/media/deploy-aspect.js.map +1 -1
  156. package/dist/commands/media/export.js +8 -1
  157. package/dist/commands/media/export.js.map +1 -1
  158. package/dist/commands/media/import.js +9 -2
  159. package/dist/commands/media/import.js.map +1 -1
  160. package/dist/commands/schema/delete.js +19 -6
  161. package/dist/commands/schema/delete.js.map +1 -1
  162. package/dist/commands/schema/deploy.js +8 -2
  163. package/dist/commands/schema/deploy.js.map +1 -1
  164. package/dist/commands/tokens/add.js +23 -1
  165. package/dist/commands/tokens/add.js.map +1 -1
  166. package/dist/commands/tokens/delete.js +19 -1
  167. package/dist/commands/tokens/delete.js.map +1 -1
  168. package/dist/commands/tokens/list.js +19 -1
  169. package/dist/commands/tokens/list.js.map +1 -1
  170. package/dist/commands/users/invite.js +23 -1
  171. package/dist/commands/users/invite.js.map +1 -1
  172. package/dist/commands/users/list.js +23 -1
  173. package/dist/commands/users/list.js.map +1 -1
  174. package/dist/hooks/prerun/flushTelemetry.worker.js +1 -1
  175. package/dist/hooks/prerun/flushTelemetry.worker.js.map +1 -1
  176. package/dist/hooks/prerun/setupTelemetry.js +2 -1
  177. package/dist/hooks/prerun/setupTelemetry.js.map +1 -1
  178. package/dist/prompts/promptForProject.js.map +1 -1
  179. package/dist/{actions/auth/login/promptProviders.js → prompts/promptForProviders.js} +3 -3
  180. package/dist/prompts/promptForProviders.js.map +1 -0
  181. package/dist/services/auth.js +36 -3
  182. package/dist/services/auth.js.map +1 -1
  183. package/dist/services/docs.js +2 -2
  184. package/dist/services/docs.js.map +1 -1
  185. package/dist/services/getUrlHeaders.js +0 -2
  186. package/dist/services/getUrlHeaders.js.map +1 -1
  187. package/dist/services/projects.js +4 -2
  188. package/dist/services/projects.js.map +1 -1
  189. package/dist/services/telemetry.js +2 -1
  190. package/dist/services/telemetry.js.map +1 -1
  191. package/dist/util/createExpiringConfig.js +64 -0
  192. package/dist/util/createExpiringConfig.js.map +1 -0
  193. package/dist/util/detectFramework.js +135 -0
  194. package/dist/util/detectFramework.js.map +1 -0
  195. package/dist/util/extractDocumentsFromNdjsonOrTarball.js +1 -2
  196. package/dist/util/extractDocumentsFromNdjsonOrTarball.js.map +1 -1
  197. package/dist/util/isSchemaError.js +11 -0
  198. package/dist/util/isSchemaError.js.map +1 -0
  199. package/dist/util/isTar.js +8 -0
  200. package/dist/util/isTar.js.map +1 -0
  201. package/dist/util/sharedFlags.js +44 -14
  202. package/dist/util/sharedFlags.js.map +1 -1
  203. package/dist/util/telemetry/cleanupOldTelemetryFiles.js +30 -0
  204. package/dist/util/telemetry/cleanupOldTelemetryFiles.js.map +1 -0
  205. package/dist/util/telemetry/createTelemetryStore.js +95 -0
  206. package/dist/util/telemetry/createTelemetryStore.js.map +1 -0
  207. package/dist/util/telemetry/createTraceId.js +10 -0
  208. package/dist/util/telemetry/createTraceId.js.map +1 -0
  209. package/dist/util/telemetry/findTelemetryFiles.js +35 -0
  210. package/dist/util/telemetry/findTelemetryFiles.js.map +1 -0
  211. package/dist/util/telemetry/flushTelemetryFiles.js +118 -0
  212. package/dist/util/telemetry/flushTelemetryFiles.js.map +1 -0
  213. package/dist/util/telemetry/generateTelemetryFilePath.js +30 -0
  214. package/dist/util/telemetry/generateTelemetryFilePath.js.map +1 -0
  215. package/dist/util/telemetry/logger.js +59 -0
  216. package/dist/util/telemetry/logger.js.map +1 -0
  217. package/dist/util/telemetry/readNDJSON.js +28 -0
  218. package/dist/util/telemetry/readNDJSON.js.map +1 -0
  219. package/dist/util/telemetry/telemetryStoreDebug.js +7 -0
  220. package/dist/util/telemetry/telemetryStoreDebug.js.map +1 -0
  221. package/dist/util/telemetry/trace.js +150 -0
  222. package/dist/util/telemetry/trace.js.map +1 -0
  223. package/dist/util/update/updateChecker.js +2 -1
  224. package/dist/util/update/updateChecker.js.map +1 -1
  225. package/oclif.manifest.json +966 -529
  226. package/package.json +19 -22
  227. package/dist/actions/auth/login/promptProviders.js.map +0 -1
@@ -2,15 +2,15 @@ import { Flags } from '@oclif/core';
2
2
  import { isInteractive, SanityCommand } from '@sanity/cli-core';
3
3
  import { confirm, spinner } from '@sanity/cli-core/ux';
4
4
  import get from 'lodash-es/get.js';
5
- import { extractFromSanitySchema } from '../../actions/graphql/extractFromSanitySchema.js';
5
+ import { extractGraphQLAPIs } from '../../actions/graphql/extractGraphQLAPIs.js';
6
6
  import gen1 from '../../actions/graphql/gen1/index.js';
7
7
  import gen2 from '../../actions/graphql/gen2/index.js';
8
8
  import gen3 from '../../actions/graphql/gen3/index.js';
9
- import { getGraphQLAPIs } from '../../actions/graphql/getGraphQLAPIs.js';
10
9
  import { graphqlDebug } from '../../actions/graphql/graphqlDebug.js';
11
10
  import { resolveApiGeneration } from '../../actions/graphql/resolveApiGeneration.js';
12
11
  import { SchemaError } from '../../actions/graphql/SchemaError.js';
13
12
  import { deployGraphQLAPI, getClientUrl, getCurrentSchemaProps, validateGraphQLAPI } from '../../services/graphql.js';
13
+ import { getDatasetFlag } from '../../util/sharedFlags.js';
14
14
  const apiIdRegex = /^[a-z0-9_-]+$/;
15
15
  const generations = {
16
16
  gen1,
@@ -48,7 +48,7 @@ export class GraphQLDeployCommand extends SanityCommand {
48
48
  description: 'Only deploy API with this ID. Can be specified multiple times.',
49
49
  multiple: true
50
50
  }),
51
- dataset: Flags.string({
51
+ ...getDatasetFlag({
52
52
  description: 'Deploy API for the given dataset'
53
53
  }),
54
54
  'dry-run': Flags.boolean({
@@ -87,10 +87,21 @@ export class GraphQLDeployCommand extends SanityCommand {
87
87
  let apiDefs = [];
88
88
  let spin;
89
89
  try {
90
- apiDefs = await getGraphQLAPIs(workDir);
90
+ apiDefs = await extractGraphQLAPIs(workDir, {
91
+ nonNullDocumentFieldsFlag,
92
+ withUnionCache
93
+ });
91
94
  } catch (error) {
92
- debug('Failed to get GraphQL APIs', error);
93
- this.error('Failed to get GraphQL APIs', {
95
+ if (error instanceof SchemaError) {
96
+ debug('Schema validation errors: %O', error.problemGroups);
97
+ error.print(this.output);
98
+ this.error('Fix the schema errors above and try again', {
99
+ exit: 1
100
+ });
101
+ }
102
+ debug('Failed to resolve GraphQL APIs: %O', error);
103
+ const message = error instanceof Error ? error.message : String(error);
104
+ this.error(`Failed to resolve GraphQL APIs: ${message}`, {
94
105
  exit: 1
95
106
  });
96
107
  }
@@ -141,7 +152,7 @@ export class GraphQLDeployCommand extends SanityCommand {
141
152
  });
142
153
  }
143
154
  if (apiDef.id) {
144
- if (typeof apiDef.id !== 'string' || !apiIdRegex.test(apiDef.id)) {
155
+ if (!apiIdRegex.test(apiDef.id)) {
145
156
  this.error(`Invalid GraphQL API id "${apiDef.id}" - only a-z, 0-9, underscore and dashes are allowed`, {
146
157
  exit: 1
147
158
  });
@@ -165,7 +176,7 @@ export class GraphQLDeployCommand extends SanityCommand {
165
176
  }
166
177
  index++;
167
178
  const { apiName, dataset, tag } = this.getApiIdentifiers(apiDef, datasetFlag, tagFlag);
168
- const { nonNullDocumentFields, playground, projectId, schema } = apiDef;
179
+ const { playground, projectId } = apiDef;
169
180
  spin = spinner(`Generating GraphQL API: ${apiName}`).start();
170
181
  if (!dataset) {
171
182
  spin.fail();
@@ -173,6 +184,27 @@ export class GraphQLDeployCommand extends SanityCommand {
173
184
  exit: 1
174
185
  });
175
186
  }
187
+ // Handle extraction errors early (computed in worker), before network calls and prompts.
188
+ // Continue the loop so all API errors are reported — don't exit on the first failure.
189
+ if (apiDef.schemaErrors?.length) {
190
+ spin.fail();
191
+ new SchemaError(apiDef.schemaErrors).print(this.output, `Schema errors in ${apiName}`);
192
+ hasErrors = true;
193
+ continue;
194
+ }
195
+ if (apiDef.extractionError) {
196
+ debug('Failed to extract schema', apiDef.extractionError);
197
+ spin.fail();
198
+ this.log(`Failed to extract schema for ${apiName}: ${apiDef.extractionError}`);
199
+ hasErrors = true;
200
+ continue;
201
+ }
202
+ if (!apiDef.extracted) {
203
+ spin.fail();
204
+ this.log(`Failed to extract schema for ${apiName}: No extraction result`);
205
+ hasErrors = true;
206
+ continue;
207
+ }
176
208
  let currentGeneration;
177
209
  let playgroundEnabled;
178
210
  try {
@@ -216,28 +248,16 @@ export class GraphQLDeployCommand extends SanityCommand {
216
248
  let apiSpec;
217
249
  try {
218
250
  const generateSchema = generations[generation];
219
- const extracted = extractFromSanitySchema(schema, {
220
- // Allow CLI flag to override configured setting
221
- nonNullDocumentFields: nonNullDocumentFieldsFlag === undefined ? nonNullDocumentFields : nonNullDocumentFieldsFlag,
222
- withUnionCache
223
- });
224
- apiSpec = generateSchema(extracted, {
251
+ apiSpec = generateSchema(apiDef.extracted, {
225
252
  filterSuffix: apiDef.filterSuffix
226
253
  });
227
254
  } catch (err) {
228
- debug('Failed to extract schema', err);
255
+ debug('Failed to generate schema', err);
229
256
  spin.fail();
230
- if (err instanceof SchemaError) {
231
- err.print(this.output);
232
- this.error('Failed to extract schema', {
233
- exit: 1
234
- });
235
- } else {
236
- const message = err instanceof Error ? err.message : 'Unknown error';
237
- this.error(`Failed to extract schema: ${message}`, {
238
- exit: 1
239
- });
240
- }
257
+ const message = err instanceof Error ? err.message : 'Unknown error';
258
+ this.error(`Failed to generate schema: ${message}`, {
259
+ exit: 1
260
+ });
241
261
  }
242
262
  let valid;
243
263
  try {
@@ -287,8 +307,15 @@ export class GraphQLDeployCommand extends SanityCommand {
287
307
  }
288
308
  spin.succeed();
289
309
  } else if (dryRun) {
290
- spin.succeed();
291
- this.log('GraphQL API is valid and has no breaking changes');
310
+ // isResultValid() already set the spinner state (succeed or warn).
311
+ // Check whether changes were forced so we print the correct message.
312
+ const { breakingChanges, dangerousChanges } = this.filterChanges(valid);
313
+ if (breakingChanges.length > 0 || dangerousChanges.length > 0) {
314
+ this.renderBreakingChanges(valid);
315
+ this.log('Forced with `--force`, skipping deploy (dry run)');
316
+ } else {
317
+ this.log('GraphQL API is valid and has no breaking changes');
318
+ }
292
319
  continue;
293
320
  }
294
321
  deployTasks.push({
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/commands/graphql/deploy.ts"],"sourcesContent":["import {Flags} from '@oclif/core'\nimport {isInteractive, SanityCommand} from '@sanity/cli-core'\nimport {confirm, spinner} from '@sanity/cli-core/ux'\nimport get from 'lodash-es/get.js'\n\nimport {extractFromSanitySchema} from '../../actions/graphql/extractFromSanitySchema.js'\nimport gen1 from '../../actions/graphql/gen1/index.js'\nimport gen2 from '../../actions/graphql/gen2/index.js'\nimport gen3 from '../../actions/graphql/gen3/index.js'\nimport {getGraphQLAPIs} from '../../actions/graphql/getGraphQLAPIs.js'\nimport {graphqlDebug} from '../../actions/graphql/graphqlDebug.js'\nimport {resolveApiGeneration} from '../../actions/graphql/resolveApiGeneration.js'\nimport {SchemaError} from '../../actions/graphql/SchemaError.js'\nimport {\n type GeneratedApiSpecification,\n type ResolvedGraphQLAPI,\n type ValidationResponse,\n} from '../../actions/graphql/types.js'\nimport {\n deployGraphQLAPI,\n getClientUrl,\n getCurrentSchemaProps,\n validateGraphQLAPI,\n} from '../../services/graphql.js'\n\ninterface DeployTask {\n dataset: string\n enablePlayground: boolean\n projectId: string\n schema: GeneratedApiSpecification\n tag: string\n}\n\nconst apiIdRegex = /^[a-z0-9_-]+$/\nconst generations = {\n gen1,\n gen2,\n gen3,\n}\n\nconst ignoredBreaking = new Set<string>(['OPTIONAL_INPUT_FIELD_ADDED'])\n// Reserved for future use to filter out specific dangerous change types\nconst ignoredWarnings = new Set<string>()\n\nconst debug = graphqlDebug.extend('deploy')\n\nexport class GraphQLDeployCommand extends SanityCommand<typeof GraphQLDeployCommand> {\n static override description = 'Deploy a GraphQL API from the current Sanity schema'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'Deploy all defined GraphQL APIs',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --dry-run',\n description: 'Validate defined GraphQL APIs, check for breaking changes, skip deploy',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --api staging --api ios',\n description: 'Deploy only the GraphQL APIs with the IDs \"staging\" and \"ios\"',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --playground',\n description: 'Deploy all defined GraphQL APIs, overriding any playground setting',\n },\n ]\n\n static override flags = {\n api: Flags.string({\n description: 'Only deploy API with this ID. Can be specified multiple times.',\n multiple: true,\n }),\n dataset: Flags.string({\n description: 'Deploy API for the given dataset',\n }),\n 'dry-run': Flags.boolean({\n default: false,\n description: 'Validate defined GraphQL APIs, check for breaking changes, skip deploy',\n }),\n force: Flags.boolean({\n description: 'Deploy API without confirming breaking changes',\n }),\n generation: Flags.string({\n description: 'API generation to deploy (defaults to \"gen3\")',\n options: ['gen1', 'gen2', 'gen3'],\n }),\n 'non-null-document-fields': Flags.boolean({\n description: 'Use non-null document fields (_id, _type etc)',\n }),\n playground: Flags.boolean({\n allowNo: true,\n description: 'Enable GraphQL playground for easier debugging',\n }),\n tag: Flags.string({\n description: 'Deploy API(s) to given tag (defaults to \"default\")',\n }),\n 'with-union-cache': Flags.boolean({\n description:\n 'Enable union cache that optimizes schema generation for schemas with many self referencing types',\n }),\n }\n\n public async run(): Promise<void> {\n const {flags} = await this.parse(GraphQLDeployCommand)\n const {\n api: onlyApis,\n dataset: datasetFlag,\n 'dry-run': dryRun,\n generation: generationFlag,\n 'non-null-document-fields': nonNullDocumentFieldsFlag,\n playground: playgroundFlag,\n tag: tagFlag,\n 'with-union-cache': withUnionCache,\n } = flags\n\n const workDir = (await this.getProjectRoot()).directory\n\n let apiDefs: ResolvedGraphQLAPI[] = []\n let spin: ReturnType<typeof spinner>\n\n try {\n apiDefs = await getGraphQLAPIs(workDir)\n } catch (error) {\n debug('Failed to get GraphQL APIs', error)\n this.error('Failed to get GraphQL APIs', {exit: 1})\n }\n\n const hasMultipleApis = flags.api ? flags.api.length > 1 : apiDefs.length > 1\n\n const usedFlags = [\n datasetFlag && '--dataset',\n tagFlag && '--tag',\n playgroundFlag !== undefined && '--playground',\n generationFlag !== undefined && '--generation',\n nonNullDocumentFieldsFlag !== undefined && '--non-null-document-fields',\n ].filter(Boolean)\n\n if (hasMultipleApis && usedFlags.length > 0) {\n this.warn(`More than one API defined, and ${usedFlags.join('/')} is specified`)\n this.warn(`This will use the specified flag(s) for ALL APIs, overriding config!`)\n\n if (flags.force) {\n this.warn(`--force specified, continuing...`)\n } else {\n const confirmed = await confirm({\n default: false,\n message: 'Continue with flag overrides for all APIs?',\n })\n if (!confirmed) {\n this.error('Operation cancelled', {exit: 1})\n }\n }\n }\n\n const deployTasks: DeployTask[] = []\n let hasErrors = false\n\n for (const apiId of onlyApis || []) {\n if (!apiDefs.some((apiDef) => apiDef.id === apiId)) {\n this.error(`GraphQL API with id \"${apiId}\" not found`, {exit: 1})\n }\n }\n\n const apiNames = new Set<string>()\n const apiIds = new Set<string>()\n\n for (const apiDef of apiDefs) {\n if (onlyApis && (!apiDef.id || !onlyApis.includes(apiDef.id))) {\n continue\n }\n\n const {apiName} = this.getApiIdentifiers(apiDef, datasetFlag, tagFlag)\n if (apiNames.has(apiName)) {\n this.error(`Multiple GraphQL APIs with the same dataset and tag found (${apiName})`, {\n exit: 1,\n })\n }\n\n if (apiDef.id) {\n if (typeof apiDef.id !== 'string' || !apiIdRegex.test(apiDef.id)) {\n this.error(\n `Invalid GraphQL API id \"${apiDef.id}\" - only a-z, 0-9, underscore and dashes are allowed`,\n {exit: 1},\n )\n }\n\n if (apiIds.has(apiDef.id)) {\n this.error(`Multiple GraphQL APIs with the same ID found (${apiDef.id})`, {exit: 1})\n }\n\n apiIds.add(apiDef.id)\n }\n\n apiNames.add(apiName)\n }\n\n if (onlyApis) {\n this.warn(`Deploying only specified APIs: ${onlyApis.join(', ')}`)\n }\n\n let index = -1\n for (const apiDef of apiDefs) {\n if (onlyApis && (!apiDef.id || !onlyApis.includes(apiDef.id))) {\n continue\n }\n\n index++\n\n const {apiName, dataset, tag} = this.getApiIdentifiers(apiDef, datasetFlag, tagFlag)\n const {nonNullDocumentFields, playground, projectId, schema} = apiDef\n spin = spinner(`Generating GraphQL API: ${apiName}`).start()\n\n if (!dataset) {\n spin.fail()\n this.error(`No dataset specified for API at index ${index}`, {exit: 1})\n }\n\n let currentGeneration: string | undefined\n let playgroundEnabled: boolean | undefined\n try {\n const schemaProps = await getCurrentSchemaProps(projectId, dataset, tag)\n currentGeneration = schemaProps.currentGeneration\n playgroundEnabled = schemaProps.playgroundEnabled\n } catch (err) {\n debug('Failed to get current GraphQL schema properties', err)\n spin.fail()\n this.error('Failed to get current GraphQL schema properties', {exit: 1})\n }\n\n // CLI flag takes precedence over configuration\n const specifiedGeneration = generationFlag === undefined ? apiDef.generation : generationFlag\n\n const generation = await resolveApiGeneration({\n currentGeneration,\n force: flags.force,\n index,\n output: this.output,\n specifiedGeneration,\n })\n\n if (!generation) {\n // User cancelled\n spin.fail()\n continue\n }\n\n if (!this.isRecognizedApiGeneration(generation)) {\n spin.fail()\n this.error(`Unknown API generation \"${generation}\" for API at index ${index}`, {exit: 1})\n }\n\n const enablePlayground = await this.shouldEnablePlayground({\n dryRun,\n playgroundCliFlag: playgroundFlag,\n playgroundConfiguration: playground,\n playgroundCurrentlyEnabled: playgroundEnabled,\n spin,\n })\n\n let apiSpec: GeneratedApiSpecification\n try {\n const generateSchema = generations[generation]\n const extracted = extractFromSanitySchema(schema, {\n // Allow CLI flag to override configured setting\n nonNullDocumentFields:\n nonNullDocumentFieldsFlag === undefined\n ? nonNullDocumentFields\n : nonNullDocumentFieldsFlag,\n withUnionCache,\n })\n\n apiSpec = generateSchema(extracted, {filterSuffix: apiDef.filterSuffix})\n } catch (err) {\n debug('Failed to extract schema', err)\n spin.fail()\n\n if (err instanceof SchemaError) {\n err.print(this.output)\n this.error('Failed to extract schema', {exit: 1})\n } else {\n const message = err instanceof Error ? err.message : 'Unknown error'\n this.error(`Failed to extract schema: ${message}`, {exit: 1})\n }\n }\n\n let valid: ValidationResponse | undefined\n try {\n valid = await validateGraphQLAPI({\n dataset,\n enablePlayground,\n projectId,\n schema: apiSpec,\n tag,\n })\n } catch (err) {\n debug('validateGraphQLAPI error', err)\n const validationError = get(err, 'response.body.validationError')\n spin.fail()\n this.error(validationError ?? 'Failed to validate GraphQL API', {exit: 1})\n }\n\n // when the result is not valid and there are breaking changes afoot!\n if (!this.isResultValid(valid, {force: flags.force, spin})) {\n // not valid and a dry run? then it can exit with a error\n if (dryRun) {\n spin.fail()\n this.renderBreakingChanges(valid)\n hasErrors = true\n continue\n }\n\n if (!isInteractive()) {\n spin.fail()\n this.renderBreakingChanges(valid)\n this.error(\n 'Dangerous changes found - falling back. Re-run the command with the `--force` flag to force deployment.',\n {exit: 1},\n )\n }\n\n spin.stop()\n this.renderBreakingChanges(valid)\n const shouldDeploy = await confirm({\n default: false,\n message: 'Do you want to deploy a new API despite the dangerous changes?',\n })\n\n if (!shouldDeploy) {\n spin.fail()\n continue\n }\n\n spin.succeed()\n } else if (dryRun) {\n spin.succeed()\n this.log('GraphQL API is valid and has no breaking changes')\n continue\n }\n\n deployTasks.push({\n dataset,\n enablePlayground,\n projectId,\n schema: apiSpec,\n tag,\n })\n }\n\n // Give some space for deployment tasks\n this.log('')\n\n for (const task of deployTasks) {\n const {dataset, enablePlayground, projectId, schema, tag} = task\n\n this.log(`Project: ${projectId}`)\n this.log(`Dataset: ${dataset}`)\n this.log(`Tag: ${tag}`)\n\n spin = spinner('Deploying GraphQL API').start()\n\n try {\n const response = await deployGraphQLAPI({\n dataset,\n enablePlayground,\n projectId,\n schema,\n tag,\n })\n\n spin.stop()\n const apiUrl = await getClientUrl(\n projectId,\n response.location.replace(/^\\/(v1|v\\d{4}-\\d{2}-\\d{2})\\//, '/'),\n )\n this.log(`URL: ${apiUrl}`)\n spin.start('Deployed!').succeed()\n this.log('')\n } catch (error) {\n spin.fail()\n debug('Failed to deploy GraphQL API', error)\n this.error('Failed to deploy GraphQL API', {exit: 1})\n }\n }\n\n if (hasErrors) {\n this.exit(1)\n }\n }\n\n private filterChanges(valid: ValidationResponse) {\n const {breakingChanges: breaking, dangerousChanges: dangerous} = valid\n return {\n breakingChanges: breaking.filter((change) => !ignoredBreaking.has(change.type)),\n dangerousChanges: dangerous.filter((change) => !ignoredWarnings.has(change.type)),\n }\n }\n\n private getApiIdentifiers(apiDef: ResolvedGraphQLAPI, datasetFlag?: string, tagFlag?: string) {\n const dataset = datasetFlag || apiDef.dataset\n const tag = tagFlag || apiDef.tag || 'default'\n const apiName = [dataset, tag].join('/')\n return {apiName, dataset, tag}\n }\n\n private isRecognizedApiGeneration(generation: string): generation is 'gen1' | 'gen2' | 'gen3' {\n return ['gen1', 'gen2', 'gen3'].includes(generation)\n }\n\n private isResultValid(\n valid: ValidationResponse,\n {force, spin}: {force?: boolean; spin: ReturnType<typeof spinner>},\n ) {\n const {validationError} = valid\n if (validationError) {\n spin.fail()\n this.error(`GraphQL schema is not valid:\\n\\n${validationError}`, {exit: 1})\n }\n\n const {breakingChanges, dangerousChanges} = this.filterChanges(valid)\n\n const hasProblematicChanges = breakingChanges.length > 0 || dangerousChanges.length > 0\n\n if (!hasProblematicChanges) {\n spin.succeed()\n return true\n }\n\n if (force) {\n spin.text = 'Validating GraphQL API: Dangerous changes. Forced with `--force`.'\n spin.warn()\n return true\n }\n\n spin.warn()\n return false\n }\n\n private renderBreakingChanges(valid: ValidationResponse) {\n const {breakingChanges, dangerousChanges} = this.filterChanges(valid)\n\n if (dangerousChanges.length > 0) {\n this.log('\\nFound potentially dangerous changes from previous schema:')\n for (const change of dangerousChanges) this.log(` - ${change.description}`)\n }\n\n if (breakingChanges.length > 0) {\n this.log('\\nFound BREAKING changes from previous schema:')\n for (const change of breakingChanges) this.log(` - ${change.description}`)\n }\n\n this.output.log('')\n }\n\n private async shouldEnablePlayground({\n dryRun,\n playgroundCliFlag,\n playgroundConfiguration,\n playgroundCurrentlyEnabled,\n spin,\n }: {\n dryRun: boolean\n playgroundCliFlag?: boolean\n playgroundConfiguration?: boolean\n playgroundCurrentlyEnabled?: boolean\n spin: ReturnType<typeof spinner>\n }): Promise<boolean> {\n // On a dry run, it doesn't matter, return true 🤷‍♂️\n if (dryRun) {\n return true\n }\n\n // Prioritize CLI flag if set\n if (playgroundCliFlag !== undefined) {\n return playgroundCliFlag\n }\n\n // If explicitly set true/false in configuration, use that\n if (playgroundConfiguration !== undefined) {\n return playgroundConfiguration\n }\n\n // If API is already deployed, use the current state\n if (playgroundCurrentlyEnabled !== undefined) {\n return playgroundCurrentlyEnabled\n }\n\n // If no API is deployed, default to true if non-interactive\n if (!isInteractive()) {\n return true\n }\n\n // Interactive environment, so prompt the user\n const prevText = spin.text\n spin.warn()\n const shouldDeploy = await confirm({\n default: true,\n message: 'Do you want to enable a GraphQL playground?',\n })\n spin.clear().start(prevText)\n\n return shouldDeploy\n }\n}\n"],"names":["Flags","isInteractive","SanityCommand","confirm","spinner","get","extractFromSanitySchema","gen1","gen2","gen3","getGraphQLAPIs","graphqlDebug","resolveApiGeneration","SchemaError","deployGraphQLAPI","getClientUrl","getCurrentSchemaProps","validateGraphQLAPI","apiIdRegex","generations","ignoredBreaking","Set","ignoredWarnings","debug","extend","GraphQLDeployCommand","description","examples","command","flags","api","string","multiple","dataset","boolean","default","force","generation","options","playground","allowNo","tag","run","parse","onlyApis","datasetFlag","dryRun","generationFlag","nonNullDocumentFieldsFlag","playgroundFlag","tagFlag","withUnionCache","workDir","getProjectRoot","directory","apiDefs","spin","error","exit","hasMultipleApis","length","usedFlags","undefined","filter","Boolean","warn","join","confirmed","message","deployTasks","hasErrors","apiId","some","apiDef","id","apiNames","apiIds","includes","apiName","getApiIdentifiers","has","test","add","index","nonNullDocumentFields","projectId","schema","start","fail","currentGeneration","playgroundEnabled","schemaProps","err","specifiedGeneration","output","isRecognizedApiGeneration","enablePlayground","shouldEnablePlayground","playgroundCliFlag","playgroundConfiguration","playgroundCurrentlyEnabled","apiSpec","generateSchema","extracted","filterSuffix","print","Error","valid","validationError","isResultValid","renderBreakingChanges","stop","shouldDeploy","succeed","log","push","task","response","apiUrl","location","replace","filterChanges","breakingChanges","breaking","dangerousChanges","dangerous","change","type","hasProblematicChanges","text","prevText","clear"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/commands/graphql/deploy.ts"],"sourcesContent":["import {Flags} from '@oclif/core'\nimport {isInteractive, SanityCommand} from '@sanity/cli-core'\nimport {confirm, spinner} from '@sanity/cli-core/ux'\nimport get from 'lodash-es/get.js'\n\nimport {extractGraphQLAPIs} from '../../actions/graphql/extractGraphQLAPIs.js'\nimport gen1 from '../../actions/graphql/gen1/index.js'\nimport gen2 from '../../actions/graphql/gen2/index.js'\nimport gen3 from '../../actions/graphql/gen3/index.js'\nimport {graphqlDebug} from '../../actions/graphql/graphqlDebug.js'\nimport {resolveApiGeneration} from '../../actions/graphql/resolveApiGeneration.js'\nimport {SchemaError} from '../../actions/graphql/SchemaError.js'\nimport {\n type ExtractedGraphQLAPI,\n type GeneratedApiSpecification,\n type ValidationResponse,\n} from '../../actions/graphql/types.js'\nimport {\n deployGraphQLAPI,\n getClientUrl,\n getCurrentSchemaProps,\n validateGraphQLAPI,\n} from '../../services/graphql.js'\nimport {getDatasetFlag} from '../../util/sharedFlags.js'\n\ninterface DeployTask {\n dataset: string\n enablePlayground: boolean\n projectId: string\n schema: GeneratedApiSpecification\n tag: string\n}\n\nconst apiIdRegex = /^[a-z0-9_-]+$/\nconst generations = {\n gen1,\n gen2,\n gen3,\n}\n\nconst ignoredBreaking = new Set<string>(['OPTIONAL_INPUT_FIELD_ADDED'])\n// Reserved for future use to filter out specific dangerous change types\nconst ignoredWarnings = new Set<string>()\n\nconst debug = graphqlDebug.extend('deploy')\n\nexport class GraphQLDeployCommand extends SanityCommand<typeof GraphQLDeployCommand> {\n static override description = 'Deploy a GraphQL API from the current Sanity schema'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'Deploy all defined GraphQL APIs',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --dry-run',\n description: 'Validate defined GraphQL APIs, check for breaking changes, skip deploy',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --api staging --api ios',\n description: 'Deploy only the GraphQL APIs with the IDs \"staging\" and \"ios\"',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --playground',\n description: 'Deploy all defined GraphQL APIs, overriding any playground setting',\n },\n ]\n\n static override flags = {\n api: Flags.string({\n description: 'Only deploy API with this ID. Can be specified multiple times.',\n multiple: true,\n }),\n ...getDatasetFlag({description: 'Deploy API for the given dataset'}),\n 'dry-run': Flags.boolean({\n default: false,\n description: 'Validate defined GraphQL APIs, check for breaking changes, skip deploy',\n }),\n force: Flags.boolean({\n description: 'Deploy API without confirming breaking changes',\n }),\n generation: Flags.string({\n description: 'API generation to deploy (defaults to \"gen3\")',\n options: ['gen1', 'gen2', 'gen3'],\n }),\n 'non-null-document-fields': Flags.boolean({\n description: 'Use non-null document fields (_id, _type etc)',\n }),\n playground: Flags.boolean({\n allowNo: true,\n description: 'Enable GraphQL playground for easier debugging',\n }),\n tag: Flags.string({\n description: 'Deploy API(s) to given tag (defaults to \"default\")',\n }),\n 'with-union-cache': Flags.boolean({\n description:\n 'Enable union cache that optimizes schema generation for schemas with many self referencing types',\n }),\n }\n\n public async run(): Promise<void> {\n const {flags} = await this.parse(GraphQLDeployCommand)\n const {\n api: onlyApis,\n dataset: datasetFlag,\n 'dry-run': dryRun,\n generation: generationFlag,\n 'non-null-document-fields': nonNullDocumentFieldsFlag,\n playground: playgroundFlag,\n tag: tagFlag,\n 'with-union-cache': withUnionCache,\n } = flags\n\n const workDir = (await this.getProjectRoot()).directory\n\n let apiDefs: ExtractedGraphQLAPI[] = []\n let spin: ReturnType<typeof spinner>\n\n try {\n apiDefs = await extractGraphQLAPIs(workDir, {\n nonNullDocumentFieldsFlag,\n withUnionCache,\n })\n } catch (error) {\n if (error instanceof SchemaError) {\n debug('Schema validation errors: %O', error.problemGroups)\n error.print(this.output)\n this.error('Fix the schema errors above and try again', {exit: 1})\n }\n debug('Failed to resolve GraphQL APIs: %O', error)\n const message = error instanceof Error ? error.message : String(error)\n this.error(`Failed to resolve GraphQL APIs: ${message}`, {exit: 1})\n }\n\n const hasMultipleApis = flags.api ? flags.api.length > 1 : apiDefs.length > 1\n\n const usedFlags = [\n datasetFlag && '--dataset',\n tagFlag && '--tag',\n playgroundFlag !== undefined && '--playground',\n generationFlag !== undefined && '--generation',\n nonNullDocumentFieldsFlag !== undefined && '--non-null-document-fields',\n ].filter(Boolean)\n\n if (hasMultipleApis && usedFlags.length > 0) {\n this.warn(`More than one API defined, and ${usedFlags.join('/')} is specified`)\n this.warn(`This will use the specified flag(s) for ALL APIs, overriding config!`)\n\n if (flags.force) {\n this.warn(`--force specified, continuing...`)\n } else {\n const confirmed = await confirm({\n default: false,\n message: 'Continue with flag overrides for all APIs?',\n })\n if (!confirmed) {\n this.error('Operation cancelled', {exit: 1})\n }\n }\n }\n\n const deployTasks: DeployTask[] = []\n let hasErrors = false\n\n for (const apiId of onlyApis || []) {\n if (!apiDefs.some((apiDef) => apiDef.id === apiId)) {\n this.error(`GraphQL API with id \"${apiId}\" not found`, {exit: 1})\n }\n }\n\n const apiNames = new Set<string>()\n const apiIds = new Set<string>()\n\n for (const apiDef of apiDefs) {\n if (onlyApis && (!apiDef.id || !onlyApis.includes(apiDef.id))) {\n continue\n }\n\n const {apiName} = this.getApiIdentifiers(apiDef, datasetFlag, tagFlag)\n if (apiNames.has(apiName)) {\n this.error(`Multiple GraphQL APIs with the same dataset and tag found (${apiName})`, {\n exit: 1,\n })\n }\n\n if (apiDef.id) {\n if (!apiIdRegex.test(apiDef.id)) {\n this.error(\n `Invalid GraphQL API id \"${apiDef.id}\" - only a-z, 0-9, underscore and dashes are allowed`,\n {exit: 1},\n )\n }\n\n if (apiIds.has(apiDef.id)) {\n this.error(`Multiple GraphQL APIs with the same ID found (${apiDef.id})`, {exit: 1})\n }\n\n apiIds.add(apiDef.id)\n }\n\n apiNames.add(apiName)\n }\n\n if (onlyApis) {\n this.warn(`Deploying only specified APIs: ${onlyApis.join(', ')}`)\n }\n\n let index = -1\n for (const apiDef of apiDefs) {\n if (onlyApis && (!apiDef.id || !onlyApis.includes(apiDef.id))) {\n continue\n }\n\n index++\n\n const {apiName, dataset, tag} = this.getApiIdentifiers(apiDef, datasetFlag, tagFlag)\n const {playground, projectId} = apiDef\n spin = spinner(`Generating GraphQL API: ${apiName}`).start()\n\n if (!dataset) {\n spin.fail()\n this.error(`No dataset specified for API at index ${index}`, {exit: 1})\n }\n\n // Handle extraction errors early (computed in worker), before network calls and prompts.\n // Continue the loop so all API errors are reported — don't exit on the first failure.\n if (apiDef.schemaErrors?.length) {\n spin.fail()\n new SchemaError(apiDef.schemaErrors).print(this.output, `Schema errors in ${apiName}`)\n hasErrors = true\n continue\n }\n\n if (apiDef.extractionError) {\n debug('Failed to extract schema', apiDef.extractionError)\n spin.fail()\n this.log(`Failed to extract schema for ${apiName}: ${apiDef.extractionError}`)\n hasErrors = true\n continue\n }\n\n if (!apiDef.extracted) {\n spin.fail()\n this.log(`Failed to extract schema for ${apiName}: No extraction result`)\n hasErrors = true\n continue\n }\n\n let currentGeneration: string | undefined\n let playgroundEnabled: boolean | undefined\n try {\n const schemaProps = await getCurrentSchemaProps(projectId, dataset, tag)\n currentGeneration = schemaProps.currentGeneration\n playgroundEnabled = schemaProps.playgroundEnabled\n } catch (err) {\n debug('Failed to get current GraphQL schema properties', err)\n spin.fail()\n this.error('Failed to get current GraphQL schema properties', {exit: 1})\n }\n\n // CLI flag takes precedence over configuration\n const specifiedGeneration = generationFlag === undefined ? apiDef.generation : generationFlag\n\n const generation = await resolveApiGeneration({\n currentGeneration,\n force: flags.force,\n index,\n output: this.output,\n specifiedGeneration,\n })\n\n if (!generation) {\n // User cancelled\n spin.fail()\n continue\n }\n\n if (!this.isRecognizedApiGeneration(generation)) {\n spin.fail()\n this.error(`Unknown API generation \"${generation}\" for API at index ${index}`, {exit: 1})\n }\n\n const enablePlayground = await this.shouldEnablePlayground({\n dryRun,\n playgroundCliFlag: playgroundFlag,\n playgroundConfiguration: playground,\n playgroundCurrentlyEnabled: playgroundEnabled,\n spin,\n })\n\n let apiSpec: GeneratedApiSpecification\n try {\n const generateSchema = generations[generation]\n apiSpec = generateSchema(apiDef.extracted, {filterSuffix: apiDef.filterSuffix})\n } catch (err) {\n debug('Failed to generate schema', err)\n spin.fail()\n const message = err instanceof Error ? err.message : 'Unknown error'\n this.error(`Failed to generate schema: ${message}`, {exit: 1})\n }\n\n let valid: ValidationResponse | undefined\n try {\n valid = await validateGraphQLAPI({\n dataset,\n enablePlayground,\n projectId,\n schema: apiSpec,\n tag,\n })\n } catch (err) {\n debug('validateGraphQLAPI error', err)\n const validationError = get(err, 'response.body.validationError')\n spin.fail()\n this.error(validationError ?? 'Failed to validate GraphQL API', {exit: 1})\n }\n\n // when the result is not valid and there are breaking changes afoot!\n if (!this.isResultValid(valid, {force: flags.force, spin})) {\n // not valid and a dry run? then it can exit with a error\n if (dryRun) {\n spin.fail()\n this.renderBreakingChanges(valid)\n hasErrors = true\n continue\n }\n\n if (!isInteractive()) {\n spin.fail()\n this.renderBreakingChanges(valid)\n this.error(\n 'Dangerous changes found - falling back. Re-run the command with the `--force` flag to force deployment.',\n {exit: 1},\n )\n }\n\n spin.stop()\n this.renderBreakingChanges(valid)\n const shouldDeploy = await confirm({\n default: false,\n message: 'Do you want to deploy a new API despite the dangerous changes?',\n })\n\n if (!shouldDeploy) {\n spin.fail()\n continue\n }\n\n spin.succeed()\n } else if (dryRun) {\n // isResultValid() already set the spinner state (succeed or warn).\n // Check whether changes were forced so we print the correct message.\n const {breakingChanges, dangerousChanges} = this.filterChanges(valid)\n if (breakingChanges.length > 0 || dangerousChanges.length > 0) {\n this.renderBreakingChanges(valid)\n this.log('Forced with `--force`, skipping deploy (dry run)')\n } else {\n this.log('GraphQL API is valid and has no breaking changes')\n }\n continue\n }\n\n deployTasks.push({\n dataset,\n enablePlayground,\n projectId,\n schema: apiSpec,\n tag,\n })\n }\n\n // Give some space for deployment tasks\n this.log('')\n\n for (const task of deployTasks) {\n const {dataset, enablePlayground, projectId, schema, tag} = task\n\n this.log(`Project: ${projectId}`)\n this.log(`Dataset: ${dataset}`)\n this.log(`Tag: ${tag}`)\n\n spin = spinner('Deploying GraphQL API').start()\n\n try {\n const response = await deployGraphQLAPI({\n dataset,\n enablePlayground,\n projectId,\n schema,\n tag,\n })\n\n spin.stop()\n const apiUrl = await getClientUrl(\n projectId,\n response.location.replace(/^\\/(v1|v\\d{4}-\\d{2}-\\d{2})\\//, '/'),\n )\n this.log(`URL: ${apiUrl}`)\n spin.start('Deployed!').succeed()\n this.log('')\n } catch (error) {\n spin.fail()\n debug('Failed to deploy GraphQL API', error)\n this.error('Failed to deploy GraphQL API', {exit: 1})\n }\n }\n\n if (hasErrors) {\n this.exit(1)\n }\n }\n\n private filterChanges(valid: ValidationResponse) {\n const {breakingChanges: breaking, dangerousChanges: dangerous} = valid\n return {\n breakingChanges: breaking.filter((change) => !ignoredBreaking.has(change.type)),\n dangerousChanges: dangerous.filter((change) => !ignoredWarnings.has(change.type)),\n }\n }\n\n private getApiIdentifiers(apiDef: ExtractedGraphQLAPI, datasetFlag?: string, tagFlag?: string) {\n const dataset = datasetFlag || apiDef.dataset\n const tag = tagFlag || apiDef.tag || 'default'\n const apiName = [dataset, tag].join('/')\n return {apiName, dataset, tag}\n }\n\n private isRecognizedApiGeneration(generation: string): generation is 'gen1' | 'gen2' | 'gen3' {\n return ['gen1', 'gen2', 'gen3'].includes(generation)\n }\n\n private isResultValid(\n valid: ValidationResponse,\n {force, spin}: {force?: boolean; spin: ReturnType<typeof spinner>},\n ) {\n const {validationError} = valid\n if (validationError) {\n spin.fail()\n this.error(`GraphQL schema is not valid:\\n\\n${validationError}`, {exit: 1})\n }\n\n const {breakingChanges, dangerousChanges} = this.filterChanges(valid)\n\n const hasProblematicChanges = breakingChanges.length > 0 || dangerousChanges.length > 0\n\n if (!hasProblematicChanges) {\n spin.succeed()\n return true\n }\n\n if (force) {\n spin.text = 'Validating GraphQL API: Dangerous changes. Forced with `--force`.'\n spin.warn()\n return true\n }\n\n spin.warn()\n return false\n }\n\n private renderBreakingChanges(valid: ValidationResponse) {\n const {breakingChanges, dangerousChanges} = this.filterChanges(valid)\n\n if (dangerousChanges.length > 0) {\n this.log('\\nFound potentially dangerous changes from previous schema:')\n for (const change of dangerousChanges) this.log(` - ${change.description}`)\n }\n\n if (breakingChanges.length > 0) {\n this.log('\\nFound BREAKING changes from previous schema:')\n for (const change of breakingChanges) this.log(` - ${change.description}`)\n }\n\n this.output.log('')\n }\n\n private async shouldEnablePlayground({\n dryRun,\n playgroundCliFlag,\n playgroundConfiguration,\n playgroundCurrentlyEnabled,\n spin,\n }: {\n dryRun: boolean\n playgroundCliFlag?: boolean\n playgroundConfiguration?: boolean\n playgroundCurrentlyEnabled?: boolean\n spin: ReturnType<typeof spinner>\n }): Promise<boolean> {\n // On a dry run, it doesn't matter, return true 🤷‍♂️\n if (dryRun) {\n return true\n }\n\n // Prioritize CLI flag if set\n if (playgroundCliFlag !== undefined) {\n return playgroundCliFlag\n }\n\n // If explicitly set true/false in configuration, use that\n if (playgroundConfiguration !== undefined) {\n return playgroundConfiguration\n }\n\n // If API is already deployed, use the current state\n if (playgroundCurrentlyEnabled !== undefined) {\n return playgroundCurrentlyEnabled\n }\n\n // If no API is deployed, default to true if non-interactive\n if (!isInteractive()) {\n return true\n }\n\n // Interactive environment, so prompt the user\n const prevText = spin.text\n spin.warn()\n const shouldDeploy = await confirm({\n default: true,\n message: 'Do you want to enable a GraphQL playground?',\n })\n spin.clear().start(prevText)\n\n return shouldDeploy\n }\n}\n"],"names":["Flags","isInteractive","SanityCommand","confirm","spinner","get","extractGraphQLAPIs","gen1","gen2","gen3","graphqlDebug","resolveApiGeneration","SchemaError","deployGraphQLAPI","getClientUrl","getCurrentSchemaProps","validateGraphQLAPI","getDatasetFlag","apiIdRegex","generations","ignoredBreaking","Set","ignoredWarnings","debug","extend","GraphQLDeployCommand","description","examples","command","flags","api","string","multiple","boolean","default","force","generation","options","playground","allowNo","tag","run","parse","onlyApis","dataset","datasetFlag","dryRun","generationFlag","nonNullDocumentFieldsFlag","playgroundFlag","tagFlag","withUnionCache","workDir","getProjectRoot","directory","apiDefs","spin","error","problemGroups","print","output","exit","message","Error","String","hasMultipleApis","length","usedFlags","undefined","filter","Boolean","warn","join","confirmed","deployTasks","hasErrors","apiId","some","apiDef","id","apiNames","apiIds","includes","apiName","getApiIdentifiers","has","test","add","index","projectId","start","fail","schemaErrors","extractionError","log","extracted","currentGeneration","playgroundEnabled","schemaProps","err","specifiedGeneration","isRecognizedApiGeneration","enablePlayground","shouldEnablePlayground","playgroundCliFlag","playgroundConfiguration","playgroundCurrentlyEnabled","apiSpec","generateSchema","filterSuffix","valid","schema","validationError","isResultValid","renderBreakingChanges","stop","shouldDeploy","succeed","breakingChanges","dangerousChanges","filterChanges","push","task","response","apiUrl","location","replace","breaking","dangerous","change","type","hasProblematicChanges","text","prevText","clear"],"mappings":"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"}
@@ -1,6 +1,8 @@
1
1
  import { styleText } from 'node:util';
2
2
  import { getProjectCliClient, SanityCommand, subdebug } from '@sanity/cli-core';
3
+ import { promptForProject } from '../../prompts/promptForProject.js';
3
4
  import { GRAPHQL_API_VERSION, listGraphQLEndpoints } from '../../services/graphql.js';
5
+ import { getProjectIdFlag } from '../../util/sharedFlags.js';
4
6
  const listGraphQLDebug = subdebug('graphql:list');
5
7
  export class List extends SanityCommand {
6
8
  static description = 'List all GraphQL endpoints deployed for this project';
@@ -8,11 +10,22 @@ export class List extends SanityCommand {
8
10
  {
9
11
  command: '<%= config.bin %> <%= command.id %>',
10
12
  description: 'List GraphQL endpoints for the current project'
13
+ },
14
+ {
15
+ command: '<%= config.bin %> <%= command.id %> --project-id abc123',
16
+ description: 'List GraphQL endpoints for a specific project'
11
17
  }
12
18
  ];
19
+ static flags = {
20
+ ...getProjectIdFlag({
21
+ description: 'Project ID to list GraphQL endpoints for (overrides CLI configuration)'
22
+ })
23
+ };
13
24
  async run() {
14
25
  await this.parse(List);
15
- const projectId = await this.getProjectId();
26
+ const projectId = await this.getProjectId({
27
+ fallback: ()=>promptForProject({})
28
+ });
16
29
  let endpoints;
17
30
  try {
18
31
  endpoints = await listGraphQLEndpoints(projectId);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/commands/graphql/list.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {getProjectCliClient, SanityCommand, subdebug} from '@sanity/cli-core'\n\nimport {\n GRAPHQL_API_VERSION,\n type GraphQLEndpoint,\n listGraphQLEndpoints,\n} from '../../services/graphql.js'\n\nconst listGraphQLDebug = subdebug('graphql:list')\n\nexport class List extends SanityCommand<typeof List> {\n static override description = 'List all GraphQL endpoints deployed for this project'\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'List GraphQL endpoints for the current project',\n },\n ]\n\n public async run(): Promise<void> {\n await this.parse(List)\n\n const projectId = await this.getProjectId()\n\n let endpoints: GraphQLEndpoint[] | undefined\n try {\n endpoints = await listGraphQLEndpoints(projectId)\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n\n listGraphQLDebug(`Error fetching GraphQL endpoints for project ${projectId}`, error)\n this.error(`GraphQL endpoints list retrieval failed:\\n${message}`, {exit: 1})\n }\n\n if (!endpoints || endpoints.length === 0) {\n this.log(\"This project doesn't have any GraphQL endpoints deployed.\")\n return\n }\n\n const client = await getProjectCliClient({\n apiVersion: GRAPHQL_API_VERSION,\n projectId,\n })\n\n this.log('Here are the GraphQL endpoints deployed for this project:')\n for (const [index, endpoint] of endpoints.entries()) {\n const {dataset, tag} = endpoint\n const url = client.getUrl(`/graphql/${dataset}/${tag}`)\n\n this.log(`${index + 1}. ${styleText('bold', 'Dataset:')} ${dataset}`)\n this.log(` ${styleText('bold', 'Tag:')} ${tag}`)\n this.log(` ${styleText('bold', 'Generation:')} ${endpoint.generation}`)\n this.log(` ${styleText('bold', 'Playground:')} ${endpoint.playgroundEnabled}`)\n this.log(` ${styleText('bold', 'URL:')} ${url}\\n`)\n }\n }\n}\n"],"names":["styleText","getProjectCliClient","SanityCommand","subdebug","GRAPHQL_API_VERSION","listGraphQLEndpoints","listGraphQLDebug","List","description","examples","command","run","parse","projectId","getProjectId","endpoints","error","message","Error","String","exit","length","log","client","apiVersion","index","endpoint","entries","dataset","tag","url","getUrl","generation","playgroundEnabled"],"mappings":"AAAA,SAAQA,SAAS,QAAO,YAAW;AAEnC,SAAQC,mBAAmB,EAAEC,aAAa,EAAEC,QAAQ,QAAO,mBAAkB;AAE7E,SACEC,mBAAmB,EAEnBC,oBAAoB,QACf,4BAA2B;AAElC,MAAMC,mBAAmBH,SAAS;AAElC,OAAO,MAAMI,aAAaL;IACxB,OAAgBM,cAAc,uDAAsD;IACpF,OAAgBC,WAAW;QACzB;YACEC,SAAS;YACTF,aAAa;QACf;KACD,CAAA;IAED,MAAaG,MAAqB;QAChC,MAAM,IAAI,CAACC,KAAK,CAACL;QAEjB,MAAMM,YAAY,MAAM,IAAI,CAACC,YAAY;QAEzC,IAAIC;QACJ,IAAI;YACFA,YAAY,MAAMV,qBAAqBQ;QACzC,EAAE,OAAOG,OAAO;YACd,MAAMC,UAAUD,iBAAiBE,QAAQF,MAAMC,OAAO,GAAGE,OAAOH;YAEhEV,iBAAiB,CAAC,6CAA6C,EAAEO,WAAW,EAAEG;YAC9E,IAAI,CAACA,KAAK,CAAC,CAAC,0CAA0C,EAAEC,SAAS,EAAE;gBAACG,MAAM;YAAC;QAC7E;QAEA,IAAI,CAACL,aAAaA,UAAUM,MAAM,KAAK,GAAG;YACxC,IAAI,CAACC,GAAG,CAAC;YACT;QACF;QAEA,MAAMC,SAAS,MAAMtB,oBAAoB;YACvCuB,YAAYpB;YACZS;QACF;QAEA,IAAI,CAACS,GAAG,CAAC;QACT,KAAK,MAAM,CAACG,OAAOC,SAAS,IAAIX,UAAUY,OAAO,GAAI;YACnD,MAAM,EAACC,OAAO,EAAEC,GAAG,EAAC,GAAGH;YACvB,MAAMI,MAAMP,OAAOQ,MAAM,CAAC,CAAC,SAAS,EAAEH,QAAQ,CAAC,EAAEC,KAAK;YAEtD,IAAI,CAACP,GAAG,CAAC,GAAGG,QAAQ,EAAE,GAAG,EAAEzB,UAAU,QAAQ,YAAY,KAAK,EAAE4B,SAAS;YACzE,IAAI,CAACN,GAAG,CAAC,CAAC,IAAI,EAAEtB,UAAU,QAAQ,QAAQ,SAAS,EAAE6B,KAAK;YAC1D,IAAI,CAACP,GAAG,CAAC,CAAC,IAAI,EAAEtB,UAAU,QAAQ,eAAe,EAAE,EAAE0B,SAASM,UAAU,EAAE;YAC1E,IAAI,CAACV,GAAG,CAAC,CAAC,IAAI,EAAEtB,UAAU,QAAQ,eAAe,EAAE,EAAE0B,SAASO,iBAAiB,EAAE;YACjF,IAAI,CAACX,GAAG,CAAC,CAAC,IAAI,EAAEtB,UAAU,QAAQ,QAAQ,EAAE,EAAE8B,IAAI,EAAE,CAAC;QACvD;IACF;AACF"}
1
+ {"version":3,"sources":["../../../src/commands/graphql/list.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {getProjectCliClient, SanityCommand, subdebug} from '@sanity/cli-core'\n\nimport {promptForProject} from '../../prompts/promptForProject.js'\nimport {\n GRAPHQL_API_VERSION,\n type GraphQLEndpoint,\n listGraphQLEndpoints,\n} from '../../services/graphql.js'\nimport {getProjectIdFlag} from '../../util/sharedFlags.js'\n\nconst listGraphQLDebug = subdebug('graphql:list')\n\nexport class List extends SanityCommand<typeof List> {\n static override description = 'List all GraphQL endpoints deployed for this project'\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'List GraphQL endpoints for the current project',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --project-id abc123',\n description: 'List GraphQL endpoints for a specific project',\n },\n ]\n\n static override flags = {\n ...getProjectIdFlag({\n description: 'Project ID to list GraphQL endpoints for (overrides CLI configuration)',\n }),\n }\n\n public async run(): Promise<void> {\n await this.parse(List)\n\n const projectId = await this.getProjectId({\n fallback: () => promptForProject({}),\n })\n\n let endpoints: GraphQLEndpoint[] | undefined\n try {\n endpoints = await listGraphQLEndpoints(projectId)\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n\n listGraphQLDebug(`Error fetching GraphQL endpoints for project ${projectId}`, error)\n this.error(`GraphQL endpoints list retrieval failed:\\n${message}`, {exit: 1})\n }\n\n if (!endpoints || endpoints.length === 0) {\n this.log(\"This project doesn't have any GraphQL endpoints deployed.\")\n return\n }\n\n const client = await getProjectCliClient({\n apiVersion: GRAPHQL_API_VERSION,\n projectId,\n })\n\n this.log('Here are the GraphQL endpoints deployed for this project:')\n for (const [index, endpoint] of endpoints.entries()) {\n const {dataset, tag} = endpoint\n const url = client.getUrl(`/graphql/${dataset}/${tag}`)\n\n this.log(`${index + 1}. ${styleText('bold', 'Dataset:')} ${dataset}`)\n this.log(` ${styleText('bold', 'Tag:')} ${tag}`)\n this.log(` ${styleText('bold', 'Generation:')} ${endpoint.generation}`)\n this.log(` ${styleText('bold', 'Playground:')} ${endpoint.playgroundEnabled}`)\n this.log(` ${styleText('bold', 'URL:')} ${url}\\n`)\n }\n }\n}\n"],"names":["styleText","getProjectCliClient","SanityCommand","subdebug","promptForProject","GRAPHQL_API_VERSION","listGraphQLEndpoints","getProjectIdFlag","listGraphQLDebug","List","description","examples","command","flags","run","parse","projectId","getProjectId","fallback","endpoints","error","message","Error","String","exit","length","log","client","apiVersion","index","endpoint","entries","dataset","tag","url","getUrl","generation","playgroundEnabled"],"mappings":"AAAA,SAAQA,SAAS,QAAO,YAAW;AAEnC,SAAQC,mBAAmB,EAAEC,aAAa,EAAEC,QAAQ,QAAO,mBAAkB;AAE7E,SAAQC,gBAAgB,QAAO,oCAAmC;AAClE,SACEC,mBAAmB,EAEnBC,oBAAoB,QACf,4BAA2B;AAClC,SAAQC,gBAAgB,QAAO,4BAA2B;AAE1D,MAAMC,mBAAmBL,SAAS;AAElC,OAAO,MAAMM,aAAaP;IACxB,OAAgBQ,cAAc,uDAAsD;IACpF,OAAgBC,WAAW;QACzB;YACEC,SAAS;YACTF,aAAa;QACf;QACA;YACEE,SAAS;YACTF,aAAa;QACf;KACD,CAAA;IAED,OAAgBG,QAAQ;QACtB,GAAGN,iBAAiB;YAClBG,aAAa;QACf,EAAE;IACJ,EAAC;IAED,MAAaI,MAAqB;QAChC,MAAM,IAAI,CAACC,KAAK,CAACN;QAEjB,MAAMO,YAAY,MAAM,IAAI,CAACC,YAAY,CAAC;YACxCC,UAAU,IAAMd,iBAAiB,CAAC;QACpC;QAEA,IAAIe;QACJ,IAAI;YACFA,YAAY,MAAMb,qBAAqBU;QACzC,EAAE,OAAOI,OAAO;YACd,MAAMC,UAAUD,iBAAiBE,QAAQF,MAAMC,OAAO,GAAGE,OAAOH;YAEhEZ,iBAAiB,CAAC,6CAA6C,EAAEQ,WAAW,EAAEI;YAC9E,IAAI,CAACA,KAAK,CAAC,CAAC,0CAA0C,EAAEC,SAAS,EAAE;gBAACG,MAAM;YAAC;QAC7E;QAEA,IAAI,CAACL,aAAaA,UAAUM,MAAM,KAAK,GAAG;YACxC,IAAI,CAACC,GAAG,CAAC;YACT;QACF;QAEA,MAAMC,SAAS,MAAM1B,oBAAoB;YACvC2B,YAAYvB;YACZW;QACF;QAEA,IAAI,CAACU,GAAG,CAAC;QACT,KAAK,MAAM,CAACG,OAAOC,SAAS,IAAIX,UAAUY,OAAO,GAAI;YACnD,MAAM,EAACC,OAAO,EAAEC,GAAG,EAAC,GAAGH;YACvB,MAAMI,MAAMP,OAAOQ,MAAM,CAAC,CAAC,SAAS,EAAEH,QAAQ,CAAC,EAAEC,KAAK;YAEtD,IAAI,CAACP,GAAG,CAAC,GAAGG,QAAQ,EAAE,GAAG,EAAE7B,UAAU,QAAQ,YAAY,KAAK,EAAEgC,SAAS;YACzE,IAAI,CAACN,GAAG,CAAC,CAAC,IAAI,EAAE1B,UAAU,QAAQ,QAAQ,SAAS,EAAEiC,KAAK;YAC1D,IAAI,CAACP,GAAG,CAAC,CAAC,IAAI,EAAE1B,UAAU,QAAQ,eAAe,EAAE,EAAE8B,SAASM,UAAU,EAAE;YAC1E,IAAI,CAACV,GAAG,CAAC,CAAC,IAAI,EAAE1B,UAAU,QAAQ,eAAe,EAAE,EAAE8B,SAASO,iBAAiB,EAAE;YACjF,IAAI,CAACX,GAAG,CAAC,CAAC,IAAI,EAAE1B,UAAU,QAAQ,QAAQ,EAAE,EAAEkC,IAAI,EAAE,CAAC;QACvD;IACF;AACF"}
@@ -2,7 +2,9 @@ import { Flags } from '@oclif/core';
2
2
  import { SanityCommand, subdebug } from '@sanity/cli-core';
3
3
  import { confirm } from '@sanity/cli-core/ux';
4
4
  import { getGraphQLAPIs } from '../../actions/graphql/getGraphQLAPIs.js';
5
+ import { promptForProject } from '../../prompts/promptForProject.js';
5
6
  import { deleteGraphQLAPI } from '../../services/graphql.js';
7
+ import { getDatasetFlag, getProjectIdFlag } from '../../util/sharedFlags.js';
6
8
  const undeployGraphqlDebug = subdebug('graphql:undeploy');
7
9
  export class Undeploy extends SanityCommand {
8
10
  static description = 'Remove a deployed GraphQL API';
@@ -26,23 +28,37 @@ export class Undeploy extends SanityCommand {
26
28
  {
27
29
  command: '<%= config.bin %> <%= command.id %> --force',
28
30
  description: 'Undeploy GraphQL API without confirmation prompt'
31
+ },
32
+ {
33
+ command: '<%= config.bin %> <%= command.id %> --project-id abc123 --dataset production',
34
+ description: 'Undeploy GraphQL API for a specific project and dataset'
29
35
  }
30
36
  ];
31
37
  static flags = {
38
+ ...getProjectIdFlag({
39
+ description: 'Project ID to undeploy GraphQL API from (overrides CLI configuration)'
40
+ }),
32
41
  api: Flags.string({
33
- description: 'Undeploy API with this ID (project, dataset and tag flags take precedence)',
42
+ description: 'Undeploy API with this ID',
43
+ exclusive: [
44
+ 'project-id',
45
+ 'project'
46
+ ],
34
47
  required: false
35
48
  }),
36
- dataset: Flags.string({
37
- description: 'Dataset to undeploy GraphQL API from',
38
- required: false
49
+ ...getDatasetFlag({
50
+ description: 'Dataset to undeploy GraphQL API from'
39
51
  }),
40
52
  force: Flags.boolean({
41
53
  description: 'Skip confirmation prompt',
42
54
  required: false
43
55
  }),
44
56
  project: Flags.string({
57
+ deprecated: {
58
+ to: 'project-id'
59
+ },
45
60
  description: 'Project ID to delete GraphQL API for',
61
+ hidden: true,
46
62
  required: false
47
63
  }),
48
64
  tag: Flags.string({
@@ -53,13 +69,13 @@ export class Undeploy extends SanityCommand {
53
69
  };
54
70
  async run() {
55
71
  const { flags } = await this.parse(Undeploy);
56
- const { api: apiFlag, dataset: datasetFlag, force, project: projectFlag, tag: tagFlag } = flags;
57
- let projectId = projectFlag;
72
+ const { api: apiFlag, dataset: datasetFlag, force, tag: tagFlag } = flags;
73
+ let projectId;
58
74
  let dataset = datasetFlag;
59
75
  let tag = tagFlag;
60
76
  // If specifying --api, use it for the flags not provided
61
77
  if (apiFlag) {
62
- const workDir = process.cwd();
78
+ const workDir = (await this.getProjectRoot()).directory;
63
79
  const apiDefs = await getGraphQLAPIs(workDir);
64
80
  const apiDef = apiDefs.find((def)=>def.id === apiFlag);
65
81
  if (!apiDef) {
@@ -67,11 +83,7 @@ export class Undeploy extends SanityCommand {
67
83
  exit: 1
68
84
  });
69
85
  }
70
- if (projectId && projectId !== apiDef.projectId) {
71
- this.warn(`Both --api and --project specified, using --project ${projectId}`);
72
- } else {
73
- projectId = apiDef.projectId;
74
- }
86
+ projectId = apiDef.projectId;
75
87
  if (dataset && dataset !== apiDef.dataset) {
76
88
  this.warn(`Both --api and --dataset specified, using --dataset ${dataset}`);
77
89
  } else {
@@ -85,11 +97,21 @@ export class Undeploy extends SanityCommand {
85
97
  }
86
98
  // Get projectId from config if not specified
87
99
  if (!projectId) {
88
- projectId = await this.getProjectId();
100
+ projectId = await this.getProjectId({
101
+ deprecatedFlagName: 'project',
102
+ fallback: ()=>promptForProject({
103
+ requiredPermissions: [
104
+ {
105
+ grant: 'manage',
106
+ permission: 'sanity.project.graphql'
107
+ }
108
+ ]
109
+ })
110
+ });
89
111
  }
90
112
  // Get dataset from CLI config if not specified
91
113
  if (!dataset) {
92
- const cliConfig = await this.getCliConfig();
114
+ const cliConfig = await this.tryGetCliConfig();
93
115
  dataset = cliConfig.api?.dataset;
94
116
  }
95
117
  if (!dataset) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/commands/graphql/undeploy.ts"],"sourcesContent":["import {Flags} from '@oclif/core'\nimport {SanityCommand, subdebug} from '@sanity/cli-core'\nimport {confirm} from '@sanity/cli-core/ux'\n\nimport {getGraphQLAPIs} from '../../actions/graphql/getGraphQLAPIs.js'\nimport {deleteGraphQLAPI} from '../../services/graphql.js'\n\nconst undeployGraphqlDebug = subdebug('graphql:undeploy')\n\nexport class Undeploy extends SanityCommand<typeof Undeploy> {\n static override description = 'Remove a deployed GraphQL API'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'Undeploy GraphQL API for current project and dataset',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --api ios',\n description: 'Undeploy API with ID \"ios\"',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --dataset staging',\n description: 'Undeploy GraphQL API for staging dataset',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --dataset staging --tag next',\n description: 'Undeploy GraphQL API for staging dataset with \"next\" tag',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --force',\n description: 'Undeploy GraphQL API without confirmation prompt',\n },\n ]\n\n static override flags = {\n api: Flags.string({\n description: 'Undeploy API with this ID (project, dataset and tag flags take precedence)',\n required: false,\n }),\n dataset: Flags.string({\n description: 'Dataset to undeploy GraphQL API from',\n required: false,\n }),\n force: Flags.boolean({\n description: 'Skip confirmation prompt',\n required: false,\n }),\n project: Flags.string({\n description: 'Project ID to delete GraphQL API for',\n required: false,\n }),\n tag: Flags.string({\n default: 'default',\n description: 'Tag to undeploy GraphQL API from',\n required: false,\n }),\n }\n\n public async run(): Promise<void> {\n const {flags} = await this.parse(Undeploy)\n const {api: apiFlag, dataset: datasetFlag, force, project: projectFlag, tag: tagFlag} = flags\n\n let projectId = projectFlag\n let dataset = datasetFlag\n let tag = tagFlag\n\n // If specifying --api, use it for the flags not provided\n if (apiFlag) {\n const workDir = process.cwd()\n const apiDefs = await getGraphQLAPIs(workDir)\n const apiDef = apiDefs.find((def) => def.id === apiFlag)\n\n if (!apiDef) {\n this.error(`GraphQL API \"${apiFlag}\" not found`, {exit: 1})\n }\n\n if (projectId && projectId !== apiDef.projectId) {\n this.warn(`Both --api and --project specified, using --project ${projectId}`)\n } else {\n projectId = apiDef.projectId\n }\n\n if (dataset && dataset !== apiDef.dataset) {\n this.warn(`Both --api and --dataset specified, using --dataset ${dataset}`)\n } else {\n dataset = apiDef.dataset\n }\n\n if (tag && tag !== 'default' && apiDef.tag && tag !== apiDef.tag) {\n this.warn(`Both --api and --tag specified, using --tag ${tag}`)\n } else {\n tag = apiDef.tag || 'default'\n }\n }\n\n // Get projectId from config if not specified\n if (!projectId) {\n projectId = await this.getProjectId()\n }\n\n // Get dataset from CLI config if not specified\n if (!dataset) {\n const cliConfig = await this.getCliConfig()\n dataset = cliConfig.api?.dataset\n }\n\n if (!dataset) {\n this.error(\n 'Dataset is required. Specify it with --dataset or configure it in your project.',\n {\n exit: 1,\n },\n )\n }\n\n // Confirm deletion unless --force is used\n if (!force) {\n const confirmMessage =\n tag === 'default'\n ? `Are you absolutely sure you want to delete the current GraphQL API connected to the \"${dataset}\" dataset in project ${projectId}?`\n : `Are you absolutely sure you want to delete the GraphQL API connected to the \"${dataset}\" dataset in project ${projectId}, tagged \"${tag}\"?`\n\n try {\n const confirmed = await confirm({\n default: false,\n message: confirmMessage,\n })\n\n if (!confirmed) {\n this.log('Operation cancelled')\n return\n }\n } catch (error) {\n const err = error instanceof Error ? error : new Error(`${error}`)\n undeployGraphqlDebug('User cancelled', err)\n this.error('Operation cancelled', {exit: 1})\n }\n }\n\n try {\n await deleteGraphQLAPI({\n dataset,\n projectId,\n tag,\n })\n\n this.log('GraphQL API deleted')\n } catch (error) {\n const err = error instanceof Error ? error : new Error(`${error}`)\n undeployGraphqlDebug(`Error deleting GraphQL API for ${dataset}/${tag}`, err)\n this.error(`GraphQL API deletion failed:\\n${err.message}`, {exit: 1})\n }\n }\n}\n"],"names":["Flags","SanityCommand","subdebug","confirm","getGraphQLAPIs","deleteGraphQLAPI","undeployGraphqlDebug","Undeploy","description","examples","command","flags","api","string","required","dataset","force","boolean","project","tag","default","run","parse","apiFlag","datasetFlag","projectFlag","tagFlag","projectId","workDir","process","cwd","apiDefs","apiDef","find","def","id","error","exit","warn","getProjectId","cliConfig","getCliConfig","confirmMessage","confirmed","message","log","err","Error"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/commands/graphql/undeploy.ts"],"sourcesContent":["import {Flags} from '@oclif/core'\nimport {SanityCommand, subdebug} from '@sanity/cli-core'\nimport {confirm} from '@sanity/cli-core/ux'\n\nimport {getGraphQLAPIs} from '../../actions/graphql/getGraphQLAPIs.js'\nimport {promptForProject} from '../../prompts/promptForProject.js'\nimport {deleteGraphQLAPI} from '../../services/graphql.js'\nimport {getDatasetFlag, getProjectIdFlag} from '../../util/sharedFlags.js'\n\nconst undeployGraphqlDebug = subdebug('graphql:undeploy')\n\nexport class Undeploy extends SanityCommand<typeof Undeploy> {\n static override description = 'Remove a deployed GraphQL API'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'Undeploy GraphQL API for current project and dataset',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --api ios',\n description: 'Undeploy API with ID \"ios\"',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --dataset staging',\n description: 'Undeploy GraphQL API for staging dataset',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --dataset staging --tag next',\n description: 'Undeploy GraphQL API for staging dataset with \"next\" tag',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --force',\n description: 'Undeploy GraphQL API without confirmation prompt',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --project-id abc123 --dataset production',\n description: 'Undeploy GraphQL API for a specific project and dataset',\n },\n ]\n\n static override flags = {\n ...getProjectIdFlag({\n description: 'Project ID to undeploy GraphQL API from (overrides CLI configuration)',\n }),\n api: Flags.string({\n description: 'Undeploy API with this ID',\n exclusive: ['project-id', 'project'],\n required: false,\n }),\n ...getDatasetFlag({description: 'Dataset to undeploy GraphQL API from'}),\n force: Flags.boolean({\n description: 'Skip confirmation prompt',\n required: false,\n }),\n project: Flags.string({\n deprecated: {to: 'project-id'},\n description: 'Project ID to delete GraphQL API for',\n hidden: true,\n required: false,\n }),\n tag: Flags.string({\n default: 'default',\n description: 'Tag to undeploy GraphQL API from',\n required: false,\n }),\n }\n\n public async run(): Promise<void> {\n const {flags} = await this.parse(Undeploy)\n const {api: apiFlag, dataset: datasetFlag, force, tag: tagFlag} = flags\n\n let projectId: string | undefined\n let dataset = datasetFlag\n let tag = tagFlag\n\n // If specifying --api, use it for the flags not provided\n if (apiFlag) {\n const workDir = (await this.getProjectRoot()).directory\n const apiDefs = await getGraphQLAPIs(workDir)\n const apiDef = apiDefs.find((def) => def.id === apiFlag)\n\n if (!apiDef) {\n this.error(`GraphQL API \"${apiFlag}\" not found`, {exit: 1})\n }\n\n projectId = apiDef.projectId\n\n if (dataset && dataset !== apiDef.dataset) {\n this.warn(`Both --api and --dataset specified, using --dataset ${dataset}`)\n } else {\n dataset = apiDef.dataset\n }\n\n if (tag && tag !== 'default' && apiDef.tag && tag !== apiDef.tag) {\n this.warn(`Both --api and --tag specified, using --tag ${tag}`)\n } else {\n tag = apiDef.tag || 'default'\n }\n }\n\n // Get projectId from config if not specified\n if (!projectId) {\n projectId = await this.getProjectId({\n deprecatedFlagName: 'project',\n fallback: () =>\n promptForProject({\n requiredPermissions: [{grant: 'manage', permission: 'sanity.project.graphql'}],\n }),\n })\n }\n\n // Get dataset from CLI config if not specified\n if (!dataset) {\n const cliConfig = await this.tryGetCliConfig()\n dataset = cliConfig.api?.dataset\n }\n\n if (!dataset) {\n this.error(\n 'Dataset is required. Specify it with --dataset or configure it in your project.',\n {\n exit: 1,\n },\n )\n }\n\n // Confirm deletion unless --force is used\n if (!force) {\n const confirmMessage =\n tag === 'default'\n ? `Are you absolutely sure you want to delete the current GraphQL API connected to the \"${dataset}\" dataset in project ${projectId}?`\n : `Are you absolutely sure you want to delete the GraphQL API connected to the \"${dataset}\" dataset in project ${projectId}, tagged \"${tag}\"?`\n\n try {\n const confirmed = await confirm({\n default: false,\n message: confirmMessage,\n })\n\n if (!confirmed) {\n this.log('Operation cancelled')\n return\n }\n } catch (error) {\n const err = error instanceof Error ? error : new Error(`${error}`)\n undeployGraphqlDebug('User cancelled', err)\n this.error('Operation cancelled', {exit: 1})\n }\n }\n\n try {\n await deleteGraphQLAPI({\n dataset,\n projectId,\n tag,\n })\n\n this.log('GraphQL API deleted')\n } catch (error) {\n const err = error instanceof Error ? error : new Error(`${error}`)\n undeployGraphqlDebug(`Error deleting GraphQL API for ${dataset}/${tag}`, err)\n this.error(`GraphQL API deletion failed:\\n${err.message}`, {exit: 1})\n }\n }\n}\n"],"names":["Flags","SanityCommand","subdebug","confirm","getGraphQLAPIs","promptForProject","deleteGraphQLAPI","getDatasetFlag","getProjectIdFlag","undeployGraphqlDebug","Undeploy","description","examples","command","flags","api","string","exclusive","required","force","boolean","project","deprecated","to","hidden","tag","default","run","parse","apiFlag","dataset","datasetFlag","tagFlag","projectId","workDir","getProjectRoot","directory","apiDefs","apiDef","find","def","id","error","exit","warn","getProjectId","deprecatedFlagName","fallback","requiredPermissions","grant","permission","cliConfig","tryGetCliConfig","confirmMessage","confirmed","message","log","err","Error"],"mappings":"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"}
@@ -1,7 +1,9 @@
1
1
  import { Args } from '@oclif/core';
2
2
  import { SanityCommand, subdebug } from '@sanity/cli-core';
3
3
  import { formatFailure } from '../../actions/hook/formatFailure.js';
4
+ import { promptForProject } from '../../prompts/promptForProject.js';
4
5
  import { getHookAttempt } from '../../services/hooks.js';
6
+ import { getProjectIdFlag } from '../../util/sharedFlags.js';
5
7
  const attemptDebug = subdebug('hook:attempt');
6
8
  export class AttemptHookCommand extends SanityCommand {
7
9
  static args = {
@@ -15,12 +17,30 @@ export class AttemptHookCommand extends SanityCommand {
15
17
  {
16
18
  command: '<%= config.bin %> <%= command.id %> abc123',
17
19
  description: 'Print details of webhook delivery attempt with ID abc123'
20
+ },
21
+ {
22
+ command: '<%= config.bin %> <%= command.id %> abc123 --project-id myproject',
23
+ description: 'Get attempt details for a specific project'
18
24
  }
19
25
  ];
26
+ static flags = {
27
+ ...getProjectIdFlag({
28
+ description: 'Project ID to view webhook attempt for (overrides CLI configuration)'
29
+ })
30
+ };
20
31
  async run() {
21
32
  const { args } = await this.parse(AttemptHookCommand);
22
33
  const { attemptId } = args;
23
- const projectId = await this.getProjectId();
34
+ const projectId = await this.getProjectId({
35
+ fallback: ()=>promptForProject({
36
+ requiredPermissions: [
37
+ {
38
+ grant: 'read',
39
+ permission: 'sanity.project.webhooks'
40
+ }
41
+ ]
42
+ })
43
+ });
24
44
  let attempt;
25
45
  try {
26
46
  attempt = await getHookAttempt({
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/commands/hook/attempt.ts"],"sourcesContent":["import {Args} from '@oclif/core'\nimport {SanityCommand, subdebug} from '@sanity/cli-core'\n\nimport {formatFailure} from '../../actions/hook/formatFailure.js'\nimport {type DeliveryAttempt} from '../../actions/hook/types.js'\nimport {getHookAttempt} from '../../services/hooks.js'\n\nconst attemptDebug = subdebug('hook:attempt')\n\nexport class AttemptHookCommand extends SanityCommand<typeof AttemptHookCommand> {\n static override args = {\n attemptId: Args.string({\n description: 'The delivery attempt ID to get details for',\n required: true,\n }),\n }\n static override description = 'Print details of a given webhook delivery attempt'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> abc123',\n description: 'Print details of webhook delivery attempt with ID abc123',\n },\n ]\n\n public async run() {\n const {args} = await this.parse(AttemptHookCommand)\n const {attemptId} = args\n\n const projectId = await this.getProjectId()\n\n let attempt: DeliveryAttempt\n try {\n attempt = await getHookAttempt({attemptId, projectId})\n } catch (error) {\n const err = error as Error\n attemptDebug(`Error fetching hook attempt ${attemptId}`, err)\n this.error(`Hook attempt retrieval failed:\\n${err.message}`, {exit: 1})\n }\n\n const {createdAt, failureReason, inProgress, resultBody, resultCode} = attempt\n\n this.log(`Date: ${createdAt}`)\n this.log(`Status: ${this.getStatus(attempt)}`)\n this.log(`Status code: ${resultCode}`)\n\n if (attempt.isFailure) {\n this.log(`Failure: ${formatFailure(attempt)}`)\n }\n\n if (!inProgress && (!failureReason || failureReason === 'http')) {\n const body = resultBody ? `\\n---\\n${resultBody}\\n---\\n` : '<empty>'\n this.log(`Response body: ${body}`)\n }\n }\n\n private getStatus(attempt: DeliveryAttempt): string {\n if (attempt.isFailure) {\n return 'Failed'\n }\n\n if (attempt.inProgress) {\n return 'In progress'\n }\n\n return 'Delivered'\n }\n}\n"],"names":["Args","SanityCommand","subdebug","formatFailure","getHookAttempt","attemptDebug","AttemptHookCommand","args","attemptId","string","description","required","examples","command","run","parse","projectId","getProjectId","attempt","error","err","message","exit","createdAt","failureReason","inProgress","resultBody","resultCode","log","getStatus","isFailure","body"],"mappings":"AAAA,SAAQA,IAAI,QAAO,cAAa;AAChC,SAAQC,aAAa,EAAEC,QAAQ,QAAO,mBAAkB;AAExD,SAAQC,aAAa,QAAO,sCAAqC;AAEjE,SAAQC,cAAc,QAAO,0BAAyB;AAEtD,MAAMC,eAAeH,SAAS;AAE9B,OAAO,MAAMI,2BAA2BL;IACtC,OAAgBM,OAAO;QACrBC,WAAWR,KAAKS,MAAM,CAAC;YACrBC,aAAa;YACbC,UAAU;QACZ;IACF,EAAC;IACD,OAAgBD,cAAc,oDAAmD;IAEjF,OAAgBE,WAAW;QACzB;YACEC,SAAS;YACTH,aAAa;QACf;KACD,CAAA;IAED,MAAaI,MAAM;QACjB,MAAM,EAACP,IAAI,EAAC,GAAG,MAAM,IAAI,CAACQ,KAAK,CAACT;QAChC,MAAM,EAACE,SAAS,EAAC,GAAGD;QAEpB,MAAMS,YAAY,MAAM,IAAI,CAACC,YAAY;QAEzC,IAAIC;QACJ,IAAI;YACFA,UAAU,MAAMd,eAAe;gBAACI;gBAAWQ;YAAS;QACtD,EAAE,OAAOG,OAAO;YACd,MAAMC,MAAMD;YACZd,aAAa,CAAC,4BAA4B,EAAEG,WAAW,EAAEY;YACzD,IAAI,CAACD,KAAK,CAAC,CAAC,gCAAgC,EAAEC,IAAIC,OAAO,EAAE,EAAE;gBAACC,MAAM;YAAC;QACvE;QAEA,MAAM,EAACC,SAAS,EAAEC,aAAa,EAAEC,UAAU,EAAEC,UAAU,EAAEC,UAAU,EAAC,GAAGT;QAEvE,IAAI,CAACU,GAAG,CAAC,CAAC,MAAM,EAAEL,WAAW;QAC7B,IAAI,CAACK,GAAG,CAAC,CAAC,QAAQ,EAAE,IAAI,CAACC,SAAS,CAACX,UAAU;QAC7C,IAAI,CAACU,GAAG,CAAC,CAAC,aAAa,EAAED,YAAY;QAErC,IAAIT,QAAQY,SAAS,EAAE;YACrB,IAAI,CAACF,GAAG,CAAC,CAAC,SAAS,EAAEzB,cAAce,UAAU;QAC/C;QAEA,IAAI,CAACO,cAAe,CAAA,CAACD,iBAAiBA,kBAAkB,MAAK,GAAI;YAC/D,MAAMO,OAAOL,aAAa,CAAC,OAAO,EAAEA,WAAW,OAAO,CAAC,GAAG;YAC1D,IAAI,CAACE,GAAG,CAAC,CAAC,eAAe,EAAEG,MAAM;QACnC;IACF;IAEQF,UAAUX,OAAwB,EAAU;QAClD,IAAIA,QAAQY,SAAS,EAAE;YACrB,OAAO;QACT;QAEA,IAAIZ,QAAQO,UAAU,EAAE;YACtB,OAAO;QACT;QAEA,OAAO;IACT;AACF"}
1
+ {"version":3,"sources":["../../../src/commands/hook/attempt.ts"],"sourcesContent":["import {Args} from '@oclif/core'\nimport {SanityCommand, subdebug} from '@sanity/cli-core'\n\nimport {formatFailure} from '../../actions/hook/formatFailure.js'\nimport {type DeliveryAttempt} from '../../actions/hook/types.js'\nimport {promptForProject} from '../../prompts/promptForProject.js'\nimport {getHookAttempt} from '../../services/hooks.js'\nimport {getProjectIdFlag} from '../../util/sharedFlags.js'\n\nconst attemptDebug = subdebug('hook:attempt')\n\nexport class AttemptHookCommand extends SanityCommand<typeof AttemptHookCommand> {\n static override args = {\n attemptId: Args.string({\n description: 'The delivery attempt ID to get details for',\n required: true,\n }),\n }\n static override description = 'Print details of a given webhook delivery attempt'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> abc123',\n description: 'Print details of webhook delivery attempt with ID abc123',\n },\n {\n command: '<%= config.bin %> <%= command.id %> abc123 --project-id myproject',\n description: 'Get attempt details for a specific project',\n },\n ]\n\n static override flags = {\n ...getProjectIdFlag({\n description: 'Project ID to view webhook attempt for (overrides CLI configuration)',\n }),\n }\n\n public async run() {\n const {args} = await this.parse(AttemptHookCommand)\n const {attemptId} = args\n\n const projectId = await this.getProjectId({\n fallback: () =>\n promptForProject({\n requiredPermissions: [{grant: 'read', permission: 'sanity.project.webhooks'}],\n }),\n })\n\n let attempt: DeliveryAttempt\n try {\n attempt = await getHookAttempt({attemptId, projectId})\n } catch (error) {\n const err = error as Error\n attemptDebug(`Error fetching hook attempt ${attemptId}`, err)\n this.error(`Hook attempt retrieval failed:\\n${err.message}`, {exit: 1})\n }\n\n const {createdAt, failureReason, inProgress, resultBody, resultCode} = attempt\n\n this.log(`Date: ${createdAt}`)\n this.log(`Status: ${this.getStatus(attempt)}`)\n this.log(`Status code: ${resultCode}`)\n\n if (attempt.isFailure) {\n this.log(`Failure: ${formatFailure(attempt)}`)\n }\n\n if (!inProgress && (!failureReason || failureReason === 'http')) {\n const body = resultBody ? `\\n---\\n${resultBody}\\n---\\n` : '<empty>'\n this.log(`Response body: ${body}`)\n }\n }\n\n private getStatus(attempt: DeliveryAttempt): string {\n if (attempt.isFailure) {\n return 'Failed'\n }\n\n if (attempt.inProgress) {\n return 'In progress'\n }\n\n return 'Delivered'\n }\n}\n"],"names":["Args","SanityCommand","subdebug","formatFailure","promptForProject","getHookAttempt","getProjectIdFlag","attemptDebug","AttemptHookCommand","args","attemptId","string","description","required","examples","command","flags","run","parse","projectId","getProjectId","fallback","requiredPermissions","grant","permission","attempt","error","err","message","exit","createdAt","failureReason","inProgress","resultBody","resultCode","log","getStatus","isFailure","body"],"mappings":"AAAA,SAAQA,IAAI,QAAO,cAAa;AAChC,SAAQC,aAAa,EAAEC,QAAQ,QAAO,mBAAkB;AAExD,SAAQC,aAAa,QAAO,sCAAqC;AAEjE,SAAQC,gBAAgB,QAAO,oCAAmC;AAClE,SAAQC,cAAc,QAAO,0BAAyB;AACtD,SAAQC,gBAAgB,QAAO,4BAA2B;AAE1D,MAAMC,eAAeL,SAAS;AAE9B,OAAO,MAAMM,2BAA2BP;IACtC,OAAgBQ,OAAO;QACrBC,WAAWV,KAAKW,MAAM,CAAC;YACrBC,aAAa;YACbC,UAAU;QACZ;IACF,EAAC;IACD,OAAgBD,cAAc,oDAAmD;IAEjF,OAAgBE,WAAW;QACzB;YACEC,SAAS;YACTH,aAAa;QACf;QACA;YACEG,SAAS;YACTH,aAAa;QACf;KACD,CAAA;IAED,OAAgBI,QAAQ;QACtB,GAAGV,iBAAiB;YAClBM,aAAa;QACf,EAAE;IACJ,EAAC;IAED,MAAaK,MAAM;QACjB,MAAM,EAACR,IAAI,EAAC,GAAG,MAAM,IAAI,CAACS,KAAK,CAACV;QAChC,MAAM,EAACE,SAAS,EAAC,GAAGD;QAEpB,MAAMU,YAAY,MAAM,IAAI,CAACC,YAAY,CAAC;YACxCC,UAAU,IACRjB,iBAAiB;oBACfkB,qBAAqB;wBAAC;4BAACC,OAAO;4BAAQC,YAAY;wBAAyB;qBAAE;gBAC/E;QACJ;QAEA,IAAIC;QACJ,IAAI;YACFA,UAAU,MAAMpB,eAAe;gBAACK;gBAAWS;YAAS;QACtD,EAAE,OAAOO,OAAO;YACd,MAAMC,MAAMD;YACZnB,aAAa,CAAC,4BAA4B,EAAEG,WAAW,EAAEiB;YACzD,IAAI,CAACD,KAAK,CAAC,CAAC,gCAAgC,EAAEC,IAAIC,OAAO,EAAE,EAAE;gBAACC,MAAM;YAAC;QACvE;QAEA,MAAM,EAACC,SAAS,EAAEC,aAAa,EAAEC,UAAU,EAAEC,UAAU,EAAEC,UAAU,EAAC,GAAGT;QAEvE,IAAI,CAACU,GAAG,CAAC,CAAC,MAAM,EAAEL,WAAW;QAC7B,IAAI,CAACK,GAAG,CAAC,CAAC,QAAQ,EAAE,IAAI,CAACC,SAAS,CAACX,UAAU;QAC7C,IAAI,CAACU,GAAG,CAAC,CAAC,aAAa,EAAED,YAAY;QAErC,IAAIT,QAAQY,SAAS,EAAE;YACrB,IAAI,CAACF,GAAG,CAAC,CAAC,SAAS,EAAEhC,cAAcsB,UAAU;QAC/C;QAEA,IAAI,CAACO,cAAe,CAAA,CAACD,iBAAiBA,kBAAkB,MAAK,GAAI;YAC/D,MAAMO,OAAOL,aAAa,CAAC,OAAO,EAAEA,WAAW,OAAO,CAAC,GAAG;YAC1D,IAAI,CAACE,GAAG,CAAC,CAAC,eAAe,EAAEG,MAAM;QACnC;IACF;IAEQF,UAAUX,OAAwB,EAAU;QAClD,IAAIA,QAAQY,SAAS,EAAE;YACrB,OAAO;QACT;QAEA,IAAIZ,QAAQO,UAAU,EAAE;YACtB,OAAO;QACT;QAEA,OAAO;IACT;AACF"}