@sanity/runtime-cli 11.2.0 → 12.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/README.md +36 -38
  2. package/dist/actions/blueprints/blueprint.d.ts +3 -0
  3. package/dist/actions/blueprints/blueprint.js +26 -14
  4. package/dist/actions/blueprints/config.d.ts +34 -3
  5. package/dist/actions/blueprints/config.js +67 -14
  6. package/dist/actions/blueprints/stacks.d.ts +1 -2
  7. package/dist/actions/blueprints/stacks.js +2 -3
  8. package/dist/commands/blueprints/config.d.ts +0 -1
  9. package/dist/commands/blueprints/config.js +4 -12
  10. package/dist/commands/blueprints/deploy.js +1 -1
  11. package/dist/commands/blueprints/destroy.js +3 -3
  12. package/dist/commands/blueprints/info.js +2 -2
  13. package/dist/commands/blueprints/init.d.ts +1 -0
  14. package/dist/commands/blueprints/init.js +4 -0
  15. package/dist/commands/blueprints/logs.js +2 -2
  16. package/dist/commands/blueprints/plan.js +1 -0
  17. package/dist/config.d.ts +2 -1
  18. package/dist/config.js +8 -1
  19. package/dist/cores/blueprints/config.d.ts +1 -1
  20. package/dist/cores/blueprints/config.js +92 -78
  21. package/dist/cores/blueprints/deploy.js +8 -8
  22. package/dist/cores/blueprints/destroy.d.ts +1 -0
  23. package/dist/cores/blueprints/destroy.js +22 -26
  24. package/dist/cores/blueprints/doctor.js +24 -72
  25. package/dist/cores/blueprints/info.d.ts +1 -0
  26. package/dist/cores/blueprints/info.js +5 -4
  27. package/dist/cores/blueprints/init.d.ts +1 -1
  28. package/dist/cores/blueprints/init.js +50 -78
  29. package/dist/cores/blueprints/logs.d.ts +1 -0
  30. package/dist/cores/blueprints/logs.js +7 -7
  31. package/dist/cores/blueprints/plan.d.ts +3 -0
  32. package/dist/cores/blueprints/plan.js +5 -4
  33. package/dist/cores/blueprints/stacks.d.ts +1 -0
  34. package/dist/cores/blueprints/stacks.js +1 -2
  35. package/dist/cores/functions/add.js +58 -70
  36. package/dist/cores/functions/logs.js +2 -4
  37. package/dist/cores/index.js +3 -3
  38. package/dist/server/static/vendor/vendor.bundle.js +515 -234
  39. package/dist/utils/display/blueprints-formatting.js +8 -3
  40. package/dist/utils/display/errors.js +2 -2
  41. package/dist/utils/display/presenters.d.ts +2 -0
  42. package/dist/utils/display/presenters.js +7 -0
  43. package/dist/utils/display/prompt.d.ts +14 -2
  44. package/dist/utils/display/prompt.js +60 -41
  45. package/dist/utils/types.d.ts +0 -1
  46. package/oclif.manifest.json +19 -26
  47. package/package.json +6 -5
package/README.md CHANGED
@@ -20,7 +20,7 @@ $ npm install -g @sanity/runtime-cli
20
20
  $ sanity-run COMMAND
21
21
  running command...
22
22
  $ sanity-run (--version)
23
- @sanity/runtime-cli/11.2.0 linux-x64 node-v24.11.1
23
+ @sanity/runtime-cli/12.0.0 linux-x64 node-v24.11.1
24
24
  $ sanity-run --help [COMMAND]
25
25
  USAGE
26
26
  $ sanity-run COMMAND
@@ -92,7 +92,7 @@ EXAMPLES
92
92
  $ sanity-run blueprints add function --name my-function --fn-type document-create --fn-type document-update --lang js
93
93
  ```
94
94
 
95
- _See code: [src/commands/blueprints/add.ts](https://github.com/sanity-io/runtime-cli/blob/v11.2.0/src/commands/blueprints/add.ts)_
95
+ _See code: [src/commands/blueprints/add.ts](https://github.com/sanity-io/runtime-cli/blob/v12.0.0/src/commands/blueprints/add.ts)_
96
96
 
97
97
  ## `sanity-run blueprints config`
98
98
 
@@ -100,14 +100,13 @@ View or edit Blueprint configuration
100
100
 
101
101
  ```
102
102
  USAGE
103
- $ sanity-run blueprints config [-t] [--project-id <value> -e] [--organization-id <value> ] [--stack-id <value> ]
103
+ $ sanity-run blueprints config [--project-id <value> -e] [--organization-id <value> ] [--stack-id <value> ]
104
104
 
105
105
  FLAGS
