@sanity/runtime-cli 3.1.0 → 4.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.
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/3.1.0 linux-x64 node-v22.14.0
23
+ @sanity/runtime-cli/4.0.0 linux-x64 node-v22.14.0
24
24
  $ sanity-run --help [COMMAND]
25
25
  USAGE
26
26
  $ sanity-run COMMAND
@@ -32,6 +32,7 @@ USAGE
32
32
  * [`sanity-run blueprints add TYPE`](#sanity-run-blueprints-add-type)
33
33
  * [`sanity-run blueprints config`](#sanity-run-blueprints-config)
34
34
  * [`sanity-run blueprints deploy`](#sanity-run-blueprints-deploy)
35
+ * [`sanity-run blueprints destroy`](#sanity-run-blueprints-destroy)
35
36
  * [`sanity-run blueprints info`](#sanity-run-blueprints-info)
36
37
  * [`sanity-run blueprints init`](#sanity-run-blueprints-init)
37
38
  * [`sanity-run blueprints logs`](#sanity-run-blueprints-logs)
@@ -63,7 +64,7 @@ EXAMPLES
63
64
  $ sanity-run blueprints add function
64
65
  ```
65
66
 
66
- _See code: [src/commands/blueprints/add.ts](https://github.com/sanity-io/runtime-cli/blob/v3.1.0/src/commands/blueprints/add.ts)_
67
+ _See code: [src/commands/blueprints/add.ts](https://github.com/sanity-io/runtime-cli/blob/v4.0.0/src/commands/blueprints/add.ts)_
67
68
 
68
69
  ## `sanity-run blueprints config`
69
70
 
@@ -85,7 +86,7 @@ EXAMPLES
85
86
  $ sanity-run blueprints config --edit
86
87
  ```
87
88
 
88
- _See code: [src/commands/blueprints/config.ts](https://github.com/sanity-io/runtime-cli/blob/v3.1.0/src/commands/blueprints/config.ts)_
89
+ _See code: [src/commands/blueprints/config.ts](https://github.com/sanity-io/runtime-cli/blob/v4.0.0/src/commands/blueprints/config.ts)_
89
90
 
90
91
  ## `sanity-run blueprints deploy`
91
92
 
@@ -93,7 +94,10 @@ Deploy a Blueprint
93
94
 
94
95
  ```
95
96
  USAGE
96
- $ sanity-run blueprints deploy
97
+ $ sanity-run blueprints deploy [--no-wait]
98
+
99
+ FLAGS
100
+ --no-wait Do not wait for deployment to complete
97
101
 
98
102
  DESCRIPTION
99
103
  Deploy a Blueprint
@@ -102,11 +106,34 @@ EXAMPLES
102
106
  $ sanity-run blueprints deploy
103
107
  ```
104
108
 
105
- _See code: [src/commands/blueprints/deploy.ts](https://github.com/sanity-io/runtime-cli/blob/v3.1.0/src/commands/blueprints/deploy.ts)_
109
+ _See code: [src/commands/blueprints/deploy.ts](https://github.com/sanity-io/runtime-cli/blob/v4.0.0/src/commands/blueprints/deploy.ts)_
110
+
111
+ ## `sanity-run blueprints destroy`
112
+
113
+ Destroy a deployed Blueprint Stack
114
+
115
+ ```
116
+ USAGE
117
+ $ sanity-run blueprints destroy [--id <value>] [--force]
118
+
119
+ FLAGS
120
+ --force Force destroy (skip confirmation)
121
+ --id=<value> Stack ID to destroy (defaults to current Stack)
122
+
123
+ DESCRIPTION
124
+ Destroy a deployed Blueprint Stack
125
+
126
+ EXAMPLES
127
+ $ sanity-run blueprints destroy
128
+
129
+ $ sanity-run blueprints destroy --id ST-a1b2c3
130
+ ```
131
+
132
+ _See code: [src/commands/blueprints/destroy.ts](https://github.com/sanity-io/runtime-cli/blob/v4.0.0/src/commands/blueprints/destroy.ts)_
106
133
 
107
134
  ## `sanity-run blueprints info`
108
135
 
109
- Show information about a Blueprint
136
+ Show information about a deployed Blueprint Stack
110
137
 
111
138
  ```
112
139
  USAGE
@@ -116,15 +143,15 @@ FLAGS
116
143
  --id=<value> Stack ID to show info for (defaults to current stack)
117
144
 
118
145
  DESCRIPTION
119
- Show information about a Blueprint
146
+ Show information about a deployed Blueprint Stack
120
147
 
121
148
  EXAMPLES
122
149
  $ sanity-run blueprints info
123
150
 
124
- $ sanity-run blueprints info --id abc123
151
+ $ sanity-run blueprints info --id ST-a1b2c3
125
152
  ```
126
153
 
127
- _See code: [src/commands/blueprints/info.ts](https://github.com/sanity-io/runtime-cli/blob/v3.1.0/src/commands/blueprints/info.ts)_
154
+ _See code: [src/commands/blueprints/info.ts](https://github.com/sanity-io/runtime-cli/blob/v4.0.0/src/commands/blueprints/info.ts)_
128
155
 
129
156
  ## `sanity-run blueprints init`
130
157
 
@@ -141,7 +168,7 @@ EXAMPLES
141
168
  $ sanity-run blueprints init
142
169
  ```
143
170
 
144
- _See code: [src/commands/blueprints/init.ts](https://github.com/sanity-io/runtime-cli/blob/v3.1.0/src/commands/blueprints/init.ts)_
171
+ _See code: [src/commands/blueprints/init.ts](https://github.com/sanity-io/runtime-cli/blob/v4.0.0/src/commands/blueprints/init.ts)_
145
172
 
146
173
  ## `sanity-run blueprints logs`
147
174
 
@@ -163,7 +190,7 @@ EXAMPLES
163
190
  $ sanity-run blueprints logs --watch
164
191
  ```
165
192
 
166
- _See code: [src/commands/blueprints/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v3.1.0/src/commands/blueprints/logs.ts)_
193
+ _See code: [src/commands/blueprints/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v4.0.0/src/commands/blueprints/logs.ts)_
167
194
 
168
195
  ## `sanity-run blueprints plan`
169
196
 
@@ -180,7 +207,7 @@ EXAMPLES
180
207
  $ sanity-run blueprints plan
181
208
  ```
182
209
 
183
- _See code: [src/commands/blueprints/plan.ts](https://github.com/sanity-io/runtime-cli/blob/v3.1.0/src/commands/blueprints/plan.ts)_
210
+ _See code: [src/commands/blueprints/plan.ts](https://github.com/sanity-io/runtime-cli/blob/v4.0.0/src/commands/blueprints/plan.ts)_
184
211
 
185
212
  ## `sanity-run blueprints stacks`
186
213
 
@@ -188,16 +215,21 @@ List all Blueprint stacks
188
215
 
189
216
  ```
190
217
  USAGE
191
- $ sanity-run blueprints stacks
218
+ $ sanity-run blueprints stacks [--projectId <value>]
219
+
220
+ FLAGS
221
+ --projectId=<value> Project ID to show stacks for
192
222
 
193
223
  DESCRIPTION
194
224
  List all Blueprint stacks
195
225
 
196
226
  EXAMPLES
197
227
  $ sanity-run blueprints stacks
228
+
229
+ $ sanity-run blueprints stacks --projectId a1b2c3
198
230
  ```
199
231
 
200
- _See code: [src/commands/blueprints/stacks.ts](https://github.com/sanity-io/runtime-cli/blob/v3.1.0/src/commands/blueprints/stacks.ts)_
232
+ _See code: [src/commands/blueprints/stacks.ts](https://github.com/sanity-io/runtime-cli/blob/v4.0.0/src/commands/blueprints/stacks.ts)_
201
233
 
202
234
  ## `sanity-run functions dev`
203
235
 
@@ -217,7 +249,7 @@ EXAMPLES
217
249
  $ sanity-run functions dev --port 8974
218
250
  ```
219
251
 
220
- _See code: [src/commands/functions/dev.ts](https://github.com/sanity-io/runtime-cli/blob/v3.1.0/src/commands/functions/dev.ts)_
252
+ _See code: [src/commands/functions/dev.ts](https://github.com/sanity-io/runtime-cli/blob/v4.0.0/src/commands/functions/dev.ts)_
221
253
 
222
254
  ## `sanity-run functions env add NAME KEY VALUE`
223
255
 
@@ -239,7 +271,7 @@ EXAMPLES
239
271
  $ sanity-run functions env add MyFunction API_URL https://api.example.com/
240
272
  ```
241
273
 
242
- _See code: [src/commands/functions/env/add.ts](https://github.com/sanity-io/runtime-cli/blob/v3.1.0/src/commands/functions/env/add.ts)_
274
+ _See code: [src/commands/functions/env/add.ts](https://github.com/sanity-io/runtime-cli/blob/v4.0.0/src/commands/functions/env/add.ts)_
243
275
 
244
276
  ## `sanity-run functions env remove NAME KEY`
245
277
 
@@ -260,7 +292,7 @@ EXAMPLES
260
292
  $ sanity-run functions env remove MyFunction API_URL
261
293
  ```
262
294
 
263
- _See code: [src/commands/functions/env/remove.ts](https://github.com/sanity-io/runtime-cli/blob/v3.1.0/src/commands/functions/env/remove.ts)_
295
+ _See code: [src/commands/functions/env/remove.ts](https://github.com/sanity-io/runtime-cli/blob/v4.0.0/src/commands/functions/env/remove.ts)_
264
296
 
265
297
  ## `sanity-run functions invoke NAME`
266
298
 
@@ -286,7 +318,7 @@ EXAMPLES
286
318
  $ sanity-run functions invoke <name> --file 'payload.json'
287
319
  ```
288
320
 
289
- _See code: [src/commands/functions/invoke.ts](https://github.com/sanity-io/runtime-cli/blob/v3.1.0/src/commands/functions/invoke.ts)_
321
+ _See code: [src/commands/functions/invoke.ts](https://github.com/sanity-io/runtime-cli/blob/v4.0.0/src/commands/functions/invoke.ts)_
290
322
 
291
323
  ## `sanity-run functions logs NAME`
292
324
 
@@ -318,7 +350,7 @@ EXAMPLES
318
350
  $ sanity-run functions logs <name> --delete
319
351
  ```
320
352
 
321
- _See code: [src/commands/functions/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v3.1.0/src/commands/functions/logs.ts)_
353
+ _See code: [src/commands/functions/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v4.0.0/src/commands/functions/logs.ts)_
322
354
 
323
355
  ## `sanity-run functions test NAME`
324
356
 
@@ -351,7 +383,7 @@ EXAMPLES
351
383
  $ sanity-run functions test <name> --data '{ "id": 1 }' --timeout 60
352
384
  ```
353
385
 
354
- _See code: [src/commands/functions/test.ts](https://github.com/sanity-io/runtime-cli/blob/v3.1.0/src/commands/functions/test.ts)_
386
+ _See code: [src/commands/functions/test.ts](https://github.com/sanity-io/runtime-cli/blob/v4.0.0/src/commands/functions/test.ts)_
355
387
 
356
388
  ## `sanity-run help [COMMAND]`
357
389
 
@@ -1,45 +1,52 @@
1
1
  import type { BlueprintParserError, LocalBlueprint, LocalResource, Stack } from '../../utils/types.js';
2
- export declare const DEFAULT_BLUEPRINT_CONTENT: {
3
- blueprintVersion: string;
4
- resources: never[];
5
- };
2
+ declare const SUPPORTED_FILE_EXTENSIONS: readonly [".json", ".js", ".mjs", ".cjs", ".ts"];
3
+ type BlueprintFileExtension = (typeof SUPPORTED_FILE_EXTENSIONS)[number];
4
+ export declare const DEFAULT_BLUEPRINT_CONTENT: LocalBlueprint;
6
5
  /**
7
6
  * Finds the blueprint file in the given path or current working directory
8
7
  * @param blueprintFilePath - The full path of the blueprint file
9
8
  * @returns The path, file name, and extension of the blueprint file
10
9
  */
11
10
  export declare function findBlueprintFile(blueprintFilePath?: string): {
12
- path: string;
11
+ blueprintFilePath: string;
13
12
  fileName: string;
14
- extension: string;
13
+ extension: BlueprintFileExtension;
15
14
  } | null;
16
- export declare function readBlueprintOnDisk({ blueprintPath, getStack, token, }?: {
17
- blueprintPath?: string;
15
+ /**
16
+ * Reads the blueprint file from disk and parses it
17
+ * @todo rename to loadBlueprint or similar
18
+ * @todo extract "getStack" into a separate function
19
+ * @returns Known information about the Blueprint, config, and Stack
20
+ */
21
+ export declare function readBlueprintOnDisk({ blueprintFilePath, getStack, token, }?: {
22
+ blueprintFilePath?: string;
18
23
  getStack?: boolean;
19
24
  token?: string;
20
25
  }): Promise<{
21
26
  fileInfo: {
22
- path: string;
27
+ blueprintFilePath: string;
23
28
  fileName: string;
24
29
  extension: string;
25
30
  };
31
+ rawBlueprint: LocalBlueprint;
26
32
  parsedBlueprint: LocalBlueprint;
27
33
  errors: BlueprintParserError[];
34
+ configPath?: string;
28
35
  projectId?: string;
29
36
  stackId?: string;
30
37
  deployedStack?: Stack;
31
38
  }>;
32
- export declare function writeBlueprintToDisk({ path, fileType, content, }: {
33
- path: string;
34
- fileType: 'json' | 'js' | 'ts';
35
- content?: Record<string, unknown>;
39
+ export declare function writeBlueprintToDisk({ blueprintFilePath, content, }: {
40
+ blueprintFilePath: string;
41
+ content?: LocalBlueprint;
36
42
  }): string;
37
- export declare function readConfigFile(blueprintPath?: string | undefined): {
43
+ export declare function readConfigFile(blueprintFilePath?: string | undefined): {
44
+ configPath?: string;
38
45
  projectId?: string;
39
46
  stackId?: string;
40
47
  } | null;
41
- export declare function writeConfigFile({ blueprintPath, projectId, stackId, }: {
42
- blueprintPath?: string;
48
+ export declare function writeConfigFile({ blueprintFilePath, projectId, stackId, }: {
49
+ blueprintFilePath?: string;
43
50
  projectId: string;
44
51
  stackId?: string;
45
52
  }): void;
@@ -47,3 +54,12 @@ export declare function addResourceToBlueprint({ blueprintFilePath, resource, }:
47
54
  blueprintFilePath?: string;
48
55
  resource: LocalResource;
49
56
  }): LocalResource | undefined;
57
+ export declare function updateBlueprintMetadata({ blueprintFilePath, metadata, }: {
58
+ blueprintFilePath?: string;
59
+ metadata: LocalBlueprint['metadata'];
60
+ }): void;
61
+ export declare function updateBlueprintValues({ blueprintFilePath, values, }: {
62
+ blueprintFilePath: string;
63
+ values: LocalBlueprint['values'];
64
+ }): void;
65
+ export {};
@@ -1,17 +1,11 @@
1
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
1
+ import { existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from 'node:fs';
2
2
  import { createRequire } from 'node:module';
3
- import { dirname, extname, join } from 'node:path';
3
+ import { basename, dirname, extname, join } from 'node:path';
4
4
  import { cwd } from 'node:process';
5
- import { BlueprintParserErrorType } from '../../utils/types.js';
6
5
  import { blueprintParserValidator } from '../../utils/vendor/parser-validator.js';
7
6
  import { getStack as getStackById } from './stacks.js';
8
- const SUPPORTED_FILE_NAMES_IN_PRIORITY_ORDER = [
9
- 'blueprint.json',
10
- 'blueprint.js',
11
- 'blueprint.mjs',
12
- 'blueprint.cjs',
13
- 'blueprint.ts',
14
- ];
7
+ const SUPPORTED_FILE_EXTENSIONS = ['.json', '.js', '.mjs', '.cjs', '.ts'];
8
+ const SUPPORTED_FILE_NAMES_IN_PRIORITY_ORDER = SUPPORTED_FILE_EXTENSIONS.map((ext) => `blueprint${ext}`);
15
9
  export const DEFAULT_BLUEPRINT_CONTENT = {
16
10
  blueprintVersion: '2024-10-01',
17
11
  resources: [],
@@ -22,55 +16,73 @@ export const DEFAULT_BLUEPRINT_CONTENT = {
22
16
  * @returns The path, file name, and extension of the blueprint file
23
17
  */
24
18
  export function findBlueprintFile(blueprintFilePath) {
19
+ let dirToSearch = cwd();
25
20
  if (blueprintFilePath) {
26
- if (existsSync(blueprintFilePath)) {
27
- return {
28
- path: blueprintFilePath,
29
- fileName: blueprintFilePath,
30
- extension: extname(blueprintFilePath),
31
- };
21
+ try {
22
+ const stat = statSync(blueprintFilePath);
23
+ if (stat.isFile()) {
24
+ return {
25
+ blueprintFilePath: blueprintFilePath,
26
+ fileName: basename(blueprintFilePath),
27
+ extension: extname(blueprintFilePath),
28
+ };
29
+ }
30
+ if (stat.isDirectory()) {
31
+ dirToSearch = blueprintFilePath;
32
+ }
33
+ }
34
+ catch {
35
+ throw Error(`Blueprint file not found: ${blueprintFilePath}`);
32
36
  }
33
- throw Error(`Blueprint file not found: ${blueprintFilePath}`);
34
37
  }
35
38
  for (const fileName of SUPPORTED_FILE_NAMES_IN_PRIORITY_ORDER) {
36
- const filePath = join(cwd(), fileName);
39
+ const filePath = join(dirToSearch, fileName);
37
40
  if (existsSync(filePath)) {
38
- return { path: filePath, fileName, extension: extname(filePath) };
41
+ return {
42
+ blueprintFilePath: filePath,
43
+ fileName,
44
+ extension: extname(filePath),
45
+ };
39
46
  }
40
47
  }
41
48
  return null;
42
49
  }
43
- export async function readBlueprintOnDisk({ blueprintPath, getStack, token, } = {}) {
50
+ /**
51
+ * Reads the blueprint file from disk and parses it
52
+ * @todo rename to loadBlueprint or similar
53
+ * @todo extract "getStack" into a separate function
54
+ * @returns Known information about the Blueprint, config, and Stack
55
+ */
56
+ export async function readBlueprintOnDisk({ blueprintFilePath, getStack, token, } = {}) {
57
+ const blueprintFile = findBlueprintFile(blueprintFilePath);
58
+ if (!blueprintFile)
59
+ throw Error('Could not find Blueprint file! Use the init command.');
60
+ const { blueprintFilePath: foundPath, fileName, extension } = blueprintFile;
61
+ let rawBlueprint;
62
+ let blueprintModule;
44
63
  try {
45
- const blueprintFile = findBlueprintFile(blueprintPath);
46
- if (!blueprintFile)
47
- throw Error('Could not find Blueprint file! Use the init command.');
48
- const { path, fileName, extension } = blueprintFile;
49
- let blueprintString;
50
- let blueprintJson;
51
- let blueprintModule;
52
64
  switch (extension) {
53
65
  case '.json': {
54
- blueprintString = readFileSync(path, 'utf8').toString();
55
- blueprintJson = JSON.parse(blueprintString);
66
+ const blueprintString = readFileSync(foundPath, 'utf8').toString();
67
+ rawBlueprint = JSON.parse(blueprintString);
56
68
  break;
57
69
  }
58
70
  case '.js':
59
71
  case '.mjs': {
60
- const module = await import(path);
72
+ const module = await import(foundPath);
61
73
  blueprintModule = module.default;
62
74
  break;
63
75
  }
64
76
  case '.cjs': {
65
77
  const require = createRequire(import.meta.url);
66
- blueprintModule = require(path);
78
+ blueprintModule = require(foundPath);
67
79
  break;
68
80
  }
69
81
  case '.ts': {
70
82
  console.warn('\x1b[2mSupport for Typescript blueprints is experimental.\x1b[0m');
71
83
  try {
72
84
  const { tsImport } = await import('tsx/esm/api');
73
- const module = await tsImport(path, dirname(path));
85
+ const module = await tsImport(foundPath, dirname(foundPath));
74
86
  blueprintModule = module.default;
75
87
  }
76
88
  catch (err) {
@@ -84,95 +96,108 @@ export async function readBlueprintOnDisk({ blueprintPath, getStack, token, } =
84
96
  default:
85
97
  throw Error(`Unsupported blueprint file extension: ${extension}`);
86
98
  }
87
- if (blueprintModule) {
88
- if (typeof blueprintModule !== 'function')
89
- throw Error(`Blueprint ${fileName} must export a default function`);
90
- blueprintJson = blueprintModule();
91
- }
92
- const parserResult = blueprintParserValidator(blueprintJson);
93
- const { blueprint: parsedBlueprint } = parserResult;
94
- const errors = parserResult.errors || [];
95
- // find project and stack IDs from .blueprint/config.json first,
96
- // then fallback to metadata in blueprint file,
97
- // finally fallback to resources array...
98
- let projectId;
99
- let stackId;
100
- const configIds = readConfigFile(blueprintPath);
101
- const blueprintMetadata = parsedBlueprint.metadata;
102
- // find/create project resource
103
- if (configIds?.projectId) {
104
- projectId = configIds.projectId;
105
- }
106
- else if (blueprintMetadata?.projectId) {
107
- projectId = blueprintMetadata.projectId;
108
- }
109
- else {
110
- const projectResource = parsedBlueprint.resources.find((r) => r.type === 'sanity.project');
111
- if (projectResource)
112
- projectId = projectResource.id;
113
- }
114
- // find/create stack resource
115
- if (configIds?.stackId) {
116
- stackId = configIds.stackId;
117
- }
118
- else if (blueprintMetadata?.stackId) {
119
- stackId = blueprintMetadata.stackId;
120
- }
121
- else {
122
- const stackResource = parsedBlueprint.resources.find((r) => r.type === 'sanity.blueprints.stack');
123
- if (stackResource)
124
- stackId = stackResource.id;
99
+ }
100
+ catch {
101
+ throw Error(`Error parsing Blueprint file: ${fileName}`);
102
+ }
103
+ if (blueprintModule) {
104
+ if (typeof blueprintModule !== 'function')
105
+ throw Error(`Blueprint ${fileName} must export a default function`);
106
+ try {
107
+ rawBlueprint = blueprintModule();
125
108
  }
126
- let deployedStack;
127
- if (getStack && token && stackId && projectId) {
128
- const { stack } = await getStackById({ stackId, auth: { token, projectId } });
129
- if (!stack) {
130
- errors.push({
131
- message: 'Stack not found',
132
- type: BlueprintParserErrorType.InvalidStack,
133
- });
134
- }
135
- deployedStack = stack;
109
+ catch (err) {
110
+ throw Error(`Error executing Blueprint file: ${fileName}`);
136
111
  }
137
- return {
138
- fileInfo: { path, fileName, extension },
139
- errors,
140
- projectId,
141
- stackId,
142
- deployedStack,
143
- parsedBlueprint,
144
- };
145
112
  }
146
- catch (err) {
147
- throw Error(`Unable to parse Blueprint file: ${err}`);
113
+ const parserResult = blueprintParserValidator(rawBlueprint);
114
+ const { blueprint: parsedBlueprint } = parserResult;
115
+ const errors = parserResult.errors || [];
116
+ const configIds = readConfigFile(foundPath);
117
+ const configPath = configIds?.configPath;
118
+ const blueprintMetadata = parsedBlueprint.metadata;
119
+ // find/create project resource
120
+ let projectId;
121
+ if (configIds?.projectId) {
122
+ projectId = configIds.projectId;
123
+ }
124
+ else if (blueprintMetadata?.projectId) {
125
+ projectId = blueprintMetadata.projectId;
148
126
  }
127
+ else {
128
+ const projectResource = parsedBlueprint.resources.find((r) => r.type === 'sanity.project');
129
+ if (projectResource)
130
+ projectId = projectResource.id;
131
+ }
132
+ // find/create stack resource
133
+ let stackId;
134
+ if (configIds?.stackId) {
135
+ stackId = configIds.stackId;
136
+ }
137
+ else if (blueprintMetadata?.stackId) {
138
+ stackId = blueprintMetadata.stackId;
139
+ }
140
+ else {
141
+ const stackResource = parsedBlueprint.resources.find((r) => r.type === 'sanity.blueprints.stack');
142
+ if (stackResource)
143
+ stackId = stackResource.id;
144
+ }
145
+ let deployedStack;
146
+ if (getStack && token && stackId && projectId) {
147
+ const { stack, ok, error } = await getStackById({ stackId, auth: { token, projectId } });
148
+ if (!ok) {
149
+ throw Error(error || 'Unable to retrieve Stack');
150
+ }
151
+ deployedStack = stack;
152
+ }
153
+ return {
154
+ fileInfo: { blueprintFilePath: foundPath, fileName, extension },
155
+ rawBlueprint: rawBlueprint,
156
+ errors,
157
+ projectId,
158
+ stackId,
159
+ configPath,
160
+ deployedStack,
161
+ parsedBlueprint,
162
+ };
149
163
  }
150
- export function writeBlueprintToDisk({ path, fileType, content = DEFAULT_BLUEPRINT_CONTENT, }) {
164
+ export function writeBlueprintToDisk({ blueprintFilePath, content = DEFAULT_BLUEPRINT_CONTENT, }) {
165
+ const extension = extname(blueprintFilePath);
151
166
  let blueprintContent;
152
- switch (fileType) {
153
- case 'json': {
167
+ switch (extension) {
168
+ case '.json': {
154
169
  blueprintContent = JSON.stringify(content, null, 2);
155
170
  break;
156
171
  }
157
- case 'js':
158
- case 'ts': {
172
+ case '.js':
173
+ case '.mjs':
174
+ case '.ts': {
159
175
  blueprintContent = `export default function() {
160
- return ${JSON.stringify(content)}
176
+ return ${JSON.stringify(content, null, 2)}
161
177
  }`;
162
178
  break;
163
179
  }
180
+ case '.cjs': {
181
+ blueprintContent = `module.exports = function() {
182
+ return ${JSON.stringify(content, null, 2)}
183
+ }`;
184
+ break;
185
+ }
186
+ default: {
187
+ throw Error(`Unsupported blueprint file extension: ${extension}`);
188
+ }
164
189
  }
165
- writeFileSync(path, blueprintContent);
190
+ writeFileSync(blueprintFilePath, blueprintContent);
166
191
  return blueprintContent;
167
192
  }
168
- export function readConfigFile(blueprintPath) {
169
- if (blueprintPath) {
170
- const blueprintDir = dirname(blueprintPath);
193
+ export function readConfigFile(blueprintFilePath) {
194
+ if (blueprintFilePath) {
195
+ const blueprintDir = dirname(blueprintFilePath);
171
196
  const configPath = join(blueprintDir, '.blueprint', 'config.json');
172
197
  if (existsSync(configPath)) {
173
198
  try {
174
199
  const config = JSON.parse(readFileSync(configPath, 'utf8'));
175
- return config || null;
200
+ return { configPath, ...config };
176
201
  }
177
202
  catch (err) {
178
203
  return null;
@@ -190,8 +215,8 @@ export function readConfigFile(blueprintPath) {
190
215
  return null;
191
216
  }
192
217
  }
193
- export function writeConfigFile({ blueprintPath, projectId, stackId, }) {
194
- const blueprintDir = blueprintPath ? dirname(blueprintPath) : cwd();
218
+ export function writeConfigFile({ blueprintFilePath, projectId, stackId, }) {
219
+ const blueprintDir = blueprintFilePath ? dirname(blueprintFilePath) : cwd();
195
220
  const configDir = join(blueprintDir, '.blueprint');
196
221
  const configPath = join(configDir, 'config.json');
197
222
  if (!existsSync(configDir)) {
@@ -214,15 +239,41 @@ export function addResourceToBlueprint({ blueprintFilePath, resource, }) {
214
239
  const blueprintFile = findBlueprintFile(blueprintFilePath);
215
240
  if (!blueprintFile)
216
241
  throw Error('Could not find Blueprint file');
217
- const { path, extension } = blueprintFile;
242
+ const { blueprintFilePath: foundPath, extension } = blueprintFile;
218
243
  // modify .json files directly
219
244
  if (extension === '.json') {
220
- const blueprintString = readFileSync(path, 'utf8').toString();
245
+ const blueprintString = readFileSync(foundPath, 'utf8').toString();
221
246
  const blueprint = JSON.parse(blueprintString);
222
247
  blueprint.resources = blueprint.resources || [];
223
248
  blueprint.resources.push(resource);
224
- writeFileSync(path, JSON.stringify(blueprint, null, 2));
249
+ writeFileSync(foundPath, JSON.stringify(blueprint, null, 2));
225
250
  return;
226
251
  }
227
252
  return resource;
228
253
  }
254
+ export function updateBlueprintMetadata({ blueprintFilePath, metadata, }) {
255
+ const blueprintFile = findBlueprintFile(blueprintFilePath);
256
+ if (!blueprintFile)
257
+ throw Error('Could not find Blueprint file');
258
+ const { blueprintFilePath: foundPath, extension } = blueprintFile;
259
+ if (extension === '.json') {
260
+ const blueprintString = readFileSync(foundPath, 'utf8').toString();
261
+ const blueprint = JSON.parse(blueprintString);
262
+ blueprint.metadata = blueprint.metadata || {};
263
+ blueprint.metadata = { ...blueprint.metadata, ...metadata };
264
+ writeFileSync(foundPath, JSON.stringify(blueprint, null, 2));
265
+ }
266
+ }
267
+ export function updateBlueprintValues({ blueprintFilePath, values, }) {
268
+ const blueprintFile = findBlueprintFile(blueprintFilePath);
269
+ if (!blueprintFile)
270
+ throw Error('Could not find Blueprint file');
271
+ const { blueprintFilePath: foundPath, extension } = blueprintFile;
272
+ if (extension === '.json') {
273
+ const blueprintString = readFileSync(foundPath, 'utf8').toString();
274
+ const blueprint = JSON.parse(blueprintString);
275
+ blueprint.values = blueprint.values || {};
276
+ blueprint.values = { ...blueprint.values, ...values };
277
+ writeFileSync(foundPath, JSON.stringify(blueprint, null, 2));
278
+ }
279
+ }
@@ -46,4 +46,13 @@ export declare function updateStack({ stackId, stackPayload, auth, }: {
46
46
  stackPayload: StackPayload;
47
47
  auth: AuthParams;
48
48
  }): Promise<UpdateStackResponse>;
49
+ interface DestroyStackResponse {
50
+ ok: boolean;
51
+ error: string | null;
52
+ stack: Stack;
53
+ }
54
+ export declare function destroyStack({ stackId, auth, }: {
55
+ stackId: string;
56
+ auth: AuthParams;
57
+ }): Promise<DestroyStackResponse>;
49
58
  export {};
@@ -51,7 +51,7 @@ export async function getStack({ stackId, auth, }) {
51
51
  const stack = await response.json();
52
52
  return {
53
53
  ok: response.ok,
54
- error: response.ok ? null : stack.message,
54
+ error: response.ok ? null : stack.message || stack.error?.message,
55
55
  stack,
56
56
  };
57
57
  }
@@ -81,3 +81,15 @@ export async function updateStack({ stackId, stackPayload, auth, }) {
81
81
  stack,
82
82
  };
83
83
  }
84
+ export async function destroyStack({ stackId, auth, }) {
85
+ const response = await fetch(`${stacksUrl}/${stackId}`, {
86
+ method: 'DELETE',
87
+ headers: getHeaders(auth),
88
+ });
89
+ const stack = await response.json();
90
+ return {
91
+ ok: response.ok,
92
+ error: response.ok ? null : stack.message,
93
+ stack,
94
+ };
95
+ }