@sanity/runtime-cli 10.9.2 → 10.11.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 (42) hide show
  1. package/README.md +39 -18
  2. package/dist/actions/blueprints/config.d.ts +1 -1
  3. package/dist/actions/blueprints/config.js +2 -11
  4. package/dist/actions/blueprints/stacks.d.ts +1 -0
  5. package/dist/actions/blueprints/stacks.js +1 -0
  6. package/dist/actions/functions/dev.d.ts +2 -1
  7. package/dist/actions/functions/dev.js +2 -2
  8. package/dist/commands/blueprints/doctor.d.ts +10 -0
  9. package/dist/commands/blueprints/doctor.js +28 -0
  10. package/dist/commands/functions/dev.d.ts +1 -0
  11. package/dist/commands/functions/dev.js +5 -0
  12. package/dist/cores/blueprints/doctor.d.ts +9 -0
  13. package/dist/cores/blueprints/doctor.js +188 -0
  14. package/dist/cores/functions/dev.d.ts +1 -0
  15. package/dist/cores/functions/dev.js +6 -2
  16. package/dist/cores/index.d.ts +4 -1
  17. package/dist/server/app.d.ts +2 -1
  18. package/dist/server/app.js +3 -3
  19. package/dist/server/handlers/invoke.d.ts +2 -2
  20. package/dist/server/handlers/invoke.js +3 -3
  21. package/dist/utils/get-headers.js +1 -0
  22. package/oclif.manifest.json +46 -1
  23. package/package.json +2 -1
  24. package/dist/server/static/api.d.ts +0 -24
  25. package/dist/server/static/components/api-base.d.ts +0 -20
  26. package/dist/server/static/components/clear-button.d.ts +0 -6
  27. package/dist/server/static/components/codemirror-theme.d.ts +0 -6
  28. package/dist/server/static/components/console-panel.d.ts +0 -1
  29. package/dist/server/static/components/fetch-button.d.ts +0 -7
  30. package/dist/server/static/components/filters.d.ts +0 -1
  31. package/dist/server/static/components/function-list.d.ts +0 -1
  32. package/dist/server/static/components/help-button.d.ts +0 -3
  33. package/dist/server/static/components/network-spinner.d.ts +0 -1
  34. package/dist/server/static/components/payload-panel.d.ts +0 -1
  35. package/dist/server/static/components/response-panel.d.ts +0 -1
  36. package/dist/server/static/components/rule-panel.d.ts +0 -1
  37. package/dist/server/static/components/run-panel.d.ts +0 -1
  38. package/dist/server/static/components/select-dropdown.d.ts +0 -1
  39. package/dist/server/static/components/toggle-switch.d.ts +0 -11
  40. package/dist/server/static/hot-reload.d.ts +0 -1
  41. package/dist/server/static/vendor/vendor.bundle.d.ts +0 -2008
  42. package/dist/utils/child-process-wrapper.d.ts +0 -1
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/10.9.2 linux-x64 node-v22.19.0
23
+ @sanity/runtime-cli/10.11.0 linux-x64 node-v22.20.0
24
24
  $ sanity-run --help [COMMAND]
25
25
  USAGE
26
26
  $ sanity-run COMMAND
