@sanity/runtime-cli 7.6.7 → 8.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 (35) hide show
  1. package/README.md +65 -25
  2. package/bin/dev.cmd +1 -1
  3. package/bin/dev.js +1 -1
  4. package/dist/actions/blueprints/blueprint.d.ts +20 -2
  5. package/dist/actions/blueprints/blueprint.js +88 -35
  6. package/dist/actions/blueprints/resources.js +1 -13
  7. package/dist/actions/blueprints/stacks.d.ts +6 -0
  8. package/dist/actions/blueprints/stacks.js +17 -3
  9. package/dist/commands/blueprints/add.d.ts +1 -1
  10. package/dist/commands/blueprints/add.js +2 -5
  11. package/dist/commands/blueprints/config.js +1 -3
  12. package/dist/commands/blueprints/destroy.js +1 -4
  13. package/dist/commands/blueprints/info.js +1 -3
  14. package/dist/commands/blueprints/init.js +2 -6
  15. package/dist/commands/blueprints/stacks.d.ts +1 -2
  16. package/dist/commands/blueprints/stacks.js +3 -5
  17. package/dist/cores/blueprints/add.js +26 -7
  18. package/dist/cores/blueprints/config.js +3 -28
  19. package/dist/cores/blueprints/init.js +45 -75
  20. package/dist/cores/blueprints/plan.js +3 -3
  21. package/dist/cores/blueprints/stacks.d.ts +1 -1
  22. package/dist/cores/blueprints/stacks.js +2 -2
  23. package/dist/utils/display/blueprints-formatting.js +3 -3
  24. package/dist/utils/display/presenters.d.ts +1 -0
  25. package/dist/utils/display/presenters.js +6 -3
  26. package/dist/utils/display/prompt.d.ts +4 -0
  27. package/dist/utils/display/prompt.js +44 -1
  28. package/dist/utils/other/npmjs.d.ts +1 -0
  29. package/dist/utils/other/npmjs.js +13 -0
  30. package/oclif.manifest.json +18 -19
  31. package/package.json +6 -7
  32. package/dist/utils/format-error.d.ts +0 -4
  33. package/dist/utils/format-error.js +0 -9
  34. package/dist/utils/is-dependency.d.ts +0 -1
  35. package/dist/utils/is-dependency.js +0 -7
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/7.6.7 linux-x64 node-v22.16.0
23
+ @sanity/runtime-cli/8.0.0 linux-x64 node-v22.16.0
24
24
  $ sanity-run --help [COMMAND]
25
25
  USAGE
26
26
  $ sanity-run COMMAND
