@sanity/runtime-cli 1.0.2

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.
Files changed (50) hide show
  1. package/README.md +548 -0
  2. package/bin/dev.cmd +3 -0
  3. package/bin/dev.js +5 -0
  4. package/bin/run.cmd +3 -0
  5. package/bin/run.js +5 -0
  6. package/dist/actions/functions/dev.d.ts +1 -0
  7. package/dist/actions/functions/dev.js +5 -0
  8. package/dist/actions/functions/invoke.d.ts +2 -0
  9. package/dist/actions/functions/invoke.js +17 -0
  10. package/dist/actions/functions/logs.d.ts +1 -0
  11. package/dist/actions/functions/logs.js +14 -0
  12. package/dist/actions/functions/test.d.ts +2 -0
  13. package/dist/actions/functions/test.js +13 -0
  14. package/dist/commands/functions/dev.d.ts +9 -0
  15. package/dist/commands/functions/dev.js +15 -0
  16. package/dist/commands/functions/invoke.d.ts +13 -0
  17. package/dist/commands/functions/invoke.js +25 -0
  18. package/dist/commands/functions/logs.d.ts +9 -0
  19. package/dist/commands/functions/logs.js +14 -0
  20. package/dist/commands/functions/test.d.ts +14 -0
  21. package/dist/commands/functions/test.js +43 -0
  22. package/dist/config.d.ts +6 -0
  23. package/dist/config.js +9 -0
  24. package/dist/index.d.ts +5 -0
  25. package/dist/index.js +5 -0
  26. package/dist/server/app.d.ts +3 -0
  27. package/dist/server/app.js +36 -0
  28. package/dist/server/static/api.js +50 -0
  29. package/dist/server/static/components/api-base.js +10 -0
  30. package/dist/server/static/components/app.css +155 -0
  31. package/dist/server/static/components/function-list.js +49 -0
  32. package/dist/server/static/components/network-spinner.js +71 -0
  33. package/dist/server/static/components/payload-panel.js +45 -0
  34. package/dist/server/static/components/response-panel.js +83 -0
  35. package/dist/server/static/index.html +55 -0
  36. package/dist/server/static/sanity-logo-sm.svg +1 -0
  37. package/dist/server/static/vendor/vendor.bundle.js +26857 -0
  38. package/dist/utils/build-payload.d.ts +2 -0
  39. package/dist/utils/build-payload.js +15 -0
  40. package/dist/utils/child-process-wrapper.js +33 -0
  41. package/dist/utils/invoke-local.d.ts +2 -0
  42. package/dist/utils/invoke-local.js +51 -0
  43. package/dist/utils/is-dependency.d.ts +1 -0
  44. package/dist/utils/is-dependency.js +7 -0
  45. package/dist/utils/is-json.d.ts +1 -0
  46. package/dist/utils/is-json.js +12 -0
  47. package/dist/utils/types.d.ts +16 -0
  48. package/dist/utils/types.js +1 -0
  49. package/oclif.manifest.json +179 -0
  50. package/package.json +85 -0