106
- -e, --edit Edit the configuration
107
- -t, --test-config Validate the configuration
108
- --organization-id=<value> Update the Organization ID in the configuration. Requires --edit flag
109
- --project-id=<value> Update the Project ID in the configuration. Requires --edit flag
110
- --stack-id=<value> Update the Stack ID in the configuration. Requires --edit flag
106
+ -e, --edit Modify the configuration interactively, or directly when combined with ID flags.
107
+ --organization-id=<value> Directly set the Organization ID in the configuration. Requires --edit flag
108
+ --project-id=<value> Directly set the Project ID in the configuration. Requires --edit flag
109
+ --stack-id=<value> Directly set the Stack ID in the configuration. Requires --edit flag
111
110
 
112
111
  DESCRIPTION
113
112
  View or edit Blueprint configuration
@@ -115,8 +114,6 @@ DESCRIPTION
115
114
  EXAMPLES
116
115
  $ sanity-run blueprints config
117
116
 
118
- $ sanity-run blueprints config --test-config
119
-
120
117
  $ sanity-run blueprints config --edit
121
118
 
122
119
  $ sanity-run blueprints config --edit --project-id <projectId>
@@ -124,7 +121,7 @@ EXAMPLES
124
121
  $ sanity-run blueprints config --edit --project-id <projectId> --stack-id <stackId>
125
122
  ```
126
123
 
127
- _See code: [src/commands/blueprints/config.ts](https://github.com/sanity-io/runtime-cli/blob/v11.2.0/src/commands/blueprints/config.ts)_
124
+ _See code: [src/commands/blueprints/config.ts](https://github.com/sanity-io/runtime-cli/blob/v12.0.0/src/commands/blueprints/config.ts)_
128
125
 
129
126
  ## `sanity-run blueprints deploy`
130
127
 
@@ -135,7 +132,7 @@ USAGE
135
132
  $ sanity-run blueprints deploy [--no-wait]
136
133
 
137
134
  FLAGS
138
- --no-wait Do not wait for deployment to complete
135
+ --no-wait Do not wait for Stack deployment to complete
139
136
 
140
137
  DESCRIPTION
141
138
  Deploy a Blueprint
@@ -146,11 +143,11 @@ EXAMPLES
146
143
  $ sanity-run blueprints deploy --no-wait
147
144
  ```
148
145
 