@@ -37,6 +37,7 @@ USAGE
37
37
  * [`sanity-run blueprints init [DIR]`](#sanity-run-blueprints-init-dir)
38
38
  * [`sanity-run blueprints logs`](#sanity-run-blueprints-logs)
39
39
  * [`sanity-run blueprints plan`](#sanity-run-blueprints-plan)
40
+ * [`sanity-run blueprints stacks`](#sanity-run-blueprints-stacks)
40
41
  * [`sanity-run functions dev`](#sanity-run-functions-dev)
41
42
  * [`sanity-run functions env add NAME KEY VALUE`](#sanity-run-functions-env-add-name-key-value)
42
43
  * [`sanity-run functions env list NAME`](#sanity-run-functions-env-list-name)
@@ -51,7 +52,7 @@ Add a Resource to a Blueprint
51
52
 
52
53
  ```
53
54
  USAGE
54
- $ sanity-run blueprints add TYPE [--fn-type document-publish -n <value>] [--language ts|js] [--javascript]
55
+ $ sanity-run blueprints add TYPE [--fn-type document-publish -n <value>] [--fn-language ts|js] [--javascript]
55
56
  [--fn-helpers] [-i | --fn-installer skip|npm|pnpm|yarn]
56
57
 
57
58
  ARGUMENTS
@@ -63,11 +64,11 @@ FLAGS
63
64
  --[no-]fn-helpers Add helpers to the new Function
64
65
  --fn-installer=<option> How to install the @sanity/functions helpers
65
66
  <options: skip|npm|pnpm|yarn>
67
+ --fn-language=<option> [default: ts] Language of the new Function
68
+ <options: ts|js>
66
69
  --fn-type=<option> Type of new Function
67
70
  <options: document-publish>
68
71
  --javascript Use JavaScript instead of TypeScript
69
- --language=<option> [default: ts] Language of the new Function
70
- <options: ts|js>
71
72
 
72
73
  DESCRIPTION
73
74
  Add a Resource to a Blueprint
@@ -84,7 +85,7 @@ EXAMPLES
84
85
  $ sanity-run blueprints add function --name my-function --fn-type document-publish --lang js
85
86
  ```
86
87
 
87
- _See code: [src/commands/blueprints/add.ts](https://github.com/sanity-io/runtime-cli/blob/v7.6.7/src/commands/blueprints/add.ts)_
88
+ _See code: [src/commands/blueprints/add.ts](https://github.com/sanity-io/runtime-cli/blob/v8.0.0/src/commands/blueprints/add.ts)_
88
89
 
89
90
  ## `sanity-run blueprints config`
90
91
 
@@ -92,12 +93,13 @@ View or edit Blueprint configuration
92
93
 
93
94
  ```
94
95
  USAGE
95
- $ sanity-run blueprints config [-t] [--project-id <value> -e]
96
+ $ sanity-run blueprints config [-t] [--project-id <value> -e] [--stack-id <value> ]
96
97
 
97
98
  FLAGS
98
99
  -e, --edit Edit the configuration
99
100
  -t, --test-config Validate the configuration
100
101
  --project-id=<value> Update the Project ID in the configuration. Requires --edit flag
102
+ --stack-id=<value> Update the Stack ID in the configuration. Requires --edit flag
101
103
 
102
104
  DESCRIPTION
103
105
  View or edit Blueprint configuration
@@ -110,9 +112,11 @@ EXAMPLES
110
112
  $ sanity-run blueprints config --edit
111
113
 
112
114
  $ sanity-run blueprints config --edit --project-id <projectId>
115
+
116
+ $ sanity-run blueprints config --edit --project-id <projectId> --stack-id <stackId>
113
117
  ```
114
118
 
115
- _See code: [src/commands/blueprints/config.ts](https://github.com/sanity-io/runtime-cli/blob/v7.6.7/src/commands/blueprints/config.ts)_
119
+ _See code: [src/commands/blueprints/config.ts](https://github.com/sanity-io/runtime-cli/blob/v8.0.0/src/commands/blueprints/config.ts)_
116
120
 
117
121
  ## `sanity-run blueprints deploy`
118
122
 
@@ -134,7 +138,7 @@ EXAMPLES
134
138
  $ sanity-run blueprints deploy --no-wait
135
139
  ```
136
140
 
137
- _See code: [src/commands/blueprints/deploy.ts](https://github.com/sanity-io/runtime-cli/blob/v7.6.7/src/commands/blueprints/deploy.ts)_
141
+ _See code: [src/commands/blueprints/deploy.ts](https://github.com/sanity-io/runtime-cli/blob/v8.0.0/src/commands/blueprints/deploy.ts)_
138
142
 
139
143
  ## `sanity-run blueprints destroy`
140
144
 
@@ -142,20 +146,24 @@ Destroy a Blueprint deployment (will not delete local files)
142
146
 
143
147
  ```
144
148
  USAGE
145
- $ sanity-run blueprints destroy [--force] [--no-wait]
149
+ $ sanity-run blueprints destroy [--project-id <value> --stack-id <value> --force] [--no-wait]
146
150
 
147
151
  FLAGS
148
- --force Force destroy (skip confirmation)
149
- --no-wait Do not wait for destruction to complete
152
+ --force Force destroy (skip confirmation)
153
+ --no-wait Do not wait for destruction to complete
154
+ --project-id=<value> Project associated with the Stack (defaults to current Project)
155
+ --stack-id=<value> Stack ID to destroy (defaults to current Stack)
150
156
 
151
157
  DESCRIPTION
152
158
  Destroy a Blueprint deployment (will not delete local files)
153
159
 
154
160
  EXAMPLES
155
161
  $ sanity-run blueprints destroy
162
+
163
+ $ sanity-run blueprints destroy --stack-id <stackId> --project-id <projectId> --force --no-wait
156
164
  ```
157
165
 
158
- _See code: [src/commands/blueprints/destroy.ts](https://github.com/sanity-io/runtime-cli/blob/v7.6.7/src/commands/blueprints/destroy.ts)_
166
+ _See code: [src/commands/blueprints/destroy.ts](https://github.com/sanity-io/runtime-cli/blob/v8.0.0/src/commands/blueprints/destroy.ts)_
159
167
 
160
168
  ## `sanity-run blueprints info`
161
169
 
@@ -163,16 +171,21 @@ Show information about a Blueprint deployment
163
171
 
164
172
  ```
165
173
  USAGE
166
- $ sanity-run blueprints info
174
+ $ sanity-run blueprints info [--id <value>]
175
+
176
+ FLAGS
177
+ --id=<value> Stack ID to show info for (defaults to current stack)
167
178
 
168
179
  DESCRIPTION
169
180
  Show information about a Blueprint deployment
170
181
 
171
182
  EXAMPLES
172
183
  $ sanity-run blueprints info
184
+
185
+ $ sanity-run blueprints info --stack-id <stackId>
173
186
  ```
174
187
 
175
- _See code: [src/commands/blueprints/info.ts](https://github.com/sanity-io/runtime-cli/blob/v7.6.7/src/commands/blueprints/info.ts)_
188
+ _See code: [src/commands/blueprints/info.ts](https://github.com/sanity-io/runtime-cli/blob/v8.0.0/src/commands/blueprints/info.ts)_
176
189
 
177
190
  ## `sanity-run blueprints init [DIR]`
178
191
 
@@ -180,7 +193,8 @@ Initialize a new Blueprint
180
193
 
181
194
  ```
182
195
  USAGE
183
- $ sanity-run blueprints init [DIR] [--dir <value>] [--blueprint-type json|js|ts] [--project-id <value>]
196
+ $ sanity-run blueprints init [DIR] [--dir <value>] [--blueprint-type json|js|ts] [--stack-name <value> |
197
+ [--stack-id <value> --project-id <value>]]
184
198
 
185
199
  ARGUMENTS
186
200
  DIR Directory to create the Blueprint in
@@ -190,6 +204,8 @@ FLAGS
190
204
  <options: json|js|ts>
191
205
  --dir=<value> Directory to create the Blueprint in
192
206
  --project-id=<value> Sanity Project ID to use for the Blueprint
207
+ --stack-id=<value> Existing Stack ID to use for the Blueprint
208
+ --stack-name=<value> Name to use for a NEW Stack
193
209
 
194
210
  DESCRIPTION
195
211
  Initialize a new Blueprint
@@ -201,10 +217,12 @@ EXAMPLES
201
217
 
202
218
  $ sanity-run blueprints init --blueprint-type <json|js|ts>
203
219
 
204
- $ sanity-run blueprints init --blueprint-type <json|js|ts> --project-id <projectId>
220
+ $ sanity-run blueprints init --blueprint-type <json|js|ts> --project-id <projectId> --stack-id <stackId>
221
+
222
+ $ sanity-run blueprints init --blueprint-type <json|js|ts> --stack-name <stackName>
205
223
  ```
206
224
 
207
- _See code: [src/commands/blueprints/init.ts](https://github.com/sanity-io/runtime-cli/blob/v7.6.7/src/commands/blueprints/init.ts)_
225
+ _See code: [src/commands/blueprints/init.ts](https://github.com/sanity-io/runtime-cli/blob/v8.0.0/src/commands/blueprints/init.ts)_
208
226
 
209
227
  ## `sanity-run blueprints logs`
210
228
 
@@ -226,7 +244,7 @@ EXAMPLES
226
244
  $ sanity-run blueprints logs --watch
227
245
  ```
228
246
 
229
- _See code: [src/commands/blueprints/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v7.6.7/src/commands/blueprints/logs.ts)_
247
+ _See code: [src/commands/blueprints/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v8.0.0/src/commands/blueprints/logs.ts)_
230
248
 
231
249
  ## `sanity-run blueprints plan`
232
250
 
@@ -243,7 +261,29 @@ EXAMPLES
243
261
  $ sanity-run blueprints plan
244
262
  ```
245
263
 
246
- _See code: [src/commands/blueprints/plan.ts](https://github.com/sanity-io/runtime-cli/blob/v7.6.7/src/commands/blueprints/plan.ts)_
264
+ _See code: [src/commands/blueprints/plan.ts](https://github.com/sanity-io/runtime-cli/blob/v8.0.0/src/commands/blueprints/plan.ts)_
265
+
266
+ ## `sanity-run blueprints stacks`
267
+
268
+ List all Blueprint stacks
269
+
270
+ ```
271
+ USAGE
272
+ $ sanity-run blueprints stacks [--project-id <value>]
273
+
274
+ FLAGS
275
+ --project-id=<value> Project ID to show stacks for
276
+
277
+ DESCRIPTION
278
+ List all Blueprint stacks
279
+
280
+ EXAMPLES
281
+ $ sanity-run blueprints stacks
282
+
283
+ $ sanity-run blueprints stacks --project-id <projectId>
284
+ ```
285
+
286
+ _See code: [src/commands/blueprints/stacks.ts](https://github.com/sanity-io/runtime-cli/blob/v8.0.0/src/commands/blueprints/stacks.ts)_
247
287
 
248
288
  ## `sanity-run functions dev`
249
289
 
@@ -263,7 +303,7 @@ EXAMPLES
263
303
  $ sanity-run functions dev --port 8974
264
304
  ```
265
305
 
266
- _See code: [src/commands/functions/dev.ts](https://github.com/sanity-io/runtime-cli/blob/v7.6.7/src/commands/functions/dev.ts)_
306
+ _See code: [src/commands/functions/dev.ts](https://github.com/sanity-io/runtime-cli/blob/v8.0.0/src/commands/functions/dev.ts)_
267
307
 
268
308
  ## `sanity-run functions env add NAME KEY VALUE`
269
309
 
@@ -285,7 +325,7 @@ EXAMPLES
285
325
  $ sanity-run functions env add MyFunction API_URL https://api.example.com/
286
326
  ```
287
327
 
288
- _See code: [src/commands/functions/env/add.ts](https://github.com/sanity-io/runtime-cli/blob/v7.6.7/src/commands/functions/env/add.ts)_
328
+ _See code: [src/commands/functions/env/add.ts](https://github.com/sanity-io/runtime-cli/blob/v8.0.0/src/commands/functions/env/add.ts)_
289
329
 
290
330
  ## `sanity-run functions env list NAME`
291
331
 
@@ -305,7 +345,7 @@ EXAMPLES
305
345
  $ sanity-run functions env list MyFunction
306
346
  ```
307
347
 
308
- _See code: [src/commands/functions/env/list.ts](https://github.com/sanity-io/runtime-cli/blob/v7.6.7/src/commands/functions/env/list.ts)_
348
+ _See code: [src/commands/functions/env/list.ts](https://github.com/sanity-io/runtime-cli/blob/v8.0.0/src/commands/functions/env/list.ts)_
309
349
 
310
350
  ## `sanity-run functions env remove NAME KEY`
311
351
 
@@ -326,7 +366,7 @@ EXAMPLES
326
366
  $ sanity-run functions env remove MyFunction API_URL
327
367
  ```
328
368
 
329
- _See code: [src/commands/functions/env/remove.ts](https://github.com/sanity-io/runtime-cli/blob/v7.6.7/src/commands/functions/env/remove.ts)_
369
+ _See code: [src/commands/functions/env/remove.ts](https://github.com/sanity-io/runtime-cli/blob/v8.0.0/src/commands/functions/env/remove.ts)_
330
370
 
331
371
  ## `sanity-run functions logs NAME`
332
372
 
@@ -360,7 +400,7 @@ EXAMPLES
360
400
  $ sanity-run functions logs <name> --delete
361
401
  ```
362
402
 
363
- _See code: [src/commands/functions/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v7.6.7/src/commands/functions/logs.ts)_
403
+ _See code: [src/commands/functions/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v8.0.0/src/commands/functions/logs.ts)_
364
404
 
365
405
  ## `sanity-run functions test NAME`
366
406
 
@@ -393,7 +433,7 @@ EXAMPLES
393
433
  $ sanity-run functions test <name> --data '{ "id": 1 }' --timeout 60
394
434
  ```
395
435
 
396
- _See code: [src/commands/functions/test.ts](https://github.com/sanity-io/runtime-cli/blob/v7.6.7/src/commands/functions/test.ts)_
436
+ _See code: [src/commands/functions/test.ts](https://github.com/sanity-io/runtime-cli/blob/v8.0.0/src/commands/functions/test.ts)_
397
437
 
398
438
  ## `sanity-run help [COMMAND]`
399
439
 
package/bin/dev.cmd CHANGED
@@ -1,3 +1,3 @@
1
1
  @echo off
2
2
 
3
- node --import tsx --no-warnings=ExperimentalWarning "%~dp0\dev" %*
3
+ node --import jiti/register --no-warnings=ExperimentalWarning "%~dp0\dev" %*
package/bin/dev.js CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env -S node --import tsx --disable-warning=ExperimentalWarning
1
+ #!/usr/bin/env -S node --import jiti/register --disable-warning=ExperimentalWarning
2
2
 
3
3
  import {execute} from '@oclif/core'
4
4
 
@@ -1,8 +1,19 @@
1
1
  import type { BlueprintParserError, LocalBlueprint, LocalResource } from '../../utils/types.js';
2
2
  export { BLUEPRINT_CONFIG_FILE, BLUEPRINT_CONFIG_VERSION, BLUEPRINT_DIR } from '../../config.js';
3
- declare const SUPPORTED_FILE_EXTENSIONS: readonly [".json", ".js", ".mjs", ".cjs", ".ts"];
3
+ declare const SUPPORTED_FILE_EXTENSIONS: readonly [".json", ".js", ".mjs", ".ts"];
4
4
  type BlueprintFileExtension = (typeof SUPPORTED_FILE_EXTENSIONS)[number];
5
- export declare const DEFAULT_BLUEPRINT_CONTENT: LocalBlueprint;
5
+ export declare const DEFAULT_BLUEPRINT_CONTENT: {
6
+ blueprintVersion: string;
7
+ resources: never[];
8
+ };
9
+ export declare const RESOURCE_TEMPLATE = "import {defineBlueprint} from '@sanity/blueprints'\n\nexport default defineBlueprint({{CONTENT}})\n";
10
+ export declare const GITIGNORE_FOR_FUNCTIONS = "\n# Sanity Functions\nfunctions/**/.env*\nfunctions/**/.build/\nfunctions/**/node_modules/\n";
11
+ export declare const GITIGNORE_TEMPLATE = "\nnode_modules\n.env\n\n# Sanity Functions\nfunctions/**/.env*\nfunctions/**/.build/\nfunctions/**/node_modules/\n\n";
12
+ export type BlueprintModule = ((args?: unknown) => Record<string, unknown>) & {
13
+ organizationId?: string;
14
+ projectId?: string;
15
+ stackId?: string;
16
+ };
6
17
  /**
7
18
  * Finds the blueprint file in the given path or current working directory
8
19
  * @param blueprintPath - The path of the blueprint file or directory
@@ -39,6 +50,10 @@ export declare function writeBlueprintToDisk({ blueprintFilePath, content, }: {
39
50
  blueprintFilePath: string;
40
51
  content?: LocalBlueprint;
41
52
  }): string;
53
+ export declare function writeOrUpdateNodeDependency({ blueprintFilePath, dependency, }: {
54
+ blueprintFilePath: string;
55
+ dependency: string;
56
+ }): Promise<void>;
42
57
  export declare function readConfigFile(blueprintFilePath?: string | undefined): {
43
58
  configPath?: string;
44
59
  projectId?: string;
@@ -49,6 +64,9 @@ export declare function writeConfigFile({ blueprintFilePath, projectId, stackId,
49
64
  projectId: string;
50
65
  stackId?: string;
51
66
  }): void;
67
+ export declare function writeGitignoreFile({ blueprintFilePath, }: {
68
+ blueprintFilePath: string;
69
+ }): string | null;
52
70
  export declare function addResourceToBlueprint({ blueprintFilePath, resource, }: {
53
71
  blueprintFilePath?: string;
54
72
  resource: LocalResource;
@@ -1,19 +1,39 @@
1
1
  import { existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from 'node:fs';
2
- import { createRequire } from 'node:module';
3
2
  import { basename, dirname, extname, join } from 'node:path';
4
3
  import { cwd, env } from 'node:process';
5
4
  import { findUpSync } from 'find-up';
5
+ import { createJiti } from 'jiti';
6
6
  import { BLUEPRINT_CONFIG_FILE, BLUEPRINT_CONFIG_VERSION, BLUEPRINT_DIR } from '../../config.js';
7
+ import { getLatestNpmVersion } from '../../utils/other/npmjs.js';
7
8
  import { isLocalFunctionResource } from '../../utils/types.js';
8
9
  import { validateFunctionResource } from '../../utils/validate/resource.js';
9
10
  import { blueprintParserValidator } from '../../utils/vendor/parser-validator.js';
10
11
  export { BLUEPRINT_CONFIG_FILE, BLUEPRINT_CONFIG_VERSION, BLUEPRINT_DIR } from '../../config.js';
11
- const SUPPORTED_FILE_EXTENSIONS = ['.json', '.js', '.mjs', '.cjs', '.ts'];
12
- const SUPPORTED_FILE_NAMES_IN_PRIORITY_ORDER = SUPPORTED_FILE_EXTENSIONS.map((ext) => `blueprint${ext}`);
12
+ const SUPPORTED_FILE_EXTENSIONS = ['.json', '.js', '.mjs', '.ts'];
13
+ let SUPPORTED_FILE_NAMES_IN_PRIORITY_ORDER = SUPPORTED_FILE_EXTENSIONS.map((ext) => `blueprint${ext}`);
14
+ SUPPORTED_FILE_NAMES_IN_PRIORITY_ORDER = [
15
+ ...SUPPORTED_FILE_NAMES_IN_PRIORITY_ORDER,
16
+ ...SUPPORTED_FILE_NAMES_IN_PRIORITY_ORDER.map((name) => `sanity.${name}`),
17
+ ];
13
18
  export const DEFAULT_BLUEPRINT_CONTENT = {
14
19
  blueprintVersion: '2024-10-01',
15
20
  resources: [],
16
21
  };
22
+ export const RESOURCE_TEMPLATE = `import {defineBlueprint} from '@sanity/blueprints'
23
+
24
+ export default defineBlueprint({{CONTENT}})
25
+ `;
26
+ export const GITIGNORE_FOR_FUNCTIONS = `
27
+ # Sanity Functions
28
+ functions/**/.env*
29
+ functions/**/.build/
30
+ functions/**/node_modules/
31
+ `;
32
+ export const GITIGNORE_TEMPLATE = `
33
+ node_modules
34
+ .env
35
+ ${GITIGNORE_FOR_FUNCTIONS}
36
+ `;
17
37
  /**
18
38
  * Finds the blueprint file in the given path or current working directory
19
39
  * @param blueprintPath - The path of the blueprint file or directory
@@ -75,23 +95,10 @@ export async function readLocalBlueprint(blueprintPath) {
75
95
  blueprintModule = module.default;
76
96
  break;
77
97
  }
78
- case '.cjs': {
79
- const require = createRequire(import.meta.url);
80
- blueprintModule = require(foundFilePath);
81
- break;
82
- }
83
98
  case '.ts': {
84
- try {
85
- const { tsImport } = await import('tsx/esm/api');
86
- const module = await tsImport(`file://${foundFilePath}`, dirname(foundFilePath));
87
- blueprintModule = module.default;
88
- }
89
- catch (err) {
90
- if (err instanceof Error && err.message.includes('Cannot find module')) {
91
- throw Error(`TypeScript support requires 'tsx' to be installed. Run: npm install -D tsx`);
92
- }
93
- throw err;
94
- }
99
+ const jiti = createJiti(dirname(foundFilePath));
100
+ const modDefault = await jiti.import(`file://${foundFilePath}`, { default: true });
101
+ blueprintModule = modDefault;
95
102
  break;
96
103
  }
97
104
  default:
@@ -99,16 +106,23 @@ export async function readLocalBlueprint(blueprintPath) {
99
106
  }
100
107
  }
101
108
  catch (err) {
102
- throw Error(`Error parsing Blueprint file: ${fileName}`);
109
+ throw Error(`Unable to parse Blueprint file: ${fileName}\n${err}`);
103
110
  }
111
+ let moduleProjectId;
112
+ let moduleStackId;
104
113
  if (blueprintModule) {
105
- if (typeof blueprintModule !== 'function')
106
- throw Error(`Blueprint ${fileName} must export a default function`);
107
- try {
108
- rawBlueprint = blueprintModule();
114
+ if (typeof blueprintModule === 'function') {
115
+ try {
116
+ moduleProjectId = blueprintModule.projectId;
117
+ moduleStackId = blueprintModule.stackId;
118
+ rawBlueprint = blueprintModule();
119
+ }
120
+ catch {
121
+ throw Error(`Error executing Blueprint file: ${fileName}`);
122
+ }
109
123
  }
110
- catch {
111
- throw Error(`Error executing Blueprint file: ${fileName}`);
124
+ else {
125
+ throw Error(`Blueprint ${fileName} must export a default function`);
112
126
  }
113
127
  }
114
128
  const parserResult = blueprintParserValidator(rawBlueprint);
@@ -127,11 +141,15 @@ export async function readLocalBlueprint(blueprintPath) {
127
141
  let projectId;
128
142
  if (envProjectId)
129
143
  projectId = envProjectId;
144
+ else if (moduleProjectId)
145
+ projectId = moduleProjectId;
130
146
  else if (configIds?.projectId)
131
147
  projectId = configIds.projectId;
132
148
  let stackId;
133
149
  if (envStackId)
134
150
  stackId = envStackId;
151
+ else if (moduleStackId)
152
+ stackId = moduleStackId;
135
153
  else if (configIds?.stackId)
136
154
  stackId = configIds.stackId;
137
155
  // LAUNCH LIMIT: 1 Stack per Project - infer stackId from projectId
@@ -159,15 +177,8 @@ export function writeBlueprintToDisk({ blueprintFilePath, content = DEFAULT_BLUE
159
177
  case '.js':
160
178
  case '.mjs':
161
179
  case '.ts': {
162
- blueprintContent = `export default function() {
163
- return ${JSON.stringify(content, null, 2)}
164
- }`;
165
- break;
166
- }
167
- case '.cjs': {
168
- blueprintContent = `module.exports = function() {
169
- return ${JSON.stringify(content, null, 2)}
170
- }`;
180
+ content.blueprintVersion = undefined; // remove blueprintVersion from content
181
+ blueprintContent = RESOURCE_TEMPLATE.replace('{{CONTENT}}', JSON.stringify(content, null, 2));
171
182
  break;
172
183
  }
173
184
  default: {
@@ -178,6 +189,33 @@ export function writeBlueprintToDisk({ blueprintFilePath, content = DEFAULT_BLUE
178
189
  writeFileSync(blueprintFilePath, blueprintContent);
179
190
  return blueprintContent;
180
191
  }
192
+ export async function writeOrUpdateNodeDependency({ blueprintFilePath, dependency, }) {
193
+ const dir = dirname(blueprintFilePath);
194
+ const extension = extname(blueprintFilePath);
195
+ if (extension === '.json')
196
+ return;
197
+ const version = await getLatestNpmVersion(dependency);
198
+ const packageJsonPath = join(dir, 'package.json');
199
+ const packageExists = existsSync(packageJsonPath);
200
+ if (!packageExists) {
201
+ writeFileSync(packageJsonPath, JSON.stringify({ devDependencies: { [dependency]: version } }, null, 2));
202
+ return;
203
+ }
204
+ const packageJson = readFileSync(packageJsonPath, 'utf8');
205
+ let packageJsonObject;
206
+ try {
207
+ packageJsonObject = JSON.parse(packageJson);
208
+ }
209
+ catch (err) {
210
+ throw Error(`Unable to parse package.json: ${err}`);
211
+ }
212
+ const allDependencies = { ...packageJsonObject.dependencies, ...packageJsonObject.devDependencies };
213
+ if (allDependencies[dependency])
214
+ return;
215
+ packageJsonObject.devDependencies = packageJsonObject.devDependencies || {};
216
+ packageJsonObject.devDependencies[dependency] = version;
217
+ writeFileSync(packageJsonPath, JSON.stringify(packageJsonObject, null, 2));
218
+ }
181
219
  export function readConfigFile(blueprintFilePath) {
182
220
  if (blueprintFilePath) {
183
221
  const blueprintDir = dirname(blueprintFilePath);
@@ -225,6 +263,21 @@ export function writeConfigFile({ blueprintFilePath, projectId, stackId, }) {
225
263
  config.updatedAt = Date.now();
226
264
  writeFileSync(configPath, JSON.stringify(config, null, 2));
227
265
  }
266
+ export function writeGitignoreFile({ blueprintFilePath, }) {
267
+ const blueprintDir = blueprintFilePath ? dirname(blueprintFilePath) : cwd();
268
+ const gitignorePath = join(blueprintDir, '.gitignore');
269
+ const gitignoreExists = existsSync(gitignorePath);
270
+ let content = GITIGNORE_TEMPLATE;
271
+ if (gitignoreExists) {
272
+ // append GITIGNORE_FOR_FUNCTIONS to existing .gitignore
273
+ const existingContent = readFileSync(gitignorePath, 'utf8').toString();
274
+ if (existingContent.includes(GITIGNORE_FOR_FUNCTIONS))
275
+ return null;
276
+ content = `${existingContent}\n${GITIGNORE_FOR_FUNCTIONS}`;
277
+ }
278
+ writeFileSync(gitignorePath, content);
279
+ return content;
280
+ }
228
281
  export function addResourceToBlueprint({ blueprintFilePath, resource, }) {
229
282
  const blueprintFile = findBlueprintFile(blueprintFilePath);
230
283
  if (!blueprintFile)
@@ -4,6 +4,7 @@ import { existsSync } from 'node:fs';
4
4
  import { dirname, join } from 'node:path';
5
5
  import { cwd } from 'node:process';
6
6
  import chalk from 'chalk';
7
+ import { getLatestNpmVersion } from '../../utils/other/npmjs.js';
7
8
  import { addResourceToBlueprint } from './blueprint.js';
8
9
  const DEFAULT_FUNCTION_TEMPLATE = /*js*/ `export async function handler({context, event}) {
9
10
  const time = new Date().toLocaleTimeString()
@@ -89,19 +90,6 @@ export async function createFunctionResource(options) {
89
90
  resource: resource || resourceJson,
90
91
  };
91
92
  }
92
- async function getLatestNpmVersion(pkg) {
93
- const url = `https://registry.npmjs.org/${pkg}/latest`;
94
- try {
95
- const res = await fetch(url);
96
- if (!res.ok)
97
- throw new Error(`Failed to fetch version for ${pkg}`);
98
- const data = await res.json();
99
- return data.version;
100
- }
101
- catch (error) {
102
- return 'latest';
103
- }
104
- }
105
93
  async function runPackageInstall(cwd, command) {
106
94
  return new Promise((resolve) => {
107
95
  const install = spawn(command, ['install'], { cwd });
@@ -24,6 +24,12 @@ export declare function createStack({ stackPayload, auth, }: {
24
24
  stackPayload: StackPayload;
25
25
  auth: AuthParams;
26
26
  }): Promise<CreateStackResponse>;
27
+ export declare function createEmptyStack({ token, projectId, name, projectBased, }: {
28
+ token: string;
29
+ projectId: string;
30
+ name: string;
31
+ projectBased?: boolean;
32
+ }): Promise<Stack>;
27
33
  interface UpdateStackResponse {
28
34
  ok: boolean;
29
35
  error: string | null;
@@ -10,7 +10,7 @@ export async function listStacks(auth) {
10
10
  const stacks = await response.json();
11
11
  return {
12
12
  ok: response.ok,
13
- error: response.ok ? null : stacks.error?.message,
13
+ error: response.ok ? null : stacks.message,
14
14
  stacks,
15
15
  };
16
16
  }
@@ -22,7 +22,7 @@ export async function getStack({ stackId, auth, }) {
22
22
  const stack = await response.json();
23
23
  return {
24
24
  ok: response.ok,
25
- error: response.ok ? null : stack.message || stack.error?.message,
25
+ error: response.ok ? null : stack.message,
26
26
  stack,
27
27
  };
28
28
  }
@@ -35,10 +35,24 @@ export async function createStack({ stackPayload, auth, }) {
35
35
  const stack = await response.json();
36
36
  return {
37
37
  ok: response.ok,
38
- error: response.ok ? null : stack.message || stack.error,
38
+ error: response.ok ? null : stack.message,
39
39
  stack,
40
40
  };
41
41
  }
42
+ export async function createEmptyStack({ token, projectId, name, projectBased = true, }) {
43
+ const stackPayload = {
44
+ name,
45
+ projectId,
46
+ useProjectBasedId: projectBased,
47
+ document: { resources: [] },
48
+ };
49
+ const auth = { token, projectId };
50
+ const response = await createStack({ stackPayload, auth });
51
+ if (!response.ok) {
52
+ throw new Error(response.error || 'Failed to create new Stack');
53
+ }
54
+ return response.stack;
55
+ }
42
56
  export async function updateStack({ stackId, stackPayload, auth, }) {
43
57
  const response = await fetch(`${stacksUrl}/${stackId}`, {
44
58
  method: 'PUT',
@@ -8,7 +8,7 @@ export default class AddCommand extends BlueprintCommand<typeof AddCommand> {
8
8
  static flags: {
9
9
  name: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
10
10
  'fn-type': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
- language: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
11
+ 'fn-language': import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
12
12
  javascript: import("@oclif/core/interfaces").BooleanFlag<boolean>;
13
13
  'fn-helpers': import("@oclif/core/interfaces").BooleanFlag<boolean>;
14
14
  'fn-installer': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
@@ -26,14 +26,11 @@ export default class AddCommand extends BlueprintCommand {
26
26
  description: 'Type of new Function',
27
27
  options: ['document-publish' /*, 'document-create', 'document-delete'*/],
28
28
  aliases: ['function-type'],
29
- // default: 'document-publish', // prompting informs user of default
30
29
  dependsOn: ['name'],
31
30
  }),
32
- // TODO: this should be 'fn-language'
33
- language: Flags.string({
31
+ 'fn-language': Flags.string({
34
32
  description: 'Language of the new Function',
35
- // TODO: remove 'fn-language'
36
- aliases: ['fn-language', 'function-language', 'language', 'lang'],
33
+ aliases: ['function-language', 'language', 'lang'],
37
34
  options: ['ts', 'js'],
38
35
  default: 'ts',
39
36
  }),
@@ -8,8 +8,7 @@ export default class ConfigCommand extends BlueprintCommand {
8
8
  '<%= config.bin %> <%= command.id %> --test-config',
9
9
  '<%= config.bin %> <%= command.id %> --edit',
10
10
  '<%= config.bin %> <%= command.id %> --edit --project-id <projectId>',
11
- // LAUNCH LIMIT: 1 Stack per Project - do not allow Stack ID to be set
12
- // '<%= config.bin %> <%= command.id %> --edit --project-id <projectId> --stack-id <stackId>',
11
+ '<%= config.bin %> <%= command.id %> --edit --project-id <projectId> --stack-id <stackId>',
13
12
  ];
14
13
  static flags = {
15
14
  'test-config': Flags.boolean({
@@ -32,7 +31,6 @@ export default class ConfigCommand extends BlueprintCommand {
32
31
  description: 'Update the Stack ID in the configuration. Requires --edit flag',
33
32
  aliases: ['stack', 'stackId'],
34
33
  dependsOn: ['edit'],
35
- hidden: true, // LAUNCH LIMIT: 1 Stack per Project
36
34
  }),
37
35
  };
38
36
  async run() {
@@ -5,8 +5,7 @@ export default class DestroyCommand extends BlueprintCommand {
5
5
  static description = 'Destroy a Blueprint deployment (will not delete local files)';
6
6
  static examples = [
7
7
  '<%= config.bin %> <%= command.id %>',
8
- // LAUNCH LIMIT: 1 Stack per Project - do not allow Stack ID to be set
9
- // '<%= config.bin %> <%= command.id %> --id ST-a1b2c3 --projectId a1b2c3 --force',
8
+ '<%= config.bin %> <%= command.id %> --stack-id <stackId> --project-id <projectId> --force --no-wait',
10
9
  ];
11
10
  static flags = {
12
11
  force: Flags.boolean({
@@ -18,12 +17,10 @@ export default class DestroyCommand extends BlueprintCommand {
18
17
  description: 'Project associated with the Stack (defaults to current Project)',
19
18
  aliases: ['projectId', 'project'],
20
19
  dependsOn: ['stack-id', 'force'],
21
- hidden: true, // LAUNCH LIMIT: 1 Stack per Project
22
20
  }),
23
21
  'stack-id': Flags.string({
24
22
  description: 'Stack ID to destroy (defaults to current Stack)',
25
23
  aliases: ['stackId', 'stack'],
26
- hidden: true, // LAUNCH LIMIT: 1 Stack per Project
27
24
  }),
28
25
  'no-wait': Flags.boolean({
29
26
  description: 'Do not wait for destruction to complete',