@sanity/runtime-cli 1.5.0 → 1.8.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 +184 -122
- package/dist/actions/blueprints/blueprint.d.ts +24 -7
- package/dist/actions/blueprints/blueprint.js +114 -58
- package/dist/actions/blueprints/logs.d.ts +3 -0
- package/dist/actions/blueprints/logs.js +24 -0
- package/dist/actions/blueprints/projects.d.ts +5 -0
- package/dist/actions/blueprints/projects.js +21 -0
- package/dist/actions/blueprints/resources.d.ts +13 -0
- package/dist/actions/blueprints/resources.js +37 -0
- package/dist/actions/blueprints/stacks.js +1 -1
- package/dist/commands/blueprints/add.d.ts +10 -0
- package/dist/commands/blueprints/add.js +67 -0
- package/dist/commands/blueprints/config.d.ts +9 -0
- package/dist/commands/blueprints/config.js +72 -0
- package/dist/commands/blueprints/deploy.js +13 -12
- package/dist/commands/blueprints/info.js +1 -1
- package/dist/commands/blueprints/init.d.ts +6 -0
- package/dist/commands/blueprints/init.js +56 -0
- package/dist/commands/blueprints/logs.js +24 -64
- package/dist/commands/blueprints/stacks.js +3 -15
- package/dist/commands/functions/invoke.d.ts +1 -1
- package/dist/commands/functions/invoke.js +9 -7
- package/dist/commands/functions/logs.d.ts +1 -1
- package/dist/commands/functions/logs.js +21 -12
- package/dist/commands/functions/test.d.ts +1 -1
- package/dist/commands/functions/test.js +25 -16
- package/dist/config.d.ts +1 -0
- package/dist/config.js +10 -4
- package/dist/server/app.js +2 -2
- package/dist/server/static/api.js +43 -38
- package/dist/server/static/components/api-base.js +7 -6
- package/dist/server/static/components/function-list.js +48 -44
- package/dist/server/static/components/network-spinner.js +7 -6
- package/dist/server/static/components/payload-panel.js +36 -32
- package/dist/server/static/components/response-panel.js +64 -50
- package/dist/server/static/vendor/vendor.bundle.js +1029 -913
- package/dist/utils/display/blueprints-formatting.d.ts +3 -1
- package/dist/utils/display/blueprints-formatting.js +27 -2
- package/dist/utils/display/logs-formatting.d.ts +5 -0
- package/dist/utils/display/logs-formatting.js +50 -0
- package/dist/utils/find-function.d.ts +2 -0
- package/dist/utils/find-function.js +6 -0
- package/dist/utils/types.d.ts +0 -1
- package/oclif.manifest.json +120 -31
- package/package.json +14 -10
- package/dist/server/static/static/api.js +0 -53
- package/dist/server/static/static/components/api-base.js +0 -10
- package/dist/server/static/static/components/function-list.js +0 -54
- package/dist/server/static/static/components/network-spinner.js +0 -71
- package/dist/server/static/static/components/payload-panel.js +0 -45
- package/dist/server/static/static/components/response-panel.js +0 -83
- package/dist/server/static/static/vendor/vendor.bundle.js +0 -26879
- package/dist/utils/spinner.d.ts +0 -9
- package/dist/utils/spinner.js +0 -25
- /package/dist/server/static/{static/components → components}/app.css +0 -0
- /package/dist/server/static/{static/index.html → index.html} +0 -0
- /package/dist/server/static/{static/sanity-logo-sm.svg → sanity-logo-sm.svg} +0 -0
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { Command, Flags } from '@oclif/core';
|
|
2
|
+
import { Spinner } from 'picospinner';
|
|
2
3
|
import { readBlueprintOnDisk } from '../../actions/blueprints/blueprint.js';
|
|
3
|
-
import { getLogs, streamLogs } from '../../actions/blueprints/logs.js';
|
|
4
|
+
import { findNewestLogTimestamp, getLogs, getRecentLogs, isNewerLog, streamLogs, } from '../../actions/blueprints/logs.js';
|
|
4
5
|
import config from '../../config.js';
|
|
5
6
|
import { formatTitle } from '../../utils/display/blueprints-formatting.js';
|
|
6
|
-
import {
|
|
7
|
-
import
|
|
7
|
+
import { bold, red, yellow } from '../../utils/display/colors.js';
|
|
8
|
+
import { formatLogEntry, formatLogsByDay, organizeLogsByDay, } from '../../utils/display/logs-formatting.js';
|
|
8
9
|
export default class Logs extends Command {
|
|
9
10
|
static description = 'Display logs for a Blueprint stack';
|
|
10
11
|
static examples = [
|
|
@@ -22,11 +23,9 @@ export default class Logs extends Command {
|
|
|
22
23
|
async run() {
|
|
23
24
|
const { flags } = await this.parse(Logs);
|
|
24
25
|
const watchMode = flags.watch;
|
|
25
|
-
const s = new Spinner();
|
|
26
26
|
try {
|
|
27
27
|
const { errors, deployedStack } = await readBlueprintOnDisk({ getStack: true });
|
|
28
28
|
if (errors.length > 0) {
|
|
29
|
-
// printErrors(errors)
|
|
30
29
|
this.log('Blueprint parse errors:');
|
|
31
30
|
console.dir(errors, { depth: null });
|
|
32
31
|
return;
|
|
@@ -34,53 +33,37 @@ export default class Logs extends Command {
|
|
|
34
33
|
if (!deployedStack)
|
|
35
34
|
this.error('Stack not found'); // returns
|
|
36
35
|
const { id: stackId, projectId, name } = deployedStack;
|
|
36
|
+
const spinner = new Spinner(`Fetching logs for stack ${yellow(`<${stackId}>`)}`);
|
|
37
|
+
spinner.start();
|
|
37
38
|
if (watchMode) {
|
|
38
|
-
// recent logs
|
|
39
|
-
s.start(`Fetching recent logs for stack ${stackId}`);
|
|
40
39
|
const { ok, logs, error } = await getLogs(stackId, projectId, config.token);
|
|
41
40
|
if (!ok) {
|
|
42
|
-
|
|
41
|
+
spinner.fail(`${red('Failed')} to retrieve logs`);
|
|
43
42
|
this.log(`Error: ${error || 'Unknown error'}`);
|
|
44
43
|
return;
|
|
45
44
|
}
|
|
46
|
-
|
|
45
|
+
spinner.stop(); // stop and remove the spinner
|
|
46
|
+
this.log(`${formatTitle('Blueprint', name)} ${bold('Live')} Logs`);
|
|
47
47
|
if (logs.length > 0) {
|
|
48
48
|
this.log('\nMost recent logs:');
|
|
49
|
-
const
|
|
50
|
-
const recentLogs = sortedLogs.slice(-10);
|
|
49
|
+
const recentLogs = getRecentLogs(logs);
|
|
51
50
|
for (const log of recentLogs) {
|
|
52
|
-
|
|
53
|
-
const time = date.toLocaleTimeString();
|
|
54
|
-
const day = date.toLocaleDateString();
|
|
55
|
-
this.log(` ${bold(day)} ${yellow(time)} ${log.message}`);
|
|
51
|
+
this.log(` ${formatLogEntry(log)}`);
|
|
56
52
|
}
|
|
57
53
|
}
|
|
58
54
|
else {
|
|
59
55
|
this.log(`No recent logs found for stack ${yellow(stackId)}`);
|
|
60
56
|
}
|
|
61
57
|
const onOpen = () => {
|
|
62
|
-
this.log(
|
|
63
|
-
this.log(`Press ${bold('Ctrl+C')} to stop\n`);
|
|
58
|
+
this.log(`Watching for new logs... ${bold('ctrl+c')} to stop`);
|
|
64
59
|
};
|
|
65
|
-
let newestTimestamp =
|
|
66
|
-
if (logs.length > 0) {
|
|
67
|
-
for (const log of logs) {
|
|
68
|
-
const timestamp = new Date(log.timestamp).getTime();
|
|
69
|
-
if (timestamp > newestTimestamp) {
|
|
70
|
-
newestTimestamp = timestamp;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
60
|
+
let newestTimestamp = findNewestLogTimestamp(logs);
|
|
74
61
|
const renderLog = (log) => {
|
|
75
|
-
|
|
76
|
-
if (logTimestamp <= newestTimestamp) {
|
|
62
|
+
if (!isNewerLog(log, newestTimestamp)) {
|
|
77
63
|
return;
|
|
78
64
|
}
|
|
79
|
-
newestTimestamp =
|
|
80
|
-
|
|
81
|
-
const time = date.toLocaleTimeString();
|
|
82
|
-
const day = date.toLocaleDateString();
|
|
83
|
-
this.log(`${green('>')} ${bold(day)} ${yellow(time)} ${log.message}`);
|
|
65
|
+
newestTimestamp = new Date(log.timestamp).getTime();
|
|
66
|
+
this.log(formatLogEntry(log, true));
|
|
84
67
|
};
|
|
85
68
|
this.debug(`${yellow('Debug:')} Connecting to streaming endpoint for stack ${stackId}...`);
|
|
86
69
|
streamLogs(stackId, projectId, config.token, renderLog, onOpen, (error) => this.log(`${red('Error:')} ${error}`));
|
|
@@ -88,49 +71,26 @@ export default class Logs extends Command {
|
|
|
88
71
|
// hold the line until the user terminates with Ctrl+C
|
|
89
72
|
});
|
|
90
73
|
}
|
|
91
|
-
s.start(`Fetching logs for stack ${stackId}`);
|
|
92
74
|
const { ok, logs, error } = await getLogs(stackId, projectId, config.token);
|
|
93
75
|
if (!ok) {
|
|
94
|
-
|
|
76
|
+
spinner.fail(`${red('Failed')} to retrieve logs`);
|
|
95
77
|
this.log(`Error: ${error || 'Unknown error'}`);
|
|
96
78
|
return;
|
|
97
79
|
}
|
|
98
80
|
if (logs.length === 0) {
|
|
99
|
-
|
|
81
|
+
spinner.info(`No logs found for stack ${stackId}`);
|
|
100
82
|
return;
|
|
101
83
|
}
|
|
102
|
-
|
|
84
|
+
spinner.succeed(`${formatTitle('Blueprint', name)} Logs`);
|
|
103
85
|
this.log(`Found ${bold(logs.length.toString())} log entries for stack ${yellow(stackId)}\n`);
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
const day = date.toLocaleDateString();
|
|
108
|
-
if (!logsByDay.has(day)) {
|
|
109
|
-
logsByDay.set(day, []);
|
|
110
|
-
}
|
|
111
|
-
logsByDay.get(day)?.push(log);
|
|
112
|
-
}
|
|
113
|
-
const sortedDays = Array.from(logsByDay.keys()).sort((a, b) => {
|
|
114
|
-
return new Date(a).getTime() - new Date(b).getTime();
|
|
115
|
-
});
|
|
116
|
-
for (const day of sortedDays) {
|
|
117
|
-
this.log(`${blue('Date:')} ${bold(day)}`);
|
|
118
|
-
const dayLogs = logsByDay.get(day) || [];
|
|
119
|
-
dayLogs.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
|
|
120
|
-
for (const [i, log] of dayLogs.entries()) {
|
|
121
|
-
const date = new Date(log.timestamp);
|
|
122
|
-
const time = date.toLocaleTimeString();
|
|
123
|
-
const isLast = i === dayLogs.length - 1;
|
|
124
|
-
this.log(` ${isLast ? '└─' : '├─'} ${yellow(time)} ${log.message}`);
|
|
125
|
-
}
|
|
126
|
-
// new line between days
|
|
127
|
-
this.log('');
|
|
128
|
-
}
|
|
86
|
+
// Organize and format logs by day
|
|
87
|
+
const logsByDay = organizeLogsByDay(logs);
|
|
88
|
+
this.log(formatLogsByDay(logsByDay));
|
|
129
89
|
}
|
|
130
90
|
catch (err) {
|
|
131
|
-
|
|
91
|
+
this.warn('Failed to retrieve logs');
|
|
132
92
|
if (err instanceof Error) {
|
|
133
|
-
this.
|
|
93
|
+
this.error(`Error: ${err.message}`);
|
|
134
94
|
}
|
|
135
95
|
}
|
|
136
96
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Command } from '@oclif/core';
|
|
2
2
|
import { readBlueprintOnDisk } from '../../actions/blueprints/blueprint.js';
|
|
3
3
|
import { listStacks } from '../../actions/blueprints/stacks.js';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { formatStacksListing } from '../../utils/display/blueprints-formatting.js';
|
|
5
|
+
import { bold, yellow } from '../../utils/display/colors.js';
|
|
6
6
|
export default class Stacks extends Command {
|
|
7
7
|
static description = 'List all Blueprint stacks';
|
|
8
8
|
static examples = ['<%= config.bin %> <%= command.id %>'];
|
|
@@ -23,18 +23,6 @@ export default class Stacks extends Command {
|
|
|
23
23
|
return;
|
|
24
24
|
}
|
|
25
25
|
this.log(`${bold('Project')} <${yellow(projectId)}> ${bold('Stacks')} :\n`);
|
|
26
|
-
|
|
27
|
-
const isCurrentStack = stackId === stack.id;
|
|
28
|
-
const stackName = isCurrentStack ? boldnblue(stack.name) : bold(stack.name);
|
|
29
|
-
this.log(`${stackName} <${yellow(stack.id)}>${isCurrentStack ? ' (current)' : ''}`);
|
|
30
|
-
if (stack.createdAt) {
|
|
31
|
-
this.log(` Created: ${formatDate(stack.createdAt)}`);
|
|
32
|
-
}
|
|
33
|
-
if (stack.updatedAt) {
|
|
34
|
-
this.log(` Updated: ${formatDate(stack.updatedAt)}`);
|
|
35
|
-
}
|
|
36
|
-
this.log(` ${stack.resources.length} resource${stack.resources.length === 1 ? '' : 's'}`);
|
|
37
|
-
this.log('');
|
|
38
|
-
}
|
|
26
|
+
this.log(formatStacksListing(stacks, stackId));
|
|
39
27
|
}
|
|
40
28
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Command } from '@oclif/core';
|
|
2
2
|
export default class Invoke extends Command {
|
|
3
3
|
static args: {
|
|
4
|
-
|
|
4
|
+
name: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
5
5
|
};
|
|
6
6
|
static description: string;
|
|
7
7
|
static examples: string[];
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { Args, Command, Flags } from '@oclif/core';
|
|
2
|
+
import { Spinner } from 'picospinner';
|
|
2
3
|
import { readBlueprintOnDisk } from '../../actions/blueprints/blueprint.js';
|
|
3
4
|
import { invoke } from '../../actions/functions/invoke.js';
|
|
4
5
|
import config from '../../config.js';
|
|
5
6
|
import { red } from '../../utils/display/colors.js';
|
|
6
|
-
import
|
|
7
|
+
import { findFunctionByName } from '../../utils/find-function.js';
|
|
7
8
|
export default class Invoke extends Command {
|
|
8
9
|
static args = {
|
|
9
|
-
|
|
10
|
+
name: Args.string({ description: 'The name of the Sanity Function', required: true }),
|
|
10
11
|
};
|
|
11
12
|
static description = 'Invoke a remote Sanity Function';
|
|
12
13
|
static examples = [
|
|
@@ -23,19 +24,20 @@ export default class Invoke extends Command {
|
|
|
23
24
|
};
|
|
24
25
|
async run() {
|
|
25
26
|
const { args, flags } = await this.parse(Invoke);
|
|
26
|
-
const
|
|
27
|
+
const spinner = new Spinner(`Invoking function "${args.name}"`);
|
|
27
28
|
const { deployedStack } = await readBlueprintOnDisk({ getStack: true });
|
|
28
29
|
if (!deployedStack)
|
|
29
30
|
this.error('Stack not found'); // returns
|
|
30
31
|
const { projectId } = deployedStack;
|
|
31
|
-
|
|
32
|
-
const
|
|
32
|
+
spinner.start();
|
|
33
|
+
const { externalId } = findFunctionByName(deployedStack, args.name);
|
|
34
|
+
const result = await invoke(externalId, { data: flags.data, file: flags.file }, { token: config.token, projectId });
|
|
33
35
|
if (result.ok) {
|
|
34
|
-
|
|
36
|
+
spinner.succeed(`Invocation of ${args.name} succeeded`);
|
|
35
37
|
this.log(JSON.stringify(result.json, null, 2));
|
|
36
38
|
}
|
|
37
39
|
else {
|
|
38
|
-
|
|
40
|
+
spinner.fail(`${red('Failed')} to invoke function`);
|
|
39
41
|
this.log(`Error: ${result.error || 'Unknown error'}`);
|
|
40
42
|
}
|
|
41
43
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Command } from '@oclif/core';
|
|
2
2
|
export default class Logs extends Command {
|
|
3
3
|
static args: {
|
|
4
|
-
|
|
4
|
+
name: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
5
5
|
};
|
|
6
6
|
static description: string;
|
|
7
7
|
static examples: string[];
|
|
@@ -1,38 +1,47 @@
|
|
|
1
1
|
import { Args, Command } from '@oclif/core';
|
|
2
|
+
import { Spinner } from 'picospinner';
|
|
2
3
|
import { readBlueprintOnDisk } from '../../actions/blueprints/blueprint.js';
|
|
3
4
|
import { logs } from '../../actions/functions/logs.js';
|
|
4
5
|
import config from '../../config.js';
|
|
5
6
|
import { bold, red, yellow } from '../../utils/display/colors.js';
|
|
6
|
-
import
|
|
7
|
+
import { findFunctionByName } from '../../utils/find-function.js';
|
|
7
8
|
export default class Logs extends Command {
|
|
8
9
|
static args = {
|
|
9
|
-
|
|
10
|
+
name: Args.string({ description: 'The name of the Sanity Function', required: true }),
|
|
10
11
|
};
|
|
11
12
|
static description = 'Retrieve logs for a Sanity Function';
|
|
12
13
|
static examples = ['<%= config.bin %> <%= command.id %> <ID>'];
|
|
13
14
|
async run() {
|
|
14
15
|
const { args } = await this.parse(Logs);
|
|
15
|
-
const
|
|
16
|
+
const spinner = new Spinner(`Finding logs for function "${args.name}"`);
|
|
16
17
|
const { deployedStack } = await readBlueprintOnDisk({ getStack: true });
|
|
17
18
|
if (!deployedStack)
|
|
18
19
|
this.error('Stack not found'); // returns
|
|
19
|
-
s.start(`Finding logs for function "${args.id}"`);
|
|
20
20
|
const { name, projectId } = deployedStack;
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
spinner.start();
|
|
22
|
+
const { externalId } = findFunctionByName(deployedStack, args.name);
|
|
23
|
+
const result = await logs(externalId, { token: config.token, projectId });
|
|
23
24
|
if (result.ok) {
|
|
24
|
-
|
|
25
|
+
spinner.succeed(`Found logs ${args.name} for blueprint "${name}"`);
|
|
25
26
|
for (const logGroup of result.logs) {
|
|
26
27
|
for (const log of logGroup.events) {
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
const
|
|
30
|
-
|
|
28
|
+
const { message, timestamp } = log;
|
|
29
|
+
// INFO log format: year month date hr min sec ms req uuid
|
|
30
|
+
const logPattern = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z\s+[0-9a-f-]+/;
|
|
31
|
+
if (logPattern.test(message)) {
|
|
32
|
+
const content = message.replace(logPattern, '').trim().replace(/^INFO/, '').trim();
|
|
33
|
+
if (content) {
|
|
34
|
+
const date = new Date(timestamp);
|
|
35
|
+
const time = date.toLocaleTimeString();
|
|
36
|
+
const day = date.toLocaleDateString();
|
|
37
|
+
this.log(` ${bold(day)} ${yellow(time)} ${content}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
31
40
|
}
|
|
32
41
|
}
|
|
33
42
|
}
|
|
34
43
|
else {
|
|
35
|
-
|
|
44
|
+
spinner.fail(`${red('Failed')} to retrieve logs`);
|
|
36
45
|
this.log(`Error: ${result.error || 'Unknown error'}`);
|
|
37
46
|
}
|
|
38
47
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Command } from '@oclif/core';
|
|
2
2
|
export default class Test extends Command {
|
|
3
3
|
static args: {
|
|
4
|
-
|
|
4
|
+
name: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
5
5
|
};
|
|
6
6
|
static description: string;
|
|
7
7
|
static examples: string[];
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { Args, Command, Flags } from '@oclif/core';
|
|
2
|
+
import { readBlueprintOnDisk } from '../../actions/blueprints/blueprint.js';
|
|
2
3
|
import { testAction } from '../../actions/functions/test.js';
|
|
4
|
+
import { findFunctionByName } from '../../utils/find-function.js';
|
|
3
5
|
export default class Test extends Command {
|
|
4
6
|
static args = {
|
|
5
|
-
|
|
7
|
+
name: Args.string({ description: 'The name of the Sanity Function', required: true }),
|
|
6
8
|
};
|
|
7
9
|
static description = 'Invoke a local Sanity Function';
|
|
8
10
|
static examples = [
|
|
9
|
-
`<%= config.bin %> <%= command.id %>
|
|
10
|
-
`<%= config.bin %> <%= command.id %>
|
|
11
|
-
`<%= config.bin %> <%= command.id %>
|
|
11
|
+
`<%= config.bin %> <%= command.id %> echo-fn --data '{ "id": 1 }'`,
|
|
12
|
+
`<%= config.bin %> <%= command.id %> echo-fn --file 'payload.json'`,
|
|
13
|
+
`<%= config.bin %> <%= command.id %> echo-fn --data '{ "id": 1 }' --timeout 60`,
|
|
12
14
|
];
|
|
13
15
|
static flags = {
|
|
14
16
|
data: Flags.string({ char: 'd', description: 'Data to send to the function', required: false }),
|
|
@@ -25,19 +27,26 @@ export default class Test extends Command {
|
|
|
25
27
|
};
|
|
26
28
|
async run() {
|
|
27
29
|
const { args, flags } = await this.parse(Test);
|
|
28
|
-
const {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
30
|
+
const { parsedBlueprint } = await readBlueprintOnDisk({ getStack: false });
|
|
31
|
+
try {
|
|
32
|
+
const func = findFunctionByName(parsedBlueprint, args.name);
|
|
33
|
+
const { json, logs, error } = await testAction(func.src, {
|
|
34
|
+
data: flags.data,
|
|
35
|
+
file: flags.file,
|
|
36
|
+
timeout: flags.timeout,
|
|
37
|
+
});
|
|
38
|
+
if (!error) {
|
|
39
|
+
this.log('Logs:');
|
|
40
|
+
this.log(logs);
|
|
41
|
+
this.log('Response:');
|
|
42
|
+
this.log(JSON.stringify(json, null, 2));
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
this.log(error.toString());
|
|
46
|
+
}
|
|
38
47
|
}
|
|
39
|
-
|
|
40
|
-
this.log(error
|
|
48
|
+
catch (error) {
|
|
49
|
+
this.log(`Error: ${error || 'Unknown error'}`);
|
|
41
50
|
}
|
|
42
51
|
}
|
|
43
52
|
}
|
package/dist/config.d.ts
CHANGED
package/dist/config.js
CHANGED
|
@@ -1,23 +1,29 @@
|
|
|
1
1
|
import { env } from 'node:process';
|
|
2
2
|
import getToken from './utils/get-token.js';
|
|
3
|
-
const nodeEnv = env.NODE_ENV ?? '
|
|
3
|
+
const nodeEnv = env.NODE_ENV ?? 'production';
|
|
4
4
|
const isTest = nodeEnv === 'test';
|
|
5
5
|
const isDev = nodeEnv === 'development';
|
|
6
6
|
const useProd = nodeEnv === 'production';
|
|
7
|
-
const
|
|
7
|
+
const apiUrls = {
|
|
8
8
|
production: 'https://api.sanity.io/',
|
|
9
9
|
staging: 'https://api.sanity.work/',
|
|
10
|
+
};
|
|
11
|
+
const apiUrl = new URL(apiUrls[nodeEnv] ?? apiUrls.production);
|
|
12
|
+
const functionsUrls = {
|
|
13
|
+
production: apiUrl.toString(),
|
|
14
|
+
staging: apiUrl.toString(),
|
|
10
15
|
default: 'http://localhost:4567',
|
|
11
16
|
};
|
|
12
17
|
const blueprintsUrls = {
|
|
13
|
-
production:
|
|
14
|
-
staging:
|
|
18
|
+
production: apiUrl.toString(),
|
|
19
|
+
staging: apiUrl.toString(),
|
|
15
20
|
default: 'http://blueprints/',
|
|
16
21
|
};
|
|
17
22
|
const functionsUrl = new URL(functionsUrls[nodeEnv] ?? functionsUrls.default);
|
|
18
23
|
const blueprintsUrl = new URL(blueprintsUrls[nodeEnv] ?? blueprintsUrls.default);
|
|
19
24
|
export default {
|
|
20
25
|
token: isDev || isTest ? 'token' : getToken({ prod: useProd }),
|
|
26
|
+
apiUrl,
|
|
21
27
|
server: {
|
|
22
28
|
functions: functionsUrl,
|
|
23
29
|
blueprints: blueprintsUrl,
|
package/dist/server/app.js
CHANGED
|
@@ -10,10 +10,10 @@ const app = (port) => {
|
|
|
10
10
|
switch (req.url) {
|
|
11
11
|
case '/blueprint': {
|
|
12
12
|
try {
|
|
13
|
-
const
|
|
13
|
+
const { parsedBlueprint } = await readBlueprintOnDisk({ getStack: false });
|
|
14
14
|
res.setHeader('Content-Type', 'application/json');
|
|
15
15
|
res.writeHead(200);
|
|
16
|
-
res.end(JSON.stringify(
|
|
16
|
+
res.end(JSON.stringify(parsedBlueprint));
|
|
17
17
|
}
|
|
18
18
|
catch {
|
|
19
19
|
res.writeHead(404);
|
|
@@ -1,48 +1,53 @@
|
|
|
1
1
|
/* eslint-disable n/no-unsupported-features/node-builtins */
|
|
2
|
-
import {
|
|
2
|
+
import {Store} from './vendor/vendor.bundle.js'
|
|
3
|
+
|
|
3
4
|
// eslint-disable-next-line new-cap
|
|
4
|
-
const store = Store()
|
|
5
|
+
const store = Store()
|
|
6
|
+
|
|
5
7
|
export default function API() {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
return {
|
|
9
|
+
blueprint,
|
|
10
|
+
invoke,
|
|
11
|
+
store,
|
|
12
|
+
subscribe: store.subscribe,
|
|
13
|
+
unsubscribe: store.unsubscribe,
|
|
14
|
+
}
|
|
13
15
|
}
|
|
16
|
+
|
|
14
17
|
function invoke(payloadText = '{}') {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
18
|
+
store.inprogress = true
|
|
19
|
+
const start = Date.now()
|
|
20
|
+
const payload = {
|
|
21
|
+
data: payloadText,
|
|
22
|
+
func: store.selectedIndex,
|
|
23
|
+
}
|
|
24
|
+
fetch('/invoke', {
|
|
25
|
+
body: JSON.stringify(payload),
|
|
26
|
+
headers: {
|
|
27
|
+
'Content-Type': 'application/json',
|
|
28
|
+
},
|
|
29
|
+
method: 'POST',
|
|
30
|
+
})
|
|
31
|
+
.then((response) => response.json())
|
|
32
|
+
.then((data) => {
|
|
33
|
+
store.inprogress = false
|
|
34
|
+
store.result = {
|
|
35
|
+
...data,
|
|
36
|
+
time: Date.now() - start,
|
|
37
|
+
}
|
|
27
38
|
})
|
|
28
|
-
.then((response) => response.json())
|
|
29
|
-
.then((data) => {
|
|
30
|
-
store.inprogress = false;
|
|
31
|
-
store.result = {
|
|
32
|
-
...data,
|
|
33
|
-
time: Date.now() - start,
|
|
34
|
-
};
|
|
35
|
-
});
|
|
36
39
|
}
|
|
40
|
+
|
|
37
41
|
function blueprint() {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
fetch('/blueprint')
|
|
43
|
+
.then((response) => response.json())
|
|
44
|
+
.then((blueprint) => {
|
|
45
|
+
const functions = blueprint?.resources.filter((r) => r.type.startsWith('sanity.function.'))
|
|
46
|
+
|
|
47
|
+
store.functions = functions
|
|
48
|
+
store.selectedIndex = functions[0].src
|
|
49
|
+
})
|
|
50
|
+
.catch(() => {
|
|
51
|
+
store.functions = []
|
|
44
52
|
})
|
|
45
|
-
.catch(() => {
|
|
46
|
-
store.functions = [];
|
|
47
|
-
});
|
|
48
53
|
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/* globals HTMLElement */
|
|
2
|
-
import apiConstructor from '../api.js'
|
|
3
|
-
const api = apiConstructor()
|
|
2
|
+
import apiConstructor from '../api.js'
|
|
3
|
+
const api = apiConstructor()
|
|
4
|
+
|
|
4
5
|
export class ApiBaseElement extends HTMLElement {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
constructor() {
|
|
7
|
+
super()
|
|
8
|
+
this.api = api
|
|
9
|
+
}
|
|
9
10
|
}
|
|
@@ -1,50 +1,54 @@
|
|
|
1
1
|
/* globals customElements */
|
|
2
|
-
import {
|
|
2
|
+
import {ApiBaseElement} from './api-base.js'
|
|
3
|
+
|
|
3
4
|
const template = `<ol class="hidden-lg" type="content"></ol>
|
|
4
5
|
<fieldset class="pad-sm hidden block-lg"><select></select></fieldset>
|
|
5
|
-
|
|
6
|
+
`
|
|
7
|
+
|
|
6
8
|
class FunctionList extends ApiBaseElement {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
this.select.innerHTML = '<option>No blueprint.json file found</option>';
|
|
33
|
-
}
|
|
34
|
-
};
|
|
35
|
-
connectedCallback() {
|
|
36
|
-
this.innerHTML = template;
|
|
37
|
-
this.list = this.querySelector('ol');
|
|
38
|
-
this.select = this.querySelector('select');
|
|
39
|
-
this.list.addEventListener('click', this.functionClicked);
|
|
40
|
-
this.select.addEventListener('change', this.functionSelected);
|
|
41
|
-
this.api.subscribe(this.renderFunctions, ['functions', 'selectedIndex']);
|
|
42
|
-
this.api.blueprint();
|
|
43
|
-
}
|
|
44
|
-
disconnectedCallback() {
|
|
45
|
-
this.list.removeEventListener('click', this.functionClicked);
|
|
46
|
-
this.select.removeEventListener('change', this.functionSelected);
|
|
47
|
-
this.api.unsubscribe(this.renderFunctions);
|
|
9
|
+
functionClicked = (event) => {
|
|
10
|
+
// eslint-disable-next-line unicorn/prefer-dom-node-text-content
|
|
11
|
+
const target = this.api.store.functions.find((func) => func.name === event.srcElement.innerText)
|
|
12
|
+
this.api.store.selectedIndex = target.src
|
|
13
|
+
}
|
|
14
|
+
functionSelected = (event) => {
|
|
15
|
+
this.api.store.selectedIndex = event.srcElement.value
|
|
16
|
+
}
|
|
17
|
+
renderFunctions = () => {
|
|
18
|
+
if (this.api.store.functions.length > 0) {
|
|
19
|
+
this.list.innerHTML = this.api.store.functions
|
|
20
|
+
.map((func) => {
|
|
21
|
+
const selected = this.api.store.selectedIndex === func.src ? 'selected' : ''
|
|
22
|
+
return `<li class="pad-sm ${selected}">${func.name}</li>`
|
|
23
|
+
})
|
|
24
|
+
.join('')
|
|
25
|
+
this.select.innerHTML = this.api.store.functions
|
|
26
|
+
.map((func) => {
|
|
27
|
+
const selected = this.api.store.selectedIndex === func.src ? 'selected' : ''
|
|
28
|
+
return `<option value="${func.src}" ${selected}>${func.name}</option>`
|
|
29
|
+
})
|
|
30
|
+
.join('')
|
|
31
|
+
} else {
|
|
32
|
+
this.list.innerHTML = '<option class="pad-sm">No blueprint.json file found</li>'
|
|
33
|
+
this.select.innerHTML = '<option>No blueprint.json file found</option>'
|
|
48
34
|
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
connectedCallback() {
|
|
38
|
+
this.innerHTML = template
|
|
39
|
+
this.list = this.querySelector('ol')
|
|
40
|
+
this.select = this.querySelector('select')
|
|
41
|
+
this.list.addEventListener('click', this.functionClicked)
|
|
42
|
+
this.select.addEventListener('change', this.functionSelected)
|
|
43
|
+
this.api.subscribe(this.renderFunctions, ['functions', 'selectedIndex'])
|
|
44
|
+
this.api.blueprint()
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
disconnectedCallback() {
|
|
48
|
+
this.list.removeEventListener('click', this.functionClicked)
|
|
49
|
+
this.select.removeEventListener('change', this.functionSelected)
|
|
50
|
+
this.api.unsubscribe(this.renderFunctions)
|
|
51
|
+
}
|
|
49
52
|
}
|
|
50
|
-
|
|
53
|
+
|
|
54
|
+
customElements.define('function-list', FunctionList)
|