149
- _See code: [src/commands/blueprints/deploy.ts](https://github.com/sanity-io/runtime-cli/blob/v11.2.0/src/commands/blueprints/deploy.ts)_
146
+ _See code: [src/commands/blueprints/deploy.ts](https://github.com/sanity-io/runtime-cli/blob/v12.0.0/src/commands/blueprints/deploy.ts)_
150
147
 
151
148
  ## `sanity-run blueprints destroy`
152
149
 
153
- Destroy a Blueprint deployment (will not delete local files)
150
+ Destroy a Blueprint Stack deployment and its resources (will not delete local files)
154
151
 
155
152
  ```
156
153
  USAGE
@@ -158,14 +155,14 @@ USAGE
158
155
  [--no-wait]
159
156
 
160
157
  FLAGS
161
- --force Force destroy (skip confirmation)
162
- --no-wait Do not wait for destruction to complete
158
+ --force Force Stack destruction (skip confirmation)
159
+ --no-wait Do not wait for Stack destruction to complete
163
160
  --organization-id=<value> Organization associated with the Stack
164
161
  --project-id=<value> Project associated with the Stack
165
162
  --stack-id=<value> Stack ID to destroy (defaults to current Stack)
166
163
 
167
164
  DESCRIPTION
168
- Destroy a Blueprint deployment (will not delete local files)
165
+ Destroy a Blueprint Stack deployment and its resources (will not delete local files)
169
166
 
170
167
  EXAMPLES
171
168
  $ sanity-run blueprints destroy
@@ -173,7 +170,7 @@ EXAMPLES
173
170
  $ sanity-run blueprints destroy --stack-id <stackId> --project-id <projectId> --force --no-wait
174
171
  ```
175
172
 
176
- _See code: [src/commands/blueprints/destroy.ts](https://github.com/sanity-io/runtime-cli/blob/v11.2.0/src/commands/blueprints/destroy.ts)_
173
+ _See code: [src/commands/blueprints/destroy.ts](https://github.com/sanity-io/runtime-cli/blob/v12.0.0/src/commands/blueprints/destroy.ts)_
177
174
 
178
175
  ## `sanity-run blueprints doctor`
179
176
 
@@ -191,21 +188,21 @@ DESCRIPTION
191
188
  Diagnose potential issues with Blueprint configuration
192
189
  ```
193
190
 
194
- _See code: [src/commands/blueprints/doctor.ts](https://github.com/sanity-io/runtime-cli/blob/v11.2.0/src/commands/blueprints/doctor.ts)_
191
+ _See code: [src/commands/blueprints/doctor.ts](https://github.com/sanity-io/runtime-cli/blob/v12.0.0/src/commands/blueprints/doctor.ts)_
195
192
 
196
193
  ## `sanity-run blueprints info`
197
194
 
198
- Show information about a Blueprint deployment
195
+ Show information about a Blueprint Stack deployment
199
196
 
200
197
  ```
201
198
  USAGE
202
199
  $ sanity-run blueprints info [--id <value>]
203
200
 
204
201
  FLAGS
205
- --id=<value> Stack ID to show info for (defaults to current stack)
202
+ --id=<value> Stack ID to show info for (defaults to current Stack)
206
203
 
207
204
  DESCRIPTION
208
- Show information about a Blueprint deployment
205
+ Show information about a Blueprint Stack deployment
209
206
 
210
207
  EXAMPLES
211
208
  $ sanity-run blueprints info
@@ -213,7 +210,7 @@ EXAMPLES
213
210
  $ sanity-run blueprints info --stack-id <stackId>
214
211
  ```
215
212
 
216
- _See code: [src/commands/blueprints/info.ts](https://github.com/sanity-io/runtime-cli/blob/v11.2.0/src/commands/blueprints/info.ts)_
213
+ _See code: [src/commands/blueprints/info.ts](https://github.com/sanity-io/runtime-cli/blob/v12.0.0/src/commands/blueprints/info.ts)_
217
214
 
218
215
  ## `sanity-run blueprints init [DIR]`
219
216
 
@@ -222,7 +219,7 @@ Initialize a new Blueprint
222
219
  ```
223
220
  USAGE
224
221
  $ sanity-run blueprints init [DIR] [--dir <value>] [--example <value> | --blueprint-type json|js|ts | --stack-id
225
- <value> | --stack-name <value>] [--project-id <value>] [--organization-id <value>]
222
+ <value> | --stack-name <value>] [--project-id <value>] [--organization-id <value>] [--verbose]
226
223
 
227
224
  ARGUMENTS
228
225
  [DIR] Directory to create the Blueprint in
@@ -236,6 +233,7 @@ FLAGS
236
233
  --project-id=<value> Sanity Project ID to use for the Blueprint
237
234
  --stack-id=<value> Existing Stack ID to use for the Blueprint
238
235
  --stack-name=<value> Name to use for a NEW Stack
236
+ --verbose Verbose output
239
237
 
240
238
  DESCRIPTION
241
239
  Initialize a new Blueprint
@@ -252,21 +250,21 @@ EXAMPLES
252
250
  $ sanity-run blueprints init --blueprint-type <json|js|ts> --stack-name <stackName>
253
251
  ```
254
252
 
255
- _See code: [src/commands/blueprints/init.ts](https://github.com/sanity-io/runtime-cli/blob/v11.2.0/src/commands/blueprints/init.ts)_
253
+ _See code: [src/commands/blueprints/init.ts](https://github.com/sanity-io/runtime-cli/blob/v12.0.0/src/commands/blueprints/init.ts)_
256
254
 
257
255
  ## `sanity-run blueprints logs`
258
256
 
259
- Display logs for a Blueprint deployment
257
+ Display logs for a Blueprint Stack deployment
260
258
 
261
259
  ```
262
260
  USAGE
263
261
  $ sanity-run blueprints logs [-w]
264
262
 
265
263
  FLAGS
266
- -w, --watch Watch for new logs (streaming mode)
264
+ -w, --watch Watch for new Stack logs (streaming mode)
267
265
 
268
266
  DESCRIPTION
269
- Display logs for a Blueprint deployment
267
+ Display logs for a Blueprint Stack deployment
270
268
 
271
269
  EXAMPLES
272
270
  $ sanity-run blueprints logs
@@ -274,7 +272,7 @@ EXAMPLES
274
272
  $ sanity-run blueprints logs --watch
275
273
  ```
276
274
 
277
- _See code: [src/commands/blueprints/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v11.2.0/src/commands/blueprints/logs.ts)_
275
+ _See code: [src/commands/blueprints/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v12.0.0/src/commands/blueprints/logs.ts)_
278
276
 
279
277
  ## `sanity-run blueprints plan`
280
278
 
@@ -291,7 +289,7 @@ EXAMPLES
291
289
  $ sanity-run blueprints plan
292
290
  ```
293
291
 
294
- _See code: [src/commands/blueprints/plan.ts](https://github.com/sanity-io/runtime-cli/blob/v11.2.0/src/commands/blueprints/plan.ts)_
292
+ _See code: [src/commands/blueprints/plan.ts](https://github.com/sanity-io/runtime-cli/blob/v12.0.0/src/commands/blueprints/plan.ts)_
295
293
 
296
294
  ## `sanity-run blueprints stacks`
297
295
 
@@ -316,7 +314,7 @@ EXAMPLES
316
314
  $ sanity-run blueprints stacks --organization-id <organizationId>
317
315
  ```
318
316
 
319
- _See code: [src/commands/blueprints/stacks.ts](https://github.com/sanity-io/runtime-cli/blob/v11.2.0/src/commands/blueprints/stacks.ts)_
317
+ _See code: [src/commands/blueprints/stacks.ts](https://github.com/sanity-io/runtime-cli/blob/v12.0.0/src/commands/blueprints/stacks.ts)_
320
318
 
321
319
  ## `sanity-run functions add`
322
320
 
@@ -358,7 +356,7 @@ EXAMPLES
358
356
  $ sanity-run functions add --name my-function --type document-create --type document-update --lang js
359
357
  ```
360
358
 
361
- _See code: [src/commands/functions/add.ts](https://github.com/sanity-io/runtime-cli/blob/v11.2.0/src/commands/functions/add.ts)_
359
+ _See code: [src/commands/functions/add.ts](https://github.com/sanity-io/runtime-cli/blob/v12.0.0/src/commands/functions/add.ts)_
362
360
 
363
361
  ## `sanity-run functions dev`
364
362
 
@@ -381,7 +379,7 @@ EXAMPLES
381
379
  $ sanity-run functions dev --host 127.0.0.1 --port 8974
382
380
  ```
383
381
 
384
- _See code: [src/commands/functions/dev.ts](https://github.com/sanity-io/runtime-cli/blob/v11.2.0/src/commands/functions/dev.ts)_
382
+ _See code: [src/commands/functions/dev.ts](https://github.com/sanity-io/runtime-cli/blob/v12.0.0/src/commands/functions/dev.ts)_
385
383
 
386
384
  ## `sanity-run functions env add NAME KEY VALUE`
387
385
 
@@ -403,7 +401,7 @@ EXAMPLES
403
401
  $ sanity-run functions env add MyFunction API_URL https://api.example.com/
404
402
  ```
405
403
 
406
- _See code: [src/commands/functions/env/add.ts](https://github.com/sanity-io/runtime-cli/blob/v11.2.0/src/commands/functions/env/add.ts)_
404
+ _See code: [src/commands/functions/env/add.ts](https://github.com/sanity-io/runtime-cli/blob/v12.0.0/src/commands/functions/env/add.ts)_
407
405
 
408
406
  ## `sanity-run functions env list NAME`
409
407
 
@@ -423,7 +421,7 @@ EXAMPLES
423
421
  $ sanity-run functions env list MyFunction
424
422
  ```
425
423
 
426
- _See code: [src/commands/functions/env/list.ts](https://github.com/sanity-io/runtime-cli/blob/v11.2.0/src/commands/functions/env/list.ts)_
424
+ _See code: [src/commands/functions/env/list.ts](https://github.com/sanity-io/runtime-cli/blob/v12.0.0/src/commands/functions/env/list.ts)_
427
425
 
428
426
  ## `sanity-run functions env remove NAME KEY`
429
427
 
@@ -444,7 +442,7 @@ EXAMPLES
444
442
  $ sanity-run functions env remove MyFunction API_URL
445
443
  ```
446
444
 
447
- _See code: [src/commands/functions/env/remove.ts](https://github.com/sanity-io/runtime-cli/blob/v11.2.0/src/commands/functions/env/remove.ts)_
445
+ _See code: [src/commands/functions/env/remove.ts](https://github.com/sanity-io/runtime-cli/blob/v12.0.0/src/commands/functions/env/remove.ts)_
448
446
 
449
447
  ## `sanity-run functions logs NAME`
450
448
 
@@ -478,7 +476,7 @@ EXAMPLES
478
476
  $ sanity-run functions logs <name> --delete
479
477
  ```
480
478
 
481
- _See code: [src/commands/functions/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v11.2.0/src/commands/functions/logs.ts)_
479
+ _See code: [src/commands/functions/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v12.0.0/src/commands/functions/logs.ts)_
482
480
 
483
481
  ## `sanity-run functions test NAME`
484
482
 
@@ -527,7 +525,7 @@ EXAMPLES
527
525
  $ sanity-run functions test <name> --event update --data-before '{ "title": "before" }' --data-after '{ "title": "after" }'
528
526
  ```
529
527
 
530
- _See code: [src/commands/functions/test.ts](https://github.com/sanity-io/runtime-cli/blob/v11.2.0/src/commands/functions/test.ts)_
528
+ _See code: [src/commands/functions/test.ts](https://github.com/sanity-io/runtime-cli/blob/v12.0.0/src/commands/functions/test.ts)_
531
529
 
532
530
  ## `sanity-run help [COMMAND]`
533
531
 
@@ -1,6 +1,7 @@
1
1
  import { type Blueprint } from '@sanity/blueprints-parser';
2
2
  import type { BlueprintParserError, Resource } from '../../utils/types.js';
3
3
  import { type ScopeType } from '../../utils/types.js';
4
+ import { type BlueprintsConfig } from './config.js';
4
5
  declare const SUPPORTED_FILE_EXTENSIONS: readonly [".json", ".js", ".mjs", ".ts"];
5
6
  type BlueprintFileExtension = (typeof SUPPORTED_FILE_EXTENSIONS)[number];
6
7
  export declare const JSON_BLUEPRINT_CONTENT: {
@@ -28,9 +29,11 @@ export declare function findBlueprintFile(blueprintPath?: string): FileInfo | nu
28
29
  /** Result of the blueprint read operation */
29
30
  export interface ReadBlueprintResult {
30
31
  fileInfo: FileInfo;
32
+ blueprintConfig: BlueprintsConfig | null;
31
33
  rawBlueprint: Record<string, unknown>;
32
34
  parsedBlueprint: Blueprint;
33
35
  errors: BlueprintParserError[];
36
+ /** @deprecated - use blueprintConfig.configPath instead */
34
37
  configPath?: string;
35
38
  scopeType?: ScopeType;
36
39
  scopeId?: string;
@@ -6,7 +6,7 @@ import { findUpSync } from 'find-up';
6
6
  import { createJiti } from 'jiti';
7
7
  import { isLocalFunctionResource } from '../../utils/types.js';
8
8
  import { validateFunctionResource } from '../../utils/validate/resource.js';
9
- import { backfillOrganizationId, readConfigFile } from './config.js';
9
+ import { backfillOrganizationId, backfillProjectBasedStackId, readConfigFile, } from './config.js';
10
10
  const SUPPORTED_FILE_EXTENSIONS = ['.json', '.js', '.mjs', '.ts'];
11
11
  let SUPPORTED_FILE_NAMES = SUPPORTED_FILE_EXTENSIONS.map((ext) => `blueprint${ext}`);
12
12
  SUPPORTED_FILE_NAMES = [
@@ -130,13 +130,12 @@ export async function readLocalBlueprint(blueprintPath) {
130
130
  throw Error('Unable to read Blueprint');
131
131
  }
132
132
  const { SANITY_ORGANIZATION_ID: envOrganizationId, SANITY_PROJECT_ID: envProjectId, SANITY_BLUEPRINT_STACK_ID: envStackId, } = env;
133
- const configIds = readConfigFile(foundFilePath);
134
- const configPath = configIds?.configPath;
133
+ const blueprintConfig = readConfigFile(foundFilePath);
135
134
  // passively heal config on disk by getting organizationId from projectId
136
- if (configIds && !configIds.organizationId && configIds.projectId) {
135
+ if (blueprintConfig?.projectId && !blueprintConfig.organizationId) {
137
136
  try {
138
137
  await backfillOrganizationId({
139
- projectId: configIds.projectId,
138
+ projectId: blueprintConfig.projectId,
140
139
  blueprintFilePath: foundFilePath,
141
140
  });
142
141
  }
@@ -147,25 +146,36 @@ export async function readLocalBlueprint(blueprintPath) {
147
146
  organizationId = envOrganizationId;
148
147
  else if (moduleOrganizationId)
149
148
  organizationId = moduleOrganizationId;
150
- else if (configIds?.organizationId)
151
- organizationId = configIds.organizationId;
149
+ else if (blueprintConfig?.organizationId)
150
+ organizationId = blueprintConfig.organizationId;
152
151
  let projectId;
153
152
  if (envProjectId)
154
153
  projectId = envProjectId;
155
154
  else if (moduleProjectId)
156
155
  projectId = moduleProjectId;
157
- else if (configIds?.projectId)
158
- projectId = configIds.projectId;
156
+ else if (blueprintConfig?.projectId)
157
+ projectId = blueprintConfig.projectId;
159
158
  let stackId;
160
159
  if (envStackId)
161
160
  stackId = envStackId;
162
161
  else if (moduleStackId)
163
162
  stackId = moduleStackId;
164
- else if (configIds?.stackId)
165
- stackId = configIds.stackId;
163
+ else if (blueprintConfig?.stackId)
164
+ stackId = blueprintConfig.stackId;
166
165
  // LAUNCH LIMIT: 1 Stack per Project - infer stackId from projectId
167
- if (!stackId && projectId)
168
- stackId = `ST-${projectId}`;
166
+ // this code path exists to handle project-based stacks from initial Blueprints/Functions launch
167
+ if (!stackId && projectId) {
168
+ try {
169
+ // try to assume project-based stack if no stackId is provided
170
+ stackId = await backfillProjectBasedStackId({
171
+ blueprintFilePath: foundFilePath,
172
+ projectId,
173
+ });
174
+ }
175
+ catch {
176
+ // our assumption was wrong, so we'll leave stackId undefined
177
+ }
178
+ }
169
179
  let scopeType;
170
180
  let scopeId;
171
181
  // Scope is as specific as possible; project > organization
@@ -189,6 +199,7 @@ export async function readLocalBlueprint(blueprintPath) {
189
199
  }
190
200
  return {
191
201
  fileInfo: { blueprintFilePath: foundFilePath, fileName, extension },
202
+ blueprintConfig,
192
203
  rawBlueprint,
193
204
  errors,
194
205
  scopeType,
@@ -196,7 +207,8 @@ export async function readLocalBlueprint(blueprintPath) {
196
207
  organizationId,
197
208
  projectId,
198
209
  stackId,
199
- configPath,
210
+ /** @deprecated */
211
+ configPath: blueprintConfig?.configPath,
200
212
  // fallback to the raw blueprint if the parser found errors
201
213
  parsedBlueprint: parsedBlueprint || rawBlueprint,
202
214
  };
@@ -1,11 +1,27 @@
1
- export interface BlueprintsConfig {
2
- configPath: string;
1
+ import { BLUEPRINT_CONFIG_VERSION, RUNTIME_CLI_VERSION } from '../../config.js';
2
+ export interface ConfigUpdate {
3
3
  organizationId?: string;
4
4
  projectId?: string;
5
5
  stackId?: string;
6
6
  }
7
+ export interface BlueprintsConfig extends ConfigUpdate {
8
+ configPath: string;
9
+ blueprintConfigVersion?: typeof BLUEPRINT_CONFIG_VERSION;
10
+ runtimeCliVersion?: typeof RUNTIME_CLI_VERSION;
11
+ updatedAt?: number;
12
+ }
7
13
  export declare function readConfigFile(blueprintFilePath?: string): BlueprintsConfig | null;
8
- export declare function writeConfigFile({ blueprintFilePath, organizationId, projectId, stackId, }: {
14
+ /**
15
+ * Create or update the config file to disk.
16
+ * One of organizationId or projectId must be provided. Not both.
17
+ * Blueprint config version and updatedAt timestamp are set automatically.
18
+ * @param options - the options to write the config file
19
+ * @param options.blueprintFilePath - the path to the blueprint file
20
+ * @param options.organizationId - the organization ID
21
+ * @param options.projectId - the project ID
22
+ * @param options.stackId - the stack ID
23
+ */
24
+ export declare function writeConfigFile(options: {
9
25
  blueprintFilePath?: string;
10
26
  stackId?: string;
11
27
  } & ({
@@ -15,6 +31,17 @@ export declare function writeConfigFile({ blueprintFilePath, organizationId, pro
15
31
  projectId: string;
16
32
  organizationId?: string;
17
33
  })): void;
34
+ /**
35
+ * Update the config file with the given properties.
36
+ * Config file must already exist.
37
+ * Adds timestamp. No validation or transformation is performed.
38
+ * @param blueprintFilePath - the path to the blueprint file
39
+ * @param updateableProperties - the properties to update
40
+ * @param updateableProperties.organizationId - the organization ID
41
+ * @param updateableProperties.projectId - the project ID
42
+ * @param updateableProperties.stackId - the stack ID
43
+ */
44
+ export declare function patchConfigFile(blueprintFilePath: string, updateableProperties: ConfigUpdate): void;
18
45
  /**
19
46
  * Find and write an organizationId to the config file by getting it from the projectId
20
47
  * @throws {Error} if unable to fetch project
@@ -24,3 +51,7 @@ export declare function backfillOrganizationId({ blueprintFilePath, projectId, }
24
51
  blueprintFilePath: string;
25
52
  projectId: string;
26
53
  }): Promise<string>;
54
+ export declare function backfillProjectBasedStackId({ blueprintFilePath, projectId, }: {
55
+ blueprintFilePath: string;
56
+ projectId: string;
57
+ }): Promise<string | undefined>;
@@ -1,11 +1,12 @@
1
1
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
2
2
  import { dirname, join } from 'node:path';
3
3
  import { cwd } from 'node:process';
4
- import config, { BLUEPRINT_CONFIG_FILE, BLUEPRINT_CONFIG_VERSION, BLUEPRINT_DIR, } from '../../config.js';
4
+ import config, { BLUEPRINT_CONFIG_DIR, BLUEPRINT_CONFIG_FILE, BLUEPRINT_CONFIG_VERSION, RUNTIME_CLI_VERSION, } from '../../config.js';
5
5
  import { getProject } from '../sanity/projects.js';
6
+ import { listStacks } from './stacks.js';
6
7
  export function readConfigFile(blueprintFilePath) {
7
8
  const blueprintDir = blueprintFilePath ? dirname(blueprintFilePath) : cwd();
8
- const configPath = join(blueprintDir, BLUEPRINT_DIR, BLUEPRINT_CONFIG_FILE);
9
+ const configPath = join(blueprintDir, BLUEPRINT_CONFIG_DIR, BLUEPRINT_CONFIG_FILE);
9
10
  if (existsSync(configPath)) {
10
11
  try {
11
12
  const config = JSON.parse(readFileSync(configPath, 'utf8'));
@@ -17,22 +18,27 @@ export function readConfigFile(blueprintFilePath) {
17
18
  }
18
19
  return null;
19
20
  }
20
- export function writeConfigFile({ blueprintFilePath, organizationId, projectId, stackId, }) {
21
+ /**
22
+ * Create or update the config file to disk.
23
+ * One of organizationId or projectId must be provided. Not both.
24
+ * Blueprint config version and updatedAt timestamp are set automatically.
25
+ * @param options - the options to write the config file
26
+ * @param options.blueprintFilePath - the path to the blueprint file
27
+ * @param options.organizationId - the organization ID
28
+ * @param options.projectId - the project ID
29
+ * @param options.stackId - the stack ID
30
+ */
31
+ export function writeConfigFile(options) {
32
+ const { blueprintFilePath, organizationId, projectId, stackId } = options;
21
33
  const blueprintDir = blueprintFilePath ? dirname(blueprintFilePath) : cwd();
22
- const configDir = join(blueprintDir, BLUEPRINT_DIR);
34
+ const configDir = join(blueprintDir, BLUEPRINT_CONFIG_DIR);
23
35
  const configPath = join(configDir, BLUEPRINT_CONFIG_FILE);
24
- if (!existsSync(configDir)) {
36
+ if (!existsSync(configDir))
25
37
  mkdirSync(configDir, { recursive: true });
26
- }
27
38
  let config = {};
28
- if (existsSync(configPath)) {
29
- try {
30
- config = JSON.parse(readFileSync(configPath, 'utf8'));
31
- }
32
- catch {
33
- // config broken, start fresh
34
- }
35
- }
39
+ const existingConfig = readConfigFile(configPath);
40
+ if (existingConfig)
41
+ config = existingConfig;
36
42
  if (organizationId)
37
43
  config.organizationId = organizationId;
38
44
  if (projectId)
@@ -40,9 +46,34 @@ export function writeConfigFile({ blueprintFilePath, organizationId, projectId,
40
46
  if (stackId)
41
47
  config.stackId = stackId;
42
48
  config.blueprintConfigVersion = BLUEPRINT_CONFIG_VERSION;
49
+ config.runtimeCliVersion = RUNTIME_CLI_VERSION;
43
50
  config.updatedAt = Date.now();
44
51
  writeFileSync(configPath, JSON.stringify(config, null, 2));
45
52
  }
53
+ /**
54
+ * Update the config file with the given properties.
55
+ * Config file must already exist.
56
+ * Adds timestamp. No validation or transformation is performed.
57
+ * @param blueprintFilePath - the path to the blueprint file
58
+ * @param updateableProperties - the properties to update
59
+ * @param updateableProperties.organizationId - the organization ID
60
+ * @param updateableProperties.projectId - the project ID
61
+ * @param updateableProperties.stackId - the stack ID
62
+ */
63
+ export function patchConfigFile(blueprintFilePath, updateableProperties) {
64
+ const existingConfig = readConfigFile(blueprintFilePath);
65
+ if (!existingConfig)
66
+ throw new Error('No config file found');
67
+ const { configPath, ...existingConfigProperties } = existingConfig;
68
+ const newConfig = {
69
+ blueprintConfigVersion: BLUEPRINT_CONFIG_VERSION, // don't overwrite the version
70
+ ...existingConfigProperties,
71
+ ...updateableProperties,
72
+ updatedAt: Date.now(),
73
+ runtimeCliVersion: RUNTIME_CLI_VERSION,
74
+ };
75
+ writeFileSync(configPath, JSON.stringify(newConfig, null, 2));
76
+ }
46
77
  /**
47
78
  * Find and write an organizationId to the config file by getting it from the projectId
48
79
  * @throws {Error} if unable to fetch project
@@ -69,3 +100,25 @@ export async function backfillOrganizationId({ blueprintFilePath, projectId, })
69
100
  writeConfigFile({ blueprintFilePath, organizationId });
70
101
  return organizationId;
71
102
  }
103
+ export async function backfillProjectBasedStackId({ blueprintFilePath, projectId, }) {
104
+ const token = config.token;
105
+ if (!token)
106
+ throw new Error('No token found');
107
+ const possibleStackId = `ST-${projectId}`;
108
+ // get stack count, if 1 and it's project-based, use it
109
+ const { ok, stacks, error } = await listStacks({
110
+ token,
111
+ scopeType: 'project',
112
+ scopeId: projectId,
113
+ });
114
+ if (!ok)
115
+ throw new Error(error || 'Failed to list stacks');
116
+ if (stacks.length === 1 &&
117
+ stacks[0].scopeType === 'project' &&
118
+ stacks[0].id === possibleStackId) {
119
+ // jackpot
120
+ writeConfigFile({ blueprintFilePath, projectId, stackId: possibleStackId });
121
+ return possibleStackId;
122
+ }
123
+ return undefined;
124
+ }
@@ -25,12 +25,11 @@ export declare function createStack({ stackMutation, auth, }: {
25
25
  stackMutation: StackMutation;
26
26
  auth: AuthParams;
27
27
  }): Promise<CreateStackResponse>;
28
- export declare function createEmptyStack({ token, scopeType, scopeId, name, projectBased, }: {
28
+ export declare function createEmptyStack({ token, scopeType, scopeId, name, }: {
29
29
  token: string;
30
30
  scopeType: ScopeType;
31
31
  scopeId: string;
32
32
  name: string;
33
- projectBased?: boolean;
34
33
  }): Promise<Stack>;
35
34
  interface UpdateStackResponse {
36
35
  ok: boolean;
@@ -57,7 +57,7 @@ export async function createStack({ stackMutation, auth, }) {
57
57
  const response = await fetch(stacksUrl, {
58
58
  method: 'POST',
59
59
  headers: getHeaders(auth),
60
- body: JSON.stringify(stackMutation),
60
+ body: JSON.stringify({ ...stackMutation, useProjectBasedId: false }), // API defaults to true as of 2025-11-26
61
61
  });
62
62
  const data = await response.json();
63
63
  return {
@@ -66,12 +66,11 @@ export async function createStack({ stackMutation, auth, }) {
66
66
  stack: response.ok ? flattenStackResources(data) : data,
67
67
  };
68
68
  }
69
- export async function createEmptyStack({ token, scopeType, scopeId, name, projectBased = true, }) {
69
+ export async function createEmptyStack({ token, scopeType, scopeId, name, }) {
70
70
  const stackMutation = {
71
71
  name,
72
72
  scopeType,
73
73
  scopeId,
74
- useProjectBasedId: projectBased,
75
74
  document: { resources: [] },
76
75
  };
77
76
  const response = await createStack({
@@ -3,7 +3,6 @@ export default class ConfigCommand extends BlueprintCommand<typeof ConfigCommand
3
3
  static description: string;
4
4
  static examples: string[];
5
5
  static flags: {
6
- 'test-config': import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
6
  edit: import("@oclif/core/interfaces").BooleanFlag<boolean>;
8
7
  'project-id': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
9
8
  'organization-id': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
@@ -5,36 +5,28 @@ export default class ConfigCommand extends BlueprintCommand {
5
5
  static description = 'View or edit Blueprint configuration';
6
6
  static examples = [
7
7
  '<%= config.bin %> <%= command.id %>',
8
- '<%= config.bin %> <%= command.id %> --test-config',
9
8
  '<%= config.bin %> <%= command.id %> --edit',
10
9
  '<%= config.bin %> <%= command.id %> --edit --project-id <projectId>',
11
10
  '<%= config.bin %> <%= command.id %> --edit --project-id <projectId> --stack-id <stackId>',
12
11
  ];
13
12
  static flags = {
14
- 'test-config': Flags.boolean({
15
- char: 't',
16
- aliases: ['test', 'validate'],
17
- description: 'Validate the configuration',
18
- default: false,
19
- deprecated: true,
20
- }),
21
13
  edit: Flags.boolean({
22
14
  char: 'e',
23
- description: 'Edit the configuration',
15
+ description: 'Modify the configuration interactively, or directly when combined with ID flags.',
24
16
  default: false,
25
17
  }),
26
18
  'project-id': Flags.string({
27
- description: 'Update the Project ID in the configuration. Requires --edit flag',
19
+ description: 'Directly set the Project ID in the configuration. Requires --edit flag',
28
20
  aliases: ['project', 'projectId'],
29
21
  dependsOn: ['edit'],
30
22
  }),
31
23
  'organization-id': Flags.string({
32
- description: 'Update the Organization ID in the configuration. Requires --edit flag',
24
+ description: 'Directly set the Organization ID in the configuration. Requires --edit flag',
33
25
  aliases: ['organization', 'organizationId', 'org'],
34
26
  dependsOn: ['edit'],
35
27
  }),
36
28
  'stack-id': Flags.string({
37
- description: 'Update the Stack ID in the configuration. Requires --edit flag',
29
+ description: 'Directly set the Stack ID in the configuration. Requires --edit flag',
38
30
  aliases: ['stack', 'stackId'],
39
31
  dependsOn: ['edit'],
40
32
  }),
@@ -9,7 +9,7 @@ export default class DeployCommand extends DeployedBlueprintCommand {
9
9
  ];
10
10
  static flags = {
11
11
  'no-wait': Flags.boolean({
12
- description: 'Do not wait for deployment to complete',
12
+ description: 'Do not wait for Stack deployment to complete',
13
13
  default: false,
14
14
  }),
15
15
  };