@sanity/runtime-cli 12.1.0 → 12.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 +20 -19
- package/dist/actions/blueprints/assets.d.ts +3 -4
- package/dist/actions/blueprints/assets.js +118 -2
- package/dist/actions/blueprints/blueprint.d.ts +3 -2
- package/dist/actions/blueprints/stacks.d.ts +8 -4
- package/dist/actions/blueprints/stacks.js +6 -32
- package/dist/commands/blueprints/doctor.d.ts +1 -0
- package/dist/commands/blueprints/doctor.js +4 -0
- package/dist/commands/functions/dev.d.ts +2 -2
- package/dist/commands/functions/dev.js +3 -2
- package/dist/constants.d.ts +7 -0
- package/dist/constants.js +7 -0
- package/dist/cores/blueprints/deploy.js +29 -12
- package/dist/cores/blueprints/doctor.d.ts +1 -0
- package/dist/cores/blueprints/doctor.js +36 -5
- package/dist/cores/blueprints/info.js +2 -2
- package/dist/cores/functions/env/add.js +2 -2
- package/dist/cores/functions/env/list.js +2 -2
- package/dist/cores/functions/env/remove.js +2 -2
- package/dist/cores/functions/logs.js +2 -2
- package/dist/cores/functions/test.js +31 -23
- package/dist/server/app.js +32 -21
- package/dist/server/handlers/invoke.d.ts +2 -2
- package/dist/server/handlers/invoke.js +2 -2
- package/dist/server/static/components/api-base.js +3 -0
- package/dist/server/static/components/app.css +120 -95
- package/dist/server/static/components/clear-button.js +1 -1
- package/dist/server/static/components/console-panel.js +6 -6
- package/dist/server/static/components/fetch-button.js +1 -1
- package/dist/server/static/components/filter-api-version.js +3 -3
- package/dist/server/static/components/filter-document-id.js +5 -5
- package/dist/server/static/components/filter-with-token.js +4 -4
- package/dist/server/static/components/filters.js +2 -2
- package/dist/server/static/components/function-list.js +14 -5
- package/dist/server/static/components/help-button.js +4 -1
- package/dist/server/static/components/payload-panel.js +9 -9
- package/dist/server/static/components/response-panel.js +8 -8
- package/dist/server/static/components/rule-panel.js +4 -4
- package/dist/server/static/components/run-panel.js +4 -4
- package/dist/server/static/components/select-dropdown.js +5 -25
- package/dist/server/static/index.html +9 -9
- package/dist/server/static/vendor/m-.css +1 -0
- package/dist/server/static/vendor/m-.woff2 +0 -0
- package/dist/utils/display/blueprints-formatting.d.ts +3 -2
- package/dist/utils/display/blueprints-formatting.js +102 -50
- package/dist/utils/display/resources-formatting.d.ts +6 -2
- package/dist/utils/display/resources-formatting.js +71 -17
- package/dist/utils/find-function.d.ts +2 -2
- package/dist/utils/find-function.js +9 -2
- package/dist/utils/invoke-local.d.ts +2 -2
- package/dist/utils/invoke-local.js +27 -16
- package/dist/utils/types.d.ts +66 -24
- package/dist/utils/types.js +25 -2
- package/dist/utils/validate/resource.js +144 -23
- package/oclif.manifest.json +14 -1
- package/package.json +2 -2
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/12.
|
|
23
|
+
@sanity/runtime-cli/12.3.0 linux-x64 node-v24.11.1
|
|
24
24
|
$ sanity-run --help [COMMAND]
|
|
25
25
|
USAGE
|
|
26
26
|
$ sanity-run COMMAND
|
|
@@ -92,7 +92,7 @@ EXAMPLES
|
|
|
92
92
|
$ sanity-run blueprints add function --name my-function --fn-type document-create --fn-type document-update --lang js
|
|
93
93
|
```
|
|
94
94
|
|
|
95
|
-
_See code: [src/commands/blueprints/add.ts](https://github.com/sanity-io/runtime-cli/blob/v12.
|
|
95
|
+
_See code: [src/commands/blueprints/add.ts](https://github.com/sanity-io/runtime-cli/blob/v12.3.0/src/commands/blueprints/add.ts)_
|
|
96
96
|
|
|
97
97
|
## `sanity-run blueprints config`
|
|
98
98
|
|
|
@@ -121,7 +121,7 @@ EXAMPLES
|
|
|
121
121
|
$ sanity-run blueprints config --edit --project-id <projectId> --stack-id <stackId>
|
|
122
122
|
```
|
|
123
123
|
|
|
124
|
-
_See code: [src/commands/blueprints/config.ts](https://github.com/sanity-io/runtime-cli/blob/v12.
|
|
124
|
+
_See code: [src/commands/blueprints/config.ts](https://github.com/sanity-io/runtime-cli/blob/v12.3.0/src/commands/blueprints/config.ts)_
|
|
125
125
|
|
|
126
126
|
## `sanity-run blueprints deploy`
|
|
127
127
|
|
|
@@ -143,7 +143,7 @@ EXAMPLES
|
|
|
143
143
|
$ sanity-run blueprints deploy --no-wait
|
|
144
144
|
```
|
|
145
145
|
|
|
146
|
-
_See code: [src/commands/blueprints/deploy.ts](https://github.com/sanity-io/runtime-cli/blob/v12.
|
|
146
|
+
_See code: [src/commands/blueprints/deploy.ts](https://github.com/sanity-io/runtime-cli/blob/v12.3.0/src/commands/blueprints/deploy.ts)_
|
|
147
147
|
|
|
148
148
|
## `sanity-run blueprints destroy`
|
|
149
149
|
|
|
@@ -170,7 +170,7 @@ EXAMPLES
|
|
|
170
170
|
$ sanity-run blueprints destroy --stack-id <stackId> --project-id <projectId> --force --no-wait
|
|
171
171
|
```
|
|
172
172
|
|
|
173
|
-
_See code: [src/commands/blueprints/destroy.ts](https://github.com/sanity-io/runtime-cli/blob/v12.
|
|
173
|
+
_See code: [src/commands/blueprints/destroy.ts](https://github.com/sanity-io/runtime-cli/blob/v12.3.0/src/commands/blueprints/destroy.ts)_
|
|
174
174
|
|
|
175
175
|
## `sanity-run blueprints doctor`
|
|
176
176
|
|
|
@@ -178,9 +178,10 @@ Diagnose potential issues with Blueprint configuration
|
|
|
178
178
|
|
|
179
179
|
```
|
|
180
180
|
USAGE
|
|
181
|
-
$ sanity-run blueprints doctor [--verbose] [--path <value>]
|
|
181
|
+
$ sanity-run blueprints doctor [--verbose] [--path <value>] [--fix]
|
|
182
182
|
|
|
183
183
|
FLAGS
|
|
184
|
+
--fix Interactively fix configuration issues
|
|
184
185
|
--path=<value> Path to the Blueprint configuration file
|
|
185
186
|
--verbose Provide detailed information about issues
|
|
186
187
|
|
|
@@ -188,7 +189,7 @@ DESCRIPTION
|
|
|
188
189
|
Diagnose potential issues with Blueprint configuration
|
|
189
190
|
```
|
|
190
191
|
|
|
191
|
-
_See code: [src/commands/blueprints/doctor.ts](https://github.com/sanity-io/runtime-cli/blob/v12.
|
|
192
|
+
_See code: [src/commands/blueprints/doctor.ts](https://github.com/sanity-io/runtime-cli/blob/v12.3.0/src/commands/blueprints/doctor.ts)_
|
|
192
193
|
|
|
193
194
|
## `sanity-run blueprints info`
|
|
194
195
|
|
|
@@ -210,7 +211,7 @@ EXAMPLES
|
|
|
210
211
|
$ sanity-run blueprints info --id <stackId>
|
|
211
212
|
```
|
|
212
213
|
|
|
213
|
-
_See code: [src/commands/blueprints/info.ts](https://github.com/sanity-io/runtime-cli/blob/v12.
|
|
214
|
+
_See code: [src/commands/blueprints/info.ts](https://github.com/sanity-io/runtime-cli/blob/v12.3.0/src/commands/blueprints/info.ts)_
|
|
214
215
|
|
|
215
216
|
## `sanity-run blueprints init [DIR]`
|
|
216
217
|
|
|
@@ -250,7 +251,7 @@ EXAMPLES
|
|
|
250
251
|
$ sanity-run blueprints init --blueprint-type <json|js|ts> --stack-name <stackName>
|
|
251
252
|
```
|
|
252
253
|
|
|
253
|
-
_See code: [src/commands/blueprints/init.ts](https://github.com/sanity-io/runtime-cli/blob/v12.
|
|
254
|
+
_See code: [src/commands/blueprints/init.ts](https://github.com/sanity-io/runtime-cli/blob/v12.3.0/src/commands/blueprints/init.ts)_
|
|
254
255
|
|
|
255
256
|
## `sanity-run blueprints logs`
|
|
256
257
|
|
|
@@ -272,7 +273,7 @@ EXAMPLES
|
|
|
272
273
|
$ sanity-run blueprints logs --watch
|
|
273
274
|
```
|
|
274
275
|
|
|
275
|
-
_See code: [src/commands/blueprints/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v12.
|
|
276
|
+
_See code: [src/commands/blueprints/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v12.3.0/src/commands/blueprints/logs.ts)_
|
|
276
277
|
|
|
277
278
|
## `sanity-run blueprints plan`
|
|
278
279
|
|
|
@@ -289,7 +290,7 @@ EXAMPLES
|
|
|
289
290
|
$ sanity-run blueprints plan
|
|
290
291
|
```
|
|
291
292
|
|
|
292
|
-
_See code: [src/commands/blueprints/plan.ts](https://github.com/sanity-io/runtime-cli/blob/v12.
|
|
293
|
+
_See code: [src/commands/blueprints/plan.ts](https://github.com/sanity-io/runtime-cli/blob/v12.3.0/src/commands/blueprints/plan.ts)_
|
|
293
294
|
|
|
294
295
|
## `sanity-run blueprints stacks`
|
|
295
296
|
|
|
@@ -314,7 +315,7 @@ EXAMPLES
|
|
|
314
315
|
$ sanity-run blueprints stacks --organization-id <organizationId>
|
|
315
316
|
```
|
|
316
317
|
|
|
317
|
-
_See code: [src/commands/blueprints/stacks.ts](https://github.com/sanity-io/runtime-cli/blob/v12.
|
|
318
|
+
_See code: [src/commands/blueprints/stacks.ts](https://github.com/sanity-io/runtime-cli/blob/v12.3.0/src/commands/blueprints/stacks.ts)_
|
|
318
319
|
|
|
319
320
|
## `sanity-run functions add`
|
|
320
321
|
|
|
@@ -356,7 +357,7 @@ EXAMPLES
|
|
|
356
357
|
$ sanity-run functions add --name my-function --type document-create --type document-update --lang js
|
|
357
358
|
```
|
|
358
359
|
|
|
359
|
-
_See code: [src/commands/functions/add.ts](https://github.com/sanity-io/runtime-cli/blob/v12.
|
|
360
|
+
_See code: [src/commands/functions/add.ts](https://github.com/sanity-io/runtime-cli/blob/v12.3.0/src/commands/functions/add.ts)_
|
|
360
361
|
|
|
361
362
|
## `sanity-run functions dev`
|
|
362
363
|
|
|
@@ -379,7 +380,7 @@ EXAMPLES
|
|
|
379
380
|
$ sanity-run functions dev --host 127.0.0.1 --port 8974
|
|
380
381
|
```
|
|
381
382
|
|
|
382
|
-
_See code: [src/commands/functions/dev.ts](https://github.com/sanity-io/runtime-cli/blob/v12.
|
|
383
|
+
_See code: [src/commands/functions/dev.ts](https://github.com/sanity-io/runtime-cli/blob/v12.3.0/src/commands/functions/dev.ts)_
|
|
383
384
|
|
|
384
385
|
## `sanity-run functions env add NAME KEY VALUE`
|
|
385
386
|
|
|
@@ -401,7 +402,7 @@ EXAMPLES
|
|
|
401
402
|
$ sanity-run functions env add MyFunction API_URL https://api.example.com/
|
|
402
403
|
```
|
|
403
404
|
|
|
404
|
-
_See code: [src/commands/functions/env/add.ts](https://github.com/sanity-io/runtime-cli/blob/v12.
|
|
405
|
+
_See code: [src/commands/functions/env/add.ts](https://github.com/sanity-io/runtime-cli/blob/v12.3.0/src/commands/functions/env/add.ts)_
|
|
405
406
|
|
|
406
407
|
## `sanity-run functions env list NAME`
|
|
407
408
|
|
|
@@ -421,7 +422,7 @@ EXAMPLES
|
|
|
421
422
|
$ sanity-run functions env list MyFunction
|
|
422
423
|
```
|
|
423
424
|
|
|
424
|
-
_See code: [src/commands/functions/env/list.ts](https://github.com/sanity-io/runtime-cli/blob/v12.
|
|
425
|
+
_See code: [src/commands/functions/env/list.ts](https://github.com/sanity-io/runtime-cli/blob/v12.3.0/src/commands/functions/env/list.ts)_
|
|
425
426
|
|
|
426
427
|
## `sanity-run functions env remove NAME KEY`
|
|
427
428
|
|
|
@@ -442,7 +443,7 @@ EXAMPLES
|
|
|
442
443
|
$ sanity-run functions env remove MyFunction API_URL
|
|
443
444
|
```
|
|
444
445
|
|
|
445
|
-
_See code: [src/commands/functions/env/remove.ts](https://github.com/sanity-io/runtime-cli/blob/v12.
|
|
446
|
+
_See code: [src/commands/functions/env/remove.ts](https://github.com/sanity-io/runtime-cli/blob/v12.3.0/src/commands/functions/env/remove.ts)_
|
|
446
447
|
|
|
447
448
|
## `sanity-run functions logs NAME`
|
|
448
449
|
|
|
@@ -476,7 +477,7 @@ EXAMPLES
|
|
|
476
477
|
$ sanity-run functions logs <name> --delete
|
|
477
478
|
```
|
|
478
479
|
|
|
479
|
-
_See code: [src/commands/functions/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v12.
|
|
480
|
+
_See code: [src/commands/functions/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v12.3.0/src/commands/functions/logs.ts)_
|
|
480
481
|
|
|
481
482
|
## `sanity-run functions test NAME`
|
|
482
483
|
|
|
@@ -525,7 +526,7 @@ EXAMPLES
|
|
|
525
526
|
$ sanity-run functions test <name> --event update --data-before '{ "title": "before" }' --data-after '{ "title": "after" }'
|
|
526
527
|
```
|
|
527
528
|
|
|
528
|
-
_See code: [src/commands/functions/test.ts](https://github.com/sanity-io/runtime-cli/blob/v12.
|
|
529
|
+
_See code: [src/commands/functions/test.ts](https://github.com/sanity-io/runtime-cli/blob/v12.3.0/src/commands/functions/test.ts)_
|
|
529
530
|
|
|
530
531
|
## `sanity-run help [COMMAND]`
|
|
531
532
|
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import AdmZip from 'adm-zip';
|
|
2
|
-
import type { AuthParams, FunctionResource } from '../../utils/types.js';
|
|
2
|
+
import type { AuthParams, CollectionFunction, FunctionResource } from '../../utils/types.js';
|
|
3
3
|
export declare const ASSET_CHECK_URL: string;
|
|
4
4
|
export declare const ASSET_STASH_URL: string;
|
|
5
5
|
export declare function stashAsset({ resource, auth, }: {
|
|
6
|
-
resource: FunctionResource;
|
|
6
|
+
resource: FunctionResource | CollectionFunction;
|
|
7
7
|
auth: AuthParams;
|
|
8
8
|
}): Promise<{
|
|
9
9
|
success: boolean;
|
|
10
|
+
assetId?: string;
|
|
10
11
|
exists?: boolean;
|
|
11
12
|
hash?: string;
|
|
12
|
-
assetId?: string;
|
|
13
|
-
outputPath?: string;
|
|
14
13
|
error?: string;
|
|
15
14
|
}>;
|
|
16
15
|
export declare function hashBuffer(buffer: Buffer): string;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import crypto from 'node:crypto';
|
|
2
2
|
import fs from 'node:fs';
|
|
3
|
+
import os from 'node:os';
|
|
3
4
|
import path from 'node:path';
|
|
4
5
|
import { cwd } from 'node:process';
|
|
5
6
|
import AdmZip from 'adm-zip';
|
|
@@ -10,12 +11,68 @@ import { shouldAutoResolveDependencies } from '../../utils/functions/should-auto
|
|
|
10
11
|
import { shouldTranspileFunction } from '../../utils/functions/should-transpile.js';
|
|
11
12
|
import getHeaders from '../../utils/get-headers.js';
|
|
12
13
|
import { transpileFunction } from '../../utils/transpile/transpile-function.js';
|
|
14
|
+
import { isLocalFunctionCollection } from '../../utils/types.js';
|
|
13
15
|
const { apiUrl } = config;
|
|
14
16
|
const ASSETS_URL = `${apiUrl}vX/blueprints/assets`;
|
|
15
17
|
export const ASSET_CHECK_URL = `${ASSETS_URL}/check`;
|
|
16
18
|
export const ASSET_STASH_URL = `${ASSETS_URL}/stash`;
|
|
17
19
|
const MAX_ASSET_SIZE = 209_715_200; // 200 MB in bytes
|
|
18
20
|
export async function stashAsset({ resource, auth, }) {
|
|
21
|
+
const isCollection = isLocalFunctionCollection(resource);
|
|
22
|
+
const functions = isCollection ? resource.functions : [resource];
|
|
23
|
+
const combinedAsset = [];
|
|
24
|
+
try {
|
|
25
|
+
for (const func of functions) {
|
|
26
|
+
const prepResult = await prepareAsset({ resource: func, auth });
|
|
27
|
+
if (prepResult.success && prepResult.outputPath && prepResult.cleanup) {
|
|
28
|
+
combinedAsset.push({
|
|
29
|
+
name: func.name,
|
|
30
|
+
partAsset: { outputPath: prepResult.outputPath, cleanup: prepResult.cleanup },
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (combinedAsset.length !== functions.length) {
|
|
35
|
+
const processedNames = new Set(combinedAsset.map((asset) => asset.name));
|
|
36
|
+
const failedFunctions = functions.filter((func) => !processedNames.has(func.name));
|
|
37
|
+
return {
|
|
38
|
+
success: false,
|
|
39
|
+
error: `Failed to prepare ${failedFunctions.length} function(s) in collection: ${failedFunctions.map((f) => f.name).join(', ')}`,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
let result = { success: false };
|
|
43
|
+
if (isCollection) {
|
|
44
|
+
const combinedResult = await combineAssets(combinedAsset);
|
|
45
|
+
if (combinedResult.combinedPath && combinedResult.cleanup) {
|
|
46
|
+
result = await stashSingleAsset({
|
|
47
|
+
outputPath: combinedResult.combinedPath,
|
|
48
|
+
cleanup: combinedResult.cleanup,
|
|
49
|
+
resource: resource,
|
|
50
|
+
auth,
|
|
51
|
+
collectionInfo: {
|
|
52
|
+
name: resource.name,
|
|
53
|
+
functionCount: resource.functions.length,
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
else if (combinedResult.error) {
|
|
58
|
+
result = { success: false, error: combinedResult.error };
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
result = await stashSingleAsset({
|
|
63
|
+
outputPath: combinedAsset[0].partAsset.outputPath,
|
|
64
|
+
cleanup: combinedAsset[0].partAsset.cleanup,
|
|
65
|
+
resource: resource,
|
|
66
|
+
auth,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
return result;
|
|
70
|
+
}
|
|
71
|
+
catch (err) {
|
|
72
|
+
return { success: false, error: err instanceof Error ? err.message : `${err}` };
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
async function prepareAsset({ resource, }) {
|
|
19
76
|
if (!resource.src)
|
|
20
77
|
throw new Error('Resource src is required');
|
|
21
78
|
let functionPath = path.join(cwd(), resource.src);
|
|
@@ -41,7 +98,60 @@ export async function stashAsset({ resource, auth, }) {
|
|
|
41
98
|
if (size > MAX_ASSET_SIZE) {
|
|
42
99
|
throw new Error('Resource is larger than max asset size of 200 MB.');
|
|
43
100
|
}
|
|
44
|
-
|
|
101
|
+
return { success: true, outputPath: functionPath, cleanup };
|
|
102
|
+
}
|
|
103
|
+
catch (err) {
|
|
104
|
+
return { success: false, error: err instanceof Error ? err.message : `${err}` };
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
async function combineAssets(allAssets) {
|
|
108
|
+
const combinedPath = path.join(os.tmpdir(), `assets-${Date.now()}`);
|
|
109
|
+
await fs.promises.mkdir(combinedPath, { recursive: true });
|
|
110
|
+
try {
|
|
111
|
+
for (const asset of allAssets) {
|
|
112
|
+
try {
|
|
113
|
+
await fs.promises.mkdir(path.join(combinedPath, asset.name), { recursive: true });
|
|
114
|
+
await fs.promises.cp(asset.partAsset.outputPath, path.join(combinedPath, asset.name), {
|
|
115
|
+
recursive: true,
|
|
116
|
+
});
|
|
117
|
+
await asset.partAsset.cleanup();
|
|
118
|
+
}
|
|
119
|
+
catch (err) {
|
|
120
|
+
// Clean up any partial work
|
|
121
|
+
try {
|
|
122
|
+
await fs.promises.rm(combinedPath, { recursive: true, force: true });
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
// Ignore cleanup errors
|
|
126
|
+
}
|
|
127
|
+
// Clean up remaining individual assets
|
|
128
|
+
await Promise.allSettled(allAssets.map((a) => a.partAsset.cleanup()));
|
|
129
|
+
return {
|
|
130
|
+
error: `Failed to combine asset for function '${asset.name}': ${err instanceof Error ? err.message : String(err)}`,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
const cleanupCombined = async () => {
|
|
135
|
+
await fs.promises.rm(combinedPath, { recursive: true, force: true });
|
|
136
|
+
};
|
|
137
|
+
return { combinedPath, cleanup: cleanupCombined };
|
|
138
|
+
}
|
|
139
|
+
catch (err) {
|
|
140
|
+
// Clean up any partial work
|
|
141
|
+
try {
|
|
142
|
+
await fs.promises.rm(combinedPath, { recursive: true, force: true });
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
// Ignore cleanup errors
|
|
146
|
+
}
|
|
147
|
+
// Clean up individual assets that were successfully prepared
|
|
148
|
+
await Promise.allSettled(allAssets.map((asset) => asset.partAsset.cleanup()));
|
|
149
|
+
return { error: err instanceof Error ? err.message : `${err}` };
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
async function stashSingleAsset({ outputPath, cleanup, resource, auth, collectionInfo, }) {
|
|
153
|
+
try {
|
|
154
|
+
const { b64, hash } = await pathToB64ZipHash(outputPath);
|
|
45
155
|
try {
|
|
46
156
|
const checkResponse = await fetch(`${ASSET_CHECK_URL}/${hash}`, {
|
|
47
157
|
method: 'GET',
|
|
@@ -66,7 +176,13 @@ export async function stashAsset({ resource, auth, }) {
|
|
|
66
176
|
if (assetResponse.ok) {
|
|
67
177
|
return { success: true, assetId: assetJson.id, exists: false, hash };
|
|
68
178
|
}
|
|
69
|
-
|
|
179
|
+
const contextMsg = collectionInfo
|
|
180
|
+
? ` (part of collection '${collectionInfo.name}' with ${collectionInfo.functionCount} functions)`
|
|
181
|
+
: '';
|
|
182
|
+
return {
|
|
183
|
+
success: false,
|
|
184
|
+
error: `Failed to stash asset for ${resource.name}${contextMsg}: ${assetJson.message || 'Unknown error'}`,
|
|
185
|
+
};
|
|
70
186
|
}
|
|
71
187
|
catch (err) {
|
|
72
188
|
let error = '';
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import type { BlueprintResource } from '@sanity/blueprints';
|
|
1
2
|
import { type Blueprint } from '@sanity/blueprints-parser';
|
|
2
|
-
import type { BlueprintParserError
|
|
3
|
+
import type { BlueprintParserError } from '../../utils/types.js';
|
|
3
4
|
import { type ScopeType } from '../../utils/types.js';
|
|
4
5
|
import { type LocatedBlueprintsConfig } from './config.js';
|
|
5
6
|
declare const SUPPORTED_FILE_EXTENSIONS: readonly [".json", ".js", ".mjs", ".ts"];
|
|
@@ -51,7 +52,7 @@ export declare function writeBlueprintToDisk({ blueprintFilePath, jsonContent, }
|
|
|
51
52
|
blueprintFilePath: string;
|
|
52
53
|
jsonContent?: Blueprint;
|
|
53
54
|
}): string;
|
|
54
|
-
export declare function addResourceToBlueprint<T extends
|
|
55
|
+
export declare function addResourceToBlueprint<T extends BlueprintResource>({ blueprintFilePath, resource, }: {
|
|
55
56
|
blueprintFilePath?: string;
|
|
56
57
|
resource: T;
|
|
57
58
|
}): T | undefined;
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import type { AuthParams, ScopeType, Stack, StackMutation } from '../../utils/types.js';
|
|
2
2
|
export declare const stacksUrl: string;
|
|
3
|
-
|
|
4
|
-
ok:
|
|
5
|
-
error:
|
|
3
|
+
type ListStacksResponse = {
|
|
4
|
+
ok: true;
|
|
5
|
+
error: null;
|
|
6
6
|
stacks: Stack[];
|
|
7
|
-
}
|
|
7
|
+
} | {
|
|
8
|
+
ok: false;
|
|
9
|
+
error: string;
|
|
10
|
+
stacks: unknown;
|
|
11
|
+
};
|
|
8
12
|
export declare function listStacks(auth: AuthParams): Promise<ListStacksResponse>;
|
|
9
13
|
interface GetStackResponse {
|
|
10
14
|
ok: boolean;
|
|
@@ -2,32 +2,6 @@ import config from '../../config.js';
|
|
|
2
2
|
import getHeaders from '../../utils/get-headers.js';
|
|
3
3
|
const { apiUrl } = config;
|
|
4
4
|
export const stacksUrl = `${apiUrl}vX/blueprints/stacks`;
|
|
5
|
-
/** Discriminate between Resource and Resource with parameters */
|
|
6
|
-
function hasParameters(obj) {
|
|
7
|
-
return (typeof obj === 'object' &&
|
|
8
|
-
obj !== null &&
|
|
9
|
-
'parameters' in obj &&
|
|
10
|
-
typeof obj.parameters === 'object' &&
|
|
11
|
-
obj.parameters !== null);
|
|
12
|
-
}
|
|
13
|
-
/** Flatten Resource with parameters */
|
|
14
|
-
function flattenResource(resource) {
|
|
15
|
-
if (hasParameters(resource)) {
|
|
16
|
-
const { parameters, ...rest } = resource;
|
|
17
|
-
return { ...rest, ...parameters };
|
|
18
|
-
}
|
|
19
|
-
return resource;
|
|
20
|
-
}
|
|
21
|
-
/** Flatten a Stack's resources */
|
|
22
|
-
function flattenStackResources(stack) {
|
|
23
|
-
if (stack && Array.isArray(stack.resources)) {
|
|
24
|
-
return {
|
|
25
|
-
...stack,
|
|
26
|
-
resources: stack.resources.map(flattenResource),
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
return stack;
|
|
30
|
-
}
|
|
31
5
|
export async function listStacks(auth) {
|
|
32
6
|
const response = await fetch(stacksUrl, {
|
|
33
7
|
method: 'GET',
|
|
@@ -37,7 +11,7 @@ export async function listStacks(auth) {
|
|
|
37
11
|
return {
|
|
38
12
|
ok: response.ok,
|
|
39
13
|
error: response.ok ? null : data.message,
|
|
40
|
-
stacks:
|
|
14
|
+
stacks: data,
|
|
41
15
|
};
|
|
42
16
|
}
|
|
43
17
|
export async function getStack({ stackId, auth, }) {
|
|
@@ -49,7 +23,7 @@ export async function getStack({ stackId, auth, }) {
|
|
|
49
23
|
return {
|
|
50
24
|
ok: response.ok,
|
|
51
25
|
error: response.ok ? null : data.message,
|
|
52
|
-
stack:
|
|
26
|
+
stack: data,
|
|
53
27
|
response,
|
|
54
28
|
};
|
|
55
29
|
}
|
|
@@ -63,7 +37,7 @@ export async function createStack({ stackMutation, auth, }) {
|
|
|
63
37
|
return {
|
|
64
38
|
ok: response.ok,
|
|
65
39
|
error: response.ok ? null : data.message,
|
|
66
|
-
stack:
|
|
40
|
+
stack: data,
|
|
67
41
|
};
|
|
68
42
|
}
|
|
69
43
|
export async function createEmptyStack({ token, scopeType, scopeId, name, }) {
|
|
@@ -80,7 +54,7 @@ export async function createEmptyStack({ token, scopeType, scopeId, name, }) {
|
|
|
80
54
|
if (!response.ok) {
|
|
81
55
|
throw new Error(response.error || 'Failed to create new Stack');
|
|
82
56
|
}
|
|
83
|
-
return
|
|
57
|
+
return response.stack;
|
|
84
58
|
}
|
|
85
59
|
export async function updateStack({ stackId, stackMutation, auth, }) {
|
|
86
60
|
const response = await fetch(`${stacksUrl}/${stackId}`, {
|
|
@@ -92,7 +66,7 @@ export async function updateStack({ stackId, stackMutation, auth, }) {
|
|
|
92
66
|
return {
|
|
93
67
|
ok: response.ok,
|
|
94
68
|
error: response.ok ? null : data.message,
|
|
95
|
-
stack:
|
|
69
|
+
stack: data,
|
|
96
70
|
};
|
|
97
71
|
}
|
|
98
72
|
export async function destroyStack({ stackId, auth, }) {
|
|
@@ -104,6 +78,6 @@ export async function destroyStack({ stackId, auth, }) {
|
|
|
104
78
|
return {
|
|
105
79
|
ok: response.ok,
|
|
106
80
|
error: response.ok ? null : data.message,
|
|
107
|
-
stack:
|
|
81
|
+
stack: data,
|
|
108
82
|
};
|
|
109
83
|
}
|
|
@@ -5,6 +5,7 @@ export default class DoctorCommand extends Command {
|
|
|
5
5
|
static flags: {
|
|
6
6
|
verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
7
7
|
path: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
|
+
fix: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
8
9
|
};
|
|
9
10
|
run(): Promise<void>;
|
|
10
11
|
}
|
|
@@ -12,6 +12,10 @@ export default class DoctorCommand extends Command {
|
|
|
12
12
|
path: Flags.string({
|
|
13
13
|
description: 'Path to the Blueprint configuration file',
|
|
14
14
|
}),
|
|
15
|
+
fix: Flags.boolean({
|
|
16
|
+
description: 'Interactively fix configuration issues',
|
|
17
|
+
default: false,
|
|
18
|
+
}),
|
|
15
19
|
};
|
|
16
20
|
async run() {
|
|
17
21
|
const { flags } = await this.parse(DoctorCommand);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export default class DevCommand extends
|
|
1
|
+
import { BlueprintCommand } from '../../baseCommands.js';
|
|
2
|
+
export default class DevCommand extends BlueprintCommand<typeof DevCommand> {
|
|
3
3
|
static description: string;
|
|
4
4
|
static examples: string[];
|
|
5
5
|
static flags: {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Flags } from '@oclif/core';
|
|
2
|
+
import { BlueprintCommand } from '../../baseCommands.js';
|
|
2
3
|
import { functionDevCore } from '../../cores/functions/dev.js';
|
|
3
|
-
export default class DevCommand extends
|
|
4
|
+
export default class DevCommand extends BlueprintCommand {
|
|
4
5
|
static description = 'Start the Sanity Function emulator';
|
|
5
6
|
static examples = ['<%= config.bin %> <%= command.id %> --host 127.0.0.1 --port 8974'];
|
|
6
7
|
static flags = {
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare const SANITY_ACCESS_ROLE = "sanity.access.role";
|
|
2
|
+
export declare const SANITY_FUNCTION_DOCUMENT = "sanity.function.document";
|
|
3
|
+
export declare const SANITY_FUNCTION_MEDIA_LIBRARY_ASSET = "sanity.function.media-library.asset";
|
|
4
|
+
export declare const SANITY_FUNCTION_SCHEDULE = "sanity.function.cron";
|
|
5
|
+
export declare const SANITY_PROJECT_CORS = "sanity.project.cors";
|
|
6
|
+
export declare const SANITY_PROJECT_DATASET = "sanity.project.dataset";
|
|
7
|
+
export declare const SANITY_PROJECT_WEBHOOK = "sanity.project.webhook";
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export const SANITY_ACCESS_ROLE = 'sanity.access.role';
|
|
2
|
+
export const SANITY_FUNCTION_DOCUMENT = 'sanity.function.document';
|
|
3
|
+
export const SANITY_FUNCTION_MEDIA_LIBRARY_ASSET = 'sanity.function.media-library.asset';
|
|
4
|
+
export const SANITY_FUNCTION_SCHEDULE = 'sanity.function.cron';
|
|
5
|
+
export const SANITY_PROJECT_CORS = 'sanity.project.cors';
|
|
6
|
+
export const SANITY_PROJECT_DATASET = 'sanity.project.dataset';
|
|
7
|
+
export const SANITY_PROJECT_WEBHOOK = 'sanity.project.webhook';
|
|
@@ -14,23 +14,37 @@ export async function blueprintDeployCore(options) {
|
|
|
14
14
|
try {
|
|
15
15
|
const { resources } = blueprint.parsedBlueprint;
|
|
16
16
|
const validResources = resources?.filter((r) => r.type) || [];
|
|
17
|
-
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
const allFunctionResources = experimentalFunctionCollections.flatMap((r) => r.functions);
|
|
21
|
-
functionResources = [...functionResources, ...allFunctionResources];
|
|
22
|
-
}
|
|
17
|
+
const functionResources = validResources.filter(isLocalFunctionResource);
|
|
18
|
+
const functionCollections = validResources.filter(isLocalFunctionCollection);
|
|
19
|
+
const allFunctionResources = [...functionResources, ...functionCollections];
|
|
23
20
|
// First stash all function assets
|
|
24
|
-
if (
|
|
21
|
+
if (allFunctionResources.length > 0) {
|
|
25
22
|
log('Processing function assets...');
|
|
26
|
-
for (const resource of
|
|
23
|
+
for (const resource of allFunctionResources) {
|
|
27
24
|
const fnSpinner = ora({ text: `Processing ${resource.name}...`, prefixText: ' ' }).start();
|
|
28
25
|
const result = await stashAsset({ resource, auth });
|
|
29
26
|
if (result.success && result.assetId) {
|
|
30
|
-
const src = resource.src;
|
|
31
27
|
resource.src = result.assetId;
|
|
32
|
-
|
|
33
|
-
|
|
28
|
+
if (isLocalFunctionCollection(resource)) {
|
|
29
|
+
try {
|
|
30
|
+
for (const func of resource.functions) {
|
|
31
|
+
func.src = func.name;
|
|
32
|
+
}
|
|
33
|
+
fnSpinner.succeed(`${resource.name} collection ${niceId(result.assetId)} (${resource.functions.length} functions)`);
|
|
34
|
+
log(` Functions: ${resource.functions.map((f) => f.name).join(', ')}`);
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
fnSpinner.fail(`Failed to update function collection ${resource.name}`);
|
|
38
|
+
return {
|
|
39
|
+
success: false,
|
|
40
|
+
error: `Error updating function collection '${resource.name}': ${err instanceof Error ? err.message : String(err)}`,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
fnSpinner.succeed(`${resource.name} ${niceId(result.assetId)}`);
|
|
46
|
+
log(` Source: ${resource.src}`);
|
|
47
|
+
}
|
|
34
48
|
if (verbose) {
|
|
35
49
|
if (result.hash) {
|
|
36
50
|
if (result.hash.length > 24) {
|
|
@@ -45,7 +59,10 @@ export async function blueprintDeployCore(options) {
|
|
|
45
59
|
}
|
|
46
60
|
}
|
|
47
61
|
else {
|
|
48
|
-
|
|
62
|
+
const errorMsg = isLocalFunctionCollection(resource)
|
|
63
|
+
? `Failed uploading function collection ${resource.name} (${resource.functions?.length || 0} functions), deploy has stopped`
|
|
64
|
+
: `Failed uploading ${resource.name} asset, deploy has stopped`;
|
|
65
|
+
fnSpinner.fail(errorMsg);
|
|
49
66
|
log(` Error: ${result.error}`);
|
|
50
67
|
return { success: false, error: result.error || 'Failed to process function resource' };
|
|
51
68
|
}
|