@silverbulletmd/silverbullet 2.9.0 → 2.10.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 +36 -23
- package/client/plugos/hooks/syscall.ts +24 -10
- package/client/plugos/syscalls/asset.ts +61 -23
- package/client/plugos/syscalls/clientStore.ts +32 -6
- package/client/plugos/syscalls/client_code_widget.ts +9 -4
- package/client/plugos/syscalls/code_widget.ts +26 -11
- package/client/plugos/syscalls/config.ts +146 -30
- package/client/plugos/syscalls/datastore.ts +146 -40
- package/client/plugos/syscalls/editor.ts +1432 -711
- package/client/plugos/syscalls/event.ts +46 -13
- package/client/plugos/syscalls/fetch.ts +123 -82
- package/client/plugos/syscalls/index.ts +242 -116
- package/client/plugos/syscalls/jsonschema.ts +107 -8
- package/client/plugos/syscalls/language.ts +38 -12
- package/client/plugos/syscalls/markdown.ts +166 -50
- package/client/plugos/syscalls/mq.ts +93 -20
- package/client/plugos/syscalls/schema_introspection.ts +33 -0
- package/client/plugos/syscalls/service_registry.ts +74 -20
- package/client/plugos/syscalls/shell.ts +51 -20
- package/client/plugos/syscalls/space.ts +169 -113
- package/client/plugos/syscalls/sync.ts +50 -19
- package/client/plugos/syscalls/system.ts +236 -139
- package/client/plugos/system.ts +21 -5
- package/client/space_lua/api_documentation.ts +107 -0
- package/client/space_lua/ast.ts +13 -0
- package/client/space_lua/eval.ts +12 -4
- package/client/space_lua/parse.ts +243 -108
- package/client/space_lua/pretty_print.ts +128 -54
- package/client/space_lua/query_collection.ts +4 -4
- package/client/space_lua/render_widget.ts +156 -0
- package/client/space_lua/runtime.ts +83 -22
- package/client/space_lua/stdlib/crypto.ts +8 -3
- package/client/space_lua/stdlib/encoding.ts +27 -9
- package/client/space_lua/stdlib/js.ts +137 -22
- package/client/space_lua/stdlib/load.ts +24 -15
- package/client/space_lua/stdlib/math.ts +323 -118
- package/client/space_lua/stdlib/net.ts +57 -9
- package/client/space_lua/stdlib/os.ts +111 -44
- package/client/space_lua/stdlib/space_lua.ts +344 -20
- package/client/space_lua/stdlib/string.ts +282 -104
- package/client/space_lua/stdlib/string_pack.ts +58 -19
- package/client/space_lua/stdlib/table.ts +195 -40
- package/client/space_lua/stdlib.ts +335 -93
- package/client/space_lua/syscalls.ts +270 -0
- package/dist/plug-compile.js +1 -1
- package/package.json +3 -3
- package/plug-api/lib/ref.ts +96 -0
- package/plug-api/lib/shortcut.ts +2 -1
- package/plug-api/syscalls/config.ts +5 -3
- package/plug-api/syscalls/editor.ts +16 -0
- package/plug-api/syscalls/index.ts +17 -1
- package/plug-api/syscalls/jsonschema.ts +9 -0
- package/plug-api/syscalls/lua.ts +7 -0
- package/plug-api/syscalls/shell.ts +0 -1
- package/plug-api/syscalls/system.ts +7 -0
- package/plug-api/system_mock.ts +2 -2
- package/plug-api/types/index.ts +52 -1
- package/plug-api/types/manifest.ts +22 -4
- package/plug-api/ui/cx.ts +1 -3
- package/plug-api/ui/index.ts +3 -0
- package/plug-api/ui/panel_styles.ts +4 -3
- package/plug-api/ui/slugify.ts +44 -0
- package/client/plugos/syscalls/lua.ts +0 -81
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
import type { ObjectValue } from "@silverbulletmd/silverbullet/type/index";
|
|
12
12
|
import type { Client } from "../../client.ts";
|
|
13
13
|
import type { LuaTable } from "../../space_lua/runtime.ts";
|
|
14
|
+
import { describeSchemas, tagSchema } from "./schema_introspection.ts";
|
|
14
15
|
|
|
15
16
|
export function indexSyscalls(
|
|
16
17
|
objectIndex: ObjectIndex,
|
|
@@ -18,143 +19,268 @@ export function indexSyscalls(
|
|
|
18
19
|
): SysCallMapping {
|
|
19
20
|
return {
|
|
20
21
|
// Query collection API
|
|
21
|
-
"index.tag":
|
|
22
|
-
|
|
22
|
+
"index.tag": {
|
|
23
|
+
callback: (_ctx, tagName: string): LuaQueryCollection => {
|
|
24
|
+
return objectIndex.objectsWithTag(tagName);
|
|
25
|
+
},
|
|
26
|
+
description: "Returns objects carrying a tag as a query collection.",
|
|
27
|
+
signatures: ["index.tag(tagName)"],
|
|
23
28
|
},
|
|
24
29
|
// Alias for tag
|
|
25
|
-
"index.objects":
|
|
26
|
-
|
|
30
|
+
"index.objects": {
|
|
31
|
+
callback: (_ctx, tagName: string): LuaQueryCollection => {
|
|
32
|
+
return objectIndex.objectsWithTag(tagName);
|
|
33
|
+
},
|
|
34
|
+
description: "Returns objects carrying a tag as a query collection.",
|
|
35
|
+
signatures: ["index.objects(tagName)"],
|
|
27
36
|
},
|
|
28
|
-
"index.pages":
|
|
29
|
-
|
|
37
|
+
"index.pages": {
|
|
38
|
+
callback: (_ctx, tagName?: string): LuaQueryCollection => {
|
|
39
|
+
return objectIndex.rootTaggedObjects("page", tagName);
|
|
40
|
+
},
|
|
41
|
+
description:
|
|
42
|
+
"Returns all pages, optionally filtered by an additional tag, as a query collection.",
|
|
43
|
+
signatures: ["index.pages(tagName?)"],
|
|
30
44
|
},
|
|
31
|
-
"index.subPages":
|
|
32
|
-
|
|
45
|
+
"index.subPages": {
|
|
46
|
+
callback: (_ctx, pageName: string): LuaQueryCollection => {
|
|
47
|
+
return objectIndex.subPages(pageName);
|
|
48
|
+
},
|
|
49
|
+
description:
|
|
50
|
+
"Returns pages nested below a page name as a query collection.",
|
|
51
|
+
signatures: ["index.subPages(pageName)"],
|
|
33
52
|
},
|
|
34
|
-
"index.documents":
|
|
35
|
-
|
|
53
|
+
"index.documents": {
|
|
54
|
+
callback: (): LuaQueryCollection => {
|
|
55
|
+
return objectIndex.objectsWithTag("document");
|
|
56
|
+
},
|
|
57
|
+
description: "Returns all indexed documents as a query collection.",
|
|
36
58
|
},
|
|
37
|
-
"index.links":
|
|
38
|
-
|
|
59
|
+
"index.links": {
|
|
60
|
+
callback: (): LuaQueryCollection => {
|
|
61
|
+
return objectIndex.objectsWithTag("link");
|
|
62
|
+
},
|
|
63
|
+
description: "Returns all indexed links as a query collection.",
|
|
39
64
|
},
|
|
40
|
-
"index.relations":
|
|
41
|
-
|
|
65
|
+
"index.relations": {
|
|
66
|
+
callback: (): LuaQueryCollection => {
|
|
67
|
+
return objectIndex.objectsWithTag("relation");
|
|
68
|
+
},
|
|
69
|
+
description: "Returns all indexed relations as a query collection.",
|
|
42
70
|
},
|
|
43
|
-
"index.contentPages":
|
|
44
|
-
|
|
71
|
+
"index.contentPages": {
|
|
72
|
+
callback: (_ctx, tagName?: string): LuaQueryCollection => {
|
|
73
|
+
return objectIndex.contentPages(tagName);
|
|
74
|
+
},
|
|
75
|
+
description:
|
|
76
|
+
"Returns non-meta pages, optionally filtered by an additional tag, as a query collection.",
|
|
77
|
+
signatures: ["index.contentPages(tagName?)"],
|
|
45
78
|
},
|
|
46
|
-
"index.metaPages":
|
|
47
|
-
|
|
79
|
+
"index.metaPages": {
|
|
80
|
+
callback: (): LuaQueryCollection => {
|
|
81
|
+
return objectIndex.metaPages();
|
|
82
|
+
},
|
|
83
|
+
description: "Returns all meta pages as a query collection.",
|
|
48
84
|
},
|
|
49
|
-
"index.tasks":
|
|
50
|
-
|
|
85
|
+
"index.tasks": {
|
|
86
|
+
callback: (_ctx, tagName?: string): LuaQueryCollection => {
|
|
87
|
+
return objectIndex.rootTaggedObjects("task", tagName);
|
|
88
|
+
},
|
|
89
|
+
description:
|
|
90
|
+
"Returns all tasks, optionally filtered by an additional tag, as a query collection.",
|
|
91
|
+
signatures: ["index.tasks(tagName?)"],
|
|
51
92
|
},
|
|
52
|
-
"index.headers":
|
|
53
|
-
|
|
93
|
+
"index.headers": {
|
|
94
|
+
callback: (_ctx, tagName?: string): LuaQueryCollection => {
|
|
95
|
+
return objectIndex.rootTaggedObjects("header", tagName);
|
|
96
|
+
},
|
|
97
|
+
description:
|
|
98
|
+
"Returns all headers, optionally filtered by an additional tag, as a query collection.",
|
|
99
|
+
signatures: ["index.headers(tagName?)"],
|
|
54
100
|
},
|
|
55
|
-
"index.items":
|
|
56
|
-
|
|
101
|
+
"index.items": {
|
|
102
|
+
callback: (_ctx, tagName?: string): LuaQueryCollection => {
|
|
103
|
+
return objectIndex.rootTaggedObjects("item", tagName);
|
|
104
|
+
},
|
|
105
|
+
description:
|
|
106
|
+
"Returns all list items, optionally filtered by an additional tag, as a query collection.",
|
|
107
|
+
signatures: ["index.items(tagName?)"],
|
|
57
108
|
},
|
|
58
|
-
"index.paragraphs":
|
|
59
|
-
|
|
109
|
+
"index.paragraphs": {
|
|
110
|
+
callback: (_ctx, tagName?: string): LuaQueryCollection => {
|
|
111
|
+
return objectIndex.rootTaggedObjects("paragraph", tagName);
|
|
112
|
+
},
|
|
113
|
+
description:
|
|
114
|
+
"Returns indexed paragraphs, optionally filtered by an additional tag, as a query collection.",
|
|
115
|
+
signatures: ["index.paragraphs(tagName?)"],
|
|
60
116
|
},
|
|
61
|
-
"index.tables":
|
|
62
|
-
|
|
117
|
+
"index.tables": {
|
|
118
|
+
callback: (_ctx, tagName?: string): LuaQueryCollection => {
|
|
119
|
+
return objectIndex.rootTaggedObjects("table", tagName);
|
|
120
|
+
},
|
|
121
|
+
description:
|
|
122
|
+
"Returns indexed table rows, optionally filtered by an additional tag, as a query collection.",
|
|
123
|
+
signatures: ["index.tables(tagName?)"],
|
|
63
124
|
},
|
|
64
|
-
"index.tags":
|
|
65
|
-
|
|
125
|
+
"index.tags": {
|
|
126
|
+
callback: (): LuaQueryCollection => {
|
|
127
|
+
return objectIndex.objectsWithTag("tag");
|
|
128
|
+
},
|
|
129
|
+
description: "Returns all indexed tag objects as a query collection.",
|
|
66
130
|
},
|
|
67
|
-
|
|
68
|
-
|
|
131
|
+
// Schema introspection: indexed object-type / tag schemas
|
|
132
|
+
"index.describeSchema": {
|
|
133
|
+
callback: (): Record<string, unknown> => {
|
|
134
|
+
return describeSchemas(client.config.get(["tags"], {}));
|
|
135
|
+
},
|
|
136
|
+
description:
|
|
137
|
+
"Returns raw JSON Schemas for every configured tag that declares one.",
|
|
138
|
+
},
|
|
139
|
+
"index.tagSchema": {
|
|
140
|
+
callback: (_ctx, tagName: string): unknown | null => {
|
|
141
|
+
return tagSchema(client.config.get(["tags"], {}), tagName);
|
|
142
|
+
},
|
|
143
|
+
description:
|
|
144
|
+
"Returns the raw JSON Schema for a tag, or nil when none is declared.",
|
|
145
|
+
signatures: ["index.tagSchema(tagName)"],
|
|
146
|
+
},
|
|
147
|
+
"index.aspiringPages": {
|
|
148
|
+
callback: (): LuaQueryCollection => {
|
|
149
|
+
return objectIndex.aspiringPages();
|
|
150
|
+
},
|
|
151
|
+
description:
|
|
152
|
+
"Returns linked but not yet created pages as a query collection.",
|
|
69
153
|
},
|
|
70
154
|
// Internals
|
|
71
|
-
"index.aggregates":
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
},
|
|
77
|
-
"index.
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
155
|
+
"index.aggregates": {
|
|
156
|
+
callback: (): LuaQueryCollection => {
|
|
157
|
+
return objectIndex.aggregates();
|
|
158
|
+
},
|
|
159
|
+
description: "Returns stored aggregate records as a query collection.",
|
|
160
|
+
},
|
|
161
|
+
"index.ensureFullIndex": {
|
|
162
|
+
callback: () => {
|
|
163
|
+
return objectIndex.ensureFullIndex(client.space);
|
|
164
|
+
},
|
|
165
|
+
description:
|
|
166
|
+
"Ensures the complete object index is available and current.",
|
|
167
|
+
},
|
|
168
|
+
"index.reindexSpace": {
|
|
169
|
+
callback: () => {
|
|
170
|
+
return objectIndex.reindexSpace(client.space);
|
|
171
|
+
},
|
|
172
|
+
description: "Rebuilds the object index for the entire space.",
|
|
173
|
+
},
|
|
174
|
+
"index.indexObjects": {
|
|
175
|
+
callback: (_ctx, page: string, objects: ObjectValue[]): Promise<void> => {
|
|
176
|
+
return objectIndex.indexObjects(page, objects);
|
|
177
|
+
},
|
|
178
|
+
description: "Indexes a collection of objects for a page.",
|
|
179
|
+
signatures: ["index.indexObjects(page, objects)"],
|
|
180
|
+
},
|
|
181
|
+
"index.validateObjects": {
|
|
182
|
+
callback: async (
|
|
183
|
+
_ctx,
|
|
184
|
+
page: string,
|
|
185
|
+
objects: ObjectValue[],
|
|
186
|
+
): Promise<{ error: string; object: ObjectValue } | null> => {
|
|
187
|
+
try {
|
|
188
|
+
await objectIndex.validateObjects(page, objects);
|
|
189
|
+
return null;
|
|
190
|
+
} catch (e: any) {
|
|
191
|
+
if (e instanceof ObjectValidationError) {
|
|
192
|
+
return {
|
|
193
|
+
error: e.message,
|
|
194
|
+
object: e.object,
|
|
195
|
+
};
|
|
196
|
+
} else {
|
|
197
|
+
throw e;
|
|
198
|
+
}
|
|
103
199
|
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
},
|
|
121
|
-
"index.
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
)
|
|
200
|
+
},
|
|
201
|
+
description:
|
|
202
|
+
"Validates objects for a page and returns the first validation error, if any.",
|
|
203
|
+
signatures: ["index.validateObjects(page, objects)"],
|
|
204
|
+
},
|
|
205
|
+
"index.previewProcessedObjects": {
|
|
206
|
+
callback: (
|
|
207
|
+
_ctx,
|
|
208
|
+
page: string,
|
|
209
|
+
objects: ObjectValue[],
|
|
210
|
+
): Promise<{ tag: string; object: ObjectValue }[]> => {
|
|
211
|
+
return objectIndex.previewProcessedObjects(page, objects);
|
|
212
|
+
},
|
|
213
|
+
description:
|
|
214
|
+
"Runs the indexing pipeline without writing and returns processed tag/object pairs.",
|
|
215
|
+
signatures: ["index.previewProcessedObjects(page, objects)"],
|
|
216
|
+
},
|
|
217
|
+
"index.getObjectByRef": {
|
|
218
|
+
callback: (
|
|
219
|
+
_ctx,
|
|
220
|
+
page: string,
|
|
221
|
+
tag: string,
|
|
222
|
+
ref: string,
|
|
223
|
+
): Promise<ObjectValue | undefined> => {
|
|
224
|
+
return objectIndex.getObjectByRef(page, tag, ref);
|
|
225
|
+
},
|
|
226
|
+
description:
|
|
227
|
+
"Returns an indexed object identified by page, tag, and reference.",
|
|
228
|
+
signatures: ["index.getObjectByRef(page, tag, ref)"],
|
|
229
|
+
},
|
|
230
|
+
"index.queryLuaObjects": {
|
|
231
|
+
callback: (
|
|
232
|
+
_ctx,
|
|
233
|
+
tag: string,
|
|
234
|
+
query: LuaCollectionQuery,
|
|
235
|
+
scopedVariables?: Record<string, any>,
|
|
236
|
+
): Promise<ObjectValue[]> => {
|
|
237
|
+
return objectIndex.queryLuaObjects(
|
|
238
|
+
client.clientSystem.spaceLuaEnv.env,
|
|
239
|
+
tag,
|
|
240
|
+
query,
|
|
241
|
+
scopedVariables,
|
|
242
|
+
);
|
|
243
|
+
},
|
|
244
|
+
description:
|
|
245
|
+
"Executes a structured Lua collection query against indexed objects.",
|
|
246
|
+
signatures: ["index.queryLuaObjects(tag, query, scopedVariables?)"],
|
|
133
247
|
},
|
|
134
248
|
|
|
135
|
-
"index.deleteObject":
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
249
|
+
"index.deleteObject": {
|
|
250
|
+
callback: (
|
|
251
|
+
_ctx,
|
|
252
|
+
page: string,
|
|
253
|
+
tag: string,
|
|
254
|
+
ref: string,
|
|
255
|
+
): Promise<void> => {
|
|
256
|
+
return objectIndex.deleteObject(page, tag, ref);
|
|
257
|
+
},
|
|
258
|
+
description:
|
|
259
|
+
"Deletes an indexed object identified by page, tag, and reference.",
|
|
260
|
+
signatures: ["index.deleteObject(page, tag, ref)"],
|
|
261
|
+
},
|
|
262
|
+
"lua:index.defineTag": {
|
|
263
|
+
callback: (_ctx, tagDef: LuaTable) => {
|
|
264
|
+
// Using 'lua:' prefix to _not_ convert tagDef to a JS version (but keep original LuaTable)
|
|
265
|
+
if (!tagDef.has("name")) {
|
|
266
|
+
throw new Error("A tag name is required");
|
|
267
|
+
}
|
|
268
|
+
const currentTag = client.config.get(
|
|
269
|
+
["tags", tagDef.get("name")],
|
|
270
|
+
null,
|
|
271
|
+
);
|
|
272
|
+
if (!currentTag) {
|
|
273
|
+
client.config.set(["tags", tagDef.get("name")], {
|
|
274
|
+
name: tagDef.get("name"),
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
client.config.set(
|
|
278
|
+
["tags", tagDef.get("name"), "metatable"],
|
|
279
|
+
tagDef.get("metatable"),
|
|
280
|
+
);
|
|
281
|
+
},
|
|
282
|
+
description: "Defines or updates a tag and its Lua metatable.",
|
|
283
|
+
signatures: ["index.defineTag(tagDefinition)"],
|
|
158
284
|
},
|
|
159
285
|
};
|
|
160
286
|
}
|
|
@@ -75,17 +75,116 @@ export function validateSchema(schema: any): undefined | string {
|
|
|
75
75
|
return;
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
+
/**
|
|
79
|
+
* Best-effort: infer a JSON Schema (draft 2020-12) from the *shape* of a single
|
|
80
|
+
* sample value. Types are guessed from one example, so the result is a hint,
|
|
81
|
+
* not a contract — the top-level schema is marked `"x-inferred": true`.
|
|
82
|
+
*
|
|
83
|
+
* Useful when a tag/object type has no declared schema but an example object
|
|
84
|
+
* exists and you want a plausible schema for it.
|
|
85
|
+
*/
|
|
86
|
+
export function inferFromObject(value: any): any {
|
|
87
|
+
const schema = inferSchemaNode(value);
|
|
88
|
+
schema["$schema"] = "https://json-schema.org/draft/2020-12/schema";
|
|
89
|
+
schema["x-inferred"] = true;
|
|
90
|
+
return schema;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** Infer a bare JSON Schema node for a value, recursing into arrays/objects. */
|
|
94
|
+
function inferSchemaNode(value: any): any {
|
|
95
|
+
if (value === null || value === undefined) {
|
|
96
|
+
return { type: "null" };
|
|
97
|
+
}
|
|
98
|
+
if (Array.isArray(value)) {
|
|
99
|
+
const node: any = { type: "array" };
|
|
100
|
+
if (value.length > 0) {
|
|
101
|
+
node.items = inferSchemaNode(value[0]);
|
|
102
|
+
}
|
|
103
|
+
return node;
|
|
104
|
+
}
|
|
105
|
+
switch (typeof value) {
|
|
106
|
+
case "boolean":
|
|
107
|
+
return { type: "boolean" };
|
|
108
|
+
case "number":
|
|
109
|
+
return { type: Number.isInteger(value) ? "integer" : "number" };
|
|
110
|
+
case "string":
|
|
111
|
+
return { type: "string" };
|
|
112
|
+
case "object": {
|
|
113
|
+
const properties: Record<string, any> = {};
|
|
114
|
+
for (const [k, v] of Object.entries(value)) {
|
|
115
|
+
properties[k] = inferSchemaNode(v);
|
|
116
|
+
}
|
|
117
|
+
return { type: "object", properties };
|
|
118
|
+
}
|
|
119
|
+
default:
|
|
120
|
+
// functions, symbols, bigint, … — not representable in JSON Schema.
|
|
121
|
+
return {};
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
78
125
|
export function jsonschemaSyscalls(): SysCallMapping {
|
|
79
126
|
return {
|
|
80
|
-
"jsonschema.validateObject":
|
|
81
|
-
_ctx,
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
127
|
+
"jsonschema.validateObject": {
|
|
128
|
+
callback: (_ctx, schema: any, object: any): undefined | string => {
|
|
129
|
+
return validateObject(schema, object);
|
|
130
|
+
},
|
|
131
|
+
description: "Validates a value against a JSON Schema.",
|
|
132
|
+
parameters: [
|
|
133
|
+
{
|
|
134
|
+
name: "schema",
|
|
135
|
+
type: "table",
|
|
136
|
+
description: "JSON Schema to apply.",
|
|
137
|
+
},
|
|
138
|
+
{ name: "object", description: "Value to validate." },
|
|
139
|
+
],
|
|
140
|
+
returns: [
|
|
141
|
+
{
|
|
142
|
+
type: "string",
|
|
143
|
+
description: "Validation error, or nil when valid.",
|
|
144
|
+
},
|
|
145
|
+
],
|
|
146
|
+
examples: [
|
|
147
|
+
{
|
|
148
|
+
code: 'local schema = {type = "object", properties = {name = {type = "string"}}, required = {"name"}}\nlocal err = jsonschema.validateObject(schema, {name = "John"})',
|
|
149
|
+
},
|
|
150
|
+
],
|
|
151
|
+
},
|
|
152
|
+
"jsonschema.validateSchema": {
|
|
153
|
+
callback: (_ctx, schema: any): undefined | string => {
|
|
154
|
+
return validateSchema(schema);
|
|
155
|
+
},
|
|
156
|
+
description:
|
|
157
|
+
"Checks whether a JSON Schema has a supported top-level shape.",
|
|
158
|
+
parameters: [{ name: "schema", description: "JSON Schema to validate." }],
|
|
159
|
+
returns: [
|
|
160
|
+
{ type: "string", description: "Schema error, or nil when valid." },
|
|
161
|
+
],
|
|
162
|
+
examples: [
|
|
163
|
+
{
|
|
164
|
+
code: 'local err = jsonschema.validateSchema({type = "object"})',
|
|
165
|
+
},
|
|
166
|
+
],
|
|
86
167
|
},
|
|
87
|
-
"jsonschema.
|
|
88
|
-
|
|
168
|
+
"jsonschema.inferFromObject": {
|
|
169
|
+
callback: (_ctx, object: any): any => {
|
|
170
|
+
return inferFromObject(object);
|
|
171
|
+
},
|
|
172
|
+
description:
|
|
173
|
+
"Infers a best-effort draft 2020-12 JSON Schema from a sample value.",
|
|
174
|
+
parameters: [
|
|
175
|
+
{
|
|
176
|
+
name: "object",
|
|
177
|
+
description: "Sample value whose shape is inferred.",
|
|
178
|
+
},
|
|
179
|
+
],
|
|
180
|
+
returns: [
|
|
181
|
+
{ type: "table", description: "Inferred schema marked x-inferred." },
|
|
182
|
+
],
|
|
183
|
+
examples: [
|
|
184
|
+
{
|
|
185
|
+
code: 'local schema = jsonschema.inferFromObject({name = "Widget", count = 3})',
|
|
186
|
+
},
|
|
187
|
+
],
|
|
89
188
|
},
|
|
90
189
|
};
|
|
91
190
|
}
|
|
@@ -9,19 +9,45 @@ import {
|
|
|
9
9
|
|
|
10
10
|
export function languageSyscalls(): SysCallMapping {
|
|
11
11
|
return {
|
|
12
|
-
"language.parseLanguage":
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
12
|
+
"language.parseLanguage": {
|
|
13
|
+
callback: async (
|
|
14
|
+
_ctx,
|
|
15
|
+
language: string,
|
|
16
|
+
code: string,
|
|
17
|
+
): Promise<ParseTree> => {
|
|
18
|
+
const lang = languageFor(language) ?? (await loadLanguageFor(language));
|
|
19
|
+
if (!lang) {
|
|
20
|
+
throw new Error(`Unknown language ${language}`);
|
|
21
|
+
}
|
|
22
|
+
return parse(lang, code);
|
|
23
|
+
},
|
|
24
|
+
description: "Parses code using a supported fenced-code-block language.",
|
|
25
|
+
parameters: [
|
|
26
|
+
{
|
|
27
|
+
name: "language",
|
|
28
|
+
type: "string",
|
|
29
|
+
description: "Language name or alias.",
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
name: "code",
|
|
33
|
+
type: "string",
|
|
34
|
+
description: "Source code to parse.",
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
returns: [{ type: "table", description: "Parsed syntax tree." }],
|
|
38
|
+
examples: [
|
|
39
|
+
{
|
|
40
|
+
code: 'local tree = language.parseLanguage("javascript", "const answer = 42")',
|
|
41
|
+
},
|
|
42
|
+
],
|
|
22
43
|
},
|
|
23
|
-
"language.listLanguages":
|
|
24
|
-
|
|
44
|
+
"language.listLanguages": {
|
|
45
|
+
callback: (): string[] => {
|
|
46
|
+
return allLanguageNames;
|
|
47
|
+
},
|
|
48
|
+
description: "Lists all supported fenced-code-block languages.",
|
|
49
|
+
returns: [{ type: "table", description: "Supported language names." }],
|
|
50
|
+
examples: [{ code: "local languages = language.listLanguages()" }],
|
|
25
51
|
},
|
|
26
52
|
};
|
|
27
53
|
}
|