@sanity/runtime-cli 15.2.1 → 16.0.1
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 +20 -20
- package/dist/actions/blueprints/assets.d.ts +2 -2
- package/dist/actions/blueprints/assets.js +6 -7
- package/dist/actions/blueprints/config.d.ts +9 -1
- package/dist/actions/blueprints/config.js +11 -1
- package/dist/actions/blueprints/logs.js +2 -3
- package/dist/actions/blueprints/stacks.js +2 -3
- package/dist/baseCommands.d.ts +12 -2
- package/dist/baseCommands.js +15 -2
- package/dist/commands/blueprints/destroy.d.ts +1 -1
- package/dist/commands/blueprints/destroy.js +5 -3
- package/dist/commands/blueprints/plan.js +2 -0
- package/dist/commands/blueprints/stacks.d.ts +1 -1
- package/dist/commands/blueprints/stacks.js +4 -3
- package/dist/commands/functions/add.js +2 -0
- package/dist/config.d.ts +8 -0
- package/dist/config.js +12 -0
- package/dist/cores/blueprints/deploy.js +8 -3
- package/dist/cores/blueprints/destroy.d.ts +12 -2
- package/dist/cores/blueprints/destroy.js +13 -23
- package/dist/cores/blueprints/doctor.js +33 -13
- package/dist/cores/blueprints/plan.js +4 -0
- package/dist/cores/blueprints/stacks.d.ts +9 -4
- package/dist/cores/blueprints/stacks.js +2 -24
- package/dist/cores/functions/add.js +3 -1
- package/dist/cores/index.d.ts +1 -2
- package/dist/utils/functions/transpile/function.d.ts +6 -0
- package/dist/utils/functions/transpile/function.js +34 -7
- package/dist/utils/types.d.ts +4 -0
- package/dist/utils/warnings.d.ts +14 -0
- package/dist/utils/warnings.js +45 -0
- package/dist/utils/workspace-checks.d.ts +9 -0
- package/dist/utils/workspace-checks.js +47 -0
- package/oclif.manifest.json +3 -5
- package/package.json +3 -3
- package/dist/utils/blueprints/warnings.d.ts +0 -19
- package/dist/utils/blueprints/warnings.js +0 -36
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/16.0.1 linux-x64 node-v24.16.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/v16.0.1/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/v16.0.1/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/v16.0.1/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/v16.0.1/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/v16.0.1/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/v16.0.1/src/commands/blueprints/info.ts)_
|
|
304
304
|
|
|
305
305
|
## `sanity-run blueprints init [DIR]`
|
|
306
306
|
|
|
@@ -359,7 +359,7 @@ EXAMPLES
|
|
|
359
359
|
$ sanity-run blueprints init old-stack --type <json|js|ts> --project-id <projectId> --stack-id <existingStackId>
|
|
360
360
|
```
|
|
361
361
|
|
|
362
|
-
_See code: [src/commands/blueprints/init.ts](https://github.com/sanity-io/runtime-cli/blob/
|
|
362
|
+
_See code: [src/commands/blueprints/init.ts](https://github.com/sanity-io/runtime-cli/blob/v16.0.1/src/commands/blueprints/init.ts)_
|
|
363
363
|
|
|
364
364
|
## `sanity-run blueprints logs`
|
|
365
365
|
|
|
@@ -405,7 +405,7 @@ EXAMPLES
|
|
|
405
405
|
$ sanity-run blueprints logs --before 2026-05-01T00:00:00Z
|
|
406
406
|
```
|
|
407
407
|
|
|
408
|
-
_See code: [src/commands/blueprints/logs.ts](https://github.com/sanity-io/runtime-cli/blob/
|
|
408
|
+
_See code: [src/commands/blueprints/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v16.0.1/src/commands/blueprints/logs.ts)_
|
|
409
409
|
|
|
410
410
|
## `sanity-run blueprints mint-deploy-token`
|
|
411
411
|
|
|
@@ -450,7 +450,7 @@ EXAMPLES
|
|
|
450
450
|
$ sanity-run blueprints mint-deploy-token --organization-id <orgId>
|
|
451
451
|
```
|
|
452
452
|
|
|
453
|
-
_See code: [src/commands/blueprints/mint-deploy-token.ts](https://github.com/sanity-io/runtime-cli/blob/
|
|
453
|
+
_See code: [src/commands/blueprints/mint-deploy-token.ts](https://github.com/sanity-io/runtime-cli/blob/v16.0.1/src/commands/blueprints/mint-deploy-token.ts)_
|
|
454
454
|
|
|
455
455
|
## `sanity-run blueprints plan`
|
|
456
456
|
|
|
@@ -483,7 +483,7 @@ EXAMPLES
|
|
|
483
483
|
$ sanity-run blueprints plan --organization-id <orgId> --stack <name-or-id>
|
|
484
484
|
```
|
|
485
485
|
|
|
486
|
-
_See code: [src/commands/blueprints/plan.ts](https://github.com/sanity-io/runtime-cli/blob/
|
|
486
|
+
_See code: [src/commands/blueprints/plan.ts](https://github.com/sanity-io/runtime-cli/blob/v16.0.1/src/commands/blueprints/plan.ts)_
|
|
487
487
|
|
|
488
488
|
## `sanity-run blueprints promote`
|
|
489
489
|
|
|
@@ -519,7 +519,7 @@ EXAMPLES
|
|
|
519
519
|
$ sanity-run blueprints promote --new-stack-name <new-name>
|
|
520
520
|
```
|
|
521
521
|
|
|
522
|
-
_See code: [src/commands/blueprints/promote.ts](https://github.com/sanity-io/runtime-cli/blob/
|
|
522
|
+
_See code: [src/commands/blueprints/promote.ts](https://github.com/sanity-io/runtime-cli/blob/v16.0.1/src/commands/blueprints/promote.ts)_
|
|
523
523
|
|
|
524
524
|
## `sanity-run blueprints stacks`
|
|
525
525
|
|
|
@@ -555,7 +555,7 @@ EXAMPLES
|
|
|
555
555
|
$ sanity-run blueprints stacks --organization-id <organizationId> --include-projects
|
|
556
556
|
```
|
|
557
557
|
|
|
558
|
-
_See code: [src/commands/blueprints/stacks.ts](https://github.com/sanity-io/runtime-cli/blob/
|
|
558
|
+
_See code: [src/commands/blueprints/stacks.ts](https://github.com/sanity-io/runtime-cli/blob/v16.0.1/src/commands/blueprints/stacks.ts)_
|
|
559
559
|
|
|
560
560
|
## `sanity-run functions add`
|
|
561
561
|
|
|
@@ -607,7 +607,7 @@ EXAMPLES
|
|
|
607
607
|
$ sanity-run functions add --name my-function --type document-create --type document-update --lang js
|
|
608
608
|
```
|
|
609
609
|
|
|
610
|
-
_See code: [src/commands/functions/add.ts](https://github.com/sanity-io/runtime-cli/blob/
|
|
610
|
+
_See code: [src/commands/functions/add.ts](https://github.com/sanity-io/runtime-cli/blob/v16.0.1/src/commands/functions/add.ts)_
|
|
611
611
|
|
|
612
612
|
## `sanity-run functions dev`
|
|
613
613
|
|
|
@@ -642,7 +642,7 @@ EXAMPLES
|
|
|
642
642
|
$ sanity-run functions dev --timeout 60
|
|
643
643
|
```
|
|
644
644
|
|
|
645
|
-
_See code: [src/commands/functions/dev.ts](https://github.com/sanity-io/runtime-cli/blob/
|
|
645
|
+
_See code: [src/commands/functions/dev.ts](https://github.com/sanity-io/runtime-cli/blob/v16.0.1/src/commands/functions/dev.ts)_
|
|
646
646
|
|
|
647
647
|
## `sanity-run functions env add NAME KEY VALUE`
|
|
648
648
|
|
|
@@ -672,7 +672,7 @@ EXAMPLES
|
|
|
672
672
|
$ sanity-run functions env add MyFunction API_URL https://api.example.com/
|
|
673
673
|
```
|
|
674
674
|
|
|
675
|
-
_See code: [src/commands/functions/env/add.ts](https://github.com/sanity-io/runtime-cli/blob/
|
|
675
|
+
_See code: [src/commands/functions/env/add.ts](https://github.com/sanity-io/runtime-cli/blob/v16.0.1/src/commands/functions/env/add.ts)_
|
|
676
676
|
|
|
677
677
|
## `sanity-run functions env list NAME`
|
|
678
678
|
|
|
@@ -699,7 +699,7 @@ EXAMPLES
|
|
|
699
699
|
$ sanity-run functions env list MyFunction
|
|
700
700
|
```
|
|
701
701
|
|
|
702
|
-
_See code: [src/commands/functions/env/list.ts](https://github.com/sanity-io/runtime-cli/blob/
|
|
702
|
+
_See code: [src/commands/functions/env/list.ts](https://github.com/sanity-io/runtime-cli/blob/v16.0.1/src/commands/functions/env/list.ts)_
|
|
703
703
|
|
|
704
704
|
## `sanity-run functions env remove NAME KEY`
|
|
705
705
|
|
|
@@ -728,7 +728,7 @@ EXAMPLES
|
|
|
728
728
|
$ sanity-run functions env remove MyFunction API_URL
|
|
729
729
|
```
|
|
730
730
|
|
|
731
|
-
_See code: [src/commands/functions/env/remove.ts](https://github.com/sanity-io/runtime-cli/blob/
|
|
731
|
+
_See code: [src/commands/functions/env/remove.ts](https://github.com/sanity-io/runtime-cli/blob/v16.0.1/src/commands/functions/env/remove.ts)_
|
|
732
732
|
|
|
733
733
|
## `sanity-run functions logs [NAME]`
|
|
734
734
|
|
|
@@ -768,7 +768,7 @@ EXAMPLES
|
|
|
768
768
|
$ sanity-run functions logs <name> --delete
|
|
769
769
|
```
|
|
770
770
|
|
|
771
|
-
_See code: [src/commands/functions/logs.ts](https://github.com/sanity-io/runtime-cli/blob/
|
|
771
|
+
_See code: [src/commands/functions/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v16.0.1/src/commands/functions/logs.ts)_
|
|
772
772
|
|
|
773
773
|
## `sanity-run functions test [NAME]`
|
|
774
774
|
|
|
@@ -825,7 +825,7 @@ EXAMPLES
|
|
|
825
825
|
$ sanity-run functions test <name> --event update --data-before '{ "title": "before" }' --data-after '{ "title": "after" }'
|
|
826
826
|
```
|
|
827
827
|
|
|
828
|
-
_See code: [src/commands/functions/test.ts](https://github.com/sanity-io/runtime-cli/blob/
|
|
828
|
+
_See code: [src/commands/functions/test.ts](https://github.com/sanity-io/runtime-cli/blob/v16.0.1/src/commands/functions/test.ts)_
|
|
829
829
|
|
|
830
830
|
## `sanity-run help [COMMAND]`
|
|
831
831
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import AdmZip from 'adm-zip';
|
|
2
2
|
import type { Logger } from '../../utils/logger.js';
|
|
3
3
|
import type { AssetResource, AuthParams, InstallerType } from '../../utils/types.js';
|
|
4
|
-
export declare const
|
|
5
|
-
export declare const
|
|
4
|
+
export declare const assetCheckUrl: string;
|
|
5
|
+
export declare const assetStashUrl: string;
|
|
6
6
|
export declare function stashAsset({ resource, auth, logger, installer, }: {
|
|
7
7
|
resource: AssetResource;
|
|
8
8
|
auth: AuthParams;
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import crypto from 'node:crypto';
|
|
2
2
|
import fs from 'node:fs';
|
|
3
3
|
import AdmZip from 'adm-zip';
|
|
4
|
-
import
|
|
4
|
+
import { blueprintsUrl } from '../../config.js';
|
|
5
5
|
import { CONVERT_BYTES_TO_MB, MAX_ASSET_SIZE } from '../../constants.js';
|
|
6
6
|
import { prepareAsset as prepareFunctionAsset } from '../../utils/functions/prepare-asset.js';
|
|
7
7
|
import getHeaders from '../../utils/get-headers.js';
|
|
8
8
|
import { createTracedFetch } from '../../utils/traced-fetch.js';
|
|
9
9
|
import { isLocalFunctionResource, isStudioResource } from '../../utils/types.js';
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
export const
|
|
13
|
-
export const ASSET_STASH_URL = `${ASSETS_URL}/stash`;
|
|
10
|
+
const assetsUrl = blueprintsUrl('assets');
|
|
11
|
+
export const assetCheckUrl = `${assetsUrl}/check`;
|
|
12
|
+
export const assetStashUrl = `${assetsUrl}/stash`;
|
|
14
13
|
export async function stashAsset({ resource, auth, logger, installer, }) {
|
|
15
14
|
try {
|
|
16
15
|
let b64;
|
|
@@ -88,7 +87,7 @@ async function stashSingleAsset({ b64, hash, cleanup, resource, auth, logger, ex
|
|
|
88
87
|
const fetchFn = createTracedFetch(logger);
|
|
89
88
|
try {
|
|
90
89
|
try {
|
|
91
|
-
const checkResponse = await fetchFn(`${
|
|
90
|
+
const checkResponse = await fetchFn(`${assetCheckUrl}/${hash}`, {
|
|
92
91
|
method: 'GET',
|
|
93
92
|
headers: getHeaders(auth),
|
|
94
93
|
});
|
|
@@ -99,7 +98,7 @@ async function stashSingleAsset({ b64, hash, cleanup, resource, auth, logger, ex
|
|
|
99
98
|
}
|
|
100
99
|
catch { } // Continue to stash the Asset
|
|
101
100
|
// Asset doesn't exist, so stash it
|
|
102
|
-
const assetResponse = await fetchFn(
|
|
101
|
+
const assetResponse = await fetchFn(assetStashUrl, {
|
|
103
102
|
method: 'POST',
|
|
104
103
|
headers: getHeaders(auth),
|
|
105
104
|
body: JSON.stringify({
|
|
@@ -37,7 +37,7 @@ export interface ConfigPatch {
|
|
|
37
37
|
/**
|
|
38
38
|
* Update the config file with the given properties.
|
|
39
39
|
* Config file must already exist.
|
|
40
|
-
* Adds timestamp. No
|
|
40
|
+
* Adds timestamp. No ID combination validation.
|
|
41
41
|
* @param blueprintFilePath - the path to the blueprint file
|
|
42
42
|
* @param updateableProperties - the properties to update
|
|
43
43
|
* @param updateableProperties.organizationId - the organization ID (null to remove)
|
|
@@ -45,6 +45,14 @@ export interface ConfigPatch {
|
|
|
45
45
|
* @param updateableProperties.stackId - the stack ID (null to remove)
|
|
46
46
|
*/
|
|
47
47
|
export declare function patchConfigFile(blueprintFilePath: string, updateableProperties: ConfigPatch): BlueprintsConfig;
|
|
48
|
+
/**
|
|
49
|
+
* Patch a known config using its `configPath`.
|
|
50
|
+
* Unlike {@link patchConfigFile}, this does not re-derive the config location.
|
|
51
|
+
* Adds timestamp. No ID combination validation.
|
|
52
|
+
* @param existingConfig - the located config (includes `configPath`)
|
|
53
|
+
* @param updateableProperties - the properties to update (null to remove)
|
|
54
|
+
*/
|
|
55
|
+
export declare function patchLocatedConfig(existingConfig: LocatedBlueprintsConfig, updateableProperties: ConfigPatch): BlueprintsConfig;
|
|
48
56
|
/**
|
|
49
57
|
* Find and write an organizationId to the config file by getting it from the projectId
|
|
50
58
|
* @throws {Error} if unable to fetch project
|
|
@@ -54,7 +54,7 @@ export function writeConfigFile(blueprintFilePath, options) {
|
|
|
54
54
|
/**
|
|
55
55
|
* Update the config file with the given properties.
|
|
56
56
|
* Config file must already exist.
|
|
57
|
-
* Adds timestamp. No
|
|
57
|
+
* Adds timestamp. No ID combination validation.
|
|
58
58
|
* @param blueprintFilePath - the path to the blueprint file
|
|
59
59
|
* @param updateableProperties - the properties to update
|
|
60
60
|
* @param updateableProperties.organizationId - the organization ID (null to remove)
|
|
@@ -65,6 +65,16 @@ export function patchConfigFile(blueprintFilePath, updateableProperties) {
|
|
|
65
65
|
const existingConfig = readConfigFile(blueprintFilePath);
|
|
66
66
|
if (!existingConfig)
|
|
67
67
|
throw new Error('No config file found');
|
|
68
|
+
return patchLocatedConfig(existingConfig, updateableProperties);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Patch a known config using its `configPath`.
|
|
72
|
+
* Unlike {@link patchConfigFile}, this does not re-derive the config location.
|
|
73
|
+
* Adds timestamp. No ID combination validation.
|
|
74
|
+
* @param existingConfig - the located config (includes `configPath`)
|
|
75
|
+
* @param updateableProperties - the properties to update (null to remove)
|
|
76
|
+
*/
|
|
77
|
+
export function patchLocatedConfig(existingConfig, updateableProperties) {
|
|
68
78
|
const { configPath, ...existingConfigProperties } = existingConfig;
|
|
69
79
|
const merged = {
|
|
70
80
|
blueprintConfigVersion: BLUEPRINT_CONFIG_VERSION, // patch doesn't overwrite versions
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { blueprintsUrl } from '../../config.js';
|
|
2
2
|
import getHeaders from '../../utils/get-headers.js';
|
|
3
3
|
import { createTracedFetch } from '../../utils/traced-fetch.js';
|
|
4
|
-
const
|
|
5
|
-
export const logsUrl = `${apiUrl}vX/blueprints/logs`;
|
|
4
|
+
export const logsUrl = blueprintsUrl('logs');
|
|
6
5
|
export async function getLogs(params, auth, logger) {
|
|
7
6
|
const fetchFn = createTracedFetch(logger);
|
|
8
7
|
const url = new URL(logsUrl);
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { blueprintsUrl } from '../../config.js';
|
|
2
2
|
import getHeaders from '../../utils/get-headers.js';
|
|
3
3
|
import { createTracedFetch } from '../../utils/traced-fetch.js';
|
|
4
|
-
const
|
|
5
|
-
export const stacksUrl = `${apiUrl}vX/blueprints/stacks`;
|
|
4
|
+
export const stacksUrl = blueprintsUrl('stacks');
|
|
6
5
|
export async function listStacks(auth, logger) {
|
|
7
6
|
const fetchFn = createTracedFetch(logger);
|
|
8
7
|
try {
|
package/dist/baseCommands.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { Interfaces } from '@oclif/core';
|
|
2
2
|
import { Command } from '@oclif/core';
|
|
3
3
|
import { type ReadBlueprintResult } from './actions/blueprints/blueprint.js';
|
|
4
|
+
import { type LocatedBlueprintsConfig } from './actions/blueprints/config.js';
|
|
4
5
|
import type { CoreResult } from './cores/index.js';
|
|
5
|
-
import type { Warning } from './utils/
|
|
6
|
-
import type { AuthParams, ScopeType, Stack } from './utils/types.js';
|
|
6
|
+
import type { AuthParams, ScopeType, Stack, Warning } from './utils/types.js';
|
|
7
7
|
export type Flags<T extends typeof Command> = Interfaces.InferredFlags<(typeof RuntimeCommand)['baseFlags'] & T['flags']>;
|
|
8
8
|
export type Args<T extends typeof Command> = Interfaces.InferredArgs<T['args']>;
|
|
9
9
|
export declare const pathFlagConfig: {
|
|
@@ -126,6 +126,16 @@ export declare abstract class ResolvedCommand<T extends typeof Command> extends
|
|
|
126
126
|
protected scopeType: ScopeType;
|
|
127
127
|
protected scopeId: string;
|
|
128
128
|
protected stackId: string;
|
|
129
|
+
/**
|
|
130
|
+
* locally-resolved Stack ID (flags > env > module > config)
|
|
131
|
+
* populated regardless of `needs` and is never required
|
|
132
|
+
*/
|
|
133
|
+
protected resolvedStackId?: string;
|
|
134
|
+
/**
|
|
135
|
+
* the located `.sanity/blueprint.config.json` (if any), populated regardless of
|
|
136
|
+
* `needs`. Lets commands read/update local config without requiring a manifest.
|
|
137
|
+
*/
|
|
138
|
+
protected blueprintConfig?: LocatedBlueprintsConfig | null;
|
|
129
139
|
protected auth: AuthParams;
|
|
130
140
|
protected deployedStack: Stack;
|
|
131
141
|
init(): Promise<void>;
|
package/dist/baseCommands.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// * https://oclif.io/docs/base_class
|
|
2
2
|
import { Command, CommandHelp, Flags as OclifFlags } from '@oclif/core';
|
|
3
3
|
import { findBlueprintFile, loadBlueprintFile, parseBlueprintContent, } from './actions/blueprints/blueprint.js';
|
|
4
|
-
import { backfillProjectBasedStackId, readConfigFile } from './actions/blueprints/config.js';
|
|
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
7
|
import { presentBlueprintParserErrors } from './utils/display/errors.js';
|
|
@@ -146,7 +146,7 @@ export class RuntimeCommand extends Command {
|
|
|
146
146
|
if (!warnings.length)
|
|
147
147
|
return;
|
|
148
148
|
this.log('');
|
|
149
|
-
this.log(styleText(['bold', 'yellow'], '
|
|
149
|
+
this.log(styleText(['bold', 'yellow'], 'Notice'));
|
|
150
150
|
this.log('');
|
|
151
151
|
for (const entry of warnings) {
|
|
152
152
|
entry.suggestions.forEach((sug) => {
|
|
@@ -206,6 +206,16 @@ export class ResolvedCommand extends RuntimeCommand {
|
|
|
206
206
|
scopeType;
|
|
207
207
|
scopeId;
|
|
208
208
|
stackId;
|
|
209
|
+
/**
|
|
210
|
+
* locally-resolved Stack ID (flags > env > module > config)
|
|
211
|
+
* populated regardless of `needs` and is never required
|
|
212
|
+
*/
|
|
213
|
+
resolvedStackId;
|
|
214
|
+
/**
|
|
215
|
+
* the located `.sanity/blueprint.config.json` (if any), populated regardless of
|
|
216
|
+
* `needs`. Lets commands read/update local config without requiring a manifest.
|
|
217
|
+
*/
|
|
218
|
+
blueprintConfig;
|
|
209
219
|
auth;
|
|
210
220
|
deployedStack;
|
|
211
221
|
async init() {
|
|
@@ -233,6 +243,7 @@ export class ResolvedCommand extends RuntimeCommand {
|
|
|
233
243
|
// Anchor to --path flag or the blueprint file location if found, else cwd.
|
|
234
244
|
const blueprintFileInfo = findBlueprintFile(this.flags.path);
|
|
235
245
|
const blueprintConfig = readConfigFile(blueprintFileInfo?.blueprintFilePath);
|
|
246
|
+
this.blueprintConfig = blueprintConfig;
|
|
236
247
|
// 3. Blueprint (if needed)
|
|
237
248
|
let blueprintModule;
|
|
238
249
|
if (needsBlueprint) {
|
|
@@ -292,6 +303,8 @@ export class ResolvedCommand extends RuntimeCommand {
|
|
|
292
303
|
// assumption was wrong; leave stackId undefined
|
|
293
304
|
}
|
|
294
305
|
}
|
|
306
|
+
// Expose the resolved Stack ID regardless of `needs` (optional, for listings/highlighting)
|
|
307
|
+
this.resolvedStackId = resolved.stackId;
|
|
295
308
|
// Backfill resolved IDs onto the blueprint result if it was loaded
|
|
296
309
|
if (this.blueprint) {
|
|
297
310
|
Object.assign(this.blueprint, {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ResolvedCommand } from '../../baseCommands.js';
|
|
2
2
|
export default class DestroyCommand extends ResolvedCommand<typeof DestroyCommand> {
|
|
3
|
-
static needs: readonly ["
|
|
3
|
+
static needs: readonly ["scope"];
|
|
4
4
|
static summary: string;
|
|
5
5
|
static description: string;
|
|
6
6
|
static examples: string[];
|
|
@@ -3,7 +3,7 @@ import { organizationIdFlagConfig, projectIdFlagConfig, ResolvedCommand } from '
|
|
|
3
3
|
import { blueprintDestroyCore } from '../../cores/blueprints/destroy.js';
|
|
4
4
|
import { Logger } from '../../utils/logger.js';
|
|
5
5
|
export default class DestroyCommand extends ResolvedCommand {
|
|
6
|
-
static needs = ['
|
|
6
|
+
static needs = ['scope'];
|
|
7
7
|
static summary = 'Destroy a remote Stack deployment and its resources';
|
|
8
8
|
static description = `Permanently removes the remote Stack and all its provisioned resources. Your Blueprint manifest and resource files remain intact; "stackId" is unset in your local config.
|
|
9
9
|
|
|
@@ -44,8 +44,10 @@ Exit codes: 0 destroyed, 2 destruction failed, 75 destruction accepted but compl
|
|
|
44
44
|
bin: this.config.bin,
|
|
45
45
|
log: Logger(this.log.bind(this), this.flags),
|
|
46
46
|
token: this.sanityToken,
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
scopeType: this.scopeType,
|
|
48
|
+
scopeId: this.scopeId,
|
|
49
|
+
localStackId: this.resolvedStackId,
|
|
50
|
+
blueprintConfig: this.blueprintConfig,
|
|
49
51
|
flags: this.flags,
|
|
50
52
|
});
|
|
51
53
|
if (!result.success)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ResolvedCommand } from '../../baseCommands.js';
|
|
2
2
|
export default class StacksCommand extends ResolvedCommand<typeof StacksCommand> {
|
|
3
|
-
static needs: readonly ["
|
|
3
|
+
static needs: readonly ["scope"];
|
|
4
4
|
static summary: string;
|
|
5
5
|
static description: string;
|
|
6
6
|
static examples: string[];
|
|
@@ -3,7 +3,7 @@ import { organizationIdFlagConfig, projectIdFlagConfig, ResolvedCommand } from '
|
|
|
3
3
|
import { blueprintStacksCore } from '../../cores/blueprints/stacks.js';
|
|
4
4
|
import { Logger } from '../../utils/logger.js';
|
|
5
5
|
export default class StacksCommand extends ResolvedCommand {
|
|
6
|
-
static needs = ['
|
|
6
|
+
static needs = ['scope'];
|
|
7
7
|
static summary = 'List remote Stack deployments for your project or organization';
|
|
8
8
|
static description = `Shows all Stacks associated with a project or organization. By default, lists Stacks scoped to the local Blueprint.
|
|
9
9
|
|
|
@@ -32,8 +32,9 @@ Use --include-projects with --organization-id to also list Stacks from all proje
|
|
|
32
32
|
bin: this.config.bin,
|
|
33
33
|
log: Logger(this.log.bind(this), this.flags),
|
|
34
34
|
token: this.sanityToken,
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
scopeType: this.scopeType,
|
|
36
|
+
scopeId: this.scopeId,
|
|
37
|
+
localStackId: this.resolvedStackId,
|
|
37
38
|
flags: this.flags,
|
|
38
39
|
});
|
|
39
40
|
if (!result.success)
|
package/dist/config.d.ts
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
export declare const BLUEPRINT_CONFIG_VERSION = "v2025-05-08";
|
|
2
|
+
export declare const BLUEPRINTS_API_VERSION: string;
|
|
2
3
|
export declare const BLUEPRINT_CONFIG_DIR = ".sanity";
|
|
3
4
|
export declare const BLUEPRINT_CONFIG_FILE = "blueprint.config.json";
|
|
4
5
|
export declare const RUNTIME_CLI_NAME = "@sanity/runtime-cli";
|
|
5
6
|
export declare let RUNTIME_CLI_VERSION: string | undefined;
|
|
6
7
|
export declare const RUNTIME_CLI_USER_AGENT: string;
|
|
8
|
+
/**
|
|
9
|
+
* Build a Blueprints API URL for the given path.
|
|
10
|
+
*
|
|
11
|
+
* Uses `BLUEPRINTS_API_VERSION` by default (itself overridable via the
|
|
12
|
+
* `SANITY_BLUEPRINTS_API_VERSION` env var); pass `version` to override per-endpoint.
|
|
13
|
+
*/
|
|
14
|
+
export declare function blueprintsUrl(path: string, version?: string): string;
|
|
7
15
|
declare const _default: {
|
|
8
16
|
isTest: boolean;
|
|
9
17
|
isLive: boolean;
|
package/dist/config.js
CHANGED
|
@@ -4,6 +4,9 @@ import { fileURLToPath } from 'node:url';
|
|
|
4
4
|
import * as pkg from 'empathic/package';
|
|
5
5
|
import getToken from './utils/get-token.js';
|
|
6
6
|
export const BLUEPRINT_CONFIG_VERSION = 'v2025-05-08';
|
|
7
|
+
// Default API version for Blueprints service calls.
|
|
8
|
+
// Overridable globally via env, or per-endpoint via the `version` arg to `blueprintsUrl`.
|
|
9
|
+
export const BLUEPRINTS_API_VERSION = env.SANITY_BLUEPRINTS_API_VERSION ?? 'v2026-06-15';
|
|
7
10
|
export const BLUEPRINT_CONFIG_DIR = '.sanity';
|
|
8
11
|
export const BLUEPRINT_CONFIG_FILE = 'blueprint.config.json';
|
|
9
12
|
export const RUNTIME_CLI_NAME = '@sanity/runtime-cli';
|
|
@@ -35,6 +38,15 @@ const apiUrls = {
|
|
|
35
38
|
const apiUrl = sanityEnv ? (apiUrls[sanityEnv] ?? sanityEnv) : apiUrls.default;
|
|
36
39
|
// allow override of populus URL
|
|
37
40
|
const populusApiUrl = env.POPULUS_API_URL ?? apiUrl;
|
|
41
|
+
/**
|
|
42
|
+
* Build a Blueprints API URL for the given path.
|
|
43
|
+
*
|
|
44
|
+
* Uses `BLUEPRINTS_API_VERSION` by default (itself overridable via the
|
|
45
|
+
* `SANITY_BLUEPRINTS_API_VERSION` env var); pass `version` to override per-endpoint.
|
|
46
|
+
*/
|
|
47
|
+
export function blueprintsUrl(path, version = BLUEPRINTS_API_VERSION) {
|
|
48
|
+
return `${apiUrl}${version}/blueprints/${path}`;
|
|
49
|
+
}
|
|
38
50
|
let _token;
|
|
39
51
|
function loadToken() {
|
|
40
52
|
let token = null;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { dirname } from 'node:path';
|
|
1
2
|
import { stashAsset } from '../../actions/blueprints/assets.js';
|
|
2
3
|
import { getStack, updateStack } from '../../actions/blueprints/stacks.js';
|
|
3
4
|
import { waitForOperation } from '../../actions/blueprints/wait-for-operation.js';
|
|
@@ -7,6 +8,7 @@ import { niceId } from '../../utils/display/presenters.js';
|
|
|
7
8
|
import { CODE_OPERATION_UNCONFIRMED, EXIT_OPERATION_UNCONFIRMED } from '../../utils/exit-codes.js';
|
|
8
9
|
import { styleText } from '../../utils/style-text.js';
|
|
9
10
|
import { isAssetResource } from '../../utils/types.js';
|
|
11
|
+
import { getWarnings } from '../../utils/warnings.js';
|
|
10
12
|
const DEFAULT_ASSET_TIMEOUT = 60;
|
|
11
13
|
const assetTimeoutS = Number(process.env.SANITY_ASSET_TIMEOUT) || DEFAULT_ASSET_TIMEOUT;
|
|
12
14
|
const assetTimeoutMs = assetTimeoutS * 1000;
|
|
@@ -17,6 +19,7 @@ export async function blueprintDeployCore(options) {
|
|
|
17
19
|
const noWait = flags['no-wait'] || false;
|
|
18
20
|
const stackName = flags['new-stack-name'] ?? deployedStack.name;
|
|
19
21
|
const installer = flags['fn-installer'] || undefined;
|
|
22
|
+
const workspaceWarnings = getWarnings({ dir: dirname(blueprint.fileInfo.blueprintFilePath) });
|
|
20
23
|
log(`Deploying "${stackName}" ${niceId(deployedStack.id)}...`);
|
|
21
24
|
try {
|
|
22
25
|
const { ok: checkOk, stack: currentStack } = await getStack({ stackId, auth, logger: log });
|
|
@@ -89,11 +92,12 @@ export async function blueprintDeployCore(options) {
|
|
|
89
92
|
log(styleText(['bold', 'green'], 'Stack deployment started!'));
|
|
90
93
|
log(`Use \`npx ${bin} blueprints info\` to check status`);
|
|
91
94
|
const legacyWarning = await legacyPermissionsNoticePromise;
|
|
95
|
+
const warnings = [...(legacyWarning ? [legacyWarning] : []), ...workspaceWarnings];
|
|
92
96
|
return {
|
|
93
97
|
success: true,
|
|
94
98
|
json: { stackId, resources },
|
|
95
99
|
data: { resources },
|
|
96
|
-
warnings:
|
|
100
|
+
warnings: warnings.length ? warnings : undefined,
|
|
97
101
|
};
|
|
98
102
|
}
|
|
99
103
|
log(styleText('dim', 'Stack deployment progress:'));
|
|
@@ -110,11 +114,12 @@ export async function blueprintDeployCore(options) {
|
|
|
110
114
|
if (outcome.type === 'completed') {
|
|
111
115
|
log(styleText(['bold', 'green'], 'Stack deployment completed!'));
|
|
112
116
|
const legacyWarning = await legacyPermissionsNoticePromise;
|
|
117
|
+
const warnings = [...(legacyWarning ? [legacyWarning] : []), ...workspaceWarnings];
|
|
113
118
|
return {
|
|
114
119
|
success: true,
|
|
115
120
|
json: { stackId, resources },
|
|
116
121
|
data: { resources },
|
|
117
|
-
warnings:
|
|
122
|
+
warnings: warnings.length ? warnings : undefined,
|
|
118
123
|
};
|
|
119
124
|
}
|
|
120
125
|
if (outcome.type === 'unconfirmed') {
|
|
@@ -212,7 +217,7 @@ async function checkLegacyDeployPermission({ auth, scopeType, scopeId, log, }) {
|
|
|
212
217
|
if (result.hasPermission)
|
|
213
218
|
return null;
|
|
214
219
|
return {
|
|
215
|
-
|
|
220
|
+
code: 'Legacy deploy permission',
|
|
216
221
|
suggestions: [
|
|
217
222
|
`This deploy used a legacy permission. Starting ${BLUEPRINTS_PERMISSION_ENFORCEMENT_DATE}, deploys will require the "${requiredPermission}" permission.`,
|
|
218
223
|
scopeType === 'project'
|
|
@@ -1,5 +1,15 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import { type LocatedBlueprintsConfig } from '../../actions/blueprints/config.js';
|
|
2
|
+
import type { ScopeType } from '../../utils/types.js';
|
|
3
|
+
import type { CoreConfig, CoreResult } from '../index.js';
|
|
4
|
+
export interface BlueprintDestroyOptions extends CoreConfig {
|
|
5
|
+
token: string;
|
|
6
|
+
/** Scope to destroy within, resolved by the base command (flags > env > config). */
|
|
7
|
+
scopeType?: ScopeType;
|
|
8
|
+
scopeId?: string;
|
|
9
|
+
/** Locally-configured Stack ID, used when no --stack override is provided. */
|
|
10
|
+
localStackId?: string;
|
|
11
|
+
/** Located local config, used to unset stackId after a successful destroy. */
|
|
12
|
+
blueprintConfig?: LocatedBlueprintsConfig | null;
|
|
3
13
|
flags: {
|
|
4
14
|
force?: boolean;
|
|
5
15
|
'project-id'?: string;
|
|
@@ -1,27 +1,18 @@
|
|
|
1
1
|
import { setTimeout as sleep } from 'node:timers/promises';
|
|
2
2
|
import { confirm } from '@inquirer/prompts';
|
|
3
|
-
import {
|
|
3
|
+
import { patchLocatedConfig } from '../../actions/blueprints/config.js';
|
|
4
4
|
import { destroyStack, getStack, resolveStackIdByNameOrId } from '../../actions/blueprints/stacks.js';
|
|
5
5
|
import { waitForOperation } from '../../actions/blueprints/wait-for-operation.js';
|
|
6
6
|
import { niceId } from '../../utils/display/presenters.js';
|
|
7
7
|
import { CODE_OPERATION_UNCONFIRMED, EXIT_OPERATION_UNCONFIRMED } from '../../utils/exit-codes.js';
|
|
8
8
|
import { styleText } from '../../utils/style-text.js';
|
|
9
9
|
export async function blueprintDestroyCore(options) {
|
|
10
|
-
const { bin = 'sanity', log, token,
|
|
10
|
+
const { bin = 'sanity', log, token, scopeType, scopeId, localStackId, blueprintConfig, flags, } = options;
|
|
11
11
|
const { force = false, 'project-id': flagProjectId, 'organization-id': flagOrganizationId, stack: flagStack, 'no-wait': noWait = false, verbose = false, } = flags;
|
|
12
|
-
// 3-flag combo: destroy
|
|
12
|
+
// 3-flag combo: non-interactive destroy that does not need a local Blueprint nearby.
|
|
13
|
+
// Scope comes from the --project-id/--organization-id flags (resolved by the base command).
|
|
13
14
|
if ((flagProjectId || flagOrganizationId) && flagStack && force) {
|
|
14
|
-
|
|
15
|
-
let scopeId;
|
|
16
|
-
if (flagOrganizationId) {
|
|
17
|
-
scopeType = 'organization';
|
|
18
|
-
scopeId = flagOrganizationId;
|
|
19
|
-
}
|
|
20
|
-
else if (flagProjectId) {
|
|
21
|
-
scopeType = 'project';
|
|
22
|
-
scopeId = flagProjectId;
|
|
23
|
-
}
|
|
24
|
-
else {
|
|
15
|
+
if (!scopeType || !scopeId) {
|
|
25
16
|
return { success: false, error: 'Unable to determine scope for Blueprint Destroy' };
|
|
26
17
|
}
|
|
27
18
|
const auth = { token, scopeType, scopeId };
|
|
@@ -33,7 +24,7 @@ export async function blueprintDestroyCore(options) {
|
|
|
33
24
|
});
|
|
34
25
|
if (!ok)
|
|
35
26
|
return { success: false, error: error || 'Failed to destroy Stack deployment' };
|
|
36
|
-
clearLocalStackIdFromConfig(
|
|
27
|
+
clearLocalStackIdFromConfig(blueprintConfig, stack.id, log);
|
|
37
28
|
if (noWait) {
|
|
38
29
|
log(styleText(['bold', 'magenta'], 'Stack destruction started!'));
|
|
39
30
|
return { success: true, json: { stackId: stack.id, stackName: stack.name } };
|
|
@@ -48,7 +39,6 @@ export async function blueprintDestroyCore(options) {
|
|
|
48
39
|
verbose,
|
|
49
40
|
});
|
|
50
41
|
}
|
|
51
|
-
const { scopeType, scopeId, stackId } = blueprint;
|
|
52
42
|
if (!scopeType || !scopeId)
|
|
53
43
|
return { success: false, error: 'Scope is required' };
|
|
54
44
|
const auth = { token, scopeType, scopeId };
|
|
@@ -63,8 +53,8 @@ export async function blueprintDestroyCore(options) {
|
|
|
63
53
|
return { success: false, error: overrideStack.error || 'Failed to get Stack' };
|
|
64
54
|
stack = overrideStack.stack;
|
|
65
55
|
}
|
|
66
|
-
else if (
|
|
67
|
-
const blueprintStack = await getStack({ stackId, auth, logger: log });
|
|
56
|
+
else if (localStackId) {
|
|
57
|
+
const blueprintStack = await getStack({ stackId: localStackId, auth, logger: log });
|
|
68
58
|
if (!blueprintStack.ok)
|
|
69
59
|
return { success: false, error: blueprintStack.error || 'Failed to get Stack' };
|
|
70
60
|
stack = blueprintStack.stack;
|
|
@@ -115,7 +105,7 @@ export async function blueprintDestroyCore(options) {
|
|
|
115
105
|
return { success: false, error: error || 'Failed to destroy Stack deployment' };
|
|
116
106
|
}
|
|
117
107
|
destroySpinner.stop().clear();
|
|
118
|
-
clearLocalStackIdFromConfig(
|
|
108
|
+
clearLocalStackIdFromConfig(blueprintConfig, stack.id, log);
|
|
119
109
|
if (noWait) {
|
|
120
110
|
log(styleText(['bold', 'magenta'], 'Stack destruction started!'));
|
|
121
111
|
return { success: true, json: { stackId: stack.id, stackName: stack.name } };
|
|
@@ -135,13 +125,13 @@ export async function blueprintDestroyCore(options) {
|
|
|
135
125
|
return { success: false, error: errorMessage };
|
|
136
126
|
}
|
|
137
127
|
}
|
|
138
|
-
function clearLocalStackIdFromConfig(
|
|
139
|
-
if (!
|
|
128
|
+
function clearLocalStackIdFromConfig(blueprintConfig, destroyedStackId, log) {
|
|
129
|
+
if (!blueprintConfig)
|
|
140
130
|
return;
|
|
141
|
-
if (
|
|
131
|
+
if (blueprintConfig.stackId !== destroyedStackId)
|
|
142
132
|
return;
|
|
143
133
|
try {
|
|
144
|
-
|
|
134
|
+
patchLocatedConfig(blueprintConfig, { stackId: null });
|
|
145
135
|
log(styleText('dim', 'Removed stackId from .sanity/blueprint.config.json'));
|
|
146
136
|
}
|
|
147
137
|
catch {
|
|
@@ -8,12 +8,12 @@ import { readConfigFile } from '../../actions/blueprints/config.js';
|
|
|
8
8
|
import { resolveIds } from '../../actions/blueprints/resolve.js';
|
|
9
9
|
import { getStack } from '../../actions/blueprints/stacks.js';
|
|
10
10
|
import config, { RUNTIME_CLI_VERSION } from '../../config.js';
|
|
11
|
-
import { getWarnings } from '../../utils/blueprints/warnings.js';
|
|
12
11
|
import { formatDateTime } from '../../utils/display/dates.js';
|
|
13
12
|
import { advise, check, filePathRelativeToCwd, niceId, renderSection, severe, unsure, } from '../../utils/display/presenters.js';
|
|
14
13
|
import { styleText } from '../../utils/style-text.js';
|
|
15
14
|
import { createTracedFetch } from '../../utils/traced-fetch.js';
|
|
16
15
|
import { validTokenOrErrorMessage } from '../../utils/validated-token.js';
|
|
16
|
+
import { getWarnings } from '../../utils/warnings.js';
|
|
17
17
|
import { blueprintConfigCore } from './config.js';
|
|
18
18
|
const diagLookup = {
|
|
19
19
|
online: 'Host online',
|
|
@@ -23,7 +23,9 @@ const diagLookup = {
|
|
|
23
23
|
userHasAccess: 'User has access',
|
|
24
24
|
};
|
|
25
25
|
const warnLookup = {
|
|
26
|
-
|
|
26
|
+
studio: 'In studio',
|
|
27
|
+
floating: 'In own dir',
|
|
28
|
+
functions: 'In functions dir',
|
|
27
29
|
};
|
|
28
30
|
function sourceLabel(source) {
|
|
29
31
|
switch (source) {
|
|
@@ -243,16 +245,32 @@ export async function blueprintDoctorCore(options) {
|
|
|
243
245
|
for (const key in warnLookup) {
|
|
244
246
|
warningDiagnostics[key] = { status: null };
|
|
245
247
|
}
|
|
246
|
-
//
|
|
247
|
-
let
|
|
248
|
+
// Workspace issues; IE Functions in Studio
|
|
249
|
+
let warnings = [];
|
|
248
250
|
if (localBlueprint) {
|
|
249
251
|
const blueprintDir = dirname(localBlueprint.fileInfo.blueprintFilePath || '.');
|
|
250
|
-
|
|
251
|
-
if (
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
252
|
+
warnings = getWarnings({ dir: blueprintDir });
|
|
253
|
+
if (warnings.length) {
|
|
254
|
+
for (const warning of warnings) {
|
|
255
|
+
if (warning.code === 'studio') {
|
|
256
|
+
warningDiagnostics.studio = {
|
|
257
|
+
status: true,
|
|
258
|
+
detail: 'Blueprint config in the Studio dir',
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
if (warning.code === 'functions') {
|
|
262
|
+
warningDiagnostics.functions = {
|
|
263
|
+
status: true,
|
|
264
|
+
detail: 'Blueprints config in the Functions dir',
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
if (warning.code === 'floating') {
|
|
268
|
+
warningDiagnostics.floating = {
|
|
269
|
+
status: true,
|
|
270
|
+
detail: 'Blueprint not part of a project',
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
}
|
|
256
274
|
}
|
|
257
275
|
}
|
|
258
276
|
// --- RENDER REPORT ---
|
|
@@ -292,12 +310,14 @@ export async function blueprintDoctorCore(options) {
|
|
|
292
310
|
}
|
|
293
311
|
}
|
|
294
312
|
let hasWarnings = false;
|
|
313
|
+
// Because TS is TS - narrow string keys to WarningCode before indexing warnLookup
|
|
314
|
+
const isWarningCode = (code) => code in warnLookup;
|
|
295
315
|
if (Object.values(warningDiagnostics).some((entry) => entry.status === true)) {
|
|
296
316
|
hasWarnings = true;
|
|
297
317
|
const maxLabel = Math.max(...Object.values(warnLookup).map((l) => l.length));
|
|
298
318
|
log(styleText('bold', 'Warnings'));
|
|
299
319
|
for (const [key, entry] of Object.entries(warningDiagnostics)) {
|
|
300
|
-
if (entry.status) {
|
|
320
|
+
if (entry.status && isWarningCode(key)) {
|
|
301
321
|
const label = warnLookup[key].padEnd(maxLabel);
|
|
302
322
|
const detail = entry.detail ? ` ${styleText('dim', entry.detail)}` : '';
|
|
303
323
|
log(` ${advise(label)}${detail}`);
|
|
@@ -320,7 +340,7 @@ export async function blueprintDoctorCore(options) {
|
|
|
320
340
|
success: true,
|
|
321
341
|
json: { diagnostics: flatDiagnostics },
|
|
322
342
|
data: { diagnostics: flatDiagnostics },
|
|
323
|
-
warnings: hasWarnings ?
|
|
343
|
+
warnings: hasWarnings ? warnings : undefined,
|
|
324
344
|
};
|
|
325
345
|
}
|
|
326
346
|
if (fix) {
|
|
@@ -364,7 +384,7 @@ export async function blueprintDoctorCore(options) {
|
|
|
364
384
|
flags: { edit: true, verbose: v },
|
|
365
385
|
});
|
|
366
386
|
if (fixResult.success) {
|
|
367
|
-
return { ...fixResult, warnings: hasWarnings ?
|
|
387
|
+
return { ...fixResult, warnings: hasWarnings ? warnings : undefined };
|
|
368
388
|
}
|
|
369
389
|
return fixResult;
|
|
370
390
|
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { dirname } from 'node:path';
|
|
1
2
|
import { planStack, resolveStackIdByNameOrId } from '../../actions/blueprints/stacks.js';
|
|
2
3
|
import { createHintCollector } from '../../utils/blueprints/hints.js';
|
|
3
4
|
import { formatDeploymentPlan, formatResourceTree, hasActionableChanges, } from '../../utils/display/blueprints-formatting.js';
|
|
4
5
|
import { styleText } from '../../utils/style-text.js';
|
|
6
|
+
import { getWarnings } from '../../utils/warnings.js';
|
|
5
7
|
export async function blueprintPlanCore(options) {
|
|
6
8
|
const { bin = 'sanity', log, blueprint, token, flags } = options;
|
|
7
9
|
const { verbose: _verbose = false } = flags;
|
|
@@ -69,6 +71,7 @@ export async function blueprintPlanCore(options) {
|
|
|
69
71
|
],
|
|
70
72
|
};
|
|
71
73
|
}
|
|
74
|
+
const warnings = getWarnings({ dir: dirname(fileInfo.blueprintFilePath) });
|
|
72
75
|
log('');
|
|
73
76
|
log(formatDeploymentPlan(planResponse.deploymentPlan));
|
|
74
77
|
if (hasActionableChanges(planResponse.deploymentPlan)) {
|
|
@@ -83,5 +86,6 @@ export async function blueprintPlanCore(options) {
|
|
|
83
86
|
resources,
|
|
84
87
|
plan: planResponse.deploymentPlan,
|
|
85
88
|
},
|
|
89
|
+
warnings: warnings,
|
|
86
90
|
};
|
|
87
91
|
}
|
|
@@ -1,8 +1,13 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
1
|
+
import type { ScopeType } from '../../utils/types.js';
|
|
2
|
+
import type { CoreConfig, CoreResult } from '../index.js';
|
|
3
|
+
export interface BlueprintStacksOptions extends CoreConfig {
|
|
4
|
+
token: string;
|
|
5
|
+
/** Scope to list Stacks for, resolved by the base command (flags > env > config). */
|
|
6
|
+
scopeType: ScopeType;
|
|
7
|
+
scopeId: string;
|
|
8
|
+
/** Locally-configured Stack ID, used only to highlight the current Stack in listings. */
|
|
9
|
+
localStackId?: string;
|
|
3
10
|
flags: {
|
|
4
|
-
'project-id'?: string;
|
|
5
|
-
'organization-id'?: string;
|
|
6
11
|
'include-projects'?: boolean;
|
|
7
12
|
verbose?: boolean;
|
|
8
13
|
};
|
|
@@ -6,30 +6,8 @@ import { styleText } from '../../utils/style-text.js';
|
|
|
6
6
|
/** Max projects to query for stacks during --include-projects */
|
|
7
7
|
const PROJECT_LIMIT = 50;
|
|
8
8
|
export async function blueprintStacksCore(options) {
|
|
9
|
-
const { log, token,
|
|
10
|
-
const {
|
|
11
|
-
const { 'project-id': flagProjectId, 'organization-id': flagOrganizationId, 'include-projects': includeProjects = false, verbose: _verbose = false, } = flags;
|
|
12
|
-
if (flagOrganizationId && flagProjectId) {
|
|
13
|
-
log.error('Cannot specify both --organization-id and --project-id');
|
|
14
|
-
return { success: false, error: 'Cannot specify both --organization-id and --project-id' };
|
|
15
|
-
}
|
|
16
|
-
let scopeType = blueprintScopeType;
|
|
17
|
-
let scopeId = blueprintScopeId;
|
|
18
|
-
if (flagOrganizationId) {
|
|
19
|
-
scopeType = 'organization';
|
|
20
|
-
scopeId = flagOrganizationId;
|
|
21
|
-
}
|
|
22
|
-
if (flagProjectId) {
|
|
23
|
-
scopeType = 'project';
|
|
24
|
-
scopeId = flagProjectId;
|
|
25
|
-
}
|
|
26
|
-
if (!scopeType || !scopeId) {
|
|
27
|
-
return {
|
|
28
|
-
success: false,
|
|
29
|
-
error: 'Unable to determine scope for Blueprint Stacks',
|
|
30
|
-
suggestions: ['Run in a Blueprint directory or provide a project with --project-id.'],
|
|
31
|
-
};
|
|
32
|
-
}
|
|
9
|
+
const { log, token, scopeType, scopeId, localStackId: blueprintStackId, flags } = options;
|
|
10
|
+
const { 'include-projects': includeProjects = false } = flags;
|
|
33
11
|
if (includeProjects && scopeType === 'organization') {
|
|
34
12
|
return deepListStacks({ organizationId: scopeId, token, log, blueprintStackId });
|
|
35
13
|
}
|
|
@@ -9,6 +9,7 @@ import { EVENT_DOCUMENT_CREATE, EVENT_DOCUMENT_DELETE, EVENT_DOCUMENT_UPDATE, EV
|
|
|
9
9
|
import { check, indent, warn } from '../../utils/display/presenters.js';
|
|
10
10
|
import { validateFunctionName } from '../../utils/functions/validate-name.js';
|
|
11
11
|
import { styleText } from '../../utils/style-text.js';
|
|
12
|
+
import { getWarnings } from '../../utils/warnings.js';
|
|
12
13
|
export const generateFunctionBlueprintResourceTemplate = (fnName, eventNames) => {
|
|
13
14
|
const functionType = MAP_EVENT_TO_FUNCTION_TYPE[eventNames[0]];
|
|
14
15
|
let definer = '';
|
|
@@ -40,6 +41,7 @@ export async function functionAddCore(options) {
|
|
|
40
41
|
const root = cwd();
|
|
41
42
|
const { log, blueprint, flags } = options;
|
|
42
43
|
const { blueprintFilePath } = blueprint.fileInfo;
|
|
44
|
+
const warnings = getWarnings({ dir: dirname(blueprintFilePath) });
|
|
43
45
|
const { example: flagExample, name: flagResourceName, type: flagType, javascript: flagJs, helpers: flagHelpers, install: flagI, installer: flagInstaller, } = flags;
|
|
44
46
|
let { language: flagLang } = flags;
|
|
45
47
|
flagLang = flagJs ? 'js' : flagLang;
|
|
@@ -208,7 +210,7 @@ export async function functionAddCore(options) {
|
|
|
208
210
|
else {
|
|
209
211
|
log(`Function "${styleText('bold', fnName)}" added to Blueprint file.`);
|
|
210
212
|
}
|
|
211
|
-
return { success: true };
|
|
213
|
+
return { success: true, warnings };
|
|
212
214
|
}
|
|
213
215
|
catch (err) {
|
|
214
216
|
const errorMessage = err instanceof Error ? err.message : String(err);
|
package/dist/cores/index.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { type ReadBlueprintResult } from '../actions/blueprints/blueprint.js';
|
|
2
|
-
import type { Warning } from '../utils/blueprints/warnings.js';
|
|
3
2
|
import type { Logger } from '../utils/logger.js';
|
|
4
|
-
import type { AuthParams, Result, ScopeType, Stack } from '../utils/types.js';
|
|
3
|
+
import type { AuthParams, Result, ScopeType, Stack, Warning } from '../utils/types.js';
|
|
5
4
|
export interface CoreConfig {
|
|
6
5
|
/** The CLI binary name. */
|
|
7
6
|
bin: string;
|
|
@@ -10,3 +10,9 @@ export declare function transpileFunction(resource: FunctionResource, { installe
|
|
|
10
10
|
timings: Record<string, number>;
|
|
11
11
|
bundled: boolean;
|
|
12
12
|
}>;
|
|
13
|
+
/**
|
|
14
|
+
* Vite 8's `build()` wraps failures in a `BundleError` whose `message` contains
|
|
15
|
+
* a "Build failed with N errors" preamble and full stack traces. The individual
|
|
16
|
+
* errors on `.errors` carry the original, human-readable messages.
|
|
17
|
+
*/
|
|
18
|
+
export declare function formatBuildError(err: unknown): string;
|
|
@@ -4,7 +4,6 @@ import { performance } from 'node:perf_hooks';
|
|
|
4
4
|
import { cwd } from 'node:process';
|
|
5
5
|
import * as find from 'empathic/find';
|
|
6
6
|
import { build as viteBuild } from 'vite';
|
|
7
|
-
import tsConfigPaths from 'vite-tsconfig-paths';
|
|
8
7
|
import { detectNativeModulesPlugin } from '../detect-native-modules.js';
|
|
9
8
|
import { findFunctionEntryPoint } from '../find-entry-point.js';
|
|
10
9
|
import { cleanupSourceMaps } from './cleanup-source-maps.js';
|
|
@@ -51,7 +50,7 @@ export async function transpileFunction(resource, { installer } = {}) {
|
|
|
51
50
|
minify: false,
|
|
52
51
|
sourcemap: true,
|
|
53
52
|
ssr: true,
|
|
54
|
-
|
|
53
|
+
rolldownOptions: {
|
|
55
54
|
input: entry,
|
|
56
55
|
output: {
|
|
57
56
|
format: 'esm',
|
|
@@ -66,16 +65,18 @@ export async function transpileFunction(resource, { installer } = {}) {
|
|
|
66
65
|
external: bundle ? [] : [/node_modules/],
|
|
67
66
|
},
|
|
68
67
|
},
|
|
68
|
+
resolve: {
|
|
69
|
+
// Replaces the vite-tsconfig-paths plugin; vite 8 resolves tsconfig
|
|
70
|
+
// `compilerOptions.paths` natively
|
|
71
|
+
tsconfigPaths: true,
|
|
72
|
+
},
|
|
69
73
|
ssr: {
|
|
70
74
|
noExternal: bundle ? true : [],
|
|
71
75
|
resolve: {
|
|
72
76
|
conditions: ['node'],
|
|
73
77
|
},
|
|
74
78
|
},
|
|
75
|
-
plugins: [
|
|
76
|
-
...(bundle ? [detectNativeModulesPlugin(), pnpmResolvePlugin(cwd())] : []),
|
|
77
|
-
tsConfigPaths(),
|
|
78
|
-
],
|
|
79
|
+
plugins: bundle ? [detectNativeModulesPlugin(), pnpmResolvePlugin(cwd())] : [],
|
|
79
80
|
});
|
|
80
81
|
timings['transpile:build'] = performance.now() - viteStart;
|
|
81
82
|
const verifyStart = performance.now();
|
|
@@ -99,11 +100,37 @@ export async function transpileFunction(resource, { installer } = {}) {
|
|
|
99
100
|
}
|
|
100
101
|
catch (err) {
|
|
101
102
|
await cleanupTmpDir();
|
|
102
|
-
throw new Error(`Transpiling of function failed: ${err
|
|
103
|
+
throw new Error(`Transpiling of function failed: ${formatBuildError(err)}`, {
|
|
103
104
|
cause: err,
|
|
104
105
|
});
|
|
105
106
|
}
|
|
106
107
|
}
|
|
108
|
+
/**
|
|
109
|
+
* Vite 8's `build()` wraps failures in a `BundleError` whose `message` contains
|
|
110
|
+
* a "Build failed with N errors" preamble and full stack traces. The individual
|
|
111
|
+
* errors on `.errors` carry the original, human-readable messages.
|
|
112
|
+
*/
|
|
113
|
+
export function formatBuildError(err) {
|
|
114
|
+
if (!(err instanceof Error))
|
|
115
|
+
return String(err);
|
|
116
|
+
if ('errors' in err && Array.isArray(err.errors) && err.errors.length > 0) {
|
|
117
|
+
return err.errors.map(formatBuildErrorEntry).join('\n');
|
|
118
|
+
}
|
|
119
|
+
return err.message;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* A `BundleError.errors` entry may be...
|
|
123
|
+
* a real `Error`,
|
|
124
|
+
* a plain object carrying a `message` (Rolldown/Oxc diagnostics),
|
|
125
|
+
* or unknown
|
|
126
|
+
* Prefer `.message` and fall back to `String()`
|
|
127
|
+
*/
|
|
128
|
+
function formatBuildErrorEntry(e) {
|
|
129
|
+
if (e instanceof Error)
|
|
130
|
+
return e.message;
|
|
131
|
+
const message = e?.message;
|
|
132
|
+
return typeof message === 'string' ? message : String(e);
|
|
133
|
+
}
|
|
107
134
|
async function writeTranspiledPackageJson(inputDir, outputFilePath) {
|
|
108
135
|
const baseName = path.basename(outputFilePath);
|
|
109
136
|
let original;
|
package/dist/utils/types.d.ts
CHANGED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Warning } from './types.js';
|
|
2
|
+
export type WarningCode = 'studio' | 'floating' | 'functions';
|
|
3
|
+
export type WarningContext = {
|
|
4
|
+
dir: string;
|
|
5
|
+
};
|
|
6
|
+
export type WarningType = {
|
|
7
|
+
code: WarningCode;
|
|
8
|
+
suggestions: string[];
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Generates warnings based upon the provided context by running through all rules and returning any matches
|
|
12
|
+
* @param ctx
|
|
13
|
+
*/
|
|
14
|
+
export declare const getWarnings: (ctx: WarningContext) => Warning[];
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { checkWorkspaceStruct } from './workspace-checks.js';
|
|
2
|
+
const workspaceRuleWarnings = [
|
|
3
|
+
{
|
|
4
|
+
code: 'studio',
|
|
5
|
+
suggestions: [
|
|
6
|
+
'Blueprint should not be co-located with a Sanity Studio. See docs for correct layout options:',
|
|
7
|
+
// @todo: this will need to updated once the layout is published.
|
|
8
|
+
'https://www.sanity.io/docs/blueprints/blueprints-introduction#aaeea93bdd42',
|
|
9
|
+
],
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
code: 'floating',
|
|
13
|
+
suggestions: [
|
|
14
|
+
'Blueprint is in a separate directory from its stack. See docs for recommended layout options:',
|
|
15
|
+
// @todo: this will need to updated once the layout is published.
|
|
16
|
+
'https://www.sanity.io/docs/blueprints/blueprints-introduction#aaeea93bdd42',
|
|
17
|
+
],
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
code: 'functions',
|
|
21
|
+
suggestions: [
|
|
22
|
+
'Blueprint is co-located with the functions directory. See docs for correct layout options:',
|
|
23
|
+
// @todo: this will need to updated once the layout is published.
|
|
24
|
+
'https://www.sanity.io/docs/blueprints/blueprints-introduction#aaeea93bdd42',
|
|
25
|
+
],
|
|
26
|
+
},
|
|
27
|
+
];
|
|
28
|
+
const workspaceRulesWarnings = (ctx) => {
|
|
29
|
+
const code = checkWorkspaceStruct(ctx.dir);
|
|
30
|
+
const warnings = workspaceRuleWarnings.find((w) => w.code === code);
|
|
31
|
+
return warnings ? [warnings] : [];
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Additive way of generating warnings based upon context
|
|
35
|
+
* At the moment, we have a single workspace warning check,
|
|
36
|
+
* more could be added via [workspaceRulesWarnings, otherWarningChecks, ...]
|
|
37
|
+
*/
|
|
38
|
+
const rules = [workspaceRulesWarnings];
|
|
39
|
+
/**
|
|
40
|
+
* Generates warnings based upon the provided context by running through all rules and returning any matches
|
|
41
|
+
* @param ctx
|
|
42
|
+
*/
|
|
43
|
+
export const getWarnings = (ctx) => {
|
|
44
|
+
return rules.flatMap((rule) => rule(ctx));
|
|
45
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { WarningCode } from './warnings.js';
|
|
2
|
+
/**
|
|
3
|
+
* Shared utility called by functions or blueprints to deterministically show warnings to users if it's not ideal
|
|
4
|
+
* 1. Checks to see if the given filepath is in a studio specific workspace
|
|
5
|
+
* 2. Checks to see if the given filepath is under a functions directory (/functions/sanity.blueprint.ts)
|
|
6
|
+
* 3. Checks to see if the given filepath is in a self-contained directory (/blueprints/my-blueprint/sanity.blueprint.ts)
|
|
7
|
+
* @param filePath
|
|
8
|
+
*/
|
|
9
|
+
export declare const checkWorkspaceStruct: (filePath: string) => WarningCode | undefined;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { existsSync, readdirSync } from 'node:fs';
|
|
2
|
+
import { dirname, join, relative, resolve, sep } from 'node:path';
|
|
3
|
+
/**
|
|
4
|
+
* Shared utility called by functions or blueprints to deterministically show warnings to users if it's not ideal
|
|
5
|
+
* 1. Checks to see if the given filepath is in a studio specific workspace
|
|
6
|
+
* 2. Checks to see if the given filepath is under a functions directory (/functions/sanity.blueprint.ts)
|
|
7
|
+
* 3. Checks to see if the given filepath is in a self-contained directory (/blueprints/my-blueprint/sanity.blueprint.ts)
|
|
8
|
+
* @param filePath
|
|
9
|
+
*/
|
|
10
|
+
export const checkWorkspaceStruct = (filePath) => {
|
|
11
|
+
const startDir = resolve(filePath);
|
|
12
|
+
let currentDir = startDir;
|
|
13
|
+
let packageRoot = null;
|
|
14
|
+
let underFunctionsDir = false;
|
|
15
|
+
let isInStudio = false;
|
|
16
|
+
while (true) {
|
|
17
|
+
if (existsSync(join(currentDir, 'package.json'))) {
|
|
18
|
+
packageRoot = currentDir;
|
|
19
|
+
break;
|
|
20
|
+
}
|
|
21
|
+
const parent = dirname(currentDir);
|
|
22
|
+
if (parent === currentDir)
|
|
23
|
+
break;
|
|
24
|
+
currentDir = parent;
|
|
25
|
+
}
|
|
26
|
+
try {
|
|
27
|
+
isInStudio = readdirSync(startDir, { withFileTypes: true }).some((entry) => entry.isFile() &&
|
|
28
|
+
(entry.name.startsWith('sanity.config') || entry.name.startsWith('sanity.cli')));
|
|
29
|
+
}
|
|
30
|
+
catch (_e) {
|
|
31
|
+
// readdirSync lookup failed for some reason
|
|
32
|
+
isInStudio = false;
|
|
33
|
+
}
|
|
34
|
+
if (packageRoot !== null) {
|
|
35
|
+
const rel = packageRoot ? relative(packageRoot, startDir) : '';
|
|
36
|
+
underFunctionsDir = rel.split(sep).includes('functions');
|
|
37
|
+
}
|
|
38
|
+
const isPackageRoot = packageRoot === startDir && !underFunctionsDir;
|
|
39
|
+
const isFloating = !isInStudio && !isPackageRoot && !underFunctionsDir;
|
|
40
|
+
return isInStudio
|
|
41
|
+
? 'studio'
|
|
42
|
+
: underFunctionsDir
|
|
43
|
+
? 'functions'
|
|
44
|
+
: isFloating
|
|
45
|
+
? 'floating'
|
|
46
|
+
: undefined;
|
|
47
|
+
};
|
package/oclif.manifest.json
CHANGED
|
@@ -643,8 +643,7 @@
|
|
|
643
643
|
"summary": "Destroy a remote Stack deployment and its resources",
|
|
644
644
|
"enableJsonFlag": true,
|
|
645
645
|
"needs": [
|
|
646
|
-
"
|
|
647
|
-
"blueprint"
|
|
646
|
+
"scope"
|
|
648
647
|
],
|
|
649
648
|
"isESM": true,
|
|
650
649
|
"relativePath": [
|
|
@@ -1648,8 +1647,7 @@
|
|
|
1648
1647
|
"summary": "List remote Stack deployments for your project or organization",
|
|
1649
1648
|
"enableJsonFlag": true,
|
|
1650
1649
|
"needs": [
|
|
1651
|
-
"
|
|
1652
|
-
"blueprint"
|
|
1650
|
+
"scope"
|
|
1653
1651
|
],
|
|
1654
1652
|
"isESM": true,
|
|
1655
1653
|
"relativePath": [
|
|
@@ -2998,5 +2996,5 @@
|
|
|
2998
2996
|
]
|
|
2999
2997
|
}
|
|
3000
2998
|
},
|
|
3001
|
-
"version": "
|
|
2999
|
+
"version": "16.0.1"
|
|
3002
3000
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sanity/runtime-cli",
|
|
3
3
|
"description": "Sanity's Runtime CLI for Blueprints and Functions",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "16.0.1",
|
|
5
5
|
"author": "Sanity Runtime Team",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"license": "MIT",
|
|
@@ -50,6 +50,7 @@
|
|
|
50
50
|
"test:depmgmt": "vitest run --config ./test-depmgmt/vitest.config.ts",
|
|
51
51
|
"test:coverage": "vitest run --coverage --coverage.include \"runtime-cli/src/**/*\"",
|
|
52
52
|
"test:scenarios": "vitest run test/scenarios",
|
|
53
|
+
"test:bp-version-smoke": "node ./test/blueprints-version-smoke.js",
|
|
53
54
|
"test:unit": "vitest run --exclude \"test/scenarios/**/*\"",
|
|
54
55
|
"test:vitest": "vitest run",
|
|
55
56
|
"typecheck": "tsc --project tsconfig.typecheck.json",
|
|
@@ -75,8 +76,7 @@
|
|
|
75
76
|
"mime-types": "^3.0.2",
|
|
76
77
|
"ora": "^9.4.0",
|
|
77
78
|
"tar-stream": "^3.2.0",
|
|
78
|
-
"vite": "^
|
|
79
|
-
"vite-tsconfig-paths": "^6.1.1",
|
|
79
|
+
"vite": "^8.0.16",
|
|
80
80
|
"ws": "^8.20.0",
|
|
81
81
|
"xdg-basedir": "^5.1.0"
|
|
82
82
|
},
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
export type Warning = {
|
|
2
|
-
label: string;
|
|
3
|
-
suggestions: string[];
|
|
4
|
-
};
|
|
5
|
-
export type WarningContext = {
|
|
6
|
-
dir: string;
|
|
7
|
-
};
|
|
8
|
-
export type WarningEntryCheck = {
|
|
9
|
-
label: string;
|
|
10
|
-
suggestions: string[];
|
|
11
|
-
check: (ctx: WarningContext) => boolean;
|
|
12
|
-
};
|
|
13
|
-
/**
|
|
14
|
-
* Checks if the given directory contains files Sanity Studio specific files.
|
|
15
|
-
* Directory is either the cwd where `init` is run or during the `doctor` command
|
|
16
|
-
*/
|
|
17
|
-
export declare const isStudioDir: (filePath: string) => boolean;
|
|
18
|
-
export declare const warningCheck: WarningEntryCheck[];
|
|
19
|
-
export declare const getWarnings: (ctx: WarningContext) => Warning[];
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { readdirSync } from 'node:fs';
|
|
2
|
-
import { resolve } from 'node:path';
|
|
3
|
-
/**
|
|
4
|
-
* Checks if the given directory contains files Sanity Studio specific files.
|
|
5
|
-
* Directory is either the cwd where `init` is run or during the `doctor` command
|
|
6
|
-
*/
|
|
7
|
-
export const isStudioDir = (filePath) => {
|
|
8
|
-
try {
|
|
9
|
-
const dir = resolve(filePath);
|
|
10
|
-
return readdirSync(dir, { withFileTypes: true }).some((entry) => {
|
|
11
|
-
if (entry.isFile()) {
|
|
12
|
-
return entry.name.startsWith('sanity.config') || entry.name.startsWith('sanity.cli');
|
|
13
|
-
}
|
|
14
|
-
return false;
|
|
15
|
-
});
|
|
16
|
-
}
|
|
17
|
-
catch (_err) {
|
|
18
|
-
return false;
|
|
19
|
-
}
|
|
20
|
-
};
|
|
21
|
-
export const warningCheck = [
|
|
22
|
-
{
|
|
23
|
-
label: 'Project layout',
|
|
24
|
-
suggestions: [
|
|
25
|
-
'A Blueprints file is co-located with a Sanity Studio. Please see the docs for better layout options',
|
|
26
|
-
// @todo: this will need to updated once the layout is published.
|
|
27
|
-
'https://www.sanity.io/docs/blueprints/blueprints-introduction#aaeea93bdd42',
|
|
28
|
-
],
|
|
29
|
-
check: ({ dir }) => isStudioDir(dir),
|
|
30
|
-
},
|
|
31
|
-
];
|
|
32
|
-
export const getWarnings = (ctx) => {
|
|
33
|
-
return warningCheck
|
|
34
|
-
.filter(({ check }) => check(ctx))
|
|
35
|
-
.map(({ label, suggestions }) => ({ label, suggestions }));
|
|
36
|
-
};
|