@sanity/runtime-cli 16.0.3 → 17.1.0-next.g3cb2d2e
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 +27 -22
- package/dist/actions/functions/test.js +1 -1
- package/dist/baseCommands.js +13 -2
- package/dist/commands/blueprints/init.js +5 -2
- package/dist/config.d.ts +1 -0
- package/dist/config.js +7 -1
- package/dist/constants.d.ts +1 -0
- package/dist/constants.js +1 -0
- package/dist/cores/blueprints/init.js +16 -2
- package/dist/cores/functions/test.js +44 -0
- package/dist/server/app.js +31 -3
- package/dist/server/handlers/invoke.d.ts +2 -2
- package/dist/server/handlers/invoke.js +7 -4
- package/dist/server/static/components/console-panel.js +59 -8
- package/dist/server/static/components/rule-panel.js +11 -8
- package/dist/server/static/components/shared-styles.js +24 -21
- package/dist/server/static/index.html +1 -1
- package/dist/server/static/vendor/design-tokens/color.css +48 -48
- package/dist/server/static/vendor/design-tokens/index.css +0 -1
- package/dist/server/static/vendor/vendor.bundle.js +3807 -3259
- package/dist/server/static/web-socket.js +41 -0
- package/dist/utils/functions/child-process-wrapper.js +62 -7
- package/dist/utils/functions/{invoke-local.d.ts → invoke/local.d.ts} +1 -1
- package/dist/utils/functions/invoke/local.js +306 -0
- package/dist/utils/functions/invoke/nested.d.ts +25 -0
- package/dist/utils/functions/invoke/nested.js +41 -0
- package/dist/utils/functions/invoke/prepare.d.ts +20 -0
- package/dist/utils/functions/invoke/prepare.js +90 -0
- package/dist/utils/interactive.d.ts +1 -0
- package/dist/utils/interactive.js +4 -0
- package/dist/utils/isTrueish.d.ts +6 -0
- package/dist/utils/isTrueish.js +9 -0
- package/dist/utils/logger.d.ts +1 -0
- package/dist/utils/logger.js +1 -0
- package/dist/utils/style-text.js +4 -5
- package/dist/utils/traced-fetch.js +2 -0
- package/dist/utils/types.d.ts +62 -4
- package/oclif.manifest.json +4 -3
- package/package.json +18 -14
- package/dist/server/static/hot-reload.js +0 -16
- package/dist/utils/functions/invoke-local.js +0 -185
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/
|
|
23
|
+
@sanity/runtime-cli/17.1.0-next.g3cb2d2e linux-x64 node-v24.18.0
|
|
24
24
|
$ sanity-run --help [COMMAND]
|
|
25
25
|
USAGE
|
|
26
26
|
$ sanity-run COMMAND
|
|
@@ -103,7 +103,7 @@ EXAMPLES
|
|
|
103
103
|
$ sanity-run blueprints add function --name my-function --fn-type document-create --fn-type document-update --lang js
|
|
104
104
|
```
|
|
105
105
|
|
|
106
|
-
_See code: [src/commands/blueprints/add.ts](https://github.com/sanity-io/runtime-cli/blob/
|
|
106
|
+
_See code: [src/commands/blueprints/add.ts](https://github.com/sanity-io/runtime-cli/blob/v17.1.0-next.g3cb2d2e/src/commands/blueprints/add.ts)_
|
|
107
107
|
|
|
108
108
|
## `sanity-run blueprints config`
|
|
109
109
|
|
|
@@ -140,7 +140,7 @@ EXAMPLES
|
|
|
140
140
|
$ sanity-run blueprints config --edit --project-id <projectId> --stack <name-or-id>
|
|
141
141
|
```
|
|
142
142
|
|
|
143
|
-
_See code: [src/commands/blueprints/config.ts](https://github.com/sanity-io/runtime-cli/blob/
|
|
143
|
+
_See code: [src/commands/blueprints/config.ts](https://github.com/sanity-io/runtime-cli/blob/v17.1.0-next.g3cb2d2e/src/commands/blueprints/config.ts)_
|
|
144
144
|
|
|
145
145
|
## `sanity-run blueprints deploy`
|
|
146
146
|
|
|
@@ -194,7 +194,7 @@ EXAMPLES
|
|
|
194
194
|
$ sanity-run blueprints deploy --new-stack-name <new-name>
|
|
195
195
|
```
|
|
196
196
|
|
|
197
|
-
_See code: [src/commands/blueprints/deploy.ts](https://github.com/sanity-io/runtime-cli/blob/
|
|
197
|
+
_See code: [src/commands/blueprints/deploy.ts](https://github.com/sanity-io/runtime-cli/blob/v17.1.0-next.g3cb2d2e/src/commands/blueprints/deploy.ts)_
|
|
198
198
|
|
|
199
199
|
## `sanity-run blueprints destroy`
|
|
200
200
|
|
|
@@ -232,7 +232,7 @@ EXAMPLES
|
|
|
232
232
|
$ sanity-run blueprints destroy --stack <name-or-id> --project-id <projectId> --force --no-wait
|
|
233
233
|
```
|
|
234
234
|
|
|
235
|
-
_See code: [src/commands/blueprints/destroy.ts](https://github.com/sanity-io/runtime-cli/blob/
|
|
235
|
+
_See code: [src/commands/blueprints/destroy.ts](https://github.com/sanity-io/runtime-cli/blob/v17.1.0-next.g3cb2d2e/src/commands/blueprints/destroy.ts)_
|
|
236
236
|
|
|
237
237
|
## `sanity-run blueprints doctor`
|
|
238
238
|
|
|
@@ -263,7 +263,7 @@ EXAMPLES
|
|
|
263
263
|
$ sanity-run blueprints doctor --fix
|
|
264
264
|
```
|
|
265
265
|
|
|
266
|
-
_See code: [src/commands/blueprints/doctor.ts](https://github.com/sanity-io/runtime-cli/blob/
|
|
266
|
+
_See code: [src/commands/blueprints/doctor.ts](https://github.com/sanity-io/runtime-cli/blob/v17.1.0-next.g3cb2d2e/src/commands/blueprints/doctor.ts)_
|
|
267
267
|
|
|
268
268
|
## `sanity-run blueprints info`
|
|
269
269
|
|
|
@@ -300,7 +300,7 @@ EXAMPLES
|
|
|
300
300
|
$ sanity-run blueprints info --organization-id <orgId> --stack <name-or-id>
|
|
301
301
|
```
|
|
302
302
|
|
|
303
|
-
_See code: [src/commands/blueprints/info.ts](https://github.com/sanity-io/runtime-cli/blob/
|
|
303
|
+
_See code: [src/commands/blueprints/info.ts](https://github.com/sanity-io/runtime-cli/blob/v17.1.0-next.g3cb2d2e/src/commands/blueprints/info.ts)_
|
|
304
304
|
|
|
305
305
|
## `sanity-run blueprints init [DIR]`
|
|
306
306
|
|
|
@@ -312,7 +312,7 @@ USAGE
|
|
|
312
312
|
--stack-id <value> | --stack-name <value>] [--project-id <value> | --organization-id <value>]
|
|
313
313
|
|
|
314
314
|
ARGUMENTS
|
|
315
|
-
[DIR] Directory to create the local Blueprint in
|
|
315
|
+
[DIR] Directory to create the local Blueprint in (defaults to the current directory)
|
|
316
316
|
|
|
317
317
|
FLAGS
|
|
318
318
|
--blueprint-type=<option> Blueprint manifest type to use for the local Blueprint
|
|
@@ -339,9 +339,14 @@ DESCRIPTION
|
|
|
339
339
|
|
|
340
340
|
After initialization, use 'blueprints plan' to preview changes, then 'blueprints deploy' to apply them.
|
|
341
341
|
|
|
342
|
+
Running without a directory prompts to confirm the current directory. Run 'blueprints init .' to initialize in the
|
|
343
|
+
current directory without a prompt.
|
|
344
|
+
|
|
342
345
|
EXAMPLES
|
|
343
346
|
$ sanity-run blueprints init
|
|
344
347
|
|
|
348
|
+
$ sanity-run blueprints init .
|
|
349
|
+
|
|
345
350
|
$ sanity-run blueprints init [directory]
|
|
346
351
|
|
|
347
352
|
$ sanity-run blueprints init --blueprint-type <json|js|ts>
|
|
@@ -359,7 +364,7 @@ EXAMPLES
|
|
|
359
364
|
$ sanity-run blueprints init old-stack --type <json|js|ts> --project-id <projectId> --stack-id <existingStackId>
|
|
360
365
|
```
|
|
361
366
|
|
|
362
|
-
_See code: [src/commands/blueprints/init.ts](https://github.com/sanity-io/runtime-cli/blob/
|
|
367
|
+
_See code: [src/commands/blueprints/init.ts](https://github.com/sanity-io/runtime-cli/blob/v17.1.0-next.g3cb2d2e/src/commands/blueprints/init.ts)_
|
|
363
368
|
|
|
364
369
|
## `sanity-run blueprints logs`
|
|
365
370
|
|
|
@@ -405,7 +410,7 @@ EXAMPLES
|
|
|
405
410
|
$ sanity-run blueprints logs --before 2026-05-01T00:00:00Z
|
|
406
411
|
```
|
|
407
412
|
|
|
408
|
-
_See code: [src/commands/blueprints/logs.ts](https://github.com/sanity-io/runtime-cli/blob/
|
|
413
|
+
_See code: [src/commands/blueprints/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v17.1.0-next.g3cb2d2e/src/commands/blueprints/logs.ts)_
|
|
409
414
|
|
|
410
415
|
## `sanity-run blueprints mint-deploy-token`
|
|
411
416
|
|
|
@@ -450,7 +455,7 @@ EXAMPLES
|
|
|
450
455
|
$ sanity-run blueprints mint-deploy-token --organization-id <orgId>
|
|
451
456
|
```
|
|
452
457
|
|
|
453
|
-
_See code: [src/commands/blueprints/mint-deploy-token.ts](https://github.com/sanity-io/runtime-cli/blob/
|
|
458
|
+
_See code: [src/commands/blueprints/mint-deploy-token.ts](https://github.com/sanity-io/runtime-cli/blob/v17.1.0-next.g3cb2d2e/src/commands/blueprints/mint-deploy-token.ts)_
|
|
454
459
|
|
|
455
460
|
## `sanity-run blueprints plan`
|
|
456
461
|
|
|
@@ -483,7 +488,7 @@ EXAMPLES
|
|
|
483
488
|
$ sanity-run blueprints plan --organization-id <orgId> --stack <name-or-id>
|
|
484
489
|
```
|
|
485
490
|
|
|
486
|
-
_See code: [src/commands/blueprints/plan.ts](https://github.com/sanity-io/runtime-cli/blob/
|
|
491
|
+
_See code: [src/commands/blueprints/plan.ts](https://github.com/sanity-io/runtime-cli/blob/v17.1.0-next.g3cb2d2e/src/commands/blueprints/plan.ts)_
|
|
487
492
|
|
|
488
493
|
## `sanity-run blueprints promote`
|
|
489
494
|
|
|
@@ -519,7 +524,7 @@ EXAMPLES
|
|
|
519
524
|
$ sanity-run blueprints promote --new-stack-name <new-name>
|
|
520
525
|
```
|
|
521
526
|
|
|
522
|
-
_See code: [src/commands/blueprints/promote.ts](https://github.com/sanity-io/runtime-cli/blob/
|
|
527
|
+
_See code: [src/commands/blueprints/promote.ts](https://github.com/sanity-io/runtime-cli/blob/v17.1.0-next.g3cb2d2e/src/commands/blueprints/promote.ts)_
|
|
523
528
|
|
|
524
529
|
## `sanity-run blueprints stacks`
|
|
525
530
|
|
|
@@ -555,7 +560,7 @@ EXAMPLES
|
|
|
555
560
|
$ sanity-run blueprints stacks --organization-id <organizationId> --include-projects
|
|
556
561
|
```
|
|
557
562
|
|
|
558
|
-
_See code: [src/commands/blueprints/stacks.ts](https://github.com/sanity-io/runtime-cli/blob/
|
|
563
|
+
_See code: [src/commands/blueprints/stacks.ts](https://github.com/sanity-io/runtime-cli/blob/v17.1.0-next.g3cb2d2e/src/commands/blueprints/stacks.ts)_
|
|
559
564
|
|
|
560
565
|
## `sanity-run functions add`
|
|
561
566
|
|
|
@@ -607,7 +612,7 @@ EXAMPLES
|
|
|
607
612
|
$ sanity-run functions add --name my-function --type document-create --type document-update --lang js
|
|
608
613
|
```
|
|
609
614
|
|
|
610
|
-
_See code: [src/commands/functions/add.ts](https://github.com/sanity-io/runtime-cli/blob/
|
|
615
|
+
_See code: [src/commands/functions/add.ts](https://github.com/sanity-io/runtime-cli/blob/v17.1.0-next.g3cb2d2e/src/commands/functions/add.ts)_
|
|
611
616
|
|
|
612
617
|
## `sanity-run functions dev`
|
|
613
618
|
|
|
@@ -642,7 +647,7 @@ EXAMPLES
|
|
|
642
647
|
$ sanity-run functions dev --timeout 60
|
|
643
648
|
```
|
|
644
649
|
|
|
645
|
-
_See code: [src/commands/functions/dev.ts](https://github.com/sanity-io/runtime-cli/blob/
|
|
650
|
+
_See code: [src/commands/functions/dev.ts](https://github.com/sanity-io/runtime-cli/blob/v17.1.0-next.g3cb2d2e/src/commands/functions/dev.ts)_
|
|
646
651
|
|
|
647
652
|
## `sanity-run functions env add NAME KEY VALUE`
|
|
648
653
|
|
|
@@ -672,7 +677,7 @@ EXAMPLES
|
|
|
672
677
|
$ sanity-run functions env add MyFunction API_URL https://api.example.com/
|
|
673
678
|
```
|
|
674
679
|
|
|
675
|
-
_See code: [src/commands/functions/env/add.ts](https://github.com/sanity-io/runtime-cli/blob/
|
|
680
|
+
_See code: [src/commands/functions/env/add.ts](https://github.com/sanity-io/runtime-cli/blob/v17.1.0-next.g3cb2d2e/src/commands/functions/env/add.ts)_
|
|
676
681
|
|
|
677
682
|
## `sanity-run functions env list NAME`
|
|
678
683
|
|
|
@@ -699,7 +704,7 @@ EXAMPLES
|
|
|
699
704
|
$ sanity-run functions env list MyFunction
|
|
700
705
|
```
|
|
701
706
|
|
|
702
|
-
_See code: [src/commands/functions/env/list.ts](https://github.com/sanity-io/runtime-cli/blob/
|
|
707
|
+
_See code: [src/commands/functions/env/list.ts](https://github.com/sanity-io/runtime-cli/blob/v17.1.0-next.g3cb2d2e/src/commands/functions/env/list.ts)_
|
|
703
708
|
|
|
704
709
|
## `sanity-run functions env remove NAME KEY`
|
|
705
710
|
|
|
@@ -728,7 +733,7 @@ EXAMPLES
|
|
|
728
733
|
$ sanity-run functions env remove MyFunction API_URL
|
|
729
734
|
```
|
|
730
735
|
|
|
731
|
-
_See code: [src/commands/functions/env/remove.ts](https://github.com/sanity-io/runtime-cli/blob/
|
|
736
|
+
_See code: [src/commands/functions/env/remove.ts](https://github.com/sanity-io/runtime-cli/blob/v17.1.0-next.g3cb2d2e/src/commands/functions/env/remove.ts)_
|
|
732
737
|
|
|
733
738
|
## `sanity-run functions logs [NAME]`
|
|
734
739
|
|
|
@@ -768,7 +773,7 @@ EXAMPLES
|
|
|
768
773
|
$ sanity-run functions logs <name> --delete
|
|
769
774
|
```
|
|
770
775
|
|
|
771
|
-
_See code: [src/commands/functions/logs.ts](https://github.com/sanity-io/runtime-cli/blob/
|
|
776
|
+
_See code: [src/commands/functions/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v17.1.0-next.g3cb2d2e/src/commands/functions/logs.ts)_
|
|
772
777
|
|
|
773
778
|
## `sanity-run functions test [NAME]`
|
|
774
779
|
|
|
@@ -825,7 +830,7 @@ EXAMPLES
|
|
|
825
830
|
$ sanity-run functions test <name> --event update --data-before '{ "title": "before" }' --data-after '{ "title": "after" }'
|
|
826
831
|
```
|
|
827
832
|
|
|
828
|
-
_See code: [src/commands/functions/test.ts](https://github.com/sanity-io/runtime-cli/blob/
|
|
833
|
+
_See code: [src/commands/functions/test.ts](https://github.com/sanity-io/runtime-cli/blob/v17.1.0-next.g3cb2d2e/src/commands/functions/test.ts)_
|
|
829
834
|
|
|
830
835
|
## `sanity-run help [COMMAND]`
|
|
831
836
|
|
|
@@ -845,5 +850,5 @@ DESCRIPTION
|
|
|
845
850
|
Display help for sanity-run.
|
|
846
851
|
```
|
|
847
852
|
|
|
848
|
-
_See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/6.2.
|
|
853
|
+
_See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/6.2.53/src/commands/help.ts)_
|
|
849
854
|
<!-- commandsstop -->
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import invoke from '../../utils/functions/invoke
|
|
1
|
+
import invoke from '../../utils/functions/invoke/local.js';
|
|
2
2
|
export async function testAction(resource, payload, context, options) {
|
|
3
3
|
try {
|
|
4
4
|
const { json, logs, error } = await invoke(resource, payload, context, options);
|
package/dist/baseCommands.js
CHANGED
|
@@ -4,6 +4,8 @@ import { findBlueprintFile, loadBlueprintFile, parseBlueprintContent, } from './
|
|
|
4
4
|
import { backfillProjectBasedStackId, readConfigFile, } from './actions/blueprints/config.js';
|
|
5
5
|
import { resolveIds } from './actions/blueprints/resolve.js';
|
|
6
6
|
import { getStack, resolveStackIdByNameOrId } from './actions/blueprints/stacks.js';
|
|
7
|
+
import config from './config.js';
|
|
8
|
+
import { CI_SETUP_DOCS_URL } from './constants.js';
|
|
7
9
|
import { presentBlueprintParserErrors } from './utils/display/errors.js';
|
|
8
10
|
import { Logger } from './utils/logger.js';
|
|
9
11
|
import { styleText } from './utils/style-text.js';
|
|
@@ -319,10 +321,15 @@ export class ResolvedCommand extends RuntimeCommand {
|
|
|
319
321
|
// 5. Scope
|
|
320
322
|
if (needsScope) {
|
|
321
323
|
if (!resolved.scopeType || !resolved.scopeId) {
|
|
322
|
-
|
|
324
|
+
// In CI environments, since .sanity/blueprint.config.json is not guaranteed to exist, we can provide a more specific hint
|
|
325
|
+
const errorMessage = config.isCi
|
|
326
|
+
? 'set SANITY_PROJECT_ID or SANITY_ORGANIZATION_ID.'
|
|
327
|
+
: 'provide --project-id or --organization-id, or run `blueprints init` to create a Blueprint config (.sanity/blueprint.config.json).';
|
|
328
|
+
this.error(`Missing scope: ${errorMessage}`, {
|
|
323
329
|
suggestions: [
|
|
324
330
|
`Run \`${this.config.bin} blueprints doctor\` to check your configuration.`,
|
|
325
331
|
],
|
|
332
|
+
ref: CI_SETUP_DOCS_URL,
|
|
326
333
|
});
|
|
327
334
|
}
|
|
328
335
|
this.scopeType = resolved.scopeType;
|
|
@@ -341,10 +348,14 @@ export class ResolvedCommand extends RuntimeCommand {
|
|
|
341
348
|
stackId = await resolveStackIdByNameOrId(stackOverride, auth, log);
|
|
342
349
|
}
|
|
343
350
|
if (!stackId) {
|
|
344
|
-
|
|
351
|
+
const errorMessage = config.isCi
|
|
352
|
+
? "couldn't determine which Stack to target. Set SANITY_BLUEPRINT_STACK_ID."
|
|
353
|
+
: `provide --stack, or set a Stack in your Blueprint config (\`${this.config.bin} blueprints config --edit\`).`;
|
|
354
|
+
this.error(`Missing Stack: ${errorMessage}`, {
|
|
345
355
|
suggestions: [
|
|
346
356
|
`Run \`${this.config.bin} blueprints doctor\` to check your configuration.`,
|
|
347
357
|
],
|
|
358
|
+
ref: CI_SETUP_DOCS_URL,
|
|
348
359
|
});
|
|
349
360
|
}
|
|
350
361
|
this.stackId = stackId;
|
|
@@ -11,9 +11,12 @@ export default class InitCommand extends RuntimeCommand {
|
|
|
11
11
|
This is typically the first command you run in a new project. It creates a local Blueprint manifest file (sanity.blueprint.ts, .js, or .json) and provisions a new remote Stack.
|
|
12
12
|
Additionally, a Blueprint configuration file is created in .sanity/ containing the scope and Stack IDs. This is .gitignored by default.
|
|
13
13
|
|
|
14
|
-
After initialization, use 'blueprints plan' to preview changes, then 'blueprints deploy' to apply them
|
|
14
|
+
After initialization, use 'blueprints plan' to preview changes, then 'blueprints deploy' to apply them.
|
|
15
|
+
|
|
16
|
+
Running without a directory prompts to confirm the current directory. Run 'blueprints init .' to initialize in the current directory without a prompt.`;
|
|
15
17
|
static examples = [
|
|
16
18
|
'<%= config.bin %> <%= command.id %>',
|
|
19
|
+
'<%= config.bin %> <%= command.id %> .',
|
|
17
20
|
'<%= config.bin %> <%= command.id %> [directory]',
|
|
18
21
|
'<%= config.bin %> <%= command.id %> --blueprint-type <json|js|ts>',
|
|
19
22
|
'<%= config.bin %> <%= command.id %> --organization-id <organizationId>',
|
|
@@ -25,7 +28,7 @@ After initialization, use 'blueprints plan' to preview changes, then 'blueprints
|
|
|
25
28
|
];
|
|
26
29
|
static args = {
|
|
27
30
|
dir: Args.string({
|
|
28
|
-
description: 'Directory to create the local Blueprint in',
|
|
31
|
+
description: 'Directory to create the local Blueprint in (defaults to the current directory)',
|
|
29
32
|
}),
|
|
30
33
|
};
|
|
31
34
|
static flags = {
|
package/dist/config.d.ts
CHANGED
package/dist/config.js
CHANGED
|
@@ -3,6 +3,7 @@ import { env } from 'node:process';
|
|
|
3
3
|
import { fileURLToPath } from 'node:url';
|
|
4
4
|
import * as pkg from 'empathic/package';
|
|
5
5
|
import getToken from './utils/get-token.js';
|
|
6
|
+
import isTrueish from './utils/isTrueish.js';
|
|
6
7
|
export const BLUEPRINT_CONFIG_VERSION = 'v2025-05-08';
|
|
7
8
|
// Default API version for Blueprints service calls.
|
|
8
9
|
// Overridable globally via env, or per-endpoint via the `version` arg to `blueprintsUrl`.
|
|
@@ -29,7 +30,11 @@ const isTest = nodeEnv === 'test';
|
|
|
29
30
|
const sanityEnv = env.SANITY_INTERNAL_ENV?.toLowerCase() ?? 'production';
|
|
30
31
|
const sanityProd = sanityEnv === 'production';
|
|
31
32
|
const isLive = sanityProd || sanityEnv === 'staging';
|
|
32
|
-
const isPublishing = env?.PUBLISHING
|
|
33
|
+
const isPublishing = isTrueish(env?.PUBLISHING);
|
|
34
|
+
// https://github.com/sanity-io/cli/blob/adf90ea6691ee6c36849e426de9729533706f47f/packages/%40sanity/cli-core/src/util/isCi.ts
|
|
35
|
+
const isCi =
|
|
36
|
+
// Travis CI, CircleCI, Gitlab CI, Appveyor, CodeShip, Travis CI, Jenkins, TeamCity
|
|
37
|
+
isTrueish(env?.CI) || isTrueish(env?.CONTINUOUS_INTEGRATION) || isTrueish(env?.BUILD_NUMBER);
|
|
33
38
|
const apiUrls = {
|
|
34
39
|
production: 'https://api.sanity.io/',
|
|
35
40
|
staging: 'https://api.sanity.work/',
|
|
@@ -74,6 +79,7 @@ export default {
|
|
|
74
79
|
isLive,
|
|
75
80
|
apiUrl,
|
|
76
81
|
populusApiUrl,
|
|
82
|
+
isCi,
|
|
77
83
|
get token() {
|
|
78
84
|
return _token === undefined ? loadToken() : _token;
|
|
79
85
|
},
|
package/dist/constants.d.ts
CHANGED
|
@@ -43,3 +43,4 @@ export declare const LABEL_MEDIA_LIBRARY_ASSET_UPDATE = "Media Library Asset Upd
|
|
|
43
43
|
export declare const LABEL_MEDIA_LIBRARY_ASSET_DELETE = "Media Library Asset Delete";
|
|
44
44
|
export declare const LABEL_SCHEDULED = "Scheduled";
|
|
45
45
|
export declare const LABEL_SYNC_TAG_INVALIDATE = "Sync Tag Invalidate";
|
|
46
|
+
export declare const CI_SETUP_DOCS_URL = "https://www.sanity.io/docs/blueprints/deploy-blueprints-from-ci";
|
package/dist/constants.js
CHANGED
|
@@ -48,3 +48,4 @@ export const LABEL_MEDIA_LIBRARY_ASSET_UPDATE = 'Media Library Asset Update';
|
|
|
48
48
|
export const LABEL_MEDIA_LIBRARY_ASSET_DELETE = 'Media Library Asset Delete';
|
|
49
49
|
export const LABEL_SCHEDULED = 'Scheduled';
|
|
50
50
|
export const LABEL_SYNC_TAG_INVALIDATE = 'Sync Tag Invalidate';
|
|
51
|
+
export const CI_SETUP_DOCS_URL = 'https://www.sanity.io/docs/blueprints/deploy-blueprints-from-ci';
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from 'node:fs';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
|
+
import { cwd } from 'node:process';
|
|
3
4
|
import { confirm } from '@inquirer/prompts';
|
|
4
5
|
import { findBlueprintFile, readLocalBlueprint, writeBlueprintToDisk, } from '../../actions/blueprints/blueprint.js';
|
|
5
6
|
import { writeConfigFile } from '../../actions/blueprints/config.js';
|
|
@@ -11,6 +12,7 @@ import { getProject } from '../../actions/sanity/projects.js';
|
|
|
11
12
|
import { BLUEPRINT_CONFIG_DIR, BLUEPRINT_CONFIG_FILE } from '../../config.js';
|
|
12
13
|
import { check, filePathRelativeToCwd, labeledId, warn } from '../../utils/display/presenters.js';
|
|
13
14
|
import { promptForBlueprintType, promptForOrganization, promptForProjectInOrg, promptForStack, runScopeAndStackWizard, } from '../../utils/display/prompt.js';
|
|
15
|
+
import { isInteractive } from '../../utils/interactive.js';
|
|
14
16
|
import { styleText } from '../../utils/style-text.js';
|
|
15
17
|
import { blueprintConfigCore } from './config.js';
|
|
16
18
|
/** Derive scope type and ID from mutually exclusive flag values. */
|
|
@@ -25,8 +27,10 @@ export async function blueprintInitCore(options) {
|
|
|
25
27
|
const { bin = 'sanity', log, token, knownProjectId, args, flags, validateResources } = options;
|
|
26
28
|
const { dir: flagDir, example: flagExample, 'blueprint-type': flagBlueprintType, 'project-id': flagProjectId, 'organization-id': flagOrganizationId, 'stack-id': flagStackId, 'stack-name': flagStackName, verbose = false, } = flags;
|
|
27
29
|
const { dir: argDir } = args;
|
|
28
|
-
const
|
|
29
|
-
const
|
|
30
|
+
const explicitDir = argDir || flagDir;
|
|
31
|
+
const isHere = !explicitDir || explicitDir === '.' || explicitDir === './';
|
|
32
|
+
const blueprintDir = isHere ? '.' : explicitDir;
|
|
33
|
+
const userProvidedDirName = isHere ? undefined : explicitDir;
|
|
30
34
|
const validationError = validateFlags({
|
|
31
35
|
stackId: flagStackId,
|
|
32
36
|
stackName: flagStackName,
|
|
@@ -65,6 +69,16 @@ export async function blueprintInitCore(options) {
|
|
|
65
69
|
});
|
|
66
70
|
}
|
|
67
71
|
// no blueprint on disk → create new blueprint files from scratch
|
|
72
|
+
if (!explicitDir && isInteractive) {
|
|
73
|
+
const proceed = await confirm({
|
|
74
|
+
message: `Initialize a Blueprint here in ${cwd()}?`,
|
|
75
|
+
default: true,
|
|
76
|
+
});
|
|
77
|
+
if (!proceed) {
|
|
78
|
+
log(`Run \`${bin} blueprints init <directory>\` to initialize in a different location.`);
|
|
79
|
+
return { success: false, error: 'Initialization cancelled.' };
|
|
80
|
+
}
|
|
81
|
+
}
|
|
68
82
|
return handleFreshInitialization({
|
|
69
83
|
blueprintDir,
|
|
70
84
|
userProvidedDirName,
|
|
@@ -8,6 +8,7 @@ import { resolveDeployedResources } from '../../utils/blueprints/resolve-deploye
|
|
|
8
8
|
import buildPayload from '../../utils/functions/build-payload.js';
|
|
9
9
|
import { fetchAsset, fetchDocument } from '../../utils/functions/fetch-document.js';
|
|
10
10
|
import { findFunctionInResources, getFunctionNames } from '../../utils/functions/find.js';
|
|
11
|
+
import { runFunction } from '../../utils/functions/invoke/nested.js';
|
|
11
12
|
import { parseJsonObject } from '../../utils/parse-json-object.js';
|
|
12
13
|
import { isEventType, } from '../../utils/types.js';
|
|
13
14
|
export async function functionTestCore(options) {
|
|
@@ -146,12 +147,54 @@ export async function functionTestCore(options) {
|
|
|
146
147
|
: {
|
|
147
148
|
event: 'scheduled',
|
|
148
149
|
};
|
|
150
|
+
// Records each nested context.invoke() so they can be surfaced in order after the spinner resolves.
|
|
151
|
+
const nestedRuns = [];
|
|
152
|
+
let nestedOrder = 0;
|
|
153
|
+
/**
|
|
154
|
+
* Re-entrant callback that resolves a nested context.invoke(name, payload):
|
|
155
|
+
* it finds the named function in the same blueprint, reuses the already
|
|
156
|
+
* resolved resources, and runs it via the shared invoke-chain helper (which
|
|
157
|
+
* applies the depth/cycle guard and extends the call stack). Passing itself
|
|
158
|
+
* as onNestedInvoke keeps it recursable. Every run is recorded so it can be
|
|
159
|
+
* surfaced after the spinner resolves, including failed ones — a downstream
|
|
160
|
+
* error is fire-and-forget (it doesn't reject the caller) but is still shown.
|
|
161
|
+
*/
|
|
162
|
+
const runNested = async (nestedName, nestedPayload, ctx, depth, callStack) => {
|
|
163
|
+
const order = ++nestedOrder;
|
|
164
|
+
const nestedResource = findFunctionInResources(blueprint.resources, nestedName);
|
|
165
|
+
const result = await runFunction(nestedResource, { payload: { data: nestedPayload }, event: 'nested' }, { ...ctx, resources: resolvedResources }, { depth, callStack, onNestedInvoke: runNested });
|
|
166
|
+
nestedRuns.push({ order, name: nestedName, logs: result.logs, error: result.error });
|
|
167
|
+
return result;
|
|
168
|
+
};
|
|
169
|
+
const logNestedRuns = () => {
|
|
170
|
+
for (const run of [...nestedRuns].sort((a, b) => a.order - b.order)) {
|
|
171
|
+
log(`↳ BEGIN: invoke('${run.name}')`);
|
|
172
|
+
// Show any logs received
|
|
173
|
+
if (run.logs?.trim()) {
|
|
174
|
+
log(run.logs.trim());
|
|
175
|
+
}
|
|
176
|
+
// Before any error occurs
|
|
177
|
+
if (run.error) {
|
|
178
|
+
log(run.error.stack || run.error.message || run.error.name);
|
|
179
|
+
}
|
|
180
|
+
log(`↳ END: invoke('${run.name}')`);
|
|
181
|
+
}
|
|
182
|
+
};
|
|
149
183
|
const spinner = log.ora('Executing function...').start();
|
|
150
184
|
const { json: response, logs, error, } = await testAction(resource, invokeOptions, contextOptions, {
|
|
151
185
|
timeout: timeout ? timeout : resource.timeout,
|
|
186
|
+
onNestedInvoke: runNested,
|
|
187
|
+
depth: 0,
|
|
188
|
+
callStack: [fnName],
|
|
152
189
|
});
|
|
153
190
|
if (error) {
|
|
154
191
|
spinner.fail('Function execution failed.');
|
|
192
|
+
// Surface the function's own logs even on failure
|
|
193
|
+
if (logs?.trim()) {
|
|
194
|
+
log('Logs:');
|
|
195
|
+
log(logs);
|
|
196
|
+
}
|
|
197
|
+
logNestedRuns();
|
|
155
198
|
const errorMessage = error.stack || error.message || error.name;
|
|
156
199
|
const isTimeout = error.message?.includes('Timeout');
|
|
157
200
|
return {
|
|
@@ -166,6 +209,7 @@ export async function functionTestCore(options) {
|
|
|
166
209
|
spinner.succeed('Function execution succeeded.');
|
|
167
210
|
log('Logs:');
|
|
168
211
|
log(logs || '');
|
|
212
|
+
logNestedRuns();
|
|
169
213
|
if (response) {
|
|
170
214
|
log('Response:');
|
|
171
215
|
log(JSON.stringify(response, null, 2));
|
package/dist/server/app.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { existsSync, readFileSync, watchFile } from 'node:fs';
|
|
2
2
|
import * as http from 'node:http';
|
|
3
3
|
import { default as mime } from 'mime-types';
|
|
4
|
-
import { WebSocketServer } from 'ws';
|
|
4
|
+
import { WebSocket, WebSocketServer } from 'ws';
|
|
5
5
|
import { findBlueprintFile, loadAndParseBlueprint } from '../actions/blueprints/blueprint.js';
|
|
6
6
|
import { readConfigFile } from '../actions/blueprints/config.js';
|
|
7
7
|
import { resolveIds } from '../actions/blueprints/resolve.js';
|
|
@@ -10,6 +10,35 @@ import { isRecord } from '../utils/is-record.js';
|
|
|
10
10
|
import { isEventType, isGroqContextOptions, } from '../utils/types.js';
|
|
11
11
|
import { handleInvokeRequest } from './handlers/invoke.js';
|
|
12
12
|
const app = (host, port, validateResources, executionOptions) => {
|
|
13
|
+
const wss = new WebSocketServer({ port: 8974 });
|
|
14
|
+
// Send a JSON envelope to every connected UI client.
|
|
15
|
+
const broadcast = (envelope) => {
|
|
16
|
+
const message = JSON.stringify(envelope);
|
|
17
|
+
for (const client of wss.clients) {
|
|
18
|
+
if (client.readyState === WebSocket.OPEN)
|
|
19
|
+
client.send(message);
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
let nestedOrder = 0;
|
|
23
|
+
/**
|
|
24
|
+
* Re-entrant callback that resolves a nested `context.invoke(name, payload)` by
|
|
25
|
+
* re-entering the invoke pipeline (which spawns its own child) and streams the
|
|
26
|
+
* nested run to the UI. Passing `nestedInvoke` to itself keeps it recursable.
|
|
27
|
+
*/
|
|
28
|
+
const nestedInvoke = async (name, payload, ctx, depth, callStack) => {
|
|
29
|
+
const order = ++nestedOrder;
|
|
30
|
+
const result = await handleInvokeRequest(name, { data: payload }, { event: 'nested' }, ctx, validateResources, executionOptions, depth, callStack, nestedInvoke);
|
|
31
|
+
broadcast({
|
|
32
|
+
type: 'nested-invoke',
|
|
33
|
+
name,
|
|
34
|
+
order,
|
|
35
|
+
logs: result.logs,
|
|
36
|
+
json: result.json,
|
|
37
|
+
error: result.error,
|
|
38
|
+
timings: result.timings,
|
|
39
|
+
});
|
|
40
|
+
return result;
|
|
41
|
+
};
|
|
13
42
|
const requestListener = async (req, res) => {
|
|
14
43
|
res.setHeader('Content-Type', 'application/json');
|
|
15
44
|
switch (true) {
|
|
@@ -50,7 +79,7 @@ const app = (host, port, validateResources, executionOptions) => {
|
|
|
50
79
|
delete context.clientOptions.token;
|
|
51
80
|
}
|
|
52
81
|
}
|
|
53
|
-
const result = await handleInvokeRequest(functionName, event, metadata, context, validateResources, executionOptions);
|
|
82
|
+
const result = await handleInvokeRequest(functionName, event, metadata, context, validateResources, executionOptions, 0, [], nestedInvoke);
|
|
54
83
|
// Add Server-Timing header
|
|
55
84
|
const timingHeaders = [];
|
|
56
85
|
for (const [key, value] of Object.entries(result.timings)) {
|
|
@@ -235,7 +264,6 @@ const app = (host, port, validateResources, executionOptions) => {
|
|
|
235
264
|
};
|
|
236
265
|
const server = http.createServer(requestListener);
|
|
237
266
|
server.listen(port, host, () => { });
|
|
238
|
-
const wss = new WebSocketServer({ port: 8974 });
|
|
239
267
|
wss.on('connection', function connection(ws) {
|
|
240
268
|
ws.on('error', console.error);
|
|
241
269
|
const fileInfo = findBlueprintFile();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { InvocationResponse, InvokeContextOptions, InvokeExecutionOptions, InvokePayloadMetadata } from '../../utils/types.js';
|
|
2
|
-
export declare function handleInvokeRequest(functionName: string, event: Record<string, unknown>, metadata: InvokePayloadMetadata, context: InvokeContextOptions, validateResources: boolean, executionOptions?: Partial<InvokeExecutionOptions
|
|
1
|
+
import type { InvocationResponse, InvokeContextOptions, InvokeExecutionOptions, InvokePayloadMetadata, NestedInvoke } from '../../utils/types.js';
|
|
2
|
+
export declare function handleInvokeRequest(functionName: string, event: Record<string, unknown>, metadata: InvokePayloadMetadata, context: InvokeContextOptions, validateResources: boolean, executionOptions?: Partial<InvokeExecutionOptions>, depth?: number, callStack?: string[], onNestedInvoke?: NestedInvoke): Promise<InvocationResponse & {
|
|
3
3
|
timings: Record<string, number>;
|
|
4
4
|
}>;
|
|
@@ -2,10 +2,10 @@ import { readLocalBlueprint } from '../../actions/blueprints/blueprint.js';
|
|
|
2
2
|
import config from '../../config.js';
|
|
3
3
|
import { resolveDeployedResources } from '../../utils/blueprints/resolve-deployed-resources.js';
|
|
4
4
|
import { findFunctionInResources } from '../../utils/functions/find.js';
|
|
5
|
-
import
|
|
5
|
+
import { runFunction } from '../../utils/functions/invoke/nested.js';
|
|
6
6
|
import { Logger } from '../../utils/logger.js';
|
|
7
7
|
const silentLogger = Logger(() => { });
|
|
8
|
-
export async function handleInvokeRequest(functionName, event, metadata, context, validateResources, executionOptions) {
|
|
8
|
+
export async function handleInvokeRequest(functionName, event, metadata, context, validateResources, executionOptions, depth = 0, callStack = [], onNestedInvoke) {
|
|
9
9
|
const start = performance.now();
|
|
10
10
|
const { resources, stackId, scopeType, scopeId } = await readLocalBlueprint(silentLogger, {
|
|
11
11
|
resources: validateResources,
|
|
@@ -22,9 +22,12 @@ export async function handleInvokeRequest(functionName, event, metadata, context
|
|
|
22
22
|
payload: event,
|
|
23
23
|
...metadata,
|
|
24
24
|
};
|
|
25
|
-
const response = await
|
|
25
|
+
const response = await runFunction(resource, payload, { ...context, resources: resolvedResources }, {
|
|
26
26
|
forceColor: executionOptions?.forceColor ?? false,
|
|
27
|
-
timeout: executionOptions?.timeout
|
|
27
|
+
timeout: executionOptions?.timeout,
|
|
28
|
+
depth,
|
|
29
|
+
callStack,
|
|
30
|
+
onNestedInvoke,
|
|
28
31
|
});
|
|
29
32
|
const timings = { ...response.timings, 'blueprint:read': readBlueprintTime };
|
|
30
33
|
return { ...response, timings };
|