@@ -33,6 +33,7 @@ USAGE
33
33
  * [`sanity-run blueprints config`](#sanity-run-blueprints-config)
34
34
  * [`sanity-run blueprints deploy`](#sanity-run-blueprints-deploy)
35
35
  * [`sanity-run blueprints destroy`](#sanity-run-blueprints-destroy)
36
+ * [`sanity-run blueprints doctor`](#sanity-run-blueprints-doctor)
36
37
  * [`sanity-run blueprints info`](#sanity-run-blueprints-info)
37
38
  * [`sanity-run blueprints init [DIR]`](#sanity-run-blueprints-init-dir)
38
39
  * [`sanity-run blueprints logs`](#sanity-run-blueprints-logs)
@@ -88,7 +89,7 @@ EXAMPLES
88
89
  $ sanity-run blueprints add function --name my-function --fn-type document-create --fn-type document-update --lang js
89
90
  ```
90
91
 
91
- _See code: [src/commands/blueprints/add.ts](https://github.com/sanity-io/runtime-cli/blob/v10.9.2/src/commands/blueprints/add.ts)_
92
+ _See code: [src/commands/blueprints/add.ts](https://github.com/sanity-io/runtime-cli/blob/v10.11.0/src/commands/blueprints/add.ts)_
92
93
 
93
94
  ## `sanity-run blueprints config`
94
95
 
@@ -119,7 +120,7 @@ EXAMPLES
119
120
  $ sanity-run blueprints config --edit --project-id <projectId> --stack-id <stackId>
120
121
  ```
121
122
 
122
- _See code: [src/commands/blueprints/config.ts](https://github.com/sanity-io/runtime-cli/blob/v10.9.2/src/commands/blueprints/config.ts)_
123
+ _See code: [src/commands/blueprints/config.ts](https://github.com/sanity-io/runtime-cli/blob/v10.11.0/src/commands/blueprints/config.ts)_
123
124
 
124
125
  ## `sanity-run blueprints deploy`
125
126
 
@@ -141,7 +142,7 @@ EXAMPLES
141
142
  $ sanity-run blueprints deploy --no-wait
142
143
  ```
143
144
 
144
- _See code: [src/commands/blueprints/deploy.ts](https://github.com/sanity-io/runtime-cli/blob/v10.9.2/src/commands/blueprints/deploy.ts)_
145
+ _See code: [src/commands/blueprints/deploy.ts](https://github.com/sanity-io/runtime-cli/blob/v10.11.0/src/commands/blueprints/deploy.ts)_
145
146
 
146
147
  ## `sanity-run blueprints destroy`
147
148
 
@@ -166,7 +167,25 @@ EXAMPLES
166
167
  $ sanity-run blueprints destroy --stack-id <stackId> --project-id <projectId> --force --no-wait
167
168
  ```
168
169
 
169
- _See code: [src/commands/blueprints/destroy.ts](https://github.com/sanity-io/runtime-cli/blob/v10.9.2/src/commands/blueprints/destroy.ts)_
170
+ _See code: [src/commands/blueprints/destroy.ts](https://github.com/sanity-io/runtime-cli/blob/v10.11.0/src/commands/blueprints/destroy.ts)_
171
+
172
+ ## `sanity-run blueprints doctor`
173
+
174
+ Diagnose potential issues with Blueprint configuration
175
+
176
+ ```
177
+ USAGE
178
+ $ sanity-run blueprints doctor [--verbose] [--path <value>]
179
+
180
+ FLAGS
181
+ --path=<value> Path to the Blueprint configuration file
182
+ --verbose Provide detailed information about issues
183
+
184
+ DESCRIPTION
185
+ Diagnose potential issues with Blueprint configuration
186
+ ```
187
+
188
+ _See code: [src/commands/blueprints/doctor.ts](https://github.com/sanity-io/runtime-cli/blob/v10.11.0/src/commands/blueprints/doctor.ts)_
170
189
 
171
190
  ## `sanity-run blueprints info`
172
191
 
@@ -188,7 +207,7 @@ EXAMPLES
188
207
  $ sanity-run blueprints info --stack-id <stackId>
189
208
  ```
190
209
 
191
- _See code: [src/commands/blueprints/info.ts](https://github.com/sanity-io/runtime-cli/blob/v10.9.2/src/commands/blueprints/info.ts)_
210
+ _See code: [src/commands/blueprints/info.ts](https://github.com/sanity-io/runtime-cli/blob/v10.11.0/src/commands/blueprints/info.ts)_
192
211
 
193
212
  ## `sanity-run blueprints init [DIR]`
194
213
 
@@ -226,7 +245,7 @@ EXAMPLES
226
245
  $ sanity-run blueprints init --blueprint-type <json|js|ts> --stack-name <stackName>
227
246
  ```
228
247
 
229
- _See code: [src/commands/blueprints/init.ts](https://github.com/sanity-io/runtime-cli/blob/v10.9.2/src/commands/blueprints/init.ts)_
248
+ _See code: [src/commands/blueprints/init.ts](https://github.com/sanity-io/runtime-cli/blob/v10.11.0/src/commands/blueprints/init.ts)_
230
249
 
231
250
  ## `sanity-run blueprints logs`
232
251
 
@@ -248,7 +267,7 @@ EXAMPLES
248
267
  $ sanity-run blueprints logs --watch
249
268
  ```
250
269
 
251
- _See code: [src/commands/blueprints/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v10.9.2/src/commands/blueprints/logs.ts)_
270
+ _See code: [src/commands/blueprints/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v10.11.0/src/commands/blueprints/logs.ts)_
252
271
 
253
272
  ## `sanity-run blueprints plan`
254
273
 
@@ -265,7 +284,7 @@ EXAMPLES
265
284
  $ sanity-run blueprints plan
266
285
  ```
267
286
 
268
- _See code: [src/commands/blueprints/plan.ts](https://github.com/sanity-io/runtime-cli/blob/v10.9.2/src/commands/blueprints/plan.ts)_
287
+ _See code: [src/commands/blueprints/plan.ts](https://github.com/sanity-io/runtime-cli/blob/v10.11.0/src/commands/blueprints/plan.ts)_
269
288
 
270
289
  ## `sanity-run blueprints stacks`
271
290
 
@@ -287,7 +306,7 @@ EXAMPLES
287
306
  $ sanity-run blueprints stacks --project-id <projectId>
288
307
  ```
289
308
 
290
- _See code: [src/commands/blueprints/stacks.ts](https://github.com/sanity-io/runtime-cli/blob/v10.9.2/src/commands/blueprints/stacks.ts)_
309
+ _See code: [src/commands/blueprints/stacks.ts](https://github.com/sanity-io/runtime-cli/blob/v10.11.0/src/commands/blueprints/stacks.ts)_
291
310
 
292
311
  ## `sanity-run functions dev`
293
312
 
@@ -295,10 +314,12 @@ Start the Sanity Function emulator
295
314
 
296
315
  ```
297
316
  USAGE
298
- $ sanity-run functions dev [-p <value>]
317
+ $ sanity-run functions dev [-p <value>] [-t <value>]
299
318
 
300
319
  FLAGS
301
- -p, --port=<value> Port to start emulator on
320
+ -p, --port=<value> Port to start emulator on
321
+ -t, --timeout=<value> Maximum execution time for all functions, in seconds. Takes precedence over function-specific
322
+ `timeout`
302
323
 
303
324
  DESCRIPTION
304
325
  Start the Sanity Function emulator
@@ -307,7 +328,7 @@ EXAMPLES
307
328
  $ sanity-run functions dev --port 8974
308
329
  ```
309
330
 
310
- _See code: [src/commands/functions/dev.ts](https://github.com/sanity-io/runtime-cli/blob/v10.9.2/src/commands/functions/dev.ts)_
331
+ _See code: [src/commands/functions/dev.ts](https://github.com/sanity-io/runtime-cli/blob/v10.11.0/src/commands/functions/dev.ts)_
311
332
 
312
333
  ## `sanity-run functions env add NAME KEY VALUE`
313
334
 
@@ -329,7 +350,7 @@ EXAMPLES
329
350
  $ sanity-run functions env add MyFunction API_URL https://api.example.com/
330
351
  ```
331
352
 
332
- _See code: [src/commands/functions/env/add.ts](https://github.com/sanity-io/runtime-cli/blob/v10.9.2/src/commands/functions/env/add.ts)_
353
+ _See code: [src/commands/functions/env/add.ts](https://github.com/sanity-io/runtime-cli/blob/v10.11.0/src/commands/functions/env/add.ts)_
333
354
 
334
355
  ## `sanity-run functions env list NAME`
335
356
 
@@ -349,7 +370,7 @@ EXAMPLES
349
370
  $ sanity-run functions env list MyFunction
350
371
  ```
351
372
 
352
- _See code: [src/commands/functions/env/list.ts](https://github.com/sanity-io/runtime-cli/blob/v10.9.2/src/commands/functions/env/list.ts)_
373
+ _See code: [src/commands/functions/env/list.ts](https://github.com/sanity-io/runtime-cli/blob/v10.11.0/src/commands/functions/env/list.ts)_
353
374
 
354
375
  ## `sanity-run functions env remove NAME KEY`
355
376
 
@@ -370,7 +391,7 @@ EXAMPLES
370
391
  $ sanity-run functions env remove MyFunction API_URL
371
392
  ```
372
393
 
373
- _See code: [src/commands/functions/env/remove.ts](https://github.com/sanity-io/runtime-cli/blob/v10.9.2/src/commands/functions/env/remove.ts)_
394
+ _See code: [src/commands/functions/env/remove.ts](https://github.com/sanity-io/runtime-cli/blob/v10.11.0/src/commands/functions/env/remove.ts)_
374
395
 
375
396
  ## `sanity-run functions logs NAME`
376
397
 
@@ -404,7 +425,7 @@ EXAMPLES
404
425
  $ sanity-run functions logs <name> --delete
405
426
  ```
406
427
 
407
- _See code: [src/commands/functions/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v10.9.2/src/commands/functions/logs.ts)_
428
+ _See code: [src/commands/functions/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v10.11.0/src/commands/functions/logs.ts)_
408
429
 
409
430
  ## `sanity-run functions test NAME`
410
431
 
@@ -451,7 +472,7 @@ EXAMPLES
451
472
  $ sanity-run functions test <name> --event update --data-before '{ "title": "before" }' --data-after '{ "title": "after" }'
452
473
  ```
453
474
 
454
- _See code: [src/commands/functions/test.ts](https://github.com/sanity-io/runtime-cli/blob/v10.9.2/src/commands/functions/test.ts)_
475
+ _See code: [src/commands/functions/test.ts](https://github.com/sanity-io/runtime-cli/blob/v10.11.0/src/commands/functions/test.ts)_
455
476
 
456
477
  ## `sanity-run help [COMMAND]`
457
478
 
@@ -4,7 +4,7 @@ export interface BlueprintsConfig {
4
4
  projectId?: string;
5
5
  stackId?: string;
6
6
  }
7
- export declare function readConfigFile(blueprintFilePath: string): BlueprintsConfig | null;
7
+ export declare function readConfigFile(blueprintFilePath?: string): BlueprintsConfig | null;
8
8
  export declare function writeConfigFile({ blueprintFilePath, organizationId, projectId, stackId, }: {
9
9
  blueprintFilePath?: string;
10
10
  stackId?: string;
@@ -3,7 +3,7 @@ import { dirname, join } from 'node:path';
3
3
  import { cwd } from 'node:process';
4
4
  import { BLUEPRINT_CONFIG_FILE, BLUEPRINT_CONFIG_VERSION, BLUEPRINT_DIR } from '../../config.js';
5
5
  export function readConfigFile(blueprintFilePath) {
6
- const blueprintDir = dirname(blueprintFilePath);
6
+ const blueprintDir = blueprintFilePath ? dirname(blueprintFilePath) : cwd();
7
7
  const configPath = join(blueprintDir, BLUEPRINT_DIR, BLUEPRINT_CONFIG_FILE);
8
8
  if (existsSync(configPath)) {
9
9
  try {
@@ -14,16 +14,7 @@ export function readConfigFile(blueprintFilePath) {
14
14
  return null;
15
15
  }
16
16
  }
17
- const configFilePath = join(cwd(), BLUEPRINT_DIR, BLUEPRINT_CONFIG_FILE);
18
- if (!existsSync(configFilePath))
19
- return null;
20
- try {
21
- const config = JSON.parse(readFileSync(configFilePath, 'utf8'));
22
- return config || null;
23
- }
24
- catch {
25
- return null;
26
- }
17
+ return null;
27
18
  }
28
19
  export function writeConfigFile({ blueprintFilePath, organizationId, projectId, stackId, }) {
29
20
  const blueprintDir = blueprintFilePath ? dirname(blueprintFilePath) : cwd();
@@ -10,6 +10,7 @@ interface GetStackResponse {
10
10
  ok: boolean;
11
11
  error: string | null;
12
12
  stack: Stack;
13
+ response: Response;
13
14
  }
14
15
  export declare function getStack({ stackId, auth, }: {
15
16
  stackId: string;
@@ -47,6 +47,7 @@ export async function getStack({ stackId, auth, }) {
47
47
  ok: response.ok,
48
48
  error: response.ok ? null : data.message,
49
49
  stack: response.ok ? flattenStackResources(data) : data,
50
+ response,
50
51
  };
51
52
  }
52
53
  export async function createStack({ stackMutation, auth, }) {
@@ -1 +1,2 @@
1
- export declare function dev(port: number): Promise<void>;
1
+ import type { InvokeExecutionOptions } from '../../utils/types.js';
2
+ export declare function dev(port: number, executionOptions?: Partial<InvokeExecutionOptions>): Promise<void>;
@@ -1,4 +1,4 @@
1
1
  import { app } from '../../server/app.js';
2
- export async function dev(port) {
3
- app(Number(port));
2
+ export async function dev(port, executionOptions) {
3
+ app(Number(port), executionOptions);
4
4
  }
@@ -0,0 +1,10 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class DoctorCommand extends Command {
3
+ static description: string;
4
+ static examples: never[];
5
+ static flags: {
6
+ verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
+ path: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
8
+ };
9
+ run(): Promise<void>;
10
+ }
@@ -0,0 +1,28 @@
1
+ import { Command, Flags } from '@oclif/core';
2
+ import config from '../../config.js';
3
+ import { blueprintDoctorCore } from '../../cores/blueprints/doctor.js';
4
+ export default class DoctorCommand extends Command {
5
+ static description = 'Diagnose potential issues with Blueprint configuration';
6
+ static examples = [];
7
+ static flags = {
8
+ verbose: Flags.boolean({
9
+ description: 'Provide detailed information about issues',
10
+ default: false,
11
+ }),
12
+ path: Flags.string({
13
+ description: 'Path to the Blueprint configuration file',
14
+ }),
15
+ };
16
+ async run() {
17
+ const { flags } = await this.parse(DoctorCommand);
18
+ const { token } = config;
19
+ const { success, error } = await blueprintDoctorCore({
20
+ bin: this.config.bin,
21
+ log: (message) => this.log(message),
22
+ token,
23
+ flags,
24
+ });
25
+ if (!success)
26
+ this.error(error);
27
+ }
28
+ }
@@ -4,6 +4,7 @@ export default class DevCommand extends Command {
4
4
  static examples: string[];
5
5
  static flags: {
6
6
  port: import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
+ timeout: import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
8
  };
8
9
  run(): Promise<void>;
9
10
  }
@@ -5,6 +5,11 @@ export default class DevCommand extends Command {
5
5
  static examples = ['<%= config.bin %> <%= command.id %> --port 8974'];
6
6
  static flags = {
7
7
  port: Flags.integer({ char: 'p', description: 'Port to start emulator on', required: false }),
8
+ timeout: Flags.integer({
9
+ char: 't',
10
+ description: 'Maximum execution time for all functions, in seconds. Takes precedence over function-specific `timeout`',
11
+ required: false,
12
+ }),
8
13
  };
9
14
  async run() {
10
15
  const { flags } = await this.parse(DevCommand);
@@ -0,0 +1,9 @@
1
+ import type { CoreConfig, CoreResult } from '../index.js';
2
+ export interface BlueprintDoctorOptions extends CoreConfig {
3
+ token: string | null;
4
+ flags: {
5
+ verbose: boolean;
6
+ path: string | undefined;
7
+ };
8
+ }
9
+ export declare function blueprintDoctorCore(options: BlueprintDoctorOptions): Promise<CoreResult>;
@@ -0,0 +1,188 @@
1
+ import { cwd } from 'node:process';
2
+ import chalk from 'chalk';
3
+ import ora from 'ora';
4
+ import { findBlueprintFile, readLocalBlueprint, } from '../../actions/blueprints/blueprint.js';
5
+ import { getStack } from '../../actions/blueprints/stacks.js';
6
+ import config from '../../config.js';
7
+ import { check, indent, niceId, severe, warn } from '../../utils/display/presenters.js';
8
+ import { validTokenOrErrorMessage } from '../../utils/validated-token.js';
9
+ const diagLookup = {
10
+ online: 'Online',
11
+ tokenPresent: 'Auth token present',
12
+ tokenValid: 'Auth token valid',
13
+ configFilePresent: 'Blueprints config file present',
14
+ configFileValid: 'Blueprints config file valid',
15
+ blueprintPresent: 'Blueprint file present',
16
+ blueprintValid: 'Blueprint file valid',
17
+ stackReady: 'Deployment "Stack" ready',
18
+ userHasAccess: 'User has access to "Stack"',
19
+ };
20
+ export async function blueprintDoctorCore(options) {
21
+ const { log, token, flags: { verbose: v, path: p }, } = options;
22
+ const yikes = (s) => {
23
+ log(chalk.bgRedBright.whiteBright.bold(` ${s} `));
24
+ };
25
+ const here = cwd();
26
+ const path = p || here;
27
+ if (v)
28
+ log(`Checking ${path}`);
29
+ // 3 states: null == unknown, true == good, false == bad
30
+ const diagnostics = {};
31
+ for (const key in diagLookup) {
32
+ diagnostics[key] = null;
33
+ }
34
+ let spinner;
35
+ if (!v)
36
+ spinner = ora('Checking environment').start();
37
+ // ONLINE
38
+ try {
39
+ const res = await fetch(config.apiUrl);
40
+ if (res.ok) {
41
+ if (v)
42
+ log(`Successfully pinged ${config.apiUrl}`);
43
+ diagnostics.online = res.ok;
44
+ }
45
+ else {
46
+ if (v)
47
+ yikes(`Failed to ping ${config.apiUrl}: ${res.status} ${res.statusText}`);
48
+ diagnostics.online = false;
49
+ }
50
+ }
51
+ catch {
52
+ if (v)
53
+ yikes(`Failed to ping ${config.apiUrl}`);
54
+ }
55
+ // TOKEN
56
+ if (token) {
57
+ diagnostics.tokenPresent = true;
58
+ const tokenOrError = await validTokenOrErrorMessage(token);
59
+ if (tokenOrError.ok) {
60
+ diagnostics.tokenValid = true;
61
+ }
62
+ else {
63
+ if (v)
64
+ yikes(`Token error: ${tokenOrError.error}`);
65
+ diagnostics.tokenValid = false;
66
+ }
67
+ }
68
+ else {
69
+ diagnostics.tokenPresent = false;
70
+ }
71
+ // BLUEPRINT file
72
+ const blueprintFile = findBlueprintFile(path);
73
+ if (blueprintFile?.blueprintFilePath) {
74
+ if (v)
75
+ log(`Found blueprint file at ${blueprintFile.blueprintFilePath.replace(here, '.')}`);
76
+ diagnostics.blueprintPresent = true;
77
+ }
78
+ else {
79
+ diagnostics.blueprintPresent = false;
80
+ }
81
+ let blueprint;
82
+ try {
83
+ blueprint = await readLocalBlueprint(path);
84
+ if (blueprint.errors.length === 0) {
85
+ if (v)
86
+ log(`Blueprint has no errors`);
87
+ diagnostics.blueprintValid = true;
88
+ }
89
+ else {
90
+ if (v)
91
+ log(`Blueprint errors: \n${blueprint.errors.join('\n ')}`);
92
+ diagnostics.blueprintValid = false;
93
+ }
94
+ }
95
+ catch {
96
+ if (v)
97
+ yikes(`Unable to read blueprint`);
98
+ diagnostics.blueprintValid = false;
99
+ }
100
+ if (blueprint) {
101
+ const { configPath, scopeType, scopeId, stackId, projectId } = blueprint;
102
+ // CONFIG file
103
+ if (configPath) {
104
+ if (v)
105
+ log(`Found config file at ${configPath.replace(here, '.')}`);
106
+ diagnostics.configFilePresent = true;
107
+ if (scopeType && scopeId && stackId) {
108
+ diagnostics.configFileValid = true;
109
+ if (v) {
110
+ const capitalizedScopeType = scopeType.charAt(0).toUpperCase() + scopeType.slice(1);
111
+ const configOutput = [
112
+ `${capitalizedScopeType}: ${niceId(scopeId)}`,
113
+ `Deployment: ${niceId(stackId)}`,
114
+ ].join('\n');
115
+ log(indent(configOutput));
116
+ }
117
+ }
118
+ else {
119
+ diagnostics.configFileValid = false;
120
+ }
121
+ }
122
+ else {
123
+ diagnostics.configFilePresent = false;
124
+ }
125
+ // STACK + ACCESS
126
+ if (diagnostics.online && diagnostics.tokenValid && token && stackId && projectId) {
127
+ const stackResponse = await getStack({
128
+ auth: { token, projectId },
129
+ stackId,
130
+ });
131
+ if (stackResponse.ok) {
132
+ if (v)
133
+ log(`Deployment "Stack" ${niceId(stackId)} ready`);
134
+ diagnostics.stackReady = true;
135
+ diagnostics.userHasAccess = true;
136
+ }
137
+ else if (stackResponse.response.status === 404) {
138
+ if (v)
139
+ yikes(`Deployment "Stack" <${stackId}> not found`);
140
+ diagnostics.stackReady = false;
141
+ }
142
+ else if (stackResponse.response.status === 403 || stackResponse.response.status === 401) {
143
+ if (v)
144
+ yikes(`User does not have access to "Stack" <${stackId}>`);
145
+ diagnostics.userHasAccess = false;
146
+ }
147
+ else {
148
+ if (v)
149
+ yikes(`Unknown error with "Stack" <${stackId}>: ${stackResponse.error}`);
150
+ }
151
+ }
152
+ else {
153
+ if (v)
154
+ yikes('Unable to check deployment "Stack" status.');
155
+ }
156
+ }
157
+ if (spinner)
158
+ spinner.stop();
159
+ if (v)
160
+ log('');
161
+ let allGood = true;
162
+ for (const [key, value] of Object.entries(diagnostics)) {
163
+ switch (value) {
164
+ case true:
165
+ if (v)
166
+ log(check(diagLookup[key]));
167
+ break;
168
+ case false:
169
+ allGood = false;
170
+ log(severe(diagLookup[key]));
171
+ break;
172
+ case null:
173
+ allGood = false;
174
+ log(warn(diagLookup[key]));
175
+ break;
176
+ default:
177
+ allGood = false;
178
+ log(severe(`${key} is ${value}`));
179
+ }
180
+ }
181
+ if (allGood) {
182
+ log(chalk.bold.green('All checks passed'));
183
+ return { success: true, data: { diagnostics } };
184
+ }
185
+ else {
186
+ return { success: false, error: 'One or more checks failed', data: { diagnostics } };
187
+ }
188
+ }
@@ -2,6 +2,7 @@ import type { CoreConfig, CoreResult } from '../index.js';
2
2
  export interface FunctionDevOptions extends CoreConfig {
3
3
  flags: {
4
4
  port?: number;
5
+ timeout?: number;
5
6
  };
6
7
  }
7
8
  export declare function functionDevCore(options: FunctionDevOptions): Promise<CoreResult>;
@@ -1,9 +1,13 @@
1
1
  import { dev } from '../../actions/functions/dev.js';
2
2
  export async function functionDevCore(options) {
3
3
  const { log, flags } = options;
4
- const { port = 8080 } = flags;
4
+ const { port = 8080, timeout } = flags;
5
+ // Construct execution options only if timeout is provided
6
+ const executionOptions = timeout
7
+ ? { timeout }
8
+ : undefined;
5
9
  try {
6
- await dev(Number(port));
10
+ await dev(Number(port), executionOptions);
7
11
  log(`Server is running on http://localhost:${port}\n`);
8
12
  return {
9
13
  success: true,
@@ -19,6 +19,9 @@ export interface DeployedBlueprintConfig extends BlueprintConfig {
19
19
  deployedStack: Stack;
20
20
  }
21
21
  export type CoreResult = {
22
+ /** Arbitrary data for isolated testing */
23
+ data?: Record<string, unknown>;
24
+ } & ({
22
25
  /** Something went wrong. */
23
26
  success: false;
24
27
  /** The error message, if the operation failed. */
@@ -30,7 +33,7 @@ export type CoreResult = {
30
33
  /** The streaming function, if the operation is streaming. */
31
34
  streaming?: Promise<void>;
32
35
  error?: never;
33
- };
36
+ });
34
37
  type InitBlueprintConfigParams = {
35
38
  bin: string;
36
39
  log: (msg: string) => void;
@@ -1,4 +1,5 @@
1
- declare const app: (port: number) => void;
1
+ import { type InvokeExecutionOptions } from '../utils/types.js';
2
+ declare const app: (port: number, executionOptions?: Partial<InvokeExecutionOptions>) => void;
2
3
  declare function parseDocumentUrl(url: string): {
3
4
  projectId: string;
4
5
  dataset: string;
@@ -5,10 +5,10 @@ import { WebSocketServer } from 'ws';
5
5
  import { readLocalBlueprint } from '../actions/blueprints/blueprint.js';
6
6
  import config from '../config.js';
7
7
  import { isRecord } from '../utils/is-record.js';
8
- import { isEventType } from '../utils/types.js';
8
+ import { isEventType, } from '../utils/types.js';
9
9
  import { handleInvokeRequest } from './handlers/invoke.js';
10
10
  const host = 'localhost';
11
- const app = (port) => {
11
+ const app = (port, executionOptions) => {
12
12
  const requestListener = async (req, res) => {
13
13
  res.setHeader('Content-Type', 'application/json');
14
14
  switch (true) {
@@ -41,7 +41,7 @@ const app = (port) => {
41
41
  else {
42
42
  delete context.clientOptions.token;
43
43
  }
44
- const result = await handleInvokeRequest(functionName, event, metadata, context);
44
+ const result = await handleInvokeRequest(functionName, event, metadata, context, executionOptions);
45
45
  // Add Server-Timing header
46
46
  const timingHeaders = [];
47
47
  for (const [key, value] of Object.entries(result.timings)) {
@@ -1,4 +1,4 @@
1
- import type { InvocationResponse, InvokeContextOptions, InvokePayloadOptions } from '../../utils/types.js';
2
- export declare function handleInvokeRequest(functionName: string, event: Record<string, unknown>, metadata: Pick<InvokePayloadOptions, 'event' | 'before' | 'after'>, context: InvokeContextOptions): Promise<InvocationResponse & {
1
+ import type { InvocationResponse, InvokeContextOptions, InvokeExecutionOptions, InvokePayloadOptions } from '../../utils/types.js';
2
+ export declare function handleInvokeRequest(functionName: string, event: Record<string, unknown>, metadata: Pick<InvokePayloadOptions, 'event' | 'before' | 'after'>, context: InvokeContextOptions, executionOptions?: Partial<InvokeExecutionOptions>): Promise<InvocationResponse & {
3
3
  timings: Record<string, number>;
4
4
  }>;
@@ -1,7 +1,7 @@
1
1
  import { readLocalBlueprint } from '../../actions/blueprints/blueprint.js';
2
2
  import { findFunctionByName } from '../../utils/find-function.js';
3
3
  import invoke from '../../utils/invoke-local.js';
4
- export async function handleInvokeRequest(functionName, event, metadata, context) {
4
+ export async function handleInvokeRequest(functionName, event, metadata, context, executionOptions) {
5
5
  const start = performance.now();
6
6
  const { parsedBlueprint } = await readLocalBlueprint();
7
7
  const resource = findFunctionByName(parsedBlueprint, functionName);
@@ -11,8 +11,8 @@ export async function handleInvokeRequest(functionName, event, metadata, context
11
11
  ...metadata,
12
12
  };
13
13
  const response = await invoke(resource, payload, context, {
14
- forceColor: false,
15
- timeout: resource.timeout,
14
+ forceColor: executionOptions?.forceColor ?? false,
15
+ timeout: executionOptions?.timeout ?? resource.timeout,
16
16
  });
17
17
  const timings = { ...response.timings, 'blueprint:read': readBlueprintTime };
18
18
  return { ...response, timings };
@@ -9,6 +9,7 @@ async function getUserAgent() {
9
9
  }
10
10
  }
11
11
  export default function getHeaders({ token, projectId }) {
12
+ // TODO: support organization scope type
12
13
  return {
13
14
  Accept: 'application/json',
14
15
  'Content-Type': 'application/json',