@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
|
@@ -8,6 +8,7 @@ import { createEmptyStack } from '../../actions/blueprints/stacks.js';
|
|
|
8
8
|
import { writeGitignoreFile } from '../../actions/git.js';
|
|
9
9
|
import { writeOrUpdateNodeDependency } from '../../actions/node.js';
|
|
10
10
|
import { verifyExampleExists, writeExample } from '../../actions/sanity/examples.js';
|
|
11
|
+
import { getProject } from '../../actions/sanity/projects.js';
|
|
11
12
|
import { BLUEPRINT_CONFIG_DIR, BLUEPRINT_CONFIG_FILE } from '../../config.js';
|
|
12
13
|
import { check, filePathRelativeToCwd, labeledId, warn } from '../../utils/display/presenters.js';
|
|
13
14
|
import { promptForBlueprintType, promptForProject, promptForStack, } from '../../utils/display/prompt.js';
|
|
@@ -15,7 +16,7 @@ import { blueprintConfigCore } from './config.js';
|
|
|
15
16
|
const SCOPE_PROJECT = 'project';
|
|
16
17
|
const SCOPE_ORGANIZATION = 'organization';
|
|
17
18
|
export async function blueprintInitCore(options) {
|
|
18
|
-
const { bin = 'sanity', log, token, args, flags } = options;
|
|
19
|
+
const { bin = 'sanity', log, token, knownProjectId, args, flags, validateResources } = options;
|
|
19
20
|
const { dir: flagDir, example: flagExample, 'blueprint-type': flagBlueprintType, 'project-id': flagProjectId, 'organization-id': flagOrganizationId, 'stack-id': flagStackId, 'stack-name': flagStackName, verbose: v = false, } = flags;
|
|
20
21
|
const { dir: argDir } = args;
|
|
21
22
|
const userProvidedDirName = argDir || flagDir;
|
|
@@ -54,12 +55,13 @@ export async function blueprintInitCore(options) {
|
|
|
54
55
|
if (!overwrite)
|
|
55
56
|
return { success: false, error: 'Initialization cancelled.' };
|
|
56
57
|
}
|
|
57
|
-
const existingBlueprint = await readLocalBlueprint(log, existingBlueprintFile.blueprintFilePath);
|
|
58
|
+
const existingBlueprint = await readLocalBlueprint(log, { resources: validateResources || false }, existingBlueprintFile.blueprintFilePath);
|
|
58
59
|
return blueprintConfigCore({
|
|
59
60
|
blueprint: existingBlueprint,
|
|
60
61
|
bin,
|
|
61
62
|
log,
|
|
62
63
|
token,
|
|
64
|
+
validateResources,
|
|
63
65
|
flags: {
|
|
64
66
|
edit: true,
|
|
65
67
|
'project-id': flagProjectId,
|
|
@@ -84,6 +86,7 @@ export async function blueprintInitCore(options) {
|
|
|
84
86
|
organizationId: flagOrganizationId,
|
|
85
87
|
stackId: flagStackId,
|
|
86
88
|
stackName: flagStackName,
|
|
89
|
+
knownProjectId,
|
|
87
90
|
log,
|
|
88
91
|
token,
|
|
89
92
|
});
|
|
@@ -169,7 +172,7 @@ async function handleExampleInitialization(options) {
|
|
|
169
172
|
return { success: true };
|
|
170
173
|
}
|
|
171
174
|
export async function resolveScopeAndStack(params) {
|
|
172
|
-
const { projectId, organizationId, stackId, stackName, log, token } = params;
|
|
175
|
+
const { projectId, organizationId, stackId, stackName, knownProjectId, log, token } = params;
|
|
173
176
|
let scopeType = SCOPE_PROJECT;
|
|
174
177
|
let scopeId;
|
|
175
178
|
if (projectId) {
|
|
@@ -195,10 +198,33 @@ export async function resolveScopeAndStack(params) {
|
|
|
195
198
|
resolvedStackId = stack.id;
|
|
196
199
|
}
|
|
197
200
|
if (!scopeId) {
|
|
198
|
-
log('\nBlueprints are associated with a Sanity
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
201
|
+
log('\nBlueprints are associated with a Sanity project.');
|
|
202
|
+
// If we have a CLI project ID, offer it as a suggestion
|
|
203
|
+
if (knownProjectId) {
|
|
204
|
+
const { ok, project } = await getProject({
|
|
205
|
+
token,
|
|
206
|
+
scopeId: knownProjectId,
|
|
207
|
+
scopeType: 'project',
|
|
208
|
+
logger: log,
|
|
209
|
+
});
|
|
210
|
+
if (ok && project) {
|
|
211
|
+
const useCliProject = await confirm({
|
|
212
|
+
message: `The CLI is configured to use "${project.displayName}" (${knownProjectId}). Use this for the blueprint?`,
|
|
213
|
+
default: true,
|
|
214
|
+
});
|
|
215
|
+
if (useCliProject) {
|
|
216
|
+
scopeType = SCOPE_PROJECT;
|
|
217
|
+
scopeId = knownProjectId;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
// If still no scope (no knownProjectId, lookup failed, or user declined), prompt for selection
|
|
222
|
+
if (!scopeId) {
|
|
223
|
+
log('Select a project:');
|
|
224
|
+
const pickedProject = await promptForProject({ token, logger: log });
|
|
225
|
+
scopeType = SCOPE_PROJECT;
|
|
226
|
+
scopeId = pickedProject.projectId;
|
|
227
|
+
}
|
|
202
228
|
}
|
|
203
229
|
if (!resolvedStackId) {
|
|
204
230
|
log('\nBlueprints are deployed to a "Stack".');
|
|
@@ -254,8 +280,13 @@ export async function createBlueprintFiles(params) {
|
|
|
254
280
|
...(scopeType === SCOPE_ORGANIZATION ? { organizationId: scopeId } : { projectId: scopeId }),
|
|
255
281
|
});
|
|
256
282
|
log(check(`${chalk.bold('Added configuration:')} ${displayPath}/${BLUEPRINT_CONFIG_DIR}/${BLUEPRINT_CONFIG_FILE}`));
|
|
257
|
-
writeGitignoreFile(blueprintFilePath);
|
|
258
|
-
|
|
283
|
+
const gitignoreResult = writeGitignoreFile(blueprintFilePath);
|
|
284
|
+
if (gitignoreResult.action === 'created') {
|
|
285
|
+
log(check(`${chalk.bold('Added .gitignore:')} ${displayPath}/.gitignore`));
|
|
286
|
+
}
|
|
287
|
+
else if (gitignoreResult.action === 'updated') {
|
|
288
|
+
log(check(`${chalk.bold('Updated .gitignore:')} ${displayPath}/.gitignore`));
|
|
289
|
+
}
|
|
259
290
|
if (blueprintExtension !== 'json') {
|
|
260
291
|
const blueprintsPackage = '@sanity/blueprints';
|
|
261
292
|
try {
|
|
@@ -6,6 +6,7 @@ import { highlight } from 'cardinal';
|
|
|
6
6
|
import chalk from 'chalk';
|
|
7
7
|
import { createFunctionResource } from '../../actions/blueprints/resources.js';
|
|
8
8
|
import { verifyExampleExists, writeExample } from '../../actions/sanity/examples.js';
|
|
9
|
+
import { SANITY_FUNCTION_MEDIA_LIBRARY_ASSET, SANITY_FUNCTION_SCHEDULE } from '../../constants.js';
|
|
9
10
|
import { check, indent, warn } from '../../utils/display/presenters.js';
|
|
10
11
|
import { validateFunctionName } from '../../utils/validate/resource.js';
|
|
11
12
|
const generateFunctionBlueprintResourceTemplate = (fnName, eventNames) => {
|
|
@@ -71,7 +72,17 @@ export async function functionAddCore(options) {
|
|
|
71
72
|
}
|
|
72
73
|
else {
|
|
73
74
|
const objectLiteral = configString.replace(/^(\s*)"([a-zA-Z_$][a-zA-Z0-9_$]*)":/gm, '$1$2:');
|
|
74
|
-
|
|
75
|
+
let type = 'Document';
|
|
76
|
+
switch (functionConfig.type) {
|
|
77
|
+
case SANITY_FUNCTION_MEDIA_LIBRARY_ASSET:
|
|
78
|
+
type = 'MediaLibraryAsset';
|
|
79
|
+
break;
|
|
80
|
+
case SANITY_FUNCTION_SCHEDULE:
|
|
81
|
+
type = 'Schedule';
|
|
82
|
+
break;
|
|
83
|
+
default:
|
|
84
|
+
}
|
|
85
|
+
log(indent(highlight(`define${type}Function(${objectLiteral})`)));
|
|
75
86
|
}
|
|
76
87
|
}
|
|
77
88
|
else {
|
|
@@ -7,7 +7,7 @@ export async function functionDevCore(options) {
|
|
|
7
7
|
? { timeout }
|
|
8
8
|
: undefined;
|
|
9
9
|
try {
|
|
10
|
-
await dev(host, Number(port), log, executionOptions);
|
|
10
|
+
await dev(host, Number(port), log, options.validateResources || false, executionOptions);
|
|
11
11
|
log(`Server is running on http://${host}:${port}\n`);
|
|
12
12
|
return {
|
|
13
13
|
success: true,
|
|
@@ -105,7 +105,12 @@ function formatLog(time, level, message, utc) {
|
|
|
105
105
|
const [dateString, timeString] = utc
|
|
106
106
|
? date.toISOString().slice(0, 19).split('T')
|
|
107
107
|
: [date.toLocaleDateString(), date.toLocaleTimeString()];
|
|
108
|
-
return [
|
|
108
|
+
return [
|
|
109
|
+
chalk.bold(dateString),
|
|
110
|
+
chalk.bold.blue(timeString),
|
|
111
|
+
logLevel(level.toUpperCase()),
|
|
112
|
+
message,
|
|
113
|
+
].join(' ');
|
|
109
114
|
}
|
|
110
115
|
function logLevel(level) {
|
|
111
116
|
if (level === 'ERROR')
|
package/dist/cores/index.d.ts
CHANGED
|
@@ -8,6 +8,8 @@ export interface CoreConfig {
|
|
|
8
8
|
bin: string;
|
|
9
9
|
/** The log output function. */
|
|
10
10
|
log: ReturnType<typeof Logger>;
|
|
11
|
+
/** Enable resource validation during parsing */
|
|
12
|
+
validateResources?: boolean;
|
|
11
13
|
}
|
|
12
14
|
export interface BlueprintConfig extends CoreConfig {
|
|
13
15
|
token: string;
|
|
@@ -43,7 +45,7 @@ type InitBlueprintConfigParams = CoreConfig & ({
|
|
|
43
45
|
validateToken?: false;
|
|
44
46
|
token?: string;
|
|
45
47
|
});
|
|
46
|
-
export declare function initBlueprintConfig({ bin, log, token, validateToken, }: InitBlueprintConfigParams): Promise<Result<BlueprintConfig>>;
|
|
47
|
-
export declare function initDeployedBlueprintConfig(config: Partial<BlueprintConfig> & Pick<BlueprintConfig, 'bin' | 'log' | 'token'> & {
|
|
48
|
+
export declare function initBlueprintConfig({ bin, log, token, validateResources, validateToken, }: InitBlueprintConfigParams): Promise<Result<BlueprintConfig>>;
|
|
49
|
+
export declare function initDeployedBlueprintConfig(config: Partial<BlueprintConfig> & Pick<BlueprintConfig, 'bin' | 'log' | 'token' | 'validateResources'> & {
|
|
48
50
|
validateToken?: boolean;
|
|
49
51
|
}): Promise<Result<DeployedBlueprintConfig>>;
|
package/dist/cores/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import { niceId } from '../utils/display/presenters.js';
|
|
|
5
5
|
import { validTokenOrErrorMessage } from '../utils/validated-token.js';
|
|
6
6
|
export * as blueprintsCores from './blueprints/index.js';
|
|
7
7
|
export * as functionsCores from './functions/index.js';
|
|
8
|
-
export async function initBlueprintConfig({ bin, log, token, validateToken = true, }) {
|
|
8
|
+
export async function initBlueprintConfig({ bin, log, token, validateResources = false, validateToken = true, }) {
|
|
9
9
|
let checkedToken = token;
|
|
10
10
|
if (!token || (token && validateToken)) {
|
|
11
11
|
const tokenCheck = await validTokenOrErrorMessage(log, token);
|
|
@@ -17,7 +17,7 @@ export async function initBlueprintConfig({ bin, log, token, validateToken = tru
|
|
|
17
17
|
if (!checkedToken) {
|
|
18
18
|
return { ok: false, error: 'A valid token is required but was not provided.' };
|
|
19
19
|
}
|
|
20
|
-
const blueprint = await readLocalBlueprint(log);
|
|
20
|
+
const blueprint = await readLocalBlueprint(log, { resources: validateResources });
|
|
21
21
|
if (blueprint.errors.length > 0) {
|
|
22
22
|
log(presentBlueprintParserErrors(blueprint.errors));
|
|
23
23
|
return { ok: false, error: 'Blueprint file contains errors.' };
|
|
@@ -29,6 +29,7 @@ export async function initBlueprintConfig({ bin, log, token, validateToken = tru
|
|
|
29
29
|
blueprint,
|
|
30
30
|
log,
|
|
31
31
|
token: checkedToken,
|
|
32
|
+
validateResources,
|
|
32
33
|
},
|
|
33
34
|
};
|
|
34
35
|
}
|
|
@@ -67,6 +68,7 @@ export async function initDeployedBlueprintConfig(config) {
|
|
|
67
68
|
stackId,
|
|
68
69
|
auth,
|
|
69
70
|
deployedStack: stackResponse.stack,
|
|
71
|
+
validateResources: config.validateResources,
|
|
70
72
|
},
|
|
71
73
|
};
|
|
72
74
|
}
|
package/dist/server/app.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Logger } from '../utils/logger.js';
|
|
2
2
|
import { type InvokeExecutionOptions } from '../utils/types.js';
|
|
3
|
-
declare const app: (host: string, port: number, logger: ReturnType<typeof Logger>, executionOptions?: Partial<InvokeExecutionOptions>) => void;
|
|
3
|
+
declare const app: (host: string, port: number, logger: ReturnType<typeof Logger>, validateResources: boolean, executionOptions?: Partial<InvokeExecutionOptions>) => void;
|
|
4
4
|
declare function parseDocumentUrl(url: string): {
|
|
5
5
|
projectId: string;
|
|
6
6
|
dataset: string;
|
package/dist/server/app.js
CHANGED
|
@@ -7,13 +7,15 @@ import config from '../config.js';
|
|
|
7
7
|
import { isRecord } from '../utils/is-record.js';
|
|
8
8
|
import { isEventType, isGroqContextOptions, } from '../utils/types.js';
|
|
9
9
|
import { handleInvokeRequest } from './handlers/invoke.js';
|
|
10
|
-
const app = (host, port, logger, executionOptions) => {
|
|
10
|
+
const app = (host, port, logger, validateResources, executionOptions) => {
|
|
11
11
|
const requestListener = async (req, res) => {
|
|
12
12
|
res.setHeader('Content-Type', 'application/json');
|
|
13
13
|
switch (true) {
|
|
14
14
|
case req.url === '/blueprint': {
|
|
15
15
|
try {
|
|
16
|
-
const { parsedBlueprint, projectId, organizationId } = await readLocalBlueprint(logger
|
|
16
|
+
const { parsedBlueprint, projectId, organizationId } = await readLocalBlueprint(logger, {
|
|
17
|
+
resources: validateResources,
|
|
18
|
+
});
|
|
17
19
|
res.setHeader('Content-Type', 'application/json');
|
|
18
20
|
res.writeHead(200);
|
|
19
21
|
res.end(JSON.stringify({ parsedBlueprint, projectId, organizationId })); // Use blueprint directly
|
|
@@ -42,7 +44,7 @@ const app = (host, port, logger, executionOptions) => {
|
|
|
42
44
|
delete context.clientOptions.token;
|
|
43
45
|
}
|
|
44
46
|
}
|
|
45
|
-
const result = await handleInvokeRequest(functionName, event, metadata, context, logger, executionOptions);
|
|
47
|
+
const result = await handleInvokeRequest(functionName, event, metadata, context, logger, validateResources, executionOptions);
|
|
46
48
|
// Add Server-Timing header
|
|
47
49
|
const timingHeaders = [];
|
|
48
50
|
for (const [key, value] of Object.entries(result.timings)) {
|
|
@@ -230,7 +232,7 @@ const app = (host, port, logger, executionOptions) => {
|
|
|
230
232
|
const wss = new WebSocketServer({ port: 8974 });
|
|
231
233
|
wss.on('connection', async function connection(ws) {
|
|
232
234
|
ws.on('error', console.error);
|
|
233
|
-
const { fileInfo } = await readLocalBlueprint(logger);
|
|
235
|
+
const { fileInfo } = await readLocalBlueprint(logger, { resources: validateResources });
|
|
234
236
|
watchFile(fileInfo.blueprintFilePath, { interval: 2007 }, async () => {
|
|
235
237
|
ws.send('reload-blueprint');
|
|
236
238
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Logger } from '../../utils/logger.js';
|
|
2
2
|
import type { InvocationResponse, InvokeContextOptions, InvokeExecutionOptions, InvokePayloadMetadata } from '../../utils/types.js';
|
|
3
|
-
export declare function handleInvokeRequest(functionName: string, event: Record<string, unknown>, metadata: InvokePayloadMetadata, context: InvokeContextOptions, logger: ReturnType<typeof Logger>, executionOptions?: Partial<InvokeExecutionOptions>): Promise<InvocationResponse & {
|
|
3
|
+
export declare function handleInvokeRequest(functionName: string, event: Record<string, unknown>, metadata: InvokePayloadMetadata, context: InvokeContextOptions, logger: ReturnType<typeof Logger>, validateResources: boolean, executionOptions?: Partial<InvokeExecutionOptions>): Promise<InvocationResponse & {
|
|
4
4
|
timings: Record<string, number>;
|
|
5
5
|
}>;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { readLocalBlueprint } from '../../actions/blueprints/blueprint.js';
|
|
2
2
|
import { findFunctionInBlueprint } from '../../utils/find-function.js';
|
|
3
3
|
import invoke from '../../utils/invoke-local.js';
|
|
4
|
-
export async function handleInvokeRequest(functionName, event, metadata, context, logger, executionOptions) {
|
|
4
|
+
export async function handleInvokeRequest(functionName, event, metadata, context, logger, validateResources, executionOptions) {
|
|
5
5
|
const start = performance.now();
|
|
6
|
-
const { parsedBlueprint } = await readLocalBlueprint(logger);
|
|
6
|
+
const { parsedBlueprint } = await readLocalBlueprint(logger, { resources: validateResources });
|
|
7
7
|
const resource = findFunctionInBlueprint(parsedBlueprint, functionName);
|
|
8
8
|
const readBlueprintTime = performance.now() - start;
|
|
9
9
|
const payload = {
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export type SubscribeFunc = (fn: () => void) => void
|
|
2
|
+
|
|
3
|
+
export interface ServerAPI {
|
|
4
|
+
blueprint(): Promise<void>
|
|
5
|
+
document({
|
|
6
|
+
projectId,
|
|
7
|
+
dataset,
|
|
8
|
+
docId,
|
|
9
|
+
}: {
|
|
10
|
+
projectId: string
|
|
11
|
+
dataset: string
|
|
12
|
+
docId: string
|
|
13
|
+
}): Promise<void>
|
|
14
|
+
invoke({
|
|
15
|
+
context,
|
|
16
|
+
event,
|
|
17
|
+
metadata,
|
|
18
|
+
}: {
|
|
19
|
+
context: unknown
|
|
20
|
+
event: unknown
|
|
21
|
+
metadata: unknown
|
|
22
|
+
}): Promise<void>
|
|
23
|
+
projects(): Promise<void>
|
|
24
|
+
datasets(selectedProject: string): Promise<void>
|
|
25
|
+
organizations(): Promise<void>
|
|
26
|
+
mediaLibraries(selectedOrganization: string): Promise<void>
|
|
27
|
+
asset({
|
|
28
|
+
organizationId,
|
|
29
|
+
mediaLibraryId,
|
|
30
|
+
docId,
|
|
31
|
+
}: {
|
|
32
|
+
organizationId: string
|
|
33
|
+
mediaLibraryId: string
|
|
34
|
+
docId: string
|
|
35
|
+
}): Promise<void>
|
|
36
|
+
store: Record<string, unknown> & {subscribe: SubscribeFunc; unsubscribe: SubscribeFunc}
|
|
37
|
+
subscribe: SubscribeFunc
|
|
38
|
+
unsubscribe: SubscribeFunc
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export default function API(): ServerAPI
|
|
@@ -4,6 +4,7 @@ import {Store} from './vendor/vendor.bundle.js'
|
|
|
4
4
|
// list of events to simulate
|
|
5
5
|
const events = ['create', 'update', 'delete'].map((e) => ({name: e}))
|
|
6
6
|
|
|
7
|
+
/** @type {Record<string, unknown>} */
|
|
7
8
|
// eslint-disable-next-line new-cap
|
|
8
9
|
const store = Store({events, selectedEvent: events[0].name})
|
|
9
10
|
|
|
@@ -23,6 +24,12 @@ export default function API() {
|
|
|
23
24
|
}
|
|
24
25
|
}
|
|
25
26
|
|
|
27
|
+
/**
|
|
28
|
+
* @param {object} params
|
|
29
|
+
* @param {unknown} params.context
|
|
30
|
+
* @param {unknown} params.event
|
|
31
|
+
* @param {unknown} params.metadata
|
|
32
|
+
*/
|
|
26
33
|
function invoke({context, event, metadata}) {
|
|
27
34
|
store.inprogress = true
|
|
28
35
|
const start = Date.now()
|
|
@@ -31,7 +38,7 @@ function invoke({context, event, metadata}) {
|
|
|
31
38
|
func: store.selectedIndex,
|
|
32
39
|
metadata,
|
|
33
40
|
}
|
|
34
|
-
fetch('/invoke', {
|
|
41
|
+
return fetch('/invoke', {
|
|
35
42
|
body: JSON.stringify(payload),
|
|
36
43
|
headers: {
|
|
37
44
|
'Content-Type': 'application/json',
|
|
@@ -52,7 +59,7 @@ function invoke({context, event, metadata}) {
|
|
|
52
59
|
}
|
|
53
60
|
|
|
54
61
|
function blueprint() {
|
|
55
|
-
fetch('/blueprint')
|
|
62
|
+
return fetch('/blueprint')
|
|
56
63
|
.then((response) => response.json())
|
|
57
64
|
.then((blueprint) => {
|
|
58
65
|
const {parsedBlueprint, projectId, organizationId} = blueprint
|
|
@@ -72,7 +79,7 @@ function blueprint() {
|
|
|
72
79
|
}
|
|
73
80
|
|
|
74
81
|
function projects() {
|
|
75
|
-
fetch('/projects')
|
|
82
|
+
return fetch('/projects')
|
|
76
83
|
.then((response) => response.json())
|
|
77
84
|
.then(async (projects) => {
|
|
78
85
|
store.projects = projects
|
|
@@ -84,8 +91,11 @@ function projects() {
|
|
|
84
91
|
})
|
|
85
92
|
}
|
|
86
93
|
|
|
94
|
+
/**
|
|
95
|
+
* @param {string} selectedProject
|
|
96
|
+
*/
|
|
87
97
|
function datasets(selectedProject) {
|
|
88
|
-
fetch(`/datasets?project=${selectedProject}`)
|
|
98
|
+
return fetch(`/datasets?project=${selectedProject}`)
|
|
89
99
|
.then((response) => response.json())
|
|
90
100
|
.then((datasets) => {
|
|
91
101
|
store.datasets = datasets
|
|
@@ -96,6 +106,12 @@ function datasets(selectedProject) {
|
|
|
96
106
|
})
|
|
97
107
|
}
|
|
98
108
|
|
|
109
|
+
/**
|
|
110
|
+
* @param {object} params
|
|
111
|
+
* @param {string} params.projectId
|
|
112
|
+
* @param {string} params.dataset
|
|
113
|
+
* @param {string} params.docId
|
|
114
|
+
*/
|
|
99
115
|
function document({projectId, dataset, docId}) {
|
|
100
116
|
return fetch(`/document?project=${projectId}&dataset=${dataset}&doc=${docId}`)
|
|
101
117
|
.then((response) => response.json())
|
|
@@ -108,7 +124,7 @@ function document({projectId, dataset, docId}) {
|
|
|
108
124
|
}
|
|
109
125
|
|
|
110
126
|
function organizations() {
|
|
111
|
-
fetch('/organizations')
|
|
127
|
+
return fetch('/organizations')
|
|
112
128
|
.then((response) => response.json())
|
|
113
129
|
.then(async (organizations) => {
|
|
114
130
|
store.organizations = organizations
|
|
@@ -123,7 +139,7 @@ function organizations() {
|
|
|
123
139
|
}
|
|
124
140
|
|
|
125
141
|
function mediaLibraries(selectedOrganization) {
|
|
126
|
-
fetch(`/media-libraries?organization=${selectedOrganization}`)
|
|
142
|
+
return fetch(`/media-libraries?organization=${selectedOrganization}`)
|
|
127
143
|
.then((response) => response.json())
|
|
128
144
|
.then((mediaLibraries) => {
|
|
129
145
|
store.mediaLibraries = mediaLibraries
|
|
@@ -136,6 +152,13 @@ function mediaLibraries(selectedOrganization) {
|
|
|
136
152
|
})
|
|
137
153
|
}
|
|
138
154
|
|
|
155
|
+
/**
|
|
156
|
+
*
|
|
157
|
+
* @param {object} params
|
|
158
|
+
* @param {string} params.organizationId
|
|
159
|
+
* @param {string} params.mediaLibraryId
|
|
160
|
+
* @param {string} params.docId
|
|
161
|
+
*/
|
|
139
162
|
function asset({organizationId, mediaLibraryId, docId}) {
|
|
140
163
|
return fetch(`/asset?organization=${organizationId}&medialibrary=${mediaLibraryId}&doc=${docId}`)
|
|
141
164
|
.then((response) => response.json())
|
|
@@ -56,18 +56,6 @@ form input {
|
|
|
56
56
|
</style>
|
|
57
57
|
<form class="gap-2 pad-l-3 pad-b-3 border-bottom">
|
|
58
58
|
<fieldset class="flex gap-2">
|
|
59
|
-
<legend class="config-label">Client Options</legend>
|
|
60
|
-
<div id="dynamic-dropdowns" class="flex gap-2"></div>
|
|
61
|
-
<select-dropdown
|
|
62
|
-
label="Event"
|
|
63
|
-
store-key="events"
|
|
64
|
-
selected-key="selectedEvent"
|
|
65
|
-
value-prop="name"
|
|
66
|
-
label-prop="name"
|
|
67
|
-
></select-dropdown>
|
|
68
|
-
<api-version></api-version>
|
|
69
|
-
<with-token></with-token>
|
|
70
|
-
<document-id></document-id>
|
|
71
59
|
</fieldset>
|
|
72
60
|
</form>
|
|
73
61
|
`
|
|
@@ -87,54 +75,72 @@ class FiltersComponent extends ApiBaseElement {
|
|
|
87
75
|
}
|
|
88
76
|
|
|
89
77
|
renderFilters = () => {
|
|
90
|
-
const docFunction = this.api.store.selectedFunctionType ===
|
|
78
|
+
const docFunction = this.api.store.selectedFunctionType === this.SANITY_FUNCTION_DOCUMENT
|
|
91
79
|
const mediaFunction = this.api.store.selectedFunctionType?.startsWith(
|
|
92
|
-
|
|
80
|
+
this.SANITY_FUNCTION_MEDIA_LIBRARY_ASSET,
|
|
93
81
|
)
|
|
82
|
+
const scheduleFunction = this.api.store.selectedFunctionType === this.SANITY_FUNCTION_SCHEDULE
|
|
83
|
+
|
|
84
|
+
const container = this.shadowRoot.querySelector('fieldset')
|
|
85
|
+
container.innerHTML = this.buildFilters(docFunction, mediaFunction, scheduleFunction)
|
|
86
|
+
}
|
|
94
87
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
88
|
+
buildFilters = (docFunction, mediaFunction, scheduleFunction) => {
|
|
89
|
+
return `
|
|
90
|
+
<legend class="config-label">Client Options</legend>
|
|
91
|
+
<div id="dynamic-dropdowns" class="flex gap-2">
|
|
92
|
+
${
|
|
93
|
+
docFunction || scheduleFunction
|
|
94
|
+
? `<select-dropdown
|
|
95
|
+
label="Project"
|
|
96
|
+
store-key="projects"
|
|
97
|
+
selected-key="selectedProject"
|
|
98
|
+
value-prop="id"
|
|
99
|
+
label-prop="displayName"
|
|
100
|
+
trigger-fetch
|
|
101
|
+
></select-dropdown>
|
|
102
|
+
<select-dropdown
|
|
103
|
+
label="Dataset"
|
|
104
|
+
store-key="datasets"
|
|
105
|
+
selected-key="selectedDataset"
|
|
106
|
+
value-prop="name"
|
|
107
|
+
label-prop="name"
|
|
108
|
+
subscribe-to="selectedProject"
|
|
109
|
+
></select-dropdown>`
|
|
110
|
+
: `
|
|
111
|
+
<select-dropdown
|
|
112
|
+
label="Organization"
|
|
113
|
+
store-key="organizations"
|
|
114
|
+
selected-key="selectedOrganization"
|
|
115
|
+
value-prop="id"
|
|
116
|
+
label-prop="name"
|
|
117
|
+
trigger-fetch
|
|
118
|
+
></select-dropdown>
|
|
119
|
+
<select-dropdown
|
|
120
|
+
label="Media Library"
|
|
121
|
+
store-key="mediaLibraries"
|
|
122
|
+
selected-key="selectedMediaLibrary"
|
|
123
|
+
value-prop="id"
|
|
124
|
+
label-prop="id"
|
|
125
|
+
subscribe-to="selectedOrganization"
|
|
126
|
+
></select-dropdown>`
|
|
127
|
+
}
|
|
128
|
+
</div>
|
|
129
|
+
${
|
|
130
|
+
docFunction || mediaFunction
|
|
131
|
+
? `<select-dropdown
|
|
132
|
+
label="Event"
|
|
133
|
+
store-key="events"
|
|
134
|
+
selected-key="selectedEvent"
|
|
135
|
+
value-prop="name"
|
|
136
|
+
label-prop="name"
|
|
137
|
+
></select-dropdown>`
|
|
138
|
+
: ''
|
|
137
139
|
}
|
|
140
|
+
<api-version></api-version>
|
|
141
|
+
<with-token></with-token>
|
|
142
|
+
${docFunction || mediaFunction ? `<document-id></document-id>` : ''}
|
|
143
|
+
`
|
|
138
144
|
}
|
|
139
145
|
|
|
140
146
|
disconnectedCallback() {
|
|
@@ -78,7 +78,7 @@ class FunctionList extends ApiBaseElement {
|
|
|
78
78
|
})
|
|
79
79
|
.join('')
|
|
80
80
|
} else {
|
|
81
|
-
this.list.innerHTML = '<option class="pad-2">No
|
|
81
|
+
this.list.innerHTML = '<option class="pad-2">No Functions found</li>'
|
|
82
82
|
this.select.innerHTML = '<option>No blueprint.json file found</option>'
|
|
83
83
|
}
|
|
84
84
|
}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
/* globals customElements document */
|
|
2
2
|
|
|
3
|
-
import {basicSetup, EditorView, json} from '../vendor/vendor.bundle.js'
|
|
3
|
+
import {basicSetup, Compartment, EditorView, json} from '../vendor/vendor.bundle.js'
|
|
4
4
|
import {ApiBaseElement} from './api-base.js'
|
|
5
5
|
import {sanityCodeMirrorTheme} from './codemirror-theme.js'
|
|
6
6
|
import {getSharedStyleSheets} from './shared-styles.js'
|
|
7
7
|
|
|
8
|
+
const editableCompartment = new Compartment()
|
|
9
|
+
|
|
8
10
|
const template = document.createElement('template')
|
|
9
11
|
template.innerHTML = `
|
|
10
12
|
<style>
|
|
@@ -73,8 +75,32 @@ class PayloadPanel extends ApiBaseElement {
|
|
|
73
75
|
|
|
74
76
|
this.api.subscribe(this.updatePayload, ['document'])
|
|
75
77
|
this.api.subscribe(this.updateSelectedEvent, ['selectedEvent'])
|
|
78
|
+
this.api.subscribe(this.updateCodeMirror, ['selectedFunctionType'])
|
|
76
79
|
}
|
|
77
80
|
|
|
81
|
+
updateCodeMirror = ({selectedFunctionType}) => {
|
|
82
|
+
if (selectedFunctionType === this.SANITY_FUNCTION_SCHEDULE) {
|
|
83
|
+
this.api.store.beforePayload.dispatch({
|
|
84
|
+
effects: editableCompartment.reconfigure(EditorView.editable.of(false)),
|
|
85
|
+
})
|
|
86
|
+
this.api.store.afterPayload.dispatch({
|
|
87
|
+
effects: editableCompartment.reconfigure(EditorView.editable.of(false)),
|
|
88
|
+
})
|
|
89
|
+
this.api.store.payload.dispatch({
|
|
90
|
+
effects: editableCompartment.reconfigure(EditorView.editable.of(false)),
|
|
91
|
+
})
|
|
92
|
+
} else {
|
|
93
|
+
this.api.store.beforePayload.dispatch({
|
|
94
|
+
effects: editableCompartment.reconfigure(EditorView.editable.of(true)),
|
|
95
|
+
})
|
|
96
|
+
this.api.store.afterPayload.dispatch({
|
|
97
|
+
effects: editableCompartment.reconfigure(EditorView.editable.of(true)),
|
|
98
|
+
})
|
|
99
|
+
this.api.store.payload.dispatch({
|
|
100
|
+
effects: editableCompartment.reconfigure(EditorView.editable.of(true)),
|
|
101
|
+
})
|
|
102
|
+
}
|
|
103
|
+
}
|
|
78
104
|
updatePayload = ({document}) => {
|
|
79
105
|
if (!document) return
|
|
80
106
|
|
|
@@ -93,8 +119,6 @@ class PayloadPanel extends ApiBaseElement {
|
|
|
93
119
|
view.dispatch(transaction)
|
|
94
120
|
}
|
|
95
121
|
updateSelectedEvent = ({selectedEvent}) => {
|
|
96
|
-
console.log('updateSelectedEvent', selectedEvent)
|
|
97
|
-
|
|
98
122
|
const payloadContainer = this.shadowRoot.querySelector('#payloadContainer')
|
|
99
123
|
const deltaPayloadContainer = this.shadowRoot.querySelector('#deltaPayloadContainer')
|
|
100
124
|
|
|
@@ -113,7 +137,12 @@ class PayloadPanel extends ApiBaseElement {
|
|
|
113
137
|
function attachEditorView(parent) {
|
|
114
138
|
return new EditorView({
|
|
115
139
|
doc: '\n\n\n\n',
|
|
116
|
-
extensions: [
|
|
140
|
+
extensions: [
|
|
141
|
+
basicSetup,
|
|
142
|
+
json(),
|
|
143
|
+
sanityCodeMirrorTheme,
|
|
144
|
+
editableCompartment.of(EditorView.editable.of(false)),
|
|
145
|
+
],
|
|
117
146
|
parent,
|
|
118
147
|
})
|
|
119
148
|
}
|