@sanity/runtime-cli 14.2.0 → 14.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -26
- package/dist/actions/blueprints/assets.js +9 -0
- package/dist/commands/blueprints/add.js +3 -10
- package/dist/commands/functions/add.js +2 -9
- package/dist/constants.d.ts +3 -0
- package/dist/constants.js +12 -0
- package/dist/cores/blueprints/config.js +1 -1
- package/dist/cores/blueprints/deploy.js +2 -2
- package/dist/cores/blueprints/destroy.js +1 -1
- package/dist/cores/blueprints/doctor.js +1 -1
- package/dist/cores/blueprints/init.js +1 -1
- package/dist/cores/blueprints/plan.js +6 -6
- package/dist/cores/functions/add.js +24 -20
- package/dist/utils/functions/getFolderSize.d.ts +5 -0
- package/dist/utils/functions/getFolderSize.js +24 -0
- package/dist/utils/functions/prepare-asset.js +6 -4
- package/dist/utils/transpile/transpile-function.d.ts +1 -0
- package/dist/utils/transpile/transpile-function.js +45 -6
- package/oclif.manifest.json +7 -5
- package/package.json +2 -3
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/14.
|
|
23
|
+
@sanity/runtime-cli/14.3.0 linux-x64 node-v24.14.0
|
|
24
24
|
$ sanity-run --help [COMMAND]
|
|
25
25
|
USAGE
|
|
26
26
|
$ sanity-run COMMAND
|
|
@@ -55,8 +55,8 @@ Add a function resource to a Blueprint
|
|
|
55
55
|
```
|
|
56
56
|
USAGE
|
|
57
57
|
$ sanity-run blueprints add TYPE [--example <value> | -n <value> | --fn-type
|
|
58
|
-
document-create|document-delete|document-update|
|
|
59
|
-
te|media-library-asset-delete... | --language ts|js | --javascript | --fn-helpers | --fn-installer
|
|
58
|
+
document-publish|document-create|document-delete|document-update|media-library-asset-create|media-library-asset-upda
|
|
59
|
+
te|media-library-asset-delete|schedule-function... | --language ts|js | --javascript | --fn-helpers | --fn-installer
|
|
60
60
|
skip|npm|pnpm|yarn] [-i | ]
|
|
61
61
|
|
|
62
62
|
ARGUMENTS
|
|
@@ -72,8 +72,8 @@ FLAGS
|
|
|
72
72
|
<options: skip|npm|pnpm|yarn>
|
|
73
73
|
--fn-type=<option>... Document change event(s) that should trigger the function; you can specify multiple
|
|
74
74
|
events by specifying this flag multiple times
|
|
75
|
-
<options: document-create|document-delete|document-update|
|
|
76
|
-
asset-create|media-library-asset-update|media-library-asset-delete>
|
|
75
|
+
<options: document-publish|document-create|document-delete|document-update|media-library-
|
|
76
|
+
asset-create|media-library-asset-update|media-library-asset-delete|schedule-function>
|
|
77
77
|
--javascript Use JavaScript instead of TypeScript
|
|
78
78
|
--language=<option> [default: ts] Language of the new function
|
|
79
79
|
<options: ts|js>
|
|
@@ -98,7 +98,7 @@ EXAMPLES
|
|
|
98
98
|
$ sanity-run blueprints add function --name my-function --fn-type document-create --fn-type document-update --lang js
|
|
99
99
|
```
|
|
100
100
|
|
|
101
|
-
_See code: [src/commands/blueprints/add.ts](https://github.com/sanity-io/runtime-cli/blob/v14.
|
|
101
|
+
_See code: [src/commands/blueprints/add.ts](https://github.com/sanity-io/runtime-cli/blob/v14.3.0/src/commands/blueprints/add.ts)_
|
|
102
102
|
|
|
103
103
|
## `sanity-run blueprints config`
|
|
104
104
|
|
|
@@ -133,7 +133,7 @@ EXAMPLES
|
|
|
133
133
|
$ sanity-run blueprints config --edit --project-id <projectId> --stack <name-or-id>
|
|
134
134
|
```
|
|
135
135
|
|
|
136
|
-
_See code: [src/commands/blueprints/config.ts](https://github.com/sanity-io/runtime-cli/blob/v14.
|
|
136
|
+
_See code: [src/commands/blueprints/config.ts](https://github.com/sanity-io/runtime-cli/blob/v14.3.0/src/commands/blueprints/config.ts)_
|
|
137
137
|
|
|
138
138
|
## `sanity-run blueprints deploy`
|
|
139
139
|
|
|
@@ -166,7 +166,7 @@ EXAMPLES
|
|
|
166
166
|
$ sanity-run blueprints deploy --no-wait
|
|
167
167
|
```
|
|
168
168
|
|
|
169
|
-
_See code: [src/commands/blueprints/deploy.ts](https://github.com/sanity-io/runtime-cli/blob/v14.
|
|
169
|
+
_See code: [src/commands/blueprints/deploy.ts](https://github.com/sanity-io/runtime-cli/blob/v14.3.0/src/commands/blueprints/deploy.ts)_
|
|
170
170
|
|
|
171
171
|
## `sanity-run blueprints destroy`
|
|
172
172
|
|
|
@@ -198,7 +198,7 @@ EXAMPLES
|
|
|
198
198
|
$ sanity-run blueprints destroy --stack <name-or-id> --project-id <projectId> --force --no-wait
|
|
199
199
|
```
|
|
200
200
|
|
|
201
|
-
_See code: [src/commands/blueprints/destroy.ts](https://github.com/sanity-io/runtime-cli/blob/v14.
|
|
201
|
+
_See code: [src/commands/blueprints/destroy.ts](https://github.com/sanity-io/runtime-cli/blob/v14.3.0/src/commands/blueprints/destroy.ts)_
|
|
202
202
|
|
|
203
203
|
## `sanity-run blueprints doctor`
|
|
204
204
|
|
|
@@ -224,7 +224,7 @@ DESCRIPTION
|
|
|
224
224
|
issues.
|
|
225
225
|
```
|
|
226
226
|
|
|
227
|
-
_See code: [src/commands/blueprints/doctor.ts](https://github.com/sanity-io/runtime-cli/blob/v14.
|
|
227
|
+
_See code: [src/commands/blueprints/doctor.ts](https://github.com/sanity-io/runtime-cli/blob/v14.3.0/src/commands/blueprints/doctor.ts)_
|
|
228
228
|
|
|
229
229
|
## `sanity-run blueprints info`
|
|
230
230
|
|
|
@@ -254,7 +254,7 @@ EXAMPLES
|
|
|
254
254
|
$ sanity-run blueprints info --stack <name-or-id>
|
|
255
255
|
```
|
|
256
256
|
|
|
257
|
-
_See code: [src/commands/blueprints/info.ts](https://github.com/sanity-io/runtime-cli/blob/v14.
|
|
257
|
+
_See code: [src/commands/blueprints/info.ts](https://github.com/sanity-io/runtime-cli/blob/v14.3.0/src/commands/blueprints/info.ts)_
|
|
258
258
|
|
|
259
259
|
## `sanity-run blueprints init [DIR]`
|
|
260
260
|
|
|
@@ -304,7 +304,7 @@ EXAMPLES
|
|
|
304
304
|
$ sanity-run blueprints init --blueprint-type <json|js|ts> --stack-name <stackName>
|
|
305
305
|
```
|
|
306
306
|
|
|
307
|
-
_See code: [src/commands/blueprints/init.ts](https://github.com/sanity-io/runtime-cli/blob/v14.
|
|
307
|
+
_See code: [src/commands/blueprints/init.ts](https://github.com/sanity-io/runtime-cli/blob/v14.3.0/src/commands/blueprints/init.ts)_
|
|
308
308
|
|
|
309
309
|
## `sanity-run blueprints logs`
|
|
310
310
|
|
|
@@ -333,7 +333,7 @@ EXAMPLES
|
|
|
333
333
|
$ sanity-run blueprints logs --watch
|
|
334
334
|
```
|
|
335
335
|
|
|
336
|
-
_See code: [src/commands/blueprints/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v14.
|
|
336
|
+
_See code: [src/commands/blueprints/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v14.3.0/src/commands/blueprints/logs.ts)_
|
|
337
337
|
|
|
338
338
|
## `sanity-run blueprints plan`
|
|
339
339
|
|
|
@@ -359,7 +359,7 @@ EXAMPLES
|
|
|
359
359
|
$ sanity-run blueprints plan
|
|
360
360
|
```
|
|
361
361
|
|
|
362
|
-
_See code: [src/commands/blueprints/plan.ts](https://github.com/sanity-io/runtime-cli/blob/v14.
|
|
362
|
+
_See code: [src/commands/blueprints/plan.ts](https://github.com/sanity-io/runtime-cli/blob/v14.3.0/src/commands/blueprints/plan.ts)_
|
|
363
363
|
|
|
364
364
|
## `sanity-run blueprints stacks`
|
|
365
365
|
|
|
@@ -388,7 +388,7 @@ EXAMPLES
|
|
|
388
388
|
$ sanity-run blueprints stacks --organization-id <organizationId>
|
|
389
389
|
```
|
|
390
390
|
|
|
391
|
-
_See code: [src/commands/blueprints/stacks.ts](https://github.com/sanity-io/runtime-cli/blob/v14.
|
|
391
|
+
_See code: [src/commands/blueprints/stacks.ts](https://github.com/sanity-io/runtime-cli/blob/v14.3.0/src/commands/blueprints/stacks.ts)_
|
|
392
392
|
|
|
393
393
|
## `sanity-run functions add`
|
|
394
394
|
|
|
@@ -397,8 +397,8 @@ Add a Function to your Blueprint
|
|
|
397
397
|
```
|
|
398
398
|
USAGE
|
|
399
399
|
$ sanity-run functions add [--example <value> | -n <value> | | --language ts|js | --javascript | | ] [--type
|
|
400
|
-
document-create|document-delete|document-update|
|
|
401
|
-
te|media-library-asset-delete... ] [--helpers] [--installer skip|npm|pnpm|yarn] [-i | ]
|
|
400
|
+
document-publish|document-create|document-delete|document-update|media-library-asset-create|media-library-asset-upda
|
|
401
|
+
te|media-library-asset-delete|schedule-function... ] [--helpers] [--installer skip|npm|pnpm|yarn] [-i | ]
|
|
402
402
|
|
|
403
403
|
FLAGS
|
|
404
404
|
-i, --install Shortcut for --fn-installer npm
|
|
@@ -412,8 +412,8 @@ FLAGS
|
|
|
412
412
|
<options: ts|js>
|
|
413
413
|
--type=<option>... Document change event(s) that should trigger the function; you can specify multiple events
|
|
414
414
|
by specifying this flag multiple times
|
|
415
|
-
<options: document-create|document-delete|document-update|
|
|
416
|
-
et-create|media-library-asset-update|media-library-asset-delete>
|
|
415
|
+
<options: document-publish|document-create|document-delete|document-update|media-library-ass
|
|
416
|
+
et-create|media-library-asset-update|media-library-asset-delete|schedule-function>
|
|
417
417
|
|
|
418
418
|
DESCRIPTION
|
|
419
419
|
Add a Function to your Blueprint
|
|
@@ -437,7 +437,7 @@ EXAMPLES
|
|
|
437
437
|
$ sanity-run functions add --name my-function --type document-create --type document-update --lang js
|
|
438
438
|
```
|
|
439
439
|
|
|
440
|
-
_See code: [src/commands/functions/add.ts](https://github.com/sanity-io/runtime-cli/blob/v14.
|
|
440
|
+
_See code: [src/commands/functions/add.ts](https://github.com/sanity-io/runtime-cli/blob/v14.3.0/src/commands/functions/add.ts)_
|
|
441
441
|
|
|
442
442
|
## `sanity-run functions dev`
|
|
443
443
|
|
|
@@ -471,7 +471,7 @@ EXAMPLES
|
|
|
471
471
|
$ sanity-run functions dev --timeout 60
|
|
472
472
|
```
|
|
473
473
|
|
|
474
|
-
_See code: [src/commands/functions/dev.ts](https://github.com/sanity-io/runtime-cli/blob/v14.
|
|
474
|
+
_See code: [src/commands/functions/dev.ts](https://github.com/sanity-io/runtime-cli/blob/v14.3.0/src/commands/functions/dev.ts)_
|
|
475
475
|
|
|
476
476
|
## `sanity-run functions env add NAME KEY VALUE`
|
|
477
477
|
|
|
@@ -498,7 +498,7 @@ EXAMPLES
|
|
|
498
498
|
$ sanity-run functions env add MyFunction API_URL https://api.example.com/
|
|
499
499
|
```
|
|
500
500
|
|
|
501
|
-
_See code: [src/commands/functions/env/add.ts](https://github.com/sanity-io/runtime-cli/blob/v14.
|
|
501
|
+
_See code: [src/commands/functions/env/add.ts](https://github.com/sanity-io/runtime-cli/blob/v14.3.0/src/commands/functions/env/add.ts)_
|
|
502
502
|
|
|
503
503
|
## `sanity-run functions env list NAME`
|
|
504
504
|
|
|
@@ -522,7 +522,7 @@ EXAMPLES
|
|
|
522
522
|
$ sanity-run functions env list MyFunction
|
|
523
523
|
```
|
|
524
524
|
|
|
525
|
-
_See code: [src/commands/functions/env/list.ts](https://github.com/sanity-io/runtime-cli/blob/v14.
|
|
525
|
+
_See code: [src/commands/functions/env/list.ts](https://github.com/sanity-io/runtime-cli/blob/v14.3.0/src/commands/functions/env/list.ts)_
|
|
526
526
|
|
|
527
527
|
## `sanity-run functions env remove NAME KEY`
|
|
528
528
|
|
|
@@ -548,7 +548,7 @@ EXAMPLES
|
|
|
548
548
|
$ sanity-run functions env remove MyFunction API_URL
|
|
549
549
|
```
|
|
550
550
|
|
|
551
|
-
_See code: [src/commands/functions/env/remove.ts](https://github.com/sanity-io/runtime-cli/blob/v14.
|
|
551
|
+
_See code: [src/commands/functions/env/remove.ts](https://github.com/sanity-io/runtime-cli/blob/v14.3.0/src/commands/functions/env/remove.ts)_
|
|
552
552
|
|
|
553
553
|
## `sanity-run functions logs [NAME]`
|
|
554
554
|
|
|
@@ -588,7 +588,7 @@ EXAMPLES
|
|
|
588
588
|
$ sanity-run functions logs <name> --delete
|
|
589
589
|
```
|
|
590
590
|
|
|
591
|
-
_See code: [src/commands/functions/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v14.
|
|
591
|
+
_See code: [src/commands/functions/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v14.3.0/src/commands/functions/logs.ts)_
|
|
592
592
|
|
|
593
593
|
## `sanity-run functions test [NAME]`
|
|
594
594
|
|
|
@@ -642,7 +642,7 @@ EXAMPLES
|
|
|
642
642
|
$ sanity-run functions test <name> --event update --data-before '{ "title": "before" }' --data-after '{ "title": "after" }'
|
|
643
643
|
```
|
|
644
644
|
|
|
645
|
-
_See code: [src/commands/functions/test.ts](https://github.com/sanity-io/runtime-cli/blob/v14.
|
|
645
|
+
_See code: [src/commands/functions/test.ts](https://github.com/sanity-io/runtime-cli/blob/v14.3.0/src/commands/functions/test.ts)_
|
|
646
646
|
|
|
647
647
|
## `sanity-run help [COMMAND]`
|
|
648
648
|
|
|
@@ -4,6 +4,7 @@ import os from 'node:os';
|
|
|
4
4
|
import path from 'node:path';
|
|
5
5
|
import AdmZip from 'adm-zip';
|
|
6
6
|
import config from '../../config.js';
|
|
7
|
+
import { CONVERT_BYTES_TO_MB, MAX_ASSET_SIZE } from '../../constants.js';
|
|
7
8
|
import { detectNativeModules } from '../../utils/functions/detect-native-modules.js';
|
|
8
9
|
import { prepareAsset } from '../../utils/functions/prepare-asset.js';
|
|
9
10
|
import getHeaders from '../../utils/get-headers.js';
|
|
@@ -183,6 +184,14 @@ export async function pathToZip(path) {
|
|
|
183
184
|
}
|
|
184
185
|
export async function pathToB64ZipHash(path) {
|
|
185
186
|
const zip = await pathToZip(path);
|
|
187
|
+
// Add up the uncompressed sizes of all entries to get a more accurate size of the asset being uploaded
|
|
188
|
+
const size = zip
|
|
189
|
+
.getEntries()
|
|
190
|
+
.map((entry) => entry.header.size)
|
|
191
|
+
.reduce((a, b) => a + b, 0);
|
|
192
|
+
if (size > MAX_ASSET_SIZE) {
|
|
193
|
+
throw new Error(`Asset size of ${(size / CONVERT_BYTES_TO_MB).toFixed(2)} MB exceeds the maximum allowed size of 200 MB.`);
|
|
194
|
+
}
|
|
186
195
|
const hasNativeModules = detectNativeModules(zip);
|
|
187
196
|
if (hasNativeModules?.length > 0) {
|
|
188
197
|
const errorMsg = `Native modules detected in Function:\n${hasNativeModules.join('\n')}\n\n` +
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { Args, Flags } from '@oclif/core';
|
|
7
7
|
import { LocalBlueprintCommand } from '../../baseCommands.js';
|
|
8
|
+
import { FUNCTION_TYPES } from '../../constants.js';
|
|
8
9
|
import { functionAddCore } from '../../cores/functions/index.js';
|
|
9
10
|
import { Logger } from '../../utils/logger.js';
|
|
10
11
|
// import {warn} from '../../utils/display/presenters.js'
|
|
@@ -43,15 +44,7 @@ After adding a function, use 'functions dev' to test locally, then 'blueprints d
|
|
|
43
44
|
}),
|
|
44
45
|
'fn-type': Flags.string({
|
|
45
46
|
description: 'Document change event(s) that should trigger the function; you can specify multiple events by specifying this flag multiple times',
|
|
46
|
-
options:
|
|
47
|
-
'document-create',
|
|
48
|
-
'document-delete',
|
|
49
|
-
'document-update',
|
|
50
|
-
'document-publish',
|
|
51
|
-
'media-library-asset-create',
|
|
52
|
-
'media-library-asset-update',
|
|
53
|
-
'media-library-asset-delete',
|
|
54
|
-
],
|
|
47
|
+
options: FUNCTION_TYPES,
|
|
55
48
|
aliases: ['function-type'],
|
|
56
49
|
multiple: true,
|
|
57
50
|
multipleNonGreedy: true,
|
|
@@ -91,7 +84,7 @@ After adding a function, use 'functions dev' to test locally, then 'blueprints d
|
|
|
91
84
|
}
|
|
92
85
|
// log(
|
|
93
86
|
// warn(
|
|
94
|
-
//
|
|
87
|
+
// `\`npx ${bin} blueprints add function\` is deprecated. Use \`npx ${bin} functions add\` instead.`,
|
|
95
88
|
// ),
|
|
96
89
|
// )
|
|
97
90
|
const { success, error } = await functionAddCore({
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Flags } from '@oclif/core';
|
|
2
2
|
import { LocalBlueprintCommand } from '../../baseCommands.js';
|
|
3
|
+
import { FUNCTION_TYPES } from '../../constants.js';
|
|
3
4
|
import { functionAddCore } from '../../cores/functions/index.js';
|
|
4
5
|
import { Logger } from '../../utils/logger.js';
|
|
5
6
|
export default class AddCommand extends LocalBlueprintCommand {
|
|
@@ -28,15 +29,7 @@ After adding, use 'functions dev' to test locally, then 'blueprints deploy' to p
|
|
|
28
29
|
}),
|
|
29
30
|
type: Flags.string({
|
|
30
31
|
description: 'Document change event(s) that should trigger the function; you can specify multiple events by specifying this flag multiple times',
|
|
31
|
-
options:
|
|
32
|
-
'document-create',
|
|
33
|
-
'document-delete',
|
|
34
|
-
'document-update',
|
|
35
|
-
'document-publish',
|
|
36
|
-
'media-library-asset-create',
|
|
37
|
-
'media-library-asset-update',
|
|
38
|
-
'media-library-asset-delete',
|
|
39
|
-
],
|
|
32
|
+
options: FUNCTION_TYPES,
|
|
40
33
|
multiple: true,
|
|
41
34
|
multipleNonGreedy: true,
|
|
42
35
|
dependsOn: ['name'],
|
package/dist/constants.d.ts
CHANGED
|
@@ -6,3 +6,6 @@ export declare const SANITY_FUNCTION_SCHEDULE = "sanity.function.cron";
|
|
|
6
6
|
export declare const SANITY_PROJECT_CORS = "sanity.project.cors";
|
|
7
7
|
export declare const SANITY_PROJECT_DATASET = "sanity.project.dataset";
|
|
8
8
|
export declare const SANITY_PROJECT_WEBHOOK = "sanity.project.webhook";
|
|
9
|
+
export declare const FUNCTION_TYPES: string[];
|
|
10
|
+
export declare const MAX_ASSET_SIZE = 209715200;
|
|
11
|
+
export declare const CONVERT_BYTES_TO_MB = 1048576;
|
package/dist/constants.js
CHANGED
|
@@ -6,3 +6,15 @@ export const SANITY_FUNCTION_SCHEDULE = 'sanity.function.cron';
|
|
|
6
6
|
export const SANITY_PROJECT_CORS = 'sanity.project.cors';
|
|
7
7
|
export const SANITY_PROJECT_DATASET = 'sanity.project.dataset';
|
|
8
8
|
export const SANITY_PROJECT_WEBHOOK = 'sanity.project.webhook';
|
|
9
|
+
export const FUNCTION_TYPES = [
|
|
10
|
+
'document-publish',
|
|
11
|
+
'document-create',
|
|
12
|
+
'document-delete',
|
|
13
|
+
'document-update',
|
|
14
|
+
'media-library-asset-create',
|
|
15
|
+
'media-library-asset-update',
|
|
16
|
+
'media-library-asset-delete',
|
|
17
|
+
'schedule-function',
|
|
18
|
+
];
|
|
19
|
+
export const MAX_ASSET_SIZE = 209_715_200; // 200 MB in bytes
|
|
20
|
+
export const CONVERT_BYTES_TO_MB = 1_048_576; // Used to convert bytes to megabytes (1024 * 1024)
|
|
@@ -13,7 +13,7 @@ export async function blueprintConfigCore(options) {
|
|
|
13
13
|
log(warn('Incomplete configuration.'));
|
|
14
14
|
if (!editConfig) {
|
|
15
15
|
// blueprint.json exists but no config JSON
|
|
16
|
-
log(`Run
|
|
16
|
+
log(`Run \`npx ${bin} blueprints doctor\` for diagnostics.`);
|
|
17
17
|
return { success: true }; // not necessarily fatal
|
|
18
18
|
}
|
|
19
19
|
}
|
|
@@ -123,7 +123,7 @@ export async function blueprintDeployCore(options) {
|
|
|
123
123
|
spinner.stop().clear();
|
|
124
124
|
if (noWait) {
|
|
125
125
|
log(styleText(['bold', 'green'], 'Stack deployment started!'));
|
|
126
|
-
log(`Use
|
|
126
|
+
log(`Use \`npx ${bin} blueprints info\` to check status`);
|
|
127
127
|
return { success: true, data: { resources } };
|
|
128
128
|
}
|
|
129
129
|
log(styleText('dim', 'Stack deployment progress:'));
|
|
@@ -167,7 +167,7 @@ export async function blueprintDeployCore(options) {
|
|
|
167
167
|
}
|
|
168
168
|
if (!idleMessageShown && Date.now() - lastLogAt > 60_000) {
|
|
169
169
|
log(`No new activity for 60 seconds. The deployment is still running on Sanity servers.`);
|
|
170
|
-
log(`You can safely exit and check status later with
|
|
170
|
+
log(`You can safely exit and check status later with \`npx ${bin} blueprints info\`.`);
|
|
171
171
|
idleMessageShown = true;
|
|
172
172
|
}
|
|
173
173
|
await sleep(1500);
|
|
@@ -126,7 +126,7 @@ export async function blueprintDestroyCore(options) {
|
|
|
126
126
|
}
|
|
127
127
|
if (!idleMessageShown && Date.now() - lastLogAt > 60_000) {
|
|
128
128
|
log(`No new activity for 60 seconds. The destruction is still running on Sanity servers.`);
|
|
129
|
-
log(`You can safely exit and check status later with
|
|
129
|
+
log(`You can safely exit and check status later with \`npx ${bin} blueprints info\`.`);
|
|
130
130
|
idleMessageShown = true;
|
|
131
131
|
}
|
|
132
132
|
await sleep(1500);
|
|
@@ -301,6 +301,6 @@ export async function blueprintDoctorCore(options) {
|
|
|
301
301
|
flags: { edit: true, verbose: v },
|
|
302
302
|
});
|
|
303
303
|
}
|
|
304
|
-
log(styleText('dim', ` Run
|
|
304
|
+
log(styleText('dim', ` Run \`npx ${bin} blueprints doctor --fix\` to resolve configuration issues.`));
|
|
305
305
|
return { success: false, error: errorMessage, data: { diagnostics: flatDiagnostics } };
|
|
306
306
|
}
|
|
@@ -354,7 +354,7 @@ export async function createBlueprintFiles(params) {
|
|
|
354
354
|
nextStepParts.push(`cd ${userProvidedDirName}`);
|
|
355
355
|
if (blueprintExtension !== 'json')
|
|
356
356
|
nextStepParts.push('npm install');
|
|
357
|
-
nextStepParts.push(
|
|
357
|
+
nextStepParts.push(`npx ${bin} blueprints --help`);
|
|
358
358
|
log(`\n Run "${styleText(['bold', 'magenta'], nextStepParts.join(' && '))}" to get started`);
|
|
359
359
|
return { success: true };
|
|
360
360
|
}
|
|
@@ -10,8 +10,8 @@ export async function blueprintPlanCore(options) {
|
|
|
10
10
|
if (!token || !scopeType || !scopeId) {
|
|
11
11
|
log(styleText('dim', 'Unable to retrieve live Stack deployment for comparison'));
|
|
12
12
|
const errorMessage = !token
|
|
13
|
-
? `Missing authentication token. Run
|
|
14
|
-
: `Missing Blueprint configuration. Run
|
|
13
|
+
? `Missing authentication token. Run \`npx ${bin} login\` to authenticate.`
|
|
14
|
+
: `Missing Blueprint configuration. Run \`npx ${bin} blueprints doctor --fix\` to repair.`;
|
|
15
15
|
return {
|
|
16
16
|
success: false,
|
|
17
17
|
error: errorMessage,
|
|
@@ -24,7 +24,7 @@ export async function blueprintPlanCore(options) {
|
|
|
24
24
|
log(styleText('dim', 'Unable to retrieve live Stack deployment for comparison'));
|
|
25
25
|
return {
|
|
26
26
|
success: false,
|
|
27
|
-
error: `Missing Stack deployment configuration. Run
|
|
27
|
+
error: `Missing Stack deployment configuration. Run \`npx ${bin} blueprints doctor --fix\` to repair.`,
|
|
28
28
|
};
|
|
29
29
|
}
|
|
30
30
|
const auth = { token, scopeType, scopeId };
|
|
@@ -48,7 +48,7 @@ export async function blueprintPlanCore(options) {
|
|
|
48
48
|
log(` ${styleText(['bold', 'red'], '✘')} ${msg}`);
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
|
-
log(`\n Fix the issues above before running "${styleText(['bold', 'magenta'],
|
|
51
|
+
log(`\n Fix the issues above before running "${styleText(['bold', 'magenta'], `npx ${bin} blueprints deploy`)}"`);
|
|
52
52
|
}
|
|
53
53
|
else {
|
|
54
54
|
log(styleText('dim', '\nUnable to retrieve deployment plan from server'));
|
|
@@ -58,10 +58,10 @@ export async function blueprintPlanCore(options) {
|
|
|
58
58
|
log('');
|
|
59
59
|
log(formatDeploymentPlan(planResponse.deploymentPlan));
|
|
60
60
|
if (hasActionableChanges(planResponse.deploymentPlan)) {
|
|
61
|
-
log(`\n Run "${styleText(['bold', 'magenta'],
|
|
61
|
+
log(`\n Run "${styleText(['bold', 'magenta'], `npx ${bin} blueprints deploy`)}" to apply these Stack changes`);
|
|
62
62
|
}
|
|
63
63
|
else {
|
|
64
|
-
log(`\n ${styleText('dim', `No significant changes to deploy. Run
|
|
64
|
+
log(`\n ${styleText('dim', `No significant changes to deploy. Run \`npx ${bin} blueprints deploy\` to apply.`)}`);
|
|
65
65
|
}
|
|
66
66
|
return { success: true };
|
|
67
67
|
}
|
|
@@ -5,21 +5,30 @@ import { checkbox, confirm, input, select } from '@inquirer/prompts';
|
|
|
5
5
|
import { highlight } from 'cardinal';
|
|
6
6
|
import { createFunctionResource } from '../../actions/blueprints/resources.js';
|
|
7
7
|
import { verifyExampleExists, writeExample } from '../../actions/sanity/examples.js';
|
|
8
|
-
import { SANITY_FUNCTION_MEDIA_LIBRARY_ASSET, SANITY_FUNCTION_SCHEDULE } from '../../constants.js';
|
|
8
|
+
import { FUNCTION_TYPES, SANITY_FUNCTION_MEDIA_LIBRARY_ASSET, SANITY_FUNCTION_SCHEDULE, } from '../../constants.js';
|
|
9
9
|
import { check, indent, warn } from '../../utils/display/presenters.js';
|
|
10
10
|
import { styleText } from '../../utils/style-text.js';
|
|
11
11
|
import { validateFunctionName } from '../../utils/validate/resource.js';
|
|
12
12
|
const generateFunctionBlueprintResourceTemplate = (fnName, eventNames) => {
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
: 'MediaLibraryAsset';
|
|
16
|
-
const isML = definer.startsWith('Media');
|
|
13
|
+
const functionType = eventNames[0].substring(0, eventNames[0].lastIndexOf('-'));
|
|
14
|
+
let definer = '';
|
|
17
15
|
const eventOns = eventNames.map((e) => `'${e.substring(e.lastIndexOf('-') + 1)}'`);
|
|
16
|
+
switch (functionType) {
|
|
17
|
+
case 'document':
|
|
18
|
+
definer = `defineDocumentFunction({name: '${fnName}', event: {on: [${eventOns.join(', ')}]}}), // ← add this line`;
|
|
19
|
+
break;
|
|
20
|
+
case 'media':
|
|
21
|
+
definer = `defineMediaLibraryAssetFunction({name: '${fnName}', event: {on: [${eventOns.join(', ')}], resource: {type: 'media-library', id: 'my-media-library-id'}}}), // ← add this line`;
|
|
22
|
+
break;
|
|
23
|
+
case 'schedule':
|
|
24
|
+
definer = `defineScheduleFunction({name: '${fnName}', event: {expression: '0 0 * * *'}}), // ← add this line`;
|
|
25
|
+
break;
|
|
26
|
+
}
|
|
18
27
|
return `
|
|
19
28
|
export default defineBlueprint({
|
|
20
29
|
resources: [
|
|
21
30
|
// ...
|
|
22
|
-
|
|
31
|
+
${definer}
|
|
23
32
|
],
|
|
24
33
|
})
|
|
25
34
|
`;
|
|
@@ -138,20 +147,12 @@ export async function functionAddCore(options) {
|
|
|
138
147
|
if (fnTypes.length === 0) {
|
|
139
148
|
throw new Error('At least one function type must be provided.');
|
|
140
149
|
}
|
|
141
|
-
if (!fnTypes.every((evt) =>
|
|
142
|
-
'
|
|
143
|
-
'document-create',
|
|
144
|
-
'document-delete',
|
|
145
|
-
'document-update',
|
|
146
|
-
'media-library-asset-create',
|
|
147
|
-
'media-library-asset-update',
|
|
148
|
-
'media-library-asset-delete',
|
|
149
|
-
].includes(evt))) {
|
|
150
|
-
throw new Error('Invalid function type. Must be one of: document-publish, document-create, document-delete, document-update, media-library-asset-create, media-library-asset-update, media-library-asset-delete');
|
|
150
|
+
if (!fnTypes.every((evt) => FUNCTION_TYPES.includes(evt))) {
|
|
151
|
+
throw new Error(`Invalid function type. Must be one of: ${FUNCTION_TYPES.join(', ').trim()}`);
|
|
151
152
|
}
|
|
152
153
|
const eventSources = new Set(fnTypes.map((t) => t.substring(0, t.lastIndexOf('-'))));
|
|
153
154
|
if (eventSources.size > 1) {
|
|
154
|
-
throw new Error('Invalid function type. Cannot mix document
|
|
155
|
+
throw new Error('Invalid function type. Cannot mix document-*, media-library-asset-*, and/or scheduled-* types.');
|
|
155
156
|
}
|
|
156
157
|
let addHelpers;
|
|
157
158
|
let installCommand;
|
|
@@ -235,14 +236,17 @@ async function promptForFunctionType() {
|
|
|
235
236
|
{ name: 'Media Library Asset Create', value: 'media-library-asset-create' },
|
|
236
237
|
{ name: 'Media Library Asset Update', value: 'media-library-asset-update' },
|
|
237
238
|
{ name: 'Media Library Asset Delete', value: 'media-library-asset-delete' },
|
|
239
|
+
{ name: 'Schedule', value: 'schedule-function' },
|
|
238
240
|
],
|
|
239
241
|
validate(choices) {
|
|
240
242
|
if (choices.length === 0) {
|
|
241
243
|
return 'You must choose at least one function type / document change event';
|
|
242
244
|
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
245
|
+
const hasMedia = choices.some((c) => String(c.value).startsWith('media-library'));
|
|
246
|
+
const hasDocument = choices.some((c) => String(c.value).startsWith('document'));
|
|
247
|
+
const hasSchedule = choices.some((c) => String(c.value).startsWith('schedule'));
|
|
248
|
+
if ((hasMedia && hasDocument) || (hasMedia && hasSchedule) || (hasDocument && hasSchedule)) {
|
|
249
|
+
return 'You cannot mix Document, Media Library Asset, and Schedule events together in one Function';
|
|
246
250
|
}
|
|
247
251
|
return true;
|
|
248
252
|
},
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { readdirSync, statSync } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
/**
|
|
4
|
+
* Recursively calculates the total size of a folder, including all nested files and subdirectories.
|
|
5
|
+
*/
|
|
6
|
+
export const getFolderSize = (folder) => {
|
|
7
|
+
if (!statSync(folder).isDirectory()) {
|
|
8
|
+
throw new Error('Provided path is not a directory');
|
|
9
|
+
}
|
|
10
|
+
let totalSize = 0;
|
|
11
|
+
const fileEntries = readdirSync(folder);
|
|
12
|
+
for (const file of fileEntries) {
|
|
13
|
+
const filePath = path.join(folder.toString(), file);
|
|
14
|
+
const stats = statSync(filePath);
|
|
15
|
+
if (stats.isFile()) {
|
|
16
|
+
totalSize += stats.size;
|
|
17
|
+
}
|
|
18
|
+
else if (stats.isDirectory()) {
|
|
19
|
+
const recursiveSize = getFolderSize(filePath);
|
|
20
|
+
totalSize += recursiveSize;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return totalSize;
|
|
24
|
+
};
|
|
@@ -1,33 +1,35 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import { cwd } from 'node:process';
|
|
3
|
-
import
|
|
3
|
+
import { MAX_ASSET_SIZE } from '../../constants.js';
|
|
4
4
|
import { transpileFunction } from '../transpile/transpile-function.js';
|
|
5
|
+
import { getFolderSize } from './getFolderSize.js';
|
|
5
6
|
import { resolveResourceDependencies } from './resolve-dependencies.js';
|
|
6
7
|
import { shouldAutoResolveDependencies } from './should-auto-resolve-deps.js';
|
|
7
8
|
import { shouldTranspileFunction } from './should-transpile.js';
|
|
8
|
-
const MAX_ASSET_SIZE = 209_715_200; // 200 MB in bytes
|
|
9
9
|
export async function prepareAsset({ resource, }) {
|
|
10
10
|
if (!resource.src)
|
|
11
11
|
throw new Error('Resource src is required');
|
|
12
12
|
let functionPath = path.join(cwd(), resource.src);
|
|
13
13
|
let cleanup = async () => { };
|
|
14
|
+
let wasBundled = false;
|
|
14
15
|
const shouldTranspile = await shouldTranspileFunction(resource);
|
|
15
16
|
if (shouldTranspile) {
|
|
16
17
|
try {
|
|
17
18
|
const result = await transpileFunction(resource);
|
|
18
19
|
functionPath = result.outputDir;
|
|
19
20
|
cleanup = result.cleanup;
|
|
21
|
+
wasBundled = result.bundled;
|
|
20
22
|
}
|
|
21
23
|
catch (err) {
|
|
22
24
|
return { success: false, error: err instanceof Error ? err.message : `${err}` };
|
|
23
25
|
}
|
|
24
26
|
}
|
|
25
27
|
const shouldResolveDependencies = await shouldAutoResolveDependencies(resource);
|
|
26
|
-
if (shouldResolveDependencies) {
|
|
28
|
+
if (shouldResolveDependencies && !wasBundled) {
|
|
27
29
|
await resolveResourceDependencies(resource, shouldTranspile);
|
|
28
30
|
}
|
|
29
31
|
try {
|
|
30
|
-
const size =
|
|
32
|
+
const size = getFolderSize(functionPath);
|
|
31
33
|
if (size > MAX_ASSET_SIZE) {
|
|
32
34
|
throw new Error('Resource is larger than max asset size of 200 MB.');
|
|
33
35
|
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
1
2
|
import { mkdir, readFile, rm, stat, writeFile } from 'node:fs/promises';
|
|
3
|
+
import { createRequire } from 'node:module';
|
|
2
4
|
import path from 'node:path';
|
|
3
5
|
import { performance } from 'node:perf_hooks';
|
|
4
6
|
import { cwd } from 'node:process';
|
|
@@ -33,6 +35,7 @@ export async function transpileFunction(resource) {
|
|
|
33
35
|
}
|
|
34
36
|
try {
|
|
35
37
|
const viteStart = performance.now();
|
|
38
|
+
const bundle = existsSync(path.join(cwd(), 'pnpm-workspace.yaml'));
|
|
36
39
|
const result = await viteBuild({
|
|
37
40
|
root: fnRootDir,
|
|
38
41
|
logLevel: 'silent',
|
|
@@ -48,20 +51,23 @@ export async function transpileFunction(resource) {
|
|
|
48
51
|
output: {
|
|
49
52
|
format: 'esm',
|
|
50
53
|
entryFileNames: getOutputFilename(entry),
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
+
...(bundle
|
|
55
|
+
? {}
|
|
56
|
+
: {
|
|
57
|
+
preserveModules: true,
|
|
58
|
+
preserveModulesRoot: fnRootDir,
|
|
59
|
+
}),
|
|
54
60
|
},
|
|
55
|
-
external: [/node_modules/],
|
|
61
|
+
external: bundle ? [] : [/node_modules/],
|
|
56
62
|
},
|
|
57
63
|
},
|
|
58
64
|
ssr: {
|
|
59
|
-
noExternal:
|
|
65
|
+
noExternal: bundle ? true : [],
|
|
60
66
|
resolve: {
|
|
61
67
|
conditions: ['node'],
|
|
62
68
|
},
|
|
63
69
|
},
|
|
64
|
-
plugins: [tsConfigPaths()],
|
|
70
|
+
plugins: [tsConfigPaths(), ...(bundle ? [pnpmResolvePlugin(cwd())] : [])],
|
|
65
71
|
});
|
|
66
72
|
timings['transpile:build'] = performance.now() - viteStart;
|
|
67
73
|
const verifyStart = performance.now();
|
|
@@ -80,6 +86,7 @@ export async function transpileFunction(resource) {
|
|
|
80
86
|
warnings: [],
|
|
81
87
|
cleanup: cleanupTmpDir,
|
|
82
88
|
timings,
|
|
89
|
+
bundled: bundle,
|
|
83
90
|
};
|
|
84
91
|
}
|
|
85
92
|
catch (err) {
|
|
@@ -127,3 +134,35 @@ function getOutputFilename(entryFileName) {
|
|
|
127
134
|
function logCleanupFailure(err) {
|
|
128
135
|
console.warn(`[warn] Failed to clean up temporary files: ${err instanceof Error ? err.message : err}`);
|
|
129
136
|
}
|
|
137
|
+
/**
|
|
138
|
+
* Vite plugin to resolve packages from pnpm's virtual store.
|
|
139
|
+
* In pnpm workspaces, hoisted dependencies live in node_modules/.pnpm/node_modules/
|
|
140
|
+
* which isn't reachable via standard Node resolution.
|
|
141
|
+
*/
|
|
142
|
+
function pnpmResolvePlugin(workspaceRoot) {
|
|
143
|
+
const pnpmModulesPath = path.join(workspaceRoot, 'node_modules', '.pnpm', 'node_modules');
|
|
144
|
+
// createRequire gives us Node's full module resolution algorithm rooted at
|
|
145
|
+
// the pnpm virtual store — it reads package.json exports/main and returns
|
|
146
|
+
// the absolute path to the actual entry file, not just the directory.
|
|
147
|
+
const pnpmRequire = createRequire(path.join(pnpmModulesPath, '_virtual.js'));
|
|
148
|
+
return {
|
|
149
|
+
name: 'pnpm-resolve',
|
|
150
|
+
async resolveId(source, importer, options) {
|
|
151
|
+
// Only act as fallback — let Vite try first
|
|
152
|
+
const resolved = await this.resolve(source, importer, {
|
|
153
|
+
...options,
|
|
154
|
+
skipSelf: true,
|
|
155
|
+
});
|
|
156
|
+
if (resolved)
|
|
157
|
+
return resolved;
|
|
158
|
+
// Fallback: use Node's require.resolve() from the pnpm virtual store.
|
|
159
|
+
// This properly follows package.json exports/main to the entry file.
|
|
160
|
+
try {
|
|
161
|
+
return pnpmRequire.resolve(source);
|
|
162
|
+
}
|
|
163
|
+
catch {
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
};
|
|
168
|
+
}
|
package/oclif.manifest.json
CHANGED
|
@@ -100,13 +100,14 @@
|
|
|
100
100
|
"hasDynamicHelp": false,
|
|
101
101
|
"multiple": true,
|
|
102
102
|
"options": [
|
|
103
|
+
"document-publish",
|
|
103
104
|
"document-create",
|
|
104
105
|
"document-delete",
|
|
105
106
|
"document-update",
|
|
106
|
-
"document-publish",
|
|
107
107
|
"media-library-asset-create",
|
|
108
108
|
"media-library-asset-update",
|
|
109
|
-
"media-library-asset-delete"
|
|
109
|
+
"media-library-asset-delete",
|
|
110
|
+
"schedule-function"
|
|
110
111
|
],
|
|
111
112
|
"type": "option"
|
|
112
113
|
},
|
|
@@ -1199,13 +1200,14 @@
|
|
|
1199
1200
|
"hasDynamicHelp": false,
|
|
1200
1201
|
"multiple": true,
|
|
1201
1202
|
"options": [
|
|
1203
|
+
"document-publish",
|
|
1202
1204
|
"document-create",
|
|
1203
1205
|
"document-delete",
|
|
1204
1206
|
"document-update",
|
|
1205
|
-
"document-publish",
|
|
1206
1207
|
"media-library-asset-create",
|
|
1207
1208
|
"media-library-asset-update",
|
|
1208
|
-
"media-library-asset-delete"
|
|
1209
|
+
"media-library-asset-delete",
|
|
1210
|
+
"schedule-function"
|
|
1209
1211
|
],
|
|
1210
1212
|
"type": "option"
|
|
1211
1213
|
},
|
|
@@ -2161,5 +2163,5 @@
|
|
|
2161
2163
|
]
|
|
2162
2164
|
}
|
|
2163
2165
|
},
|
|
2164
|
-
"version": "14.
|
|
2166
|
+
"version": "14.3.0"
|
|
2165
2167
|
}
|
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": "14.
|
|
4
|
+
"version": "14.3.0",
|
|
5
5
|
"author": "Sanity Runtime Team",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"license": "MIT",
|
|
@@ -97,7 +97,7 @@
|
|
|
97
97
|
"watch": "tsc --watch"
|
|
98
98
|
},
|
|
99
99
|
"dependencies": {
|
|
100
|
-
"@architect/hydrate": "^5.0.
|
|
100
|
+
"@architect/hydrate": "^5.0.2",
|
|
101
101
|
"@architect/inventory": "^5.0.0",
|
|
102
102
|
"@inquirer/prompts": "^8.2.1",
|
|
103
103
|
"@oclif/core": "^4.8.0",
|
|
@@ -110,7 +110,6 @@
|
|
|
110
110
|
"cardinal": "^2.1.1",
|
|
111
111
|
"empathic": "^2.0.0",
|
|
112
112
|
"eventsource": "^4.1.0",
|
|
113
|
-
"get-folder-size": "^5.0.0",
|
|
114
113
|
"groq-js": "^1.27.1",
|
|
115
114
|
"jiti": "^2.6.1",
|
|
116
115
|
"mime-types": "^3.0.2",
|