@@ -0,0 +1,2 @@
1
+ import type { PayloadOptions } from './types.js';
2
+ export default function buildPayload(options: PayloadOptions): object | null;
@@ -0,0 +1,15 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { cwd } from 'node:process';
4
+ import isJson from './is-json.js';
5
+ export default function buildPayload(options) {
6
+ const { data, file } = options;
7
+ let payload = {};
8
+ if (data) {
9
+ payload = isJson(data);
10
+ }
11
+ else if (file) {
12
+ payload = isJson(readFileSync(join(cwd(), file), 'utf8'));
13
+ }
14
+ return payload;
15
+ }
@@ -0,0 +1,33 @@
1
+ import {join} from 'node:path'
2
+ import process from 'node:process'
3
+
4
+ // Start when payload data arrives from parent process
5
+ process.on('message', async (data) => {
6
+ const {srcPath, payload} = JSON.parse(data)
7
+ let logs = ''
8
+ let json = null
9
+
10
+ // Import the function code
11
+ const {handler} = await import(join(process.cwd(), srcPath))
12
+
13
+ // backup stdout
14
+ const originalStdoutWrite = process.stdout.write.bind(process.stdout)
15
+
16
+ // redirect stdout to a buffer
17
+ process.stdout.write = (chunk) => {
18
+ if (typeof chunk === 'string') {
19
+ logs += chunk
20
+ }
21
+ return true
22
+ }
23
+
24
+ if (handler && typeof handler === 'function') {
25
+ json = await handler(payload)
26
+ }
27
+
28
+ // revert changes to stdout
29
+ process.stdout.write = originalStdoutWrite
30
+
31
+ // Send result of handler code to parent process.
32
+ process.send(JSON.stringify({json, logs}))
33
+ })
@@ -0,0 +1,2 @@
1
+ import type { InvocationResponse } from './types.js';
2
+ export default function invoke(srcPath: string, payload: null | object, timeout?: number): Promise<InvocationResponse>;
@@ -0,0 +1,51 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { join } from 'node:path';
3
+ import { cwd } from 'node:process';
4
+ import { setTimeout } from 'node:timers';
5
+ import isDependency from './is-dependency.js';
6
+ function getChildProcessWrapperPath() {
7
+ return isDependency('./utils/child-process-wrapper.js')
8
+ ? join(cwd(), './node_modules/@sanity/runtime-cli/dist/utils/child-process-wrapper.js')
9
+ : join(cwd(), './src/utils/child-process-wrapper.js');
10
+ }
11
+ export default async function invoke(srcPath, payload, timeout = 5) {
12
+ return new Promise((resolve, reject) => {
13
+ let child;
14
+ let timer;
15
+ function start() {
16
+ child = spawn('node', [getChildProcessWrapperPath()], {
17
+ cwd: cwd(),
18
+ stdio: ['inherit', 'inherit', 'inherit', 'ipc'],
19
+ });
20
+ // Note: start a timeout so child process doesn't run forever
21
+ child.on('message', (data) => {
22
+ const { json, logs } = JSON.parse(data.toString());
23
+ shutdown();
24
+ resolve({ json, logs, error: '' });
25
+ });
26
+ child.on('error', (error) => {
27
+ reject(new Error(`encountered error ${error.message}`));
28
+ });
29
+ child.on('exit', (code) => {
30
+ shutdown();
31
+ if (code !== 0) {
32
+ reject(new Error(`exited with code ${code}`));
33
+ }
34
+ else {
35
+ resolve({ json: {}, logs: '', error: '' });
36
+ }
37
+ });
38
+ timer = setTimeout(() => {
39
+ // timedOut = true
40
+ shutdown();
41
+ reject(new Error(`Timed out after hitting its ${timeout}s timeout!`));
42
+ }, timeout * 1000);
43
+ child.send(JSON.stringify({ srcPath, payload }, null, 2));
44
+ }
45
+ function shutdown() {
46
+ clearTimeout(timer);
47
+ child.kill();
48
+ }
49
+ start();
50
+ });
51
+ }
@@ -0,0 +1 @@
1
+ export default function isDependency(filePath: string): boolean;
@@ -0,0 +1,7 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { cwd } from 'node:process';
4
+ export default function isDependency(filePath) {
5
+ const path = join(cwd(), 'node_modules/@sanity/runtime-cli/dist/', filePath);
6
+ return existsSync(path);
7
+ }
@@ -0,0 +1 @@
1
+ export default function isJson(jsonString: string): null | object;
@@ -0,0 +1,12 @@
1
+ export default function isJson(jsonString) {
2
+ try {
3
+ const o = JSON.parse(jsonString);
4
+ if (o && typeof o === 'object') {
5
+ return o;
6
+ }
7
+ }
8
+ catch {
9
+ return null;
10
+ }
11
+ return null;
12
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * @internal
3
+ */
4
+ export interface PayloadOptions {
5
+ data: string | undefined;
6
+ file: string | undefined;
7
+ timeout?: number | undefined;
8
+ }
9
+ /**
10
+ * @internal
11
+ */
12
+ export interface InvocationResponse {
13
+ error: undefined | unknown;
14
+ json: object | undefined;
15
+ logs: string | undefined;
16
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,179 @@
1
+ {
2
+ "commands": {
3
+ "functions:dev": {
4
+ "aliases": [],
5
+ "args": {},
6
+ "description": "Start the Sanity Function emulator",
7
+ "examples": [
8
+ "<%= config.bin %> <%= command.id %> --port 8974"
9
+ ],
10
+ "flags": {
11
+ "port": {
12
+ "char": "p",
13
+ "description": "Port to start emulator on",
14
+ "name": "port",
15
+ "required": false,
16
+ "hasDynamicHelp": false,
17
+ "multiple": false,
18
+ "type": "option"
19
+ }
20
+ },
21
+ "hasDynamicHelp": false,
22
+ "hiddenAliases": [],
23
+ "id": "functions:dev",
24
+ "pluginAlias": "@sanity/runtime-cli",
25
+ "pluginName": "@sanity/runtime-cli",
26
+ "pluginType": "core",
27
+ "strict": true,
28
+ "enableJsonFlag": false,
29
+ "isESM": true,
30
+ "relativePath": [
31
+ "dist",
32
+ "commands",
33
+ "functions",
34
+ "dev.js"
35
+ ]
36
+ },
37
+ "functions:invoke": {
38
+ "aliases": [],
39
+ "args": {
40
+ "id": {
41
+ "description": "The ID of the function to invoke",
42
+ "name": "id",
43
+ "required": true
44
+ }
45
+ },
46
+ "description": "Invoke a remote Sanity Function",
47
+ "examples": [
48
+ "<%= config.bin %> <%= command.id %> <ID> --data '{ \"id\": 1 }'",
49
+ "<%= config.bin %> <%= command.id %> <ID> --file 'payload.json'"
50
+ ],
51
+ "flags": {
52
+ "data": {
53
+ "char": "d",
54
+ "description": "Data to send to the function",
55
+ "name": "data",
56
+ "required": false,
57
+ "hasDynamicHelp": false,
58
+ "multiple": false,
59
+ "type": "option"
60
+ },
61
+ "file": {
62
+ "char": "f",
63
+ "description": "Read data from file and send to the function",
64
+ "name": "file",
65
+ "required": false,
66
+ "hasDynamicHelp": false,
67
+ "multiple": false,
68
+ "type": "option"
69
+ }
70
+ },
71
+ "hasDynamicHelp": false,
72
+ "hiddenAliases": [],
73
+ "id": "functions:invoke",
74
+ "pluginAlias": "@sanity/runtime-cli",
75
+ "pluginName": "@sanity/runtime-cli",
76
+ "pluginType": "core",
77
+ "strict": true,
78
+ "enableJsonFlag": false,
79
+ "isESM": true,
80
+ "relativePath": [
81
+ "dist",
82
+ "commands",
83
+ "functions",
84
+ "invoke.js"
85
+ ]
86
+ },
87
+ "functions:logs": {
88
+ "aliases": [],
89
+ "args": {
90
+ "id": {
91
+ "description": "The ID of the function to retrieve logs for",
92
+ "name": "id",
93
+ "required": true
94
+ }
95
+ },
96
+ "description": "Retrieve logs for a Sanity Function",
97
+ "examples": [
98
+ "<%= config.bin %> <%= command.id %> <ID>"
99
+ ],
100
+ "flags": {},
101
+ "hasDynamicHelp": false,
102
+ "hiddenAliases": [],
103
+ "id": "functions:logs",
104
+ "pluginAlias": "@sanity/runtime-cli",
105
+ "pluginName": "@sanity/runtime-cli",
106
+ "pluginType": "core",
107
+ "strict": true,
108
+ "enableJsonFlag": false,
109
+ "isESM": true,
110
+ "relativePath": [
111
+ "dist",
112
+ "commands",
113
+ "functions",
114
+ "logs.js"
115
+ ]
116
+ },
117
+ "functions:test": {
118
+ "aliases": [],
119
+ "args": {
120
+ "path": {
121
+ "description": "The path to the function source code",
122
+ "name": "path",
123
+ "required": true
124
+ }
125
+ },
126
+ "description": "Invoke a local Sanity Function",
127
+ "examples": [
128
+ "<%= config.bin %> <%= command.id %> ./test.ts --data '{ \"id\": 1 }'",
129
+ "<%= config.bin %> <%= command.id %> ./test.js --file 'payload.json'",
130
+ "<%= config.bin %> <%= command.id %> ./test.ts --data '{ \"id\": 1 }' --timeout 60"
131
+ ],
132
+ "flags": {
133
+ "data": {
134
+ "char": "d",
135
+ "description": "Data to send to the function",
136
+ "name": "data",
137
+ "required": false,
138
+ "hasDynamicHelp": false,
139
+ "multiple": false,
140
+ "type": "option"
141
+ },
142
+ "file": {
143
+ "char": "f",
144
+ "description": "Read data from file and send to the function",
145
+ "name": "file",
146
+ "required": false,
147
+ "hasDynamicHelp": false,
148
+ "multiple": false,
149
+ "type": "option"
150
+ },
151
+ "timeout": {
152
+ "char": "t",
153
+ "description": "Execution timeout value in seconds",
154
+ "name": "timeout",
155
+ "required": false,
156
+ "hasDynamicHelp": false,
157
+ "multiple": false,
158
+ "type": "option"
159
+ }
160
+ },
161
+ "hasDynamicHelp": false,
162
+ "hiddenAliases": [],
163
+ "id": "functions:test",
164
+ "pluginAlias": "@sanity/runtime-cli",
165
+ "pluginName": "@sanity/runtime-cli",
166
+ "pluginType": "core",
167
+ "strict": true,
168
+ "enableJsonFlag": false,
169
+ "isESM": true,
170
+ "relativePath": [
171
+ "dist",
172
+ "commands",
173
+ "functions",
174
+ "test.js"
175
+ ]
176
+ }
177
+ },
178
+ "version": "1.0.2"
179
+ }
package/package.json ADDED
@@ -0,0 +1,85 @@
1
+ {
2
+ "name": "@sanity/runtime-cli",
3
+ "description": "A new CLI generated with oclif",
4
+ "version": "1.0.2",
5
+ "author": "Sanity Runtime Team",
6
+ "type": "module",
7
+ "license": "UNLICENSED",
8
+ "repository": "sanity-io/runtime-cli",
9
+ "bugs": "https://github.com/sanity-io/runtime-cli/issues",
10
+ "homepage": "https://github.com/sanity-io/runtime-cli",
11
+ "main": "dist/index.js",
12
+ "types": "dist/index.d.ts",
13
+ "engines": {
14
+ "node": ">=20.11.0"
15
+ },
16
+ "files": [
17
+ "./bin",
18
+ "./dist",
19
+ "./oclif.manifest.json"
20
+ ],
21
+ "bin": {
22
+ "sanity": "./bin/run.js"
23
+ },
24
+ "scripts": {
25
+ "build": "rollup -c && shx rm -rf dist && tsc -b && npm run build:static",
26
+ "build:static": "npm run copy:wrapper && npm run copy:server",
27
+ "copy:server": "shx cp -r ./src/server/static ./dist/server/static",
28
+ "copy:wrapper": "shx cp ./src/utils/child-process-wrapper.js ./dist/utils/child-process-wrapper.js",
29
+ "lint": "biome ci",
30
+ "lint:write": "biome check --write",
31
+ "postpack": "shx rm -f oclif.manifest.json",
32
+ "posttest": "npm run lint",
33
+ "prepack": "oclif manifest && oclif readme",
34
+ "test": "mocha --forbid-only \"test/**/*.test.ts\"",
35
+ "version": "oclif readme && git add README.md"
36
+ },
37
+ "dependencies": {
38
+ "@hono/node-server": "^1.13.8",
39
+ "@oclif/core": "^4",
40
+ "@oclif/plugin-help": "^6",
41
+ "@oclif/plugin-plugins": "^5",
42
+ "hono": "^4.7.2"
43
+ },
44
+ "devDependencies": {
45
+ "@biomejs/biome": "1.9.4",
46
+ "@codemirror/lang-json": "^6.0.1",
47
+ "@codemirror/state": "^6.5.2",
48
+ "@enhance/store": "^1.0.2",
49
+ "@oclif/prettier-config": "^0.2.1",
50
+ "@oclif/test": "^4",
51
+ "@rollup/plugin-node-resolve": "^16.0.0",
52
+ "@types/chai": "^5",
53
+ "@types/mocha": "^10",
54
+ "@types/node": "^20",
55
+ "chai": "^5",
56
+ "codemirror": "^6.0.1",
57
+ "mocha": "^11",
58
+ "oclif": "^4",
59
+ "pretty-bytes": "^6.1.1",
60
+ "pretty-ms": "^9.2.0",
61
+ "rollup": "^4.34.8",
62
+ "shx": "^0.3.4",
63
+ "ts-node": "^10",
64
+ "typescript": "^5"
65
+ },
66
+ "oclif": {
67
+ "bin": "sanity",
68
+ "dirname": "sanity",
69
+ "commands": "./dist/commands",
70
+ "plugins": [
71
+ "@oclif/plugin-help",
72
+ "@oclif/plugin-plugins"
73
+ ],
74
+ "topicSeparator": " ",
75
+ "topics": {
76
+ "hello": {
77
+ "description": "Say hello to the world and others"
78
+ }
79
+ }
80
+ },
81
+ "publishConfig": {
82
+ "access": "public",
83
+ "provenance": false
84
+ }
85
+ }