@sanity/runtime-cli 13.0.3 → 13.2.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 +18 -18
- package/dist/actions/blueprints/blueprint.d.ts +6 -3
- package/dist/actions/blueprints/blueprint.js +18 -8
- package/dist/actions/functions/dev.d.ts +1 -1
- package/dist/actions/functions/dev.js +2 -2
- package/dist/actions/git.d.ts +4 -1
- package/dist/actions/git.js +3 -3
- package/dist/baseCommands.d.ts +4 -0
- package/dist/baseCommands.js +8 -0
- package/dist/commands/blueprints/add.js +1 -0
- package/dist/commands/blueprints/config.js +1 -0
- package/dist/commands/blueprints/deploy.js +1 -0
- package/dist/commands/blueprints/destroy.js +1 -0
- package/dist/commands/blueprints/doctor.js +1 -0
- package/dist/commands/blueprints/info.js +1 -0
- package/dist/commands/blueprints/init.js +1 -0
- package/dist/commands/blueprints/logs.js +1 -0
- package/dist/commands/blueprints/plan.js +1 -0
- package/dist/commands/blueprints/stacks.js +1 -0
- package/dist/commands/functions/add.js +1 -0
- package/dist/commands/functions/dev.js +1 -0
- package/dist/commands/functions/env/add.js +1 -0
- package/dist/commands/functions/env/list.js +1 -0
- package/dist/commands/functions/env/remove.js +1 -0
- package/dist/commands/functions/logs.js +1 -0
- package/dist/commands/functions/test.js +1 -0
- package/dist/constants.d.ts +1 -0
- package/dist/constants.js +1 -0
- package/dist/cores/blueprints/doctor.js +3 -2
- package/dist/cores/blueprints/init.d.ts +2 -0
- package/dist/cores/blueprints/init.js +40 -9
- package/dist/cores/functions/add.js +12 -1
- package/dist/cores/functions/dev.js +1 -1
- package/dist/cores/functions/logs.js +6 -1
- package/dist/cores/index.d.ts +4 -2
- package/dist/cores/index.js +4 -2
- package/dist/server/app.d.ts +1 -1
- package/dist/server/app.js +6 -4
- package/dist/server/handlers/invoke.d.ts +1 -1
- package/dist/server/handlers/invoke.js +2 -2
- package/dist/server/static/api.d.ts +41 -0
- package/dist/server/static/api.js +29 -6
- package/dist/server/static/components/filters.js +62 -56
- package/dist/server/static/components/function-list.js +1 -1
- package/dist/server/static/components/payload-panel.js +33 -4
- package/dist/server/static/components/run-panel.js +12 -4
- package/dist/server/static/vendor/vendor.bundle.js +19 -10
- package/dist/utils/child-process-wrapper.js +3 -2
- package/dist/utils/display/blueprints-formatting.d.ts +2 -2
- package/dist/utils/display/blueprints-formatting.js +10 -3
- package/dist/utils/display/prompt.js +22 -15
- package/dist/utils/display/resources-formatting.d.ts +2 -1
- package/dist/utils/display/resources-formatting.js +31 -0
- package/dist/utils/find-function.js +6 -1
- package/dist/utils/functions/resource-to-arc.js +11 -2
- package/dist/utils/types.d.ts +10 -4
- package/dist/utils/types.js +4 -1
- package/dist/utils/validate/index.d.ts +3 -0
- package/dist/utils/validate/index.js +35 -0
- package/oclif.manifest.json +120 -1
- package/package.json +16 -17
|
@@ -23,6 +23,10 @@ class RunPanel extends ApiBaseElement {
|
|
|
23
23
|
invoke = () => {
|
|
24
24
|
const selectedEvent = this.api.store.selectedEvent
|
|
25
25
|
const docFunction = this.api.store.selectedFunctionType === this.SANITY_FUNCTION_DOCUMENT
|
|
26
|
+
const mediaFunction =
|
|
27
|
+
this.api.store.selectedFunctionType === this.SANITY_FUNCTION_MEDIA_LIBRARY_ASSET
|
|
28
|
+
const scheduleFunction = this.api.store.selectedFunctionType === this.SANITY_FUNCTION_SCHEDULE
|
|
29
|
+
const docOrScheduleFunction = docFunction || scheduleFunction
|
|
26
30
|
|
|
27
31
|
this.api.store.result = {logs: '', time: 0}
|
|
28
32
|
let event = {}
|
|
@@ -53,12 +57,16 @@ class RunPanel extends ApiBaseElement {
|
|
|
53
57
|
projectId: this.api.store.selectedProject,
|
|
54
58
|
token: this.api.store.withToken,
|
|
55
59
|
},
|
|
56
|
-
eventResourceType:
|
|
57
|
-
|
|
60
|
+
eventResourceType: scheduleFunction
|
|
61
|
+
? 'schedule'
|
|
62
|
+
: mediaFunction
|
|
63
|
+
? 'media-library'
|
|
64
|
+
: 'dataset',
|
|
65
|
+
eventResourceId: docOrScheduleFunction
|
|
58
66
|
? `${this.api.store.selectedProject}.${this.api.store.selectedDataset}`
|
|
59
67
|
: this.api.store.selectedMediaLibrary,
|
|
60
|
-
functionResourceType: 'project',
|
|
61
|
-
functionResourceId:
|
|
68
|
+
functionResourceType: docOrScheduleFunction ? 'project' : 'organization',
|
|
69
|
+
functionResourceId: docOrScheduleFunction
|
|
62
70
|
? this.api.store.selectedProject
|
|
63
71
|
: this.api.store.selectedOrganization,
|
|
64
72
|
}
|
|
@@ -5849,7 +5849,7 @@ class SelectionRange {
|
|
|
5849
5849
|
Compare this range to another range.
|
|
5850
5850
|
*/
|
|
5851
5851
|
eq(other, includeAssoc = false) {
|
|
5852
|
-
return this.anchor == other.anchor && this.head == other.head &&
|
|
5852
|
+
return this.anchor == other.anchor && this.head == other.head && this.goalColumn == other.goalColumn &&
|
|
5853
5853
|
(!includeAssoc || !this.empty || this.assoc == other.assoc);
|
|
5854
5854
|
}
|
|
5855
5855
|
/**
|
|
@@ -7338,7 +7338,8 @@ class EditorState {
|
|
|
7338
7338
|
- Other (anything else)
|
|
7339
7339
|
*/
|
|
7340
7340
|
charCategorizer(at) {
|
|
7341
|
-
|
|
7341
|
+
let chars = this.languageDataAt("wordChars", at);
|
|
7342
|
+
return makeCategorizer(chars.length ? chars[0] : "");
|
|
7342
7343
|
}
|
|
7343
7344
|
/**
|
|
7344
7345
|
Find the word at the given position, meaning the range
|
|
@@ -7524,6 +7525,9 @@ class RangeValue {
|
|
|
7524
7525
|
RangeValue.prototype.startSide = RangeValue.prototype.endSide = 0;
|
|
7525
7526
|
RangeValue.prototype.point = false;
|
|
7526
7527
|
RangeValue.prototype.mapMode = MapMode.TrackDel;
|
|
7528
|
+
function cmpVal(a, b) {
|
|
7529
|
+
return a == b || a.constructor == b.constructor && a.eq(b);
|
|
7530
|
+
}
|
|
7527
7531
|
/**
|
|
7528
7532
|
A range associates a value with a range of positions.
|
|
7529
7533
|
*/
|
|
@@ -7830,7 +7834,7 @@ class RangeSet {
|
|
|
7830
7834
|
for (;;) {
|
|
7831
7835
|
if (sideA.to != sideB.to ||
|
|
7832
7836
|
!sameValues(sideA.active, sideB.active) ||
|
|
7833
|
-
sideA.point && (!sideB.point || !sideA.point
|
|
7837
|
+
sideA.point && (!sideB.point || !cmpVal(sideA.point, sideB.point)))
|
|
7834
7838
|
return false;
|
|
7835
7839
|
if (sideA.to > to)
|
|
7836
7840
|
return true;
|
|
@@ -8305,22 +8309,27 @@ function compare(a, startA, b, startB, length, comparator) {
|
|
|
8305
8309
|
b.goto(startB);
|
|
8306
8310
|
let endB = startB + length;
|
|
8307
8311
|
let pos = startB, dPos = startB - startA;
|
|
8308
|
-
|
|
8312
|
+
let bounds = !!comparator.boundChange;
|
|
8313
|
+
for (let boundChange = false;;) {
|
|
8309
8314
|
let dEnd = (a.to + dPos) - b.to, diff = dEnd || a.endSide - b.endSide;
|
|
8310
8315
|
let end = diff < 0 ? a.to + dPos : b.to, clipEnd = Math.min(end, endB);
|
|
8311
|
-
|
|
8312
|
-
|
|
8316
|
+
let point = a.point || b.point;
|
|
8317
|
+
if (point) {
|
|
8318
|
+
if (!(a.point && b.point && cmpVal(a.point, b.point) &&
|
|
8313
8319
|
sameValues(a.activeForPoint(a.to), b.activeForPoint(b.to))))
|
|
8314
8320
|
comparator.comparePoint(pos, clipEnd, a.point, b.point);
|
|
8321
|
+
boundChange = false;
|
|
8315
8322
|
}
|
|
8316
8323
|
else {
|
|
8324
|
+
if (boundChange)
|
|
8325
|
+
comparator.boundChange(pos);
|
|
8317
8326
|
if (clipEnd > pos && !sameValues(a.active, b.active))
|
|
8318
8327
|
comparator.compareRange(pos, clipEnd, a.active, b.active);
|
|
8328
|
+
if (bounds && clipEnd < endB && (dEnd || a.openEnd(end) != b.openEnd(end)))
|
|
8329
|
+
boundChange = true;
|
|
8319
8330
|
}
|
|
8320
8331
|
if (end > endB)
|
|
8321
8332
|
break;
|
|
8322
|
-
if ((dEnd || a.openEnd != b.openEnd) && comparator.boundChange)
|
|
8323
|
-
comparator.boundChange(end);
|
|
8324
8333
|
pos = end;
|
|
8325
8334
|
if (diff <= 0)
|
|
8326
8335
|
a.next();
|
|
@@ -8332,7 +8341,7 @@ function sameValues(a, b) {
|
|
|
8332
8341
|
if (a.length != b.length)
|
|
8333
8342
|
return false;
|
|
8334
8343
|
for (let i = 0; i < a.length; i++)
|
|
8335
|
-
if (a[i] != b[i] && !a[i]
|
|
8344
|
+
if (a[i] != b[i] && !cmpVal(a[i], b[i]))
|
|
8336
8345
|
return false;
|
|
8337
8346
|
return true;
|
|
8338
8347
|
}
|
|
@@ -27250,4 +27259,4 @@ function prettyMilliseconds(milliseconds, options) {
|
|
|
27250
27259
|
return sign + result.join(separator);
|
|
27251
27260
|
}
|
|
27252
27261
|
|
|
27253
|
-
export { EditorState, EditorView, HighlightStyle, Store, basicSetup, json, prettyBytes, prettyMilliseconds, syntaxHighlighting, tags };
|
|
27262
|
+
export { Compartment, EditorState, EditorView, HighlightStyle, Store, basicSetup, json, prettyBytes, prettyMilliseconds, syntaxHighlighting, tags };
|
|
@@ -2,6 +2,7 @@ import {table as renderTable} from 'node:console'
|
|
|
2
2
|
import {existsSync, statSync} from 'node:fs'
|
|
3
3
|
import {isAbsolute, join} from 'node:path'
|
|
4
4
|
import process from 'node:process'
|
|
5
|
+
import {pathToFileURL} from 'node:url'
|
|
5
6
|
import {inspect} from 'node:util'
|
|
6
7
|
|
|
7
8
|
export function getFunctionSource(src) {
|
|
@@ -12,9 +13,9 @@ export function getFunctionSource(src) {
|
|
|
12
13
|
if (!existsSync(indexPath)) {
|
|
13
14
|
throw Error(`Function directory ${pathToCheck} has no index.js`)
|
|
14
15
|
}
|
|
15
|
-
return
|
|
16
|
+
return pathToFileURL(indexPath).href
|
|
16
17
|
}
|
|
17
|
-
return
|
|
18
|
+
return pathToFileURL(pathToCheck).href
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
// Monkey patch console menthods to have logs match server log format
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Blueprint, Resource } from '@sanity/blueprints-parser';
|
|
2
|
-
import { type
|
|
2
|
+
import { type BlueprintResourceRecord, type Stack } from '../types.js';
|
|
3
3
|
export declare function formatTitle(title: string, name: string): string;
|
|
4
|
-
export declare function formatDeployedResourceTree(resources:
|
|
4
|
+
export declare function formatDeployedResourceTree(resources: BlueprintResourceRecord[] | undefined, verbose?: boolean): string;
|
|
5
5
|
export declare function formatResourceTree(resources: Resource[] | undefined, verbose?: boolean): string;
|
|
6
6
|
export declare function formatStackInfo(stack: Stack | Blueprint, isCurrentStack?: boolean): string;
|
|
7
7
|
export declare function formatStacksListing(stacks: Stack[], currentStackId?: string): string;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { treeify } from 'array-treeify';
|
|
2
2
|
import chalk from 'chalk';
|
|
3
|
-
import { SANITY_ACCESS_ROLE, SANITY_FUNCTION_DOCUMENT, SANITY_FUNCTION_MEDIA_LIBRARY_ASSET, SANITY_FUNCTION_SCHEDULE, SANITY_PROJECT_CORS, SANITY_PROJECT_DATASET, SANITY_PROJECT_WEBHOOK, } from '../../constants.js';
|
|
4
|
-
import { isCorsOriginResource, isDatasetResource, isRoleResource, isWebhookResource, } from '../types.js';
|
|
3
|
+
import { SANITY_ACCESS_ROBOT, SANITY_ACCESS_ROLE, SANITY_FUNCTION_DOCUMENT, SANITY_FUNCTION_MEDIA_LIBRARY_ASSET, SANITY_FUNCTION_SCHEDULE, SANITY_PROJECT_CORS, SANITY_PROJECT_DATASET, SANITY_PROJECT_WEBHOOK, } from '../../constants.js';
|
|
4
|
+
import { isCorsOriginResource, isDatasetResource, isRobotResource, isRoleResource, isWebhookResource, } from '../types.js';
|
|
5
5
|
import { formatDate, formatDuration } from './dates.js';
|
|
6
6
|
import { niceId } from './presenters.js';
|
|
7
|
-
import { arrayifyCors, arrayifyDataset, arrayifyFunction, arrayifyRole, arrayifyWebhook, } from './resources-formatting.js';
|
|
7
|
+
import { arrayifyCors, arrayifyDataset, arrayifyFunction, arrayifyRobot, arrayifyRole, arrayifyWebhook, } from './resources-formatting.js';
|
|
8
8
|
const functionCategory = {
|
|
9
9
|
label: 'Functions',
|
|
10
10
|
displayNameAttribute: 'displayName',
|
|
@@ -18,6 +18,13 @@ const RESOURCE_CATEGORIES = {
|
|
|
18
18
|
return isRoleResource(res) ? arrayifyRole(res) : [];
|
|
19
19
|
},
|
|
20
20
|
},
|
|
21
|
+
[SANITY_ACCESS_ROBOT]: {
|
|
22
|
+
label: 'Robots',
|
|
23
|
+
displayNameAttribute: 'label',
|
|
24
|
+
formatDetails(res) {
|
|
25
|
+
return isRobotResource(res) ? arrayifyRobot(res) : [];
|
|
26
|
+
},
|
|
27
|
+
},
|
|
21
28
|
[SANITY_FUNCTION_DOCUMENT]: functionCategory,
|
|
22
29
|
[SANITY_FUNCTION_MEDIA_LIBRARY_ASSET]: functionCategory,
|
|
23
30
|
[SANITY_FUNCTION_SCHEDULE]: functionCategory,
|
|
@@ -32,24 +32,25 @@ export async function promptForProject({ token, knownOrganizationId, knownProjec
|
|
|
32
32
|
if (organizations.length > 1) {
|
|
33
33
|
const orgChoices = organizations.map(({ organization, projects }) => ({
|
|
34
34
|
name: `"${organization.name}" ${niceId(organization.id)}`,
|
|
35
|
-
value:
|
|
35
|
+
value: organization.id,
|
|
36
36
|
disabled: !projects || projects.length === 0 ? '(0 Projects)' : false,
|
|
37
37
|
}));
|
|
38
|
-
const
|
|
38
|
+
const pickedOrgId = await select({
|
|
39
39
|
message: 'Which Organization would you like to use?',
|
|
40
40
|
choices: orgChoices,
|
|
41
41
|
default: knownOrganizationId,
|
|
42
42
|
});
|
|
43
|
-
|
|
43
|
+
const pickedOrg = organizations.find((o) => o.organization.id === pickedOrgId);
|
|
44
|
+
projects = pickedOrg?.projects;
|
|
44
45
|
}
|
|
45
46
|
else {
|
|
46
47
|
projects = organizations[0].projects;
|
|
47
48
|
}
|
|
48
49
|
const projectChoices = projects.map(({ displayName, id: projectId }) => ({
|
|
49
50
|
name: `"${displayName}" ${niceId(projectId)}`,
|
|
50
|
-
value:
|
|
51
|
+
value: projectId,
|
|
51
52
|
}));
|
|
52
|
-
let
|
|
53
|
+
let pickedProjectId;
|
|
53
54
|
if (projectChoices.length === 1) {
|
|
54
55
|
const onlyProject = projectChoices[0];
|
|
55
56
|
const confirmed = await confirm({
|
|
@@ -57,18 +58,21 @@ export async function promptForProject({ token, knownOrganizationId, knownProjec
|
|
|
57
58
|
default: true,
|
|
58
59
|
});
|
|
59
60
|
if (confirmed)
|
|
60
|
-
|
|
61
|
+
pickedProjectId = onlyProject.value;
|
|
61
62
|
else
|
|
62
63
|
throw new Error('No project selected');
|
|
63
64
|
}
|
|
64
65
|
else {
|
|
65
|
-
|
|
66
|
+
pickedProjectId = await select({
|
|
66
67
|
message: 'Choose a Sanity Project:',
|
|
67
68
|
choices: projectChoices,
|
|
68
69
|
default: knownProjectId,
|
|
69
70
|
});
|
|
70
71
|
}
|
|
71
|
-
|
|
72
|
+
const pickedProject = projects.find((p) => p.id === pickedProjectId);
|
|
73
|
+
if (!pickedProject)
|
|
74
|
+
throw new Error('Project not found');
|
|
75
|
+
return { projectId: pickedProject.id, displayName: pickedProject.displayName };
|
|
72
76
|
}
|
|
73
77
|
/**
|
|
74
78
|
* Prompt the user for a Stack ID after selecting a Project.
|
|
@@ -83,24 +87,24 @@ export async function promptForStack({ projectId, token, logger, }) {
|
|
|
83
87
|
if (!stacksOk) {
|
|
84
88
|
throw new Error(stacksErr || 'Failed to list Stacks');
|
|
85
89
|
}
|
|
86
|
-
const
|
|
87
|
-
let pickedStackId =
|
|
90
|
+
const NEW_STACK_ID = 'new';
|
|
91
|
+
let pickedStackId = NEW_STACK_ID;
|
|
88
92
|
if (stacks.length > 0) {
|
|
89
93
|
const stackChoices = [];
|
|
90
94
|
stackChoices.push(new Separator(chalk.underline('Create a new Stack:')));
|
|
91
|
-
stackChoices.push({ name: chalk.bold('New Stack ✨'), value:
|
|
95
|
+
stackChoices.push({ name: chalk.bold('New Stack ✨'), value: NEW_STACK_ID });
|
|
92
96
|
stackChoices.push(new Separator(chalk.underline('Use an existing Stack:')));
|
|
93
97
|
stackChoices.push(...stacks.map((s) => ({
|
|
94
98
|
name: `"${s.name}" ${niceId(s.id)} ${chalk.dim(`(${s.resources.length} res)`)}`,
|
|
95
|
-
value:
|
|
99
|
+
value: s.id,
|
|
96
100
|
})));
|
|
97
101
|
pickedStackId = await select({
|
|
98
102
|
message: 'Select a deployment Stack:',
|
|
99
103
|
choices: stackChoices,
|
|
100
|
-
default:
|
|
104
|
+
default: NEW_STACK_ID,
|
|
101
105
|
});
|
|
102
106
|
}
|
|
103
|
-
if (pickedStackId
|
|
107
|
+
if (pickedStackId === NEW_STACK_ID) {
|
|
104
108
|
const stackName = await input({
|
|
105
109
|
message: 'Enter a name for your new Stack:',
|
|
106
110
|
validate: (input) => input.length > 0 || 'Stack name is required',
|
|
@@ -114,5 +118,8 @@ export async function promptForStack({ projectId, token, logger, }) {
|
|
|
114
118
|
});
|
|
115
119
|
return { stackId: stack.id, name: stackName };
|
|
116
120
|
}
|
|
117
|
-
|
|
121
|
+
const pickedStack = stacks.find((s) => s.id === pickedStackId);
|
|
122
|
+
if (!pickedStack)
|
|
123
|
+
throw new Error('Stack not found');
|
|
124
|
+
return { stackId: pickedStack.id, name: pickedStack.name };
|
|
118
125
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import type { BlueprintCorsOriginResource, BlueprintDatasetResource, BlueprintDocumentWebhookResource, BlueprintRoleResource } from '@sanity/blueprints';
|
|
1
|
+
import type { BlueprintCorsOriginResource, BlueprintDatasetResource, BlueprintDocumentWebhookResource, BlueprintRobotResource, BlueprintRoleResource } from '@sanity/blueprints';
|
|
2
2
|
import type { TreeInput } from 'array-treeify';
|
|
3
3
|
import { type FunctionResourceBase } from '../../utils/types.js';
|
|
4
4
|
export declare function arrayifyFunction(fn: FunctionResourceBase): TreeInput;
|
|
5
5
|
export declare function arrayifyCors(resource: BlueprintCorsOriginResource): TreeInput;
|
|
6
|
+
export declare function arrayifyRobot(resource: BlueprintRobotResource): TreeInput;
|
|
6
7
|
export declare function arrayifyRole(resource: BlueprintRoleResource): TreeInput;
|
|
7
8
|
export declare function arrayifyDataset(resource: BlueprintDatasetResource): TreeInput;
|
|
8
9
|
export declare function arrayifyWebhook(resource: BlueprintDocumentWebhookResource): TreeInput;
|
|
@@ -49,6 +49,37 @@ export function arrayifyFunction(fn) {
|
|
|
49
49
|
export function arrayifyCors(resource) {
|
|
50
50
|
return [formatLabeledValue('origin', resource.origin)];
|
|
51
51
|
}
|
|
52
|
+
export function arrayifyRobot(resource) {
|
|
53
|
+
const details = [formatLabeledValue('label', resource.label)];
|
|
54
|
+
if (resource.memberships.length > 0) {
|
|
55
|
+
details.push(formatLabel('memberships'));
|
|
56
|
+
const memberships = [];
|
|
57
|
+
resource.memberships.forEach((m, i) => {
|
|
58
|
+
const membership = [];
|
|
59
|
+
membership.push(formatLabeledValue('resourceType', m.resourceType));
|
|
60
|
+
membership.push(formatLabeledValue('resourceId', m.resourceId));
|
|
61
|
+
if (m.roleNames.length > 0) {
|
|
62
|
+
membership.push(formatLabeledValue('roleNames', m.roleNames.join(', ')));
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
membership.push(formatLabeledValue('roleNames', '[]'));
|
|
66
|
+
}
|
|
67
|
+
memberships.push(formatLabel(i.toString()));
|
|
68
|
+
memberships.push(membership);
|
|
69
|
+
});
|
|
70
|
+
details.push(memberships);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
details.push(formatLabeledValue('memberships', '[]'));
|
|
74
|
+
}
|
|
75
|
+
if (resource.resourceType) {
|
|
76
|
+
details.push(formatLabeledValue('resourceType', resource.resourceType));
|
|
77
|
+
}
|
|
78
|
+
if (resource.resourceId) {
|
|
79
|
+
details.push(formatLabeledValue('resourceId', resource.resourceId));
|
|
80
|
+
}
|
|
81
|
+
return details;
|
|
82
|
+
}
|
|
52
83
|
export function arrayifyRole(resource) {
|
|
53
84
|
const details = [];
|
|
54
85
|
if (resource.description)
|
|
@@ -13,7 +13,12 @@ export function findFunctionInBlueprint(blueprint, name) {
|
|
|
13
13
|
export function findFunctionInStack(stack, name) {
|
|
14
14
|
const func = stack?.resources?.find((r) => r?.type?.startsWith('sanity.function.') && r.name === name);
|
|
15
15
|
if (!func)
|
|
16
|
-
throw Error(`Unable to find function ${name}`);
|
|
16
|
+
throw Error(`Unable to find function: "${name}"`);
|
|
17
|
+
if (!isDeployedResource(func))
|
|
18
|
+
throw Error(`Unable to find deployed function: "${name}"`);
|
|
17
19
|
// return the deployed resource
|
|
18
20
|
return func;
|
|
19
21
|
}
|
|
22
|
+
function isDeployedResource(r) {
|
|
23
|
+
return 'externalId' in r && typeof r.externalId === 'string';
|
|
24
|
+
}
|
|
@@ -1,7 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { stat } from 'node:fs/promises';
|
|
2
|
+
import { resolve, sep } from 'node:path';
|
|
3
|
+
import { cwd } from 'node:process';
|
|
2
4
|
export async function convertResourceToArcFormat(resource, transpiled) {
|
|
5
|
+
if (!resource.src) {
|
|
6
|
+
throw Error('Missing `resource.src` property');
|
|
7
|
+
}
|
|
8
|
+
// Get stats from file
|
|
9
|
+
const stats = await stat(resolve(cwd(), resource.src));
|
|
10
|
+
// Convert resource.src to arc file path format
|
|
3
11
|
const srcPath = resource.src?.split(sep).join('/');
|
|
4
|
-
const
|
|
12
|
+
const entryDir = stats.isFile() ? srcPath.substring(0, srcPath.lastIndexOf('/')) : srcPath;
|
|
13
|
+
const functionPath = transpiled ? `${entryDir}/.build/function-${resource.name}` : entryDir;
|
|
5
14
|
return `@app
|
|
6
15
|
hydrate-function
|
|
7
16
|
|
package/dist/utils/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type BlueprintCorsOriginResource, type BlueprintDatasetResource, type BlueprintDocumentWebhookResource, type BlueprintResource, type BlueprintRoleResource } from '@sanity/blueprints';
|
|
1
|
+
import { type BlueprintCorsOriginResource, type BlueprintDatasetResource, type BlueprintDocumentWebhookResource, type BlueprintResource, type BlueprintRobotResource, type BlueprintRoleResource } from '@sanity/blueprints';
|
|
2
2
|
import type { Blueprint } from '@sanity/blueprints-parser';
|
|
3
3
|
import { SANITY_FUNCTION_DOCUMENT, SANITY_FUNCTION_MEDIA_LIBRARY_ASSET, SANITY_FUNCTION_SCHEDULE } from '../constants.js';
|
|
4
4
|
export type ScopeType = 'organization' | 'project';
|
|
@@ -48,11 +48,16 @@ interface FunctionResourceScheduleExpressionEvent {
|
|
|
48
48
|
expression: string;
|
|
49
49
|
}
|
|
50
50
|
type FunctionResourceScheduleEvent = FunctionResourceScheduleExplicitEvent | FunctionResourceScheduleExpressionEvent;
|
|
51
|
-
|
|
51
|
+
/** The Blueprint resource as represented in the Blueprints API database */
|
|
52
|
+
export interface BlueprintResourceRecord extends BlueprintResource {
|
|
52
53
|
id: string;
|
|
53
|
-
externalId
|
|
54
|
+
externalId?: string | null;
|
|
54
55
|
parameters: Record<string, unknown>;
|
|
55
56
|
}
|
|
57
|
+
/** The deployed resource; complete with external ID */
|
|
58
|
+
export interface DeployedResource extends BlueprintResourceRecord {
|
|
59
|
+
externalId: string;
|
|
60
|
+
}
|
|
56
61
|
export declare function isLocalFunctionResource(r: BlueprintResource): r is FunctionResourceBase;
|
|
57
62
|
export declare function isDocumentFunctionResource<T extends BlueprintResource>(r: T): r is T & FunctionResourceDocument;
|
|
58
63
|
export declare function isMediaLibraryAssetFunctionResource<T extends BlueprintResource>(r: T): r is T & FunctionResourceMediaLibraryAsset;
|
|
@@ -60,6 +65,7 @@ export declare function isScheduleFunctionResource<T extends BlueprintResource>(
|
|
|
60
65
|
export declare function isLocalFunctionCollection<T extends BlueprintResource>(r: T): r is T & FunctionsCollection;
|
|
61
66
|
export declare function isScheduleEvent(e: unknown): e is FunctionResourceScheduleEvent;
|
|
62
67
|
export declare function isCorsOriginResource(r: unknown): r is BlueprintCorsOriginResource;
|
|
68
|
+
export declare function isRobotResource(r: unknown): r is BlueprintRobotResource;
|
|
63
69
|
export declare function isRoleResource(r: unknown): r is BlueprintRoleResource;
|
|
64
70
|
export declare function isDatasetResource(r: unknown): r is BlueprintDatasetResource;
|
|
65
71
|
export declare function isWebhookResource(r: unknown): r is BlueprintDocumentWebhookResource;
|
|
@@ -114,7 +120,7 @@ export interface Stack {
|
|
|
114
120
|
displayName: string;
|
|
115
121
|
scopeType: ScopeType;
|
|
116
122
|
scopeId: string;
|
|
117
|
-
resources: Array<
|
|
123
|
+
resources: Array<BlueprintResourceRecord>;
|
|
118
124
|
createdAt?: string;
|
|
119
125
|
updatedAt?: string;
|
|
120
126
|
recentOperation?: StackOperation;
|
package/dist/utils/types.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { validateCorsOrigin, validateDataset, validateDocumentWebhook, validateRole, } from '@sanity/blueprints';
|
|
1
|
+
import { validateCorsOrigin, validateDataset, validateDocumentWebhook, validateRobot, validateRole, } from '@sanity/blueprints';
|
|
2
2
|
import { SANITY_FUNCTION_DOCUMENT, SANITY_FUNCTION_MEDIA_LIBRARY_ASSET, SANITY_FUNCTION_SCHEDULE, } from '../constants.js';
|
|
3
3
|
// type narrowing with predicate functions
|
|
4
4
|
export function isLocalFunctionResource(r) {
|
|
@@ -22,6 +22,9 @@ export function isScheduleEvent(e) {
|
|
|
22
22
|
export function isCorsOriginResource(r) {
|
|
23
23
|
return validateCorsOrigin(r).length === 0;
|
|
24
24
|
}
|
|
25
|
+
export function isRobotResource(r) {
|
|
26
|
+
return validateRobot(r).length === 0;
|
|
27
|
+
}
|
|
25
28
|
export function isRoleResource(r) {
|
|
26
29
|
return validateRole(r).length === 0;
|
|
27
30
|
}
|
|
@@ -1 +1,36 @@
|
|
|
1
|
+
import { validateCorsOrigin, validateDataset, validateDocumentFunction, validateDocumentWebhook, validateMediaLibraryAssetFunction, validateRole, validateScheduleFunction, } from '@sanity/blueprints';
|
|
2
|
+
import { SANITY_ACCESS_ROLE, SANITY_FUNCTION_DOCUMENT, SANITY_FUNCTION_MEDIA_LIBRARY_ASSET, SANITY_FUNCTION_SCHEDULE, SANITY_PROJECT_CORS, SANITY_PROJECT_DATASET, SANITY_PROJECT_WEBHOOK, } from '../../constants.js';
|
|
1
3
|
export * as validate from './resource.js';
|
|
4
|
+
const RESOURCE_VALIDATORS = {
|
|
5
|
+
[SANITY_ACCESS_ROLE]: {
|
|
6
|
+
validate: validateRole,
|
|
7
|
+
},
|
|
8
|
+
[SANITY_FUNCTION_DOCUMENT]: {
|
|
9
|
+
validate: validateDocumentFunction,
|
|
10
|
+
},
|
|
11
|
+
[SANITY_FUNCTION_MEDIA_LIBRARY_ASSET]: {
|
|
12
|
+
validate: validateMediaLibraryAssetFunction,
|
|
13
|
+
},
|
|
14
|
+
[SANITY_FUNCTION_SCHEDULE]: {
|
|
15
|
+
validate: validateScheduleFunction,
|
|
16
|
+
},
|
|
17
|
+
[SANITY_PROJECT_CORS]: {
|
|
18
|
+
validate: validateCorsOrigin,
|
|
19
|
+
},
|
|
20
|
+
[SANITY_PROJECT_DATASET]: {
|
|
21
|
+
validate: validateDataset,
|
|
22
|
+
},
|
|
23
|
+
[SANITY_PROJECT_WEBHOOK]: {
|
|
24
|
+
validate: validateDocumentWebhook,
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
export function validateResources(resources) {
|
|
28
|
+
const errors = [];
|
|
29
|
+
for (const resource of resources) {
|
|
30
|
+
const validator = RESOURCE_VALIDATORS[resource.type];
|
|
31
|
+
if (validator) {
|
|
32
|
+
errors.push(...validator.validate(resource));
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return errors;
|
|
36
|
+
}
|