diff --git a/client/plugos/hooks/syscall.ts b/client/plugos/hooks/syscall.ts index 630f39bd..a2061933 100644 --- a/client/plugos/hooks/syscall.ts +++ b/client/plugos/hooks/syscall.ts @@ -36,19 +36,15 @@ export class SyscallHook implements Hook { `${plug.manifest!.name}.${name}`, ...args, ]); - syscalls[syscallName] = - typeof syscallDefinition === "string" - ? callback - : { - callback, - documentation: { - description: syscallDefinition.description, - parameters: syscallDefinition.parameters, - returns: syscallDefinition.returns, - deprecated: syscallDefinition.deprecated, - see: syscallDefinition.see, - }, - }; + if (typeof syscallDefinition === "string") { + syscalls[syscallName] = callback; + } else { + const { name: _name, ...metadata } = syscallDefinition; + syscalls[syscallName] = { + callback, + ...metadata, + }; + } // Register the syscalls with no required permissions system.registerSyscalls([], syscalls); diff --git a/client/plugos/system.ts b/client/plugos/system.ts index cf2c86ea..66205591 100644 --- a/client/plugos/system.ts +++ b/client/plugos/system.ts @@ -29,14 +29,12 @@ type SyscallSignature = (...args: any[]) => Promise | any; export type SyscallDefinition = { callback: SyscallSignature; - documentation?: LuaFunctionDocumentation; -}; +} & LuaFunctionDocumentation; type RegisteredSyscall = { requiredPermissions: string[]; callback: SyscallSignature; - documentation: LuaFunctionDocumentation; -}; +} & LuaFunctionDocumentation; export type SystemOptions = { manifestCache?: ManifestCache; @@ -84,14 +82,12 @@ export class System extends EventEmitter> { ? name.slice("lua:".length) : name; const namespace = cleanName.split(".")[0]; - const defaultDocumentation = { see: `API/${namespace}` }; + const { callback, ...metadata } = definition; this.registeredSyscalls.set(name, { requiredPermissions: requiredCapabilities, - callback: definition.callback, - documentation: { - ...defaultDocumentation, - ...definition.documentation, - }, + callback, + see: `API/${namespace}`, + ...metadata, }); } } diff --git a/client/space_lua/runtime.test.ts b/client/space_lua/runtime.test.ts index dd35929a..1e963d4f 100644 --- a/client/space_lua/runtime.test.ts +++ b/client/space_lua/runtime.test.ts @@ -58,9 +58,7 @@ test("Test Lua Rutime", async () => { test("Lua functions accept documented definition objects", () => { const builtin = new LuaBuiltinFunction({ callback: (_sf, value) => value, - documentation: { - description: "Returns the provided value.", - }, + description: "Returns the provided value.", }); expect(builtin.call(LuaStackFrame.lostFrame, "value")).toBe("value"); expect(builtin.info).toEqual({ @@ -70,11 +68,9 @@ test("Lua functions accept documented definition objects", () => { const native = new LuaNativeJSFunction({ callback: (value) => value, - documentation: { - kind: "syscall", - name: "demo.echo", - description: "Returns the provided value.", - }, + kind: "syscall", + name: "demo.echo", + description: "Returns the provided value.", }); expect(native.call(LuaStackFrame.lostFrame, "value")).toBe("value"); expect(native.info).toEqual({ diff --git a/client/space_lua/runtime.ts b/client/space_lua/runtime.ts index 21bac0d3..3664e930 100644 --- a/client/space_lua/runtime.ts +++ b/client/space_lua/runtime.ts @@ -24,13 +24,12 @@ export type LuaType = export type LuaValue = any; export type JSValue = any; -type LuaFunctionDefinitionDocumentation = LuaFunctionDocumentation & +type LuaFunctionDefinitionMetadata = LuaFunctionDocumentation & Partial>; export type LuaFunctionDefinition = { callback: Callback; - documentation?: LuaFunctionDefinitionDocumentation; -}; +} & LuaFunctionDefinitionMetadata; export interface ILuaFunction { call(sf: LuaStackFrame, ...args: LuaValue[]): Promise | LuaValue; @@ -601,10 +600,11 @@ export class LuaNativeJSFunction implements ILuaFunction { this.fn = definition; this.info = { kind: "builtin" }; } else { - this.fn = definition.callback; + const { callback, ...info } = definition; + this.fn = callback; this.info = { kind: "builtin", - ...definition.documentation, + ...info, }; } } @@ -651,10 +651,11 @@ export class LuaBuiltinFunction implements ILuaFunction { this.fn = definition; this.info = { kind: "builtin" }; } else { - this.fn = definition.callback; + const { callback, ...info } = definition; + this.fn = callback; this.info = { kind: "builtin", - ...definition.documentation, + ...info, }; } } diff --git a/client/space_lua/stdlib.ts b/client/space_lua/stdlib.ts index 2f90aea1..aac2bcf9 100644 --- a/client/space_lua/stdlib.ts +++ b/client/space_lua/stdlib.ts @@ -44,13 +44,11 @@ const printFunction = new LuaBuiltinFunction({ ...(await Promise.all(args.map((v) => luaToString(v)))), ); }, - documentation: { - description: - "Prints string representations of its arguments to the runtime log.", - signatures: ["print(...)"], - parameters: [{ name: "...", description: "Values to print." }], - examples: [{ code: 'print("Hello, world!")' }], - }, + description: + "Prints string representations of its arguments to the runtime log.", + signatures: ["print(...)"], + parameters: [{ name: "...", description: "Values to print." }], + examples: [{ code: 'print("Hello, world!")' }], }); const assertFunction = new LuaBuiltinFunction({ @@ -59,20 +57,18 @@ const assertFunction = new LuaBuiltinFunction({ throw new LuaRuntimeError(`Assertion failed: ${message}`, sf); } }, - documentation: { - description: - "Raises an error when a value is falsy; otherwise completes successfully.", - parameters: [ - { name: "value", description: "Condition to test." }, - { - name: "message", - type: "string", - description: "Error detail.", - optional: true, - }, - ], - examples: [{ code: 'assert(user ~= nil, "user is required")' }], - }, + description: + "Raises an error when a value is falsy; otherwise completes successfully.", + parameters: [ + { name: "value", description: "Condition to test." }, + { + name: "message", + type: "string", + description: "Error detail.", + optional: true, + }, + ], + examples: [{ code: 'assert(user ~= nil, "user is required")' }], }); const ipairsFunction = new LuaBuiltinFunction({ @@ -90,19 +86,17 @@ const ipairsFunction = new LuaBuiltinFunction({ return new LuaMultiRes([i, v]); }; }, - documentation: { - description: - "Returns an iterator over consecutive integer keys starting at 1 and stopping at the first `nil`.", - parameters: [{ name: "table", type: "table" }], - returns: [ - { type: "function", description: "Iterator yielding index and value." }, - ], - examples: [ - { - code: 'for i, fruit in ipairs({"apple", "banana"}) do\n print(i, fruit)\nend', - }, - ], - }, + description: + "Returns an iterator over consecutive integer keys starting at 1 and stopping at the first `nil`.", + parameters: [{ name: "table", type: "table" }], + returns: [ + { type: "function", description: "Iterator yielding index and value." }, + ], + examples: [ + { + code: 'for i, fruit in ipairs({"apple", "banana"}) do\n print(i, fruit)\nend', + }, + ], }); const pairsFunction = new LuaBuiltinFunction({ @@ -146,22 +140,20 @@ const pairsFunction = new LuaBuiltinFunction({ // Must return (iter, state, control) for generic for return new LuaMultiRes([iter, t, null]); }, - documentation: { - description: - "Returns an iterator over all table key-value pairs, respecting `__pairs`.", - parameters: [{ name: "table", type: "table" }], - returns: [ - { - type: "function", - description: "Iterator plus its state and initial control value.", - }, - ], - examples: [ - { - code: 'for key, value in pairs({name = "Ada", age = 36}) do\n print(key, value)\nend', - }, - ], - }, + description: + "Returns an iterator over all table key-value pairs, respecting `__pairs`.", + parameters: [{ name: "table", type: "table" }], + returns: [ + { + type: "function", + description: "Iterator plus its state and initial control value.", + }, + ], + examples: [ + { + code: 'for key, value in pairs({name = "Ada", age = 36}) do\n print(key, value)\nend', + }, + ], }); export const eachFunction = new LuaBuiltinFunction({ @@ -177,28 +169,24 @@ export const eachFunction = new LuaBuiltinFunction({ return result; }; }, - documentation: { - description: - "Returns a Space Lua iterator over array-like values without yielding indices.", - parameters: [{ name: "table", type: "table" }], - returns: [{ type: "function", description: "Iterator yielding values." }], - examples: [ - { - code: 'for fruit in each({"apple", "banana"}) do\n print(fruit)\nend', - }, - ], - }, + description: + "Returns a Space Lua iterator over array-like values without yielding indices.", + parameters: [{ name: "table", type: "table" }], + returns: [{ type: "function", description: "Iterator yielding values." }], + examples: [ + { + code: 'for fruit in each({"apple", "banana"}) do\n print(fruit)\nend', + }, + ], }); const typeFunction = new LuaBuiltinFunction({ callback: (_sf, value: LuaValue): string | Promise => { return luaTypeOf(value); }, - documentation: { - description: "Returns the Lua type name of a value.", - parameters: [{ name: "value" }], - returns: [{ type: "string" }], - }, + description: "Returns the Lua type name of a value.", + parameters: [{ name: "value" }], + returns: [{ type: "string" }], }); // tostring() checks `__tostring` metamethod first (with live SF), then @@ -226,12 +214,10 @@ const tostringFunction = new LuaBuiltinFunction({ } return luaToString(value); }, - documentation: { - description: - "Converts a value to a string, respecting its `__tostring` metamethod.", - parameters: [{ name: "value" }], - returns: [{ type: "string" }], - }, + description: + "Converts a value to a string, respecting its `__tostring` metamethod.", + parameters: [{ name: "value" }], + returns: [{ type: "string" }], }); const tonumberFunction = new LuaBuiltinFunction({ @@ -267,30 +253,26 @@ const tonumberFunction = new LuaBuiltinFunction({ return result.value; }, - documentation: { - description: - "Converts a number or numeric string to a Lua number, optionally in a base from 2 through 36.", - signatures: [ - "tonumber(value): number|nil", - "tonumber(value, base): integer|nil", - ], - parameters: [ - { name: "value", type: "number|string" }, - { name: "base", type: "integer", optional: true }, - ], - returns: [{ type: "number|nil" }], - examples: [{ code: 'print(tonumber("2a", 16)) -- 42' }], - }, + description: + "Converts a number or numeric string to a Lua number, optionally in a base from 2 through 36.", + signatures: [ + "tonumber(value): number|nil", + "tonumber(value, base): integer|nil", + ], + parameters: [ + { name: "value", type: "number|string" }, + { name: "base", type: "integer", optional: true }, + ], + returns: [{ type: "number|nil" }], + examples: [{ code: 'print(tonumber("2a", 16)) -- 42' }], }); const errorFunction = new LuaBuiltinFunction({ callback: (sf, message: string) => { throw new LuaRuntimeError(message, sf); }, - documentation: { - description: "Raises a Lua runtime error with the supplied message.", - parameters: [{ name: "message", type: "string" }], - }, + description: "Raises a Lua runtime error with the supplied message.", + parameters: [{ name: "message", type: "string" }], }); async function pcallBoundary( @@ -340,22 +322,20 @@ const pcallFunction = new LuaBuiltinFunction({ } return new LuaMultiRes([false, res.message]); }, - documentation: { - description: - "Calls a function in protected mode and returns a success flag followed by results or an error message.", - signatures: ["pcall(function, ...): boolean, ..."], - parameters: [ - { name: "function", type: "function" }, - { name: "...", description: "Arguments passed to the function." }, - ], - returns: [ - { type: "boolean", description: "Whether the call succeeded." }, - { description: "Call results or error message." }, - ], - examples: [ - { code: "local ok, result = pcall(function() return mightFail() end)" }, - ], - }, + description: + "Calls a function in protected mode and returns a success flag followed by results or an error message.", + signatures: ["pcall(function, ...): boolean, ..."], + parameters: [ + { name: "function", type: "function" }, + { name: "...", description: "Arguments passed to the function." }, + ], + returns: [ + { type: "boolean", description: "Whether the call succeeded." }, + { description: "Call results or error message." }, + ], + examples: [ + { code: "local ok, result = pcall(function() return mightFail() end)" }, + ], }); const xpcallFunction = new LuaBuiltinFunction({ @@ -374,25 +354,23 @@ const xpcallFunction = new LuaBuiltinFunction({ const outVals = hr instanceof LuaMultiRes ? hr.flatten().values : [hr]; return new LuaMultiRes([false, ...outVals]); }, - documentation: { - description: - "Calls a function in protected mode and transforms any error with an error handler.", - signatures: ["xpcall(function, errorHandler, ...): boolean, ..."], - parameters: [ - { name: "function", type: "function" }, - { name: "errorHandler", type: "function" }, - { name: "...", description: "Arguments passed to the function." }, - ], - returns: [ - { type: "boolean", description: "Whether the call succeeded." }, - { description: "Call results or handler results." }, - ], - examples: [ - { - code: 'local ok, message = xpcall(riskyOperation, function(err)\n return "Operation failed: " .. tostring(err)\nend)', - }, - ], - }, + description: + "Calls a function in protected mode and transforms any error with an error handler.", + signatures: ["xpcall(function, errorHandler, ...): boolean, ..."], + parameters: [ + { name: "function", type: "function" }, + { name: "errorHandler", type: "function" }, + { name: "...", description: "Arguments passed to the function." }, + ], + returns: [ + { type: "boolean", description: "Whether the call succeeded." }, + { description: "Call results or handler results." }, + ], + examples: [ + { + code: 'local ok, message = xpcall(riskyOperation, function(err)\n return "Operation failed: " .. tostring(err)\nend)', + }, + ], }); const setmetatableFunction = new LuaBuiltinFunction({ @@ -403,44 +381,38 @@ const setmetatableFunction = new LuaBuiltinFunction({ table.metatable = metatable; return table; }, - documentation: { - description: "Sets a table's metatable and returns the table.", - parameters: [ - { name: "table", type: "table" }, - { name: "metatable", type: "table" }, - ], - returns: [{ type: "table" }], - }, + description: "Sets a table's metatable and returns the table.", + parameters: [ + { name: "table", type: "table" }, + { name: "metatable", type: "table" }, + ], + returns: [{ type: "table" }], }); const rawlenFunction = new LuaBuiltinFunction({ callback: (_sf, value: LuaValue) => luaLen(value, _sf, true), - documentation: { - description: "Returns a string or table length without invoking `__len`.", - parameters: [{ name: "value", type: "string|table" }], - returns: [{ type: "integer" }], - }, + description: "Returns a string or table length without invoking `__len`.", + parameters: [{ name: "value", type: "string|table" }], + returns: [{ type: "integer" }], }); const rawsetFunction = new LuaBuiltinFunction({ callback: (_sf, table: LuaTable, key: LuaValue, value: LuaValue) => { return (table as any).rawSet(key, value); }, - documentation: { - description: - "Sets a table key without invoking `__newindex` and returns the table.", - parameters: [ - { name: "table", type: "table" }, - { name: "key" }, - { name: "value" }, - ], - returns: [{ type: "table" }], - examples: [ - { - code: 'local t = setmetatable({}, {__newindex = function() error("blocked") end})\nrawset(t, "name", "Ada")', - }, - ], - }, + description: + "Sets a table key without invoking `__newindex` and returns the table.", + parameters: [ + { name: "table", type: "table" }, + { name: "key" }, + { name: "value" }, + ], + returns: [{ type: "table" }], + examples: [ + { + code: 'local t = setmetatable({}, {__newindex = function() error("blocked") end})\nrawset(t, "name", "Ada")', + }, + ], }); const rawgetFunction = new LuaBuiltinFunction({ @@ -495,11 +467,9 @@ const rawgetFunction = new LuaBuiltinFunction({ const v = (table as Record)[k as any]; return v === undefined ? null : v; }, - documentation: { - description: "Reads a table key without invoking `__index`.", - parameters: [{ name: "table", type: "table" }, { name: "key" }], - returns: [{ description: "Stored value or `nil`." }], - }, + description: "Reads a table key without invoking `__index`.", + parameters: [{ name: "table", type: "table" }, { name: "key" }], + returns: [{ description: "Stored value or `nil`." }], }); const rawequalFunction = new LuaBuiltinFunction({ @@ -508,20 +478,16 @@ const rawequalFunction = new LuaBuiltinFunction({ const bv = isTaggedFloat(b) ? b.value : b; return av === bv; }, - documentation: { - description: "Tests two values for equality without invoking `__eq`.", - parameters: [{ name: "a" }, { name: "b" }], - returns: [{ type: "boolean" }], - }, + description: "Tests two values for equality without invoking `__eq`.", + parameters: [{ name: "a" }, { name: "b" }], + returns: [{ type: "boolean" }], }); const getmetatableFunction = new LuaBuiltinFunction({ callback: (_sf, table: LuaTable) => (table as any).metatable, - documentation: { - description: "Returns a table's metatable, or `nil` when none is set.", - parameters: [{ name: "table", type: "table" }], - returns: [{ type: "table|nil" }], - }, + description: "Returns a table's metatable, or `nil` when none is set.", + parameters: [{ name: "table", type: "table" }], + returns: [{ type: "table|nil" }], }); const dofileFunction = new LuaBuiltinFunction({ @@ -545,16 +511,14 @@ const dofileFunction = new LuaBuiltinFunction({ ); } }, - documentation: { - description: "Reads and executes a Lua source file from the current space.", - parameters: [ - { - name: "path", - type: "string", - description: "Space-relative Lua file path.", - }, - ], - }, + description: "Reads and executes a Lua source file from the current space.", + parameters: [ + { + name: "path", + type: "string", + description: "Space-relative Lua file path.", + }, + ], }); /** @@ -577,20 +541,18 @@ const selectFunction = new LuaBuiltinFunction({ return new LuaMultiRes(args.slice(args.length + index)); } }, - documentation: { - description: - "Returns the count of extra arguments or all arguments from a selected position onward.", - signatures: ['select("#", ...): integer', "select(index, ...): ..."], - parameters: [ - { - name: "index", - type: "integer|string", - description: "One-based index, negative index from the end, or `#`.", - }, - { name: "..." }, - ], - returns: [{ description: "Argument count or selected argument values." }], - }, + description: + "Returns the count of extra arguments or all arguments from a selected position onward.", + signatures: ['select("#", ...): integer', "select(index, ...): ..."], + parameters: [ + { + name: "index", + type: "integer|string", + description: "One-based index, negative index from the end, or `#`.", + }, + { name: "..." }, + ], + returns: [{ description: "Argument count or selected argument values." }], }); /** @@ -648,18 +610,16 @@ const nextFunction = new LuaBuiltinFunction({ } return new LuaMultiRes([key, luaGet(table, key, sf.astCtx ?? null, sf)]); }, - documentation: { - description: - "Returns the next table key and value after a given key, or the first pair when the key is omitted.", - parameters: [ - { name: "table", type: "table" }, - { name: "index", description: "Previous key.", optional: true }, - ], - returns: [ - { description: "Next key or `nil`." }, - { description: "Value at the next key." }, - ], - }, + description: + "Returns the next table key and value after a given key, or the first pair when the key is omitted.", + parameters: [ + { name: "table", type: "table" }, + { name: "index", description: "Previous key.", optional: true }, + ], + returns: [ + { description: "Next key or `nil`." }, + { description: "Value at the next key." }, + ], }); // Non-standard, but useful @@ -677,38 +637,34 @@ const someFunction = new LuaBuiltinFunction({ } return value; }, - documentation: { - description: - "Returns `nil` for empty Space Lua values and otherwise returns the value unchanged.", - parameters: [ - { - name: "value", - description: - "Value to normalize; blank strings, empty tables, infinities, and NaN are empty.", - }, - ], - returns: [{ description: "Original value or `nil`." }], - examples: [ - { - code: 'print(some(" ") or "empty")\nprint(some({}) or "empty")\nprint(some(0))', - }, - ], - }, + description: + "Returns `nil` for empty Space Lua values and otherwise returns the value unchanged.", + parameters: [ + { + name: "value", + description: + "Value to normalize; blank strings, empty tables, infinities, and NaN are empty.", + }, + ], + returns: [{ description: "Original value or `nil`." }], + examples: [ + { + code: 'print(some(" ") or "empty")\nprint(some({}) or "empty")\nprint(some(0))', + }, + ], }); const loadFunction = new LuaBuiltinFunction({ callback: (sf, s) => luaLoad(s, sf), - documentation: { - description: - "Compiles Lua source into a callable chunk without executing it.", - parameters: [ - { name: "chunk", type: "string", description: "Lua source code." }, - ], - returns: [ - { type: "function|nil", description: "Compiled chunk or `nil`." }, - { type: "string", description: "Compilation error when unsuccessful." }, - ], - }, + description: + "Compiles Lua source into a callable chunk without executing it.", + parameters: [ + { name: "chunk", type: "string", description: "Lua source code." }, + ], + returns: [ + { type: "function|nil", description: "Compiled chunk or `nil`." }, + { type: "string", description: "Compilation error when unsuccessful." }, + ], }); function annotateBuiltinApi( diff --git a/client/space_lua/stdlib/crypto.ts b/client/space_lua/stdlib/crypto.ts index f6332004..eb46f113 100644 --- a/client/space_lua/stdlib/crypto.ts +++ b/client/space_lua/stdlib/crypto.ts @@ -6,12 +6,10 @@ export const cryptoApi = new LuaTable({ callback: (_sf, s: string | Uint8Array): Promise => { return hashSHA256(s); }, - documentation: { - description: "Computes the SHA-256 digest of a string or byte buffer.", - parameters: [ - { name: "data", type: "string|bytes", description: "Data to hash." }, - ], - returns: [{ type: "string", description: "Hexadecimal SHA-256 digest." }], - }, + description: "Computes the SHA-256 digest of a string or byte buffer.", + parameters: [ + { name: "data", type: "string|bytes", description: "Data to hash." }, + ], + returns: [{ type: "string", description: "Hexadecimal SHA-256 digest." }], }), }); diff --git a/client/space_lua/stdlib/encoding.ts b/client/space_lua/stdlib/encoding.ts index 6c8bb6c3..3544ea40 100644 --- a/client/space_lua/stdlib/encoding.ts +++ b/client/space_lua/stdlib/encoding.ts @@ -6,40 +6,32 @@ export const encodingApi = new LuaTable({ callback: (_sf, s: string | Uint8Array): string => { return base64Encode(s); }, - documentation: { - description: "Encodes a string or byte buffer as Base64.", - parameters: [{ name: "data", type: "string|bytes" }], - returns: [{ type: "string", description: "Base64-encoded data." }], - }, + description: "Encodes a string or byte buffer as Base64.", + parameters: [{ name: "data", type: "string|bytes" }], + returns: [{ type: "string", description: "Base64-encoded data." }], }), base64Decode: new LuaBuiltinFunction({ callback: (_sf, s: string): Uint8Array => { return base64Decode(s); }, - documentation: { - description: "Decodes a Base64 string into a byte buffer.", - parameters: [{ name: "encoded", type: "string" }], - returns: [{ type: "bytes", description: "Decoded bytes." }], - }, + description: "Decodes a Base64 string into a byte buffer.", + parameters: [{ name: "encoded", type: "string" }], + returns: [{ type: "bytes", description: "Decoded bytes." }], }), utf8Encode: new LuaBuiltinFunction({ callback: (_sf, s: string): Uint8Array => { return new TextEncoder().encode(s); }, - documentation: { - description: "Encodes a UTF-8 string into a byte buffer.", - parameters: [{ name: "value", type: "string" }], - returns: [{ type: "bytes", description: "UTF-8 encoded bytes." }], - }, + description: "Encodes a UTF-8 string into a byte buffer.", + parameters: [{ name: "value", type: "string" }], + returns: [{ type: "bytes", description: "UTF-8 encoded bytes." }], }), utf8Decode: new LuaBuiltinFunction({ callback: (_sf, data: Uint8Array): string => { return new TextDecoder().decode(data); }, - documentation: { - description: "Decodes a UTF-8 byte buffer into a string.", - parameters: [{ name: "data", type: "bytes" }], - returns: [{ type: "string", description: "Decoded text." }], - }, + description: "Decodes a UTF-8 byte buffer into a string.", + parameters: [{ name: "data", type: "bytes" }], + returns: [{ type: "string", description: "Decoded text." }], }), }); diff --git a/client/space_lua/stdlib/js.ts b/client/space_lua/stdlib/js.ts index e4681093..530a5842 100644 --- a/client/space_lua/stdlib/js.ts +++ b/client/space_lua/stdlib/js.ts @@ -17,25 +17,21 @@ export const jsApi = new LuaTable({ callback: (sf, constructorFn: any, ...args) => { return new constructorFn(...args.map((v) => luaValueToJS(v, sf))); }, - documentation: { - description: "Creates an instance of a JavaScript class.", - signatures: ["js.new(constructor, ...): userdata"], - parameters: [ - { - name: "constructor", - type: "userdata", - description: "JavaScript constructor function.", - }, - { - name: "...", - description: "Constructor arguments converted to JavaScript values.", - }, - ], - returns: [{ type: "userdata", description: "New JavaScript instance." }], - examples: [ - { code: 'local value = js.new(js.window.Date, "2024-03-14")' }, - ], - }, + description: "Creates an instance of a JavaScript class.", + signatures: ["js.new(constructor, ...): userdata"], + parameters: [ + { + name: "constructor", + type: "userdata", + description: "JavaScript constructor function.", + }, + { + name: "...", + description: "Constructor arguments converted to JavaScript values.", + }, + ], + returns: [{ type: "userdata", description: "New JavaScript instance." }], + examples: [{ code: 'local value = js.new(js.window.Date, "2024-03-14")' }], }), /** * Imports a JavaScript module. @@ -51,19 +47,17 @@ export const jsApi = new LuaTable({ } return m; }, - documentation: { - description: "Dynamically imports a JavaScript module from a URL.", - parameters: [{ name: "url", type: "string", description: "Module URL." }], - returns: [ - { - type: "userdata", - description: "Imported module, with a sole default export unwrapped.", - }, - ], - examples: [ - { code: 'local lib = js.import("https://esm.sh/lodash@4.17.21")' }, - ], - }, + description: "Dynamically imports a JavaScript module from a URL.", + parameters: [{ name: "url", type: "string", description: "Module URL." }], + returns: [ + { + type: "userdata", + description: "Imported module, with a sole default export unwrapped.", + }, + ], + examples: [ + { code: 'local lib = js.import("https://esm.sh/lodash@4.17.21")' }, + ], }), /** * Like `js.import`, but takes a path to a file in the current space (e.g. @@ -83,27 +77,25 @@ export const jsApi = new LuaTable({ } return m; }, - documentation: { - description: - "Imports a JavaScript module from a file in the current space.", - parameters: [ - { - name: "path", - type: "string", - description: - "Space-relative module path, with an optional leading slash.", - }, - ], - returns: [ - { - type: "userdata", - description: "Imported module, with a sole default export unwrapped.", - }, - ], - examples: [ - { code: 'local acme = js.importFromSpace("Library/acme/acme.js")' }, - ], - }, + description: + "Imports a JavaScript module from a file in the current space.", + parameters: [ + { + name: "path", + type: "string", + description: + "Space-relative module path, with an optional leading slash.", + }, + ], + returns: [ + { + type: "userdata", + description: "Imported module, with a sole default export unwrapped.", + }, + ], + examples: [ + { code: 'local acme = js.importFromSpace("Library/acme/acme.js")' }, + ], }), eachIterable: new LuaBuiltinFunction({ callback: (_sf, val) => { @@ -116,27 +108,25 @@ export const jsApi = new LuaTable({ return result.value; }; }, - documentation: { - description: "Creates a Lua iterator over a JavaScript async iterable.", - parameters: [ - { - name: "iterable", - type: "userdata", - description: "JavaScript async iterable.", - }, - ], - returns: [ - { - type: "function", - description: "Iterator yielding successive JavaScript values.", - }, - ], - examples: [ - { - code: "for value in js.eachIterable(someJsAsyncIterable) do\n print(value)\nend", - }, - ], - }, + description: "Creates a Lua iterator over a JavaScript async iterable.", + parameters: [ + { + name: "iterable", + type: "userdata", + description: "JavaScript async iterable.", + }, + ], + returns: [ + { + type: "function", + description: "Iterator yielding successive JavaScript values.", + }, + ], + examples: [ + { + code: "for value in js.eachIterable(someJsAsyncIterable) do\n print(value)\nend", + }, + ], }), /** * Converts a JavaScript value to a Lua value. @@ -145,14 +135,12 @@ export const jsApi = new LuaTable({ */ tolua: new LuaBuiltinFunction({ callback: (_sf, val) => jsToLuaValue(val), - documentation: { - description: "Converts a JavaScript value to its Lua representation.", - parameters: [ - { name: "value", description: "JavaScript value to convert." }, - ], - returns: [{ description: "Converted Lua value." }], - examples: [{ code: "local luaTable = js.tolua(jsArray)" }], - }, + description: "Converts a JavaScript value to its Lua representation.", + parameters: [ + { name: "value", description: "JavaScript value to convert." }, + ], + returns: [{ description: "Converted Lua value." }], + examples: [{ code: "local luaTable = js.tolua(jsArray)" }], }), /** * Converts a Lua value to a JavaScript value. @@ -161,12 +149,10 @@ export const jsApi = new LuaTable({ */ tojs: new LuaBuiltinFunction({ callback: (sf, val) => luaValueToJS(val, sf), - documentation: { - description: "Converts a Lua value to its JavaScript representation.", - parameters: [{ name: "value", description: "Lua value to convert." }], - returns: [{ description: "Converted JavaScript value." }], - examples: [{ code: "local jsArray = js.tojs({1, 2, 3})" }], - }, + description: "Converts a Lua value to its JavaScript representation.", + parameters: [{ name: "value", description: "Lua value to convert." }], + returns: [{ description: "Converted JavaScript value." }], + examples: [{ code: "local jsArray = js.tojs({1, 2, 3})" }], }), /** * Logs a message to the console. @@ -176,11 +162,9 @@ export const jsApi = new LuaTable({ callback: (_sf, ...args) => { console.log(...args); }, - documentation: { - description: "Logs values to the JavaScript console.", - parameters: [{ name: "...", description: "Values to log." }], - examples: [{ code: 'js.log("User data:", {name = "Ada"})' }], - }, + description: "Logs values to the JavaScript console.", + parameters: [{ name: "...", description: "Values to log." }], + examples: [{ code: 'js.log("User data:", {name = "Ada"})' }], }), /** * Converts a Lua value to a JSON string. @@ -189,12 +173,10 @@ export const jsApi = new LuaTable({ */ stringify: new LuaBuiltinFunction({ callback: (_sf, val) => JSON.stringify(val), - documentation: { - description: "Serializes a value as JSON using JavaScript semantics.", - parameters: [{ name: "value", description: "Value to serialize." }], - returns: [{ type: "string", description: "JSON representation." }], - examples: [{ code: "print(js.stringify({1, 2, 3})) -- [1,2,3]" }], - }, + description: "Serializes a value as JSON using JavaScript semantics.", + parameters: [{ name: "value", description: "Value to serialize." }], + returns: [{ type: "string", description: "JSON representation." }], + examples: [{ code: "print(js.stringify({1, 2, 3})) -- [1,2,3]" }], }), // Expose the global window object diff --git a/client/space_lua/stdlib/load.ts b/client/space_lua/stdlib/load.ts index d00bb70a..654e4a39 100644 --- a/client/space_lua/stdlib/load.ts +++ b/client/space_lua/stdlib/load.ts @@ -46,11 +46,9 @@ export function luaLoad(code: LuaValue, sf: LuaStackFrame): LuaValue { return null; } }, - documentation: { - description: "Executes the Lua chunk compiled by `load`.", - signatures: ["function(...)"], - returns: [{ description: "Values returned by the compiled chunk." }], - }, + description: "Executes the Lua chunk compiled by `load`.", + signatures: ["function(...)"], + returns: [{ description: "Values returned by the compiled chunk." }], }); return runner; diff --git a/client/space_lua/stdlib/math.ts b/client/space_lua/stdlib/math.ts index 198c98ba..a40d96bb 100644 --- a/client/space_lua/stdlib/math.ts +++ b/client/space_lua/stdlib/math.ts @@ -45,14 +45,10 @@ export const mathApi = new LuaTable({ } return null; }, - documentation: { - description: - "Returns `integer` or `float` for a number, or `nil` for other values.", - parameters: [{ name: "x", description: "Value to inspect." }], - returns: [ - { type: "string|nil", description: "Numeric subtype or `nil`." }, - ], - }, + description: + "Returns `integer` or `float` for a number, or `nil` for other values.", + parameters: [{ name: "x", description: "Value to inspect." }], + returns: [{ type: "string|nil", description: "Numeric subtype or `nil`." }], }), /** @@ -77,14 +73,12 @@ export const mathApi = new LuaTable({ } return null; }, - documentation: { - description: - "Converts a value to an integer when it has an exact finite integral representation.", - parameters: [{ name: "x", description: "Value to convert." }], - returns: [ - { type: "integer|nil", description: "Converted integer or `nil`." }, - ], - }, + description: + "Converts a value to an integer when it has an exact finite integral representation.", + parameters: [{ name: "x", description: "Value to convert." }], + returns: [ + { type: "integer|nil", description: "Converted integer or `nil`." }, + ], }), /** @@ -106,25 +100,23 @@ export const mathApi = new LuaTable({ throw new LuaRuntimeError(e.message, _sf); } }, - documentation: { - description: - "Returns a pseudo-random float or an integer in a requested inclusive range.", - signatures: [ - "math.random(): number", - "math.random(n): integer", - "math.random(m, n): integer", - ], - parameters: [ - { name: "m", type: "integer", optional: true }, - { name: "n", type: "integer", optional: true }, - ], - returns: [{ type: "number", description: "Pseudo-random result." }], - examples: [ - { - code: "print(math.random())\nprint(math.random(10))\nprint(math.random(5, 10))", - }, - ], - }, + description: + "Returns a pseudo-random float or an integer in a requested inclusive range.", + signatures: [ + "math.random(): number", + "math.random(n): integer", + "math.random(m, n): integer", + ], + parameters: [ + { name: "m", type: "integer", optional: true }, + { name: "n", type: "integer", optional: true }, + ], + returns: [{ type: "number", description: "Pseudo-random result." }], + examples: [ + { + code: "print(math.random())\nprint(math.random(10))\nprint(math.random(5, 10))", + }, + ], }), /** * Seeds the pseudo-random generator. With no arguments, uses a @@ -137,78 +129,64 @@ export const mathApi = new LuaTable({ const [s1, s2] = prng.randomseed(x, y); return new LuaMultiRes([s1, s2]); }, - documentation: { - description: - "Seeds the pseudo-random generator and returns the two seeds used.", - signatures: [ - "math.randomseed(): integer, integer", - "math.randomseed(x, y): integer, integer", - ], - parameters: [ - { name: "x", type: "integer", optional: true }, - { name: "y", type: "integer", optional: true }, - ], - returns: [ - { type: "integer", description: "First seed." }, - { type: "integer", description: "Second seed." }, - ], - }, + description: + "Seeds the pseudo-random generator and returns the two seeds used.", + signatures: [ + "math.randomseed(): integer, integer", + "math.randomseed(x, y): integer, integer", + ], + parameters: [ + { name: "x", type: "integer", optional: true }, + { name: "y", type: "integer", optional: true }, + ], + returns: [ + { type: "integer", description: "First seed." }, + { type: "integer", description: "Second seed." }, + ], }), // Basic functions abs: new LuaBuiltinFunction({ callback: (_sf, x: number) => Math.abs(untagNumber(x)), - documentation: { - description: "Returns the absolute value of `x`.", - parameters: [{ name: "x", type: "number" }], - returns: [{ type: "number" }], - }, + description: "Returns the absolute value of `x`.", + parameters: [{ name: "x", type: "number" }], + returns: [{ type: "number" }], }), ceil: new LuaBuiltinFunction({ callback: (_sf, x: number) => Math.ceil(untagNumber(x)), - documentation: { - description: "Returns the smallest integer greater than or equal to `x`.", - parameters: [{ name: "x", type: "number" }], - returns: [{ type: "integer" }], - }, + description: "Returns the smallest integer greater than or equal to `x`.", + parameters: [{ name: "x", type: "number" }], + returns: [{ type: "integer" }], }), floor: new LuaBuiltinFunction({ callback: (_sf, x: number) => Math.floor(untagNumber(x)), - documentation: { - description: "Returns the largest integer less than or equal to `x`.", - parameters: [{ name: "x", type: "number" }], - returns: [{ type: "integer" }], - }, + description: "Returns the largest integer less than or equal to `x`.", + parameters: [{ name: "x", type: "number" }], + returns: [{ type: "integer" }], }), max: new LuaBuiltinFunction({ callback: (_sf, ...args: number[]) => Math.max(...args.map(untagNumber)), - documentation: { - description: "Returns the greatest of its arguments.", - signatures: ["math.max(x, ...): number"], - returns: [{ type: "number" }], - }, + description: "Returns the greatest of its arguments.", + signatures: ["math.max(x, ...): number"], + returns: [{ type: "number" }], }), min: new LuaBuiltinFunction({ callback: (_sf, ...args: number[]) => Math.min(...args.map(untagNumber)), - documentation: { - description: "Returns the least of its arguments.", - signatures: ["math.min(x, ...): number"], - returns: [{ type: "number" }], - }, + description: "Returns the least of its arguments.", + signatures: ["math.min(x, ...): number"], + returns: [{ type: "number" }], }), // Rounding and remainder fmod: new LuaBuiltinFunction({ callback: (_sf, x: number, y: number) => untagNumber(x) % untagNumber(y), - documentation: { - description: - "Returns the remainder of `x / y` with the quotient rounded toward zero.", - parameters: [ - { name: "x", type: "number" }, - { name: "y", type: "number" }, - ], - returns: [{ type: "number" }], - }, + description: + "Returns the remainder of `x / y` with the quotient rounded toward zero.", + parameters: [ + { name: "x", type: "number" }, + { name: "y", type: "number" }, + ], + returns: [{ type: "number" }], }), modf: new LuaBuiltinFunction({ callback: (_sf, x: number) => { @@ -218,15 +196,13 @@ export const mathApi = new LuaTable({ const frac = makeLuaFloat(xn - int); return new LuaMultiRes([int, frac]); }, - documentation: { - description: "Splits `x` into its integral and fractional parts.", - parameters: [{ name: "x", type: "number" }], - returns: [ - { type: "integer", description: "Integral part." }, - { type: "float", description: "Fractional part." }, - ], - examples: [{ code: "local integer, fraction = math.modf(3.14)" }], - }, + description: "Splits `x` into its integral and fractional parts.", + parameters: [{ name: "x", type: "number" }], + returns: [ + { type: "integer", description: "Integral part." }, + { type: "float", description: "Fractional part." }, + ], + examples: [{ code: "local integer, fraction = math.modf(3.14)" }], }), // Returns m and e such that x = m * 2^e, 0.5 <= |m| < 1 (or m=0 when x=0). @@ -251,39 +227,33 @@ export const mathApi = new LuaTable({ } return new LuaMultiRes([m, e]); }, - documentation: { - description: - "Decomposes `x` into a normalized fraction and a power-of-two exponent.", - parameters: [{ name: "x", type: "number" }], - returns: [ - { type: "number", description: "Fraction." }, - { type: "integer", description: "Exponent." }, - ], - }, + description: + "Decomposes `x` into a normalized fraction and a power-of-two exponent.", + parameters: [{ name: "x", type: "number" }], + returns: [ + { type: "number", description: "Fraction." }, + { type: "integer", description: "Exponent." }, + ], }), // Returns m * 2^e (the inverse of frexp). Mirrors C99/Lua. ldexp: new LuaBuiltinFunction({ callback: (_sf, m: number, e: number) => untagNumber(m) * 2 ** untagNumber(e), - documentation: { - description: "Returns `m * 2^e`, the inverse of `math.frexp`.", - parameters: [ - { name: "m", type: "number" }, - { name: "e", type: "integer" }, - ], - returns: [{ type: "number" }], - }, + description: "Returns `m * 2^e`, the inverse of `math.frexp`.", + parameters: [ + { name: "m", type: "number" }, + { name: "e", type: "integer" }, + ], + returns: [{ type: "number" }], }), // Power and logarithms exp: new LuaBuiltinFunction({ callback: (_sf, x: number) => Math.exp(untagNumber(x)), - documentation: { - description: "Returns `e` raised to `x`.", - parameters: [{ name: "x", type: "number" }], - returns: [{ type: "number" }], - }, + description: "Returns `e` raised to `x`.", + parameters: [{ name: "x", type: "number" }], + returns: [{ type: "number" }], }), log: new LuaBuiltinFunction({ callback: (_sf, x: number, base?: number) => { @@ -292,79 +262,63 @@ export const mathApi = new LuaTable({ } return Math.log(untagNumber(x)) / Math.log(untagNumber(base)); }, - documentation: { - description: - "Returns the logarithm of `x`, using the natural base unless another base is supplied.", - parameters: [ - { name: "x", type: "number" }, - { name: "base", type: "number", optional: true }, - ], - returns: [{ type: "number" }], - examples: [{ code: "print(math.log(100, 10)) -- 2" }], - }, + description: + "Returns the logarithm of `x`, using the natural base unless another base is supplied.", + parameters: [ + { name: "x", type: "number" }, + { name: "base", type: "number", optional: true }, + ], + returns: [{ type: "number" }], + examples: [{ code: "print(math.log(100, 10)) -- 2" }], }), // Power function (deprecated in Lua 5.4 but retained for compatibility) pow: new LuaBuiltinFunction({ callback: (_sf, x: number, y: number) => untagNumber(x) ** untagNumber(y), - documentation: { - description: "Returns `x` raised to the power `y`.", - parameters: [ - { name: "x", type: "number" }, - { name: "y", type: "number" }, - ], - returns: [{ type: "number" }], - deprecated: "Use the `^` operator instead.", - }, + description: "Returns `x` raised to the power `y`.", + parameters: [ + { name: "x", type: "number" }, + { name: "y", type: "number" }, + ], + returns: [{ type: "number" }], + deprecated: "Use the `^` operator instead.", }), sqrt: new LuaBuiltinFunction({ callback: (_sf, x: number) => Math.sqrt(untagNumber(x)), - documentation: { - description: "Returns the square root of `x`.", - parameters: [{ name: "x", type: "number" }], - returns: [{ type: "number" }], - }, + description: "Returns the square root of `x`.", + parameters: [{ name: "x", type: "number" }], + returns: [{ type: "number" }], }), // Trigonometric functions cos: new LuaBuiltinFunction({ callback: (_sf, x: number) => Math.cos(untagNumber(x)), - documentation: { - description: "Returns the cosine of `x` radians.", - parameters: [{ name: "x", type: "number" }], - returns: [{ type: "number" }], - }, + description: "Returns the cosine of `x` radians.", + parameters: [{ name: "x", type: "number" }], + returns: [{ type: "number" }], }), sin: new LuaBuiltinFunction({ callback: (_sf, x: number) => Math.sin(untagNumber(x)), - documentation: { - description: "Returns the sine of `x` radians.", - parameters: [{ name: "x", type: "number" }], - returns: [{ type: "number" }], - }, + description: "Returns the sine of `x` radians.", + parameters: [{ name: "x", type: "number" }], + returns: [{ type: "number" }], }), tan: new LuaBuiltinFunction({ callback: (_sf, x: number) => Math.tan(untagNumber(x)), - documentation: { - description: "Returns the tangent of `x` radians.", - parameters: [{ name: "x", type: "number" }], - returns: [{ type: "number" }], - }, + description: "Returns the tangent of `x` radians.", + parameters: [{ name: "x", type: "number" }], + returns: [{ type: "number" }], }), acos: new LuaBuiltinFunction({ callback: (_sf, x: number) => Math.acos(untagNumber(x)), - documentation: { - description: "Returns the arc cosine of `x` in radians.", - parameters: [{ name: "x", type: "number" }], - returns: [{ type: "number" }], - }, + description: "Returns the arc cosine of `x` in radians.", + parameters: [{ name: "x", type: "number" }], + returns: [{ type: "number" }], }), asin: new LuaBuiltinFunction({ callback: (_sf, x: number) => Math.asin(untagNumber(x)), - documentation: { - description: "Returns the arc sine of `x` in radians.", - parameters: [{ name: "x", type: "number" }], - returns: [{ type: "number" }], - }, + description: "Returns the arc sine of `x` in radians.", + parameters: [{ name: "x", type: "number" }], + returns: [{ type: "number" }], }), atan: new LuaBuiltinFunction({ callback: (_sf, y: number, x?: number) => { @@ -373,77 +327,63 @@ export const mathApi = new LuaTable({ } return Math.atan2(untagNumber(y), untagNumber(x)); }, - documentation: { - description: - "Returns the arc tangent of `y/x` in radians, using `1` for omitted `x`.", - parameters: [ - { name: "y", type: "number" }, - { name: "x", type: "number", optional: true }, - ], - returns: [{ type: "number" }], - }, + description: + "Returns the arc tangent of `y/x` in radians, using `1` for omitted `x`.", + parameters: [ + { name: "y", type: "number" }, + { name: "x", type: "number", optional: true }, + ], + returns: [{ type: "number" }], }), // Hyperbolic functions (deprecated in Lua 5.4 but retained for compatibility) cosh: new LuaBuiltinFunction({ callback: (_sf, x: number) => Math.cosh(untagNumber(x)), - documentation: { - description: "Returns the hyperbolic cosine of `x`.", - parameters: [{ name: "x", type: "number" }], - returns: [{ type: "number" }], - deprecated: "Retained for compatibility with older Lua versions.", - }, + description: "Returns the hyperbolic cosine of `x`.", + parameters: [{ name: "x", type: "number" }], + returns: [{ type: "number" }], + deprecated: "Retained for compatibility with older Lua versions.", }), sinh: new LuaBuiltinFunction({ callback: (_sf, x: number) => Math.sinh(untagNumber(x)), - documentation: { - description: "Returns the hyperbolic sine of `x`.", - parameters: [{ name: "x", type: "number" }], - returns: [{ type: "number" }], - deprecated: "Retained for compatibility with older Lua versions.", - }, + description: "Returns the hyperbolic sine of `x`.", + parameters: [{ name: "x", type: "number" }], + returns: [{ type: "number" }], + deprecated: "Retained for compatibility with older Lua versions.", }), tanh: new LuaBuiltinFunction({ callback: (_sf, x: number) => Math.tanh(untagNumber(x)), - documentation: { - description: "Returns the hyperbolic tangent of `x`.", - parameters: [{ name: "x", type: "number" }], - returns: [{ type: "number" }], - deprecated: "Retained for compatibility with older Lua versions.", - }, + description: "Returns the hyperbolic tangent of `x`.", + parameters: [{ name: "x", type: "number" }], + returns: [{ type: "number" }], + deprecated: "Retained for compatibility with older Lua versions.", }), // Additional utility deg: new LuaBuiltinFunction({ callback: (_sf, x: number) => (untagNumber(x) * 180) / Math.PI, - documentation: { - description: "Converts an angle from radians to degrees.", - parameters: [{ name: "x", type: "number" }], - returns: [{ type: "number" }], - examples: [{ code: "print(math.deg(math.pi)) -- 180" }], - }, + description: "Converts an angle from radians to degrees.", + parameters: [{ name: "x", type: "number" }], + returns: [{ type: "number" }], + examples: [{ code: "print(math.deg(math.pi)) -- 180" }], }), rad: new LuaBuiltinFunction({ callback: (_sf, x: number) => (untagNumber(x) * Math.PI) / 180, - documentation: { - description: "Converts an angle from degrees to radians.", - parameters: [{ name: "x", type: "number" }], - returns: [{ type: "number" }], - }, + description: "Converts an angle from degrees to radians.", + parameters: [{ name: "x", type: "number" }], + returns: [{ type: "number" }], }), ult: new LuaBuiltinFunction({ callback: (_sf, m: number, n: number) => { return untagNumber(m) >>> 0 < untagNumber(n) >>> 0; }, - documentation: { - description: "Compares two integers as unsigned 32-bit values.", - parameters: [ - { name: "m", type: "integer" }, - { name: "n", type: "integer" }, - ], - returns: [{ type: "boolean" }], - examples: [{ code: "print(math.ult(2, 3)) -- true" }], - }, + description: "Compares two integers as unsigned 32-bit values.", + parameters: [ + { name: "m", type: "integer" }, + { name: "n", type: "integer" }, + ], + returns: [{ type: "boolean" }], + examples: [{ code: "print(math.ult(2, 3)) -- true" }], }), // Keep the cosineSimilarity utility function @@ -472,17 +412,13 @@ export const mathApi = new LuaTable({ return dotProduct / (Math.sqrt(normA) * Math.sqrt(normB)); }, - documentation: { - description: - "Returns the cosine similarity between two equal-length numeric vectors.", - parameters: [ - { name: "vecA", type: "table" }, - { name: "vecB", type: "table" }, - ], - returns: [{ type: "number", description: "Cosine similarity." }], - examples: [ - { code: "print(math.cosineSimilarity({1, 2, 3}, {4, 5, 6}))" }, - ], - }, + description: + "Returns the cosine similarity between two equal-length numeric vectors.", + parameters: [ + { name: "vecA", type: "table" }, + { name: "vecB", type: "table" }, + ], + returns: [{ type: "number", description: "Cosine similarity." }], + examples: [{ code: "print(math.cosineSimilarity({1, 2, 3}, {4, 5, 6}))" }], }), }); diff --git a/client/space_lua/stdlib/net.ts b/client/space_lua/stdlib/net.ts index 6f188c4d..ee9baae6 100644 --- a/client/space_lua/stdlib/net.ts +++ b/client/space_lua/stdlib/net.ts @@ -70,28 +70,26 @@ export const netApi = new LuaTable({ body: body, }; }, - documentation: { - description: - "Performs an HTTP request through the SilverBullet server to avoid browser CORS restrictions.", - signatures: ["net.proxyFetch(url, options?)"], - parameters: [ - { name: "url", type: "string", description: "URL to request." }, - { - name: "options", - type: "table", - description: - "Optional method, headers, body, and responseEncoding values.", - optional: true, - }, - ], - returns: [ - { - type: "table", - description: "Response status, headers, decoded body, and ok flag.", - }, - ], - see: "API/net", - }, + description: + "Performs an HTTP request through the SilverBullet server to avoid browser CORS restrictions.", + signatures: ["net.proxyFetch(url, options?)"], + parameters: [ + { name: "url", type: "string", description: "URL to request." }, + { + name: "options", + type: "table", + description: + "Optional method, headers, body, and responseEncoding values.", + optional: true, + }, + ], + returns: [ + { + type: "table", + description: "Response status, headers, decoded body, and ok flag.", + }, + ], + see: "API/net", }), readURI: new LuaNativeJSFunction({ callback: ( @@ -104,21 +102,19 @@ export const netApi = new LuaTable({ options, ); }, - documentation: { - description: "Reads content from a URI using the best matching service.", - signatures: ["net.readURI(uri, options?)"], - parameters: [ - { name: "uri", type: "string", description: "URI to read." }, - { - name: "options", - type: "table", - description: "Optional service-specific values such as encoding.", - optional: true, - }, - ], - returns: [{ description: "Content returned by the matching service." }], - see: "API/net", - }, + description: "Reads content from a URI using the best matching service.", + signatures: ["net.readURI(uri, options?)"], + parameters: [ + { name: "uri", type: "string", description: "URI to read." }, + { + name: "options", + type: "table", + description: "Optional service-specific values such as encoding.", + optional: true, + }, + ], + returns: [{ description: "Content returned by the matching service." }], + see: "API/net", }), writeURI: new LuaNativeJSFunction({ callback: (uri: string, content: string | Uint8Array) => { @@ -127,20 +123,18 @@ export const netApi = new LuaTable({ { uri, content }, ); }, - documentation: { - description: "Writes content to a URI using the best matching service.", - signatures: ["net.writeURI(uri, content)"], - parameters: [ - { name: "uri", type: "string", description: "URI to write." }, - { - name: "content", - type: "string|userdata", - description: "Text or binary content to write.", - }, - ], - returns: [{ description: "Result returned by the matching service." }], - see: "API/net", - }, + description: "Writes content to a URI using the best matching service.", + signatures: ["net.writeURI(uri, content)"], + parameters: [ + { name: "uri", type: "string", description: "URI to write." }, + { + name: "content", + type: "string|userdata", + description: "Text or binary content to write.", + }, + ], + returns: [{ description: "Result returned by the matching service." }], + see: "API/net", }), }); diff --git a/client/space_lua/stdlib/os.ts b/client/space_lua/stdlib/os.ts index ca652b06..20a4345f 100644 --- a/client/space_lua/stdlib/os.ts +++ b/client/space_lua/stdlib/os.ts @@ -310,28 +310,26 @@ export const osApi = new LuaTable({ return Math.floor(Date.now() / 1000); }, - documentation: { - description: - "Returns the current Unix timestamp or one built from a local date table.", - signatures: ["os.time(): integer", "os.time(dateTable): integer"], - parameters: [ - { - name: "dateTable", - type: "table", - description: - "Local date fields `year`, `month`, `day`, and optional `hour`, `min`, and `sec`.", - optional: true, - }, - ], - returns: [ - { type: "integer", description: "Seconds since the Unix epoch." }, - ], - examples: [ - { - code: "local timestamp = os.time({year = 2020, month = 1, day = 1})", - }, - ], - }, + description: + "Returns the current Unix timestamp or one built from a local date table.", + signatures: ["os.time(): integer", "os.time(dateTable): integer"], + parameters: [ + { + name: "dateTable", + type: "table", + description: + "Local date fields `year`, `month`, `day`, and optional `hour`, `min`, and `sec`.", + optional: true, + }, + ], + returns: [ + { type: "integer", description: "Seconds since the Unix epoch." }, + ], + examples: [ + { + code: "local timestamp = os.time({year = 2020, month = 1, day = 1})", + }, + ], }), // Returns the difference, from time `t1` to time `t2` in seconds @@ -340,17 +338,15 @@ export const osApi = new LuaTable({ callback: (_sf, t2: number, t1: number): number => { return t2 - t1; }, - documentation: { - description: - "Returns the difference in seconds from timestamp `t1` to `t2`.", - parameters: [ - { name: "t2", type: "number" }, - { name: "t1", type: "number" }, - ], - returns: [ - { type: "number", description: "The value `t2 - t1` in seconds." }, - ], - }, + description: + "Returns the difference in seconds from timestamp `t1` to `t2`.", + parameters: [ + { name: "t2", type: "number" }, + { name: "t1", type: "number" }, + ], + returns: [ + { type: "number", description: "The value `t2 - t1` in seconds." }, + ], }), // Returns a string or a table containing date and time, formatted @@ -394,31 +390,29 @@ export const osApi = new LuaTable({ return luaFormatTime(fmt, d, utc); }, - documentation: { - description: - "Formats a timestamp as a date string or date table, optionally in UTC.", - parameters: [ - { - name: "format", - type: "string", - description: - "`strftime`-style format, `*t` for a table, and optional leading `!` for UTC.", - optional: true, - }, - { - name: "timestamp", - type: "number", - description: "Unix timestamp; defaults to the current time.", - optional: true, - }, - ], - returns: [ - { type: "string|table", description: "Formatted date or date fields." }, - ], - examples: [ - { code: 'print(os.date("%Y-%m-%d"))\nlocal utc = os.date("!*t")' }, - ], - }, + description: + "Formats a timestamp as a date string or date table, optionally in UTC.", + parameters: [ + { + name: "format", + type: "string", + description: + "`strftime`-style format, `*t` for a table, and optional leading `!` for UTC.", + optional: true, + }, + { + name: "timestamp", + type: "number", + description: "Unix timestamp; defaults to the current time.", + optional: true, + }, + ], + returns: [ + { type: "string|table", description: "Formatted date or date fields." }, + ], + examples: [ + { code: 'print(os.date("%Y-%m-%d"))\nlocal utc = os.date("!*t")' }, + ], }), // Returns an approximation of CPU time used by the program in seconds. @@ -426,14 +420,12 @@ export const osApi = new LuaTable({ callback: (_sf): number => { return performance.now() / 1000.0; }, - documentation: { - description: "Returns a high-resolution elapsed time value in seconds.", - returns: [ - { - type: "number", - description: "Browser performance timer in seconds.", - }, - ], - }, + description: "Returns a high-resolution elapsed time value in seconds.", + returns: [ + { + type: "number", + description: "Browser performance timer in seconds.", + }, + ], }), }); diff --git a/client/space_lua/stdlib/space_lua.ts b/client/space_lua/stdlib/space_lua.ts index a995ca71..a71a82ac 100644 --- a/client/space_lua/stdlib/space_lua.ts +++ b/client/space_lua/stdlib/space_lua.ts @@ -245,53 +245,49 @@ export const spaceluaApi = new LuaTable({ typeof target === "string" ? target : undefined, ); }, - documentation: { - description: - "Returns structured documentation for a Lua function value or dotted API name.", - parameters: [ - { - name: "functionOrName", - type: "function|string", - description: "Function value or dotted API name to inspect.", - }, - ], - returns: [ - { - type: "table|nil", - description: - "Structured function metadata, or `nil` when the target is not a function.", - }, - ], - examples: [ - { - code: 'local info = spacelua.describe(editor.getText)\nprint(info.name, info.kind, info.see)\n\nlocal sameInfo = spacelua.describe("editor.getText")', - }, - ], - see: "API/spacelua", - }, + description: + "Returns structured documentation for a Lua function value or dotted API name.", + parameters: [ + { + name: "functionOrName", + type: "function|string", + description: "Function value or dotted API name to inspect.", + }, + ], + returns: [ + { + type: "table|nil", + description: + "Structured function metadata, or `nil` when the target is not a function.", + }, + ], + examples: [ + { + code: 'local info = spacelua.describe(editor.getText)\nprint(info.name, info.kind, info.see)\n\nlocal sameInfo = spacelua.describe("editor.getText")', + }, + ], + see: "API/spacelua", }), listFunctions: new LuaBuiltinFunction({ callback: (sf, target?: LuaTable | string) => jsToLuaValue(listFunctionInfo(sf, target)), - documentation: { - description: - "Lists documented functions in the global environment or an API namespace.", - parameters: [ - { - name: "namespace", - type: "table|string", - description: "Namespace table or dotted name; omit for globals.", - optional: true, - }, - ], - returns: [{ type: "table", description: "Function metadata records." }], - examples: [ - { - code: 'for info in each(spacelua.listFunctions("editor")) do\n print(info.name, info.description or info.see)\nend', - }, - ], - see: "API/spacelua", - }, + description: + "Lists documented functions in the global environment or an API namespace.", + parameters: [ + { + name: "namespace", + type: "table|string", + description: "Namespace table or dotted name; omit for globals.", + optional: true, + }, + ], + returns: [{ type: "table", description: "Function metadata records." }], + examples: [ + { + code: 'for info in each(spacelua.listFunctions("editor")) do\n print(info.name, info.description or info.see)\nend', + }, + ], + see: "API/spacelua", }), renderApiDocumentation: new LuaBuiltinFunction({ callback: (sf, target?: ILuaFunction | LuaTable | string): string => { @@ -301,33 +297,31 @@ export const spaceluaApi = new LuaTable({ selection.context, ); }, - documentation: { - description: - "Renders API documentation for a function, namespace, or the global environment as Markdown.", - parameters: [ - { - name: "target", - type: "function|table|string", - description: - "Function value, namespace table, or dotted API name to document; omit for globals.", - optional: true, - }, - ], - returns: [{ type: "string", description: "Rendered Markdown." }], - examples: [ - { - code: '${spacelua.renderApiDocumentation("lua")}', - description: "Render a namespace as a live API-page directive.", - language: "markdown", - }, - { - code: '${spacelua.renderApiDocumentation("editor.getText")}', - description: "Render one function by its dotted API name.", - language: "markdown", - }, - ], - see: "API/spacelua", - }, + description: + "Renders API documentation for a function, namespace, or the global environment as Markdown.", + parameters: [ + { + name: "target", + type: "function|table|string", + description: + "Function value, namespace table, or dotted API name to document; omit for globals.", + optional: true, + }, + ], + returns: [{ type: "string", description: "Rendered Markdown." }], + examples: [ + { + code: '${spacelua.renderApiDocumentation("lua")}', + description: "Render a namespace as a live API-page directive.", + language: "markdown", + }, + { + code: '${spacelua.renderApiDocumentation("editor.getText")}', + description: "Render one function by its dotted API name.", + language: "markdown", + }, + ], + see: "API/spacelua", }), /** * Parses a lua expression and returns the parsed expression. @@ -340,23 +334,21 @@ export const spaceluaApi = new LuaTable({ callback: (_sf, luaExpression: string) => { return parseExpressionString(luaExpression); }, - documentation: { - description: "Parses a Lua expression and returns its AST.", - parameters: [ - { - name: "luaExpression", - type: "string", - description: "Lua expression to parse.", - }, - ], - returns: [{ type: "table", description: "Parsed expression AST." }], - examples: [ - { - code: 'local parsed = spacelua.parseExpression("1 + 1")', - }, - ], - see: "API/spacelua", - }, + description: "Parses a Lua expression and returns its AST.", + parameters: [ + { + name: "luaExpression", + type: "string", + description: "Lua expression to parse.", + }, + ], + returns: [{ type: "table", description: "Parsed expression AST." }], + examples: [ + { + code: 'local parsed = spacelua.parseExpression("1 + 1")', + }, + ], + see: "API/spacelua", }), /** * Parses a lua chunk (block) and returns the parsed AST block. @@ -369,20 +361,18 @@ export const spaceluaApi = new LuaTable({ callback: (_sf, code: string): LuaBlock => { return parseBlock(code); }, - documentation: { - description: - "Parses a Lua chunk and returns its AST. Blocks retain comments in source order with their exact text, kind, and source range.", - parameters: [ - { name: "code", type: "string", description: "Lua code to parse." }, - ], - returns: [{ type: "table", description: "Parsed block AST." }], - examples: [ - { - code: 'local parsed = spacelua.parseBlock("local x = 1\\nreturn x + 2")', - }, - ], - see: "API/spacelua", - }, + description: + "Parses a Lua chunk and returns its AST. Blocks retain comments in source order with their exact text, kind, and source range.", + parameters: [ + { name: "code", type: "string", description: "Lua code to parse." }, + ], + returns: [{ type: "table", description: "Parsed block AST." }], + examples: [ + { + code: 'local parsed = spacelua.parseBlock("local x = 1\\nreturn x + 2")', + }, + ], + see: "API/spacelua", }), /** * Pretty-prints a parsed lua block AST back to formatted source. @@ -396,27 +386,25 @@ export const spaceluaApi = new LuaTable({ callback: (sf, block: LuaBlock, opts?: LuaTable): string => { return prettyPrintBlock(block, toPrintOptions(sf, opts)); }, - documentation: { - description: - "Pretty-prints a parsed Lua block AST. Comments are preserved while their placement and indentation are normalized.", - parameters: [ - { name: "block", type: "table", description: "Parsed block AST." }, - { - name: "options", - type: "table", - description: - "Formatting options: `indentWidth`, `quote`, and `trailingComma`.", - optional: true, - }, - ], - returns: [{ type: "string", description: "Formatted Lua source." }], - examples: [ - { - code: 'local formatted = spacelua.prettyPrintBlock(spacelua.parseBlock("if a then return 1 end"))\nprint(formatted)', - }, - ], - see: "API/spacelua", - }, + description: + "Pretty-prints a parsed Lua block AST. Comments are preserved while their placement and indentation are normalized.", + parameters: [ + { name: "block", type: "table", description: "Parsed block AST." }, + { + name: "options", + type: "table", + description: + "Formatting options: `indentWidth`, `quote`, and `trailingComma`.", + optional: true, + }, + ], + returns: [{ type: "string", description: "Formatted Lua source." }], + examples: [ + { + code: 'local formatted = spacelua.prettyPrintBlock(spacelua.parseBlock("if a then return 1 end"))\nprint(formatted)', + }, + ], + see: "API/spacelua", }), /** * Pretty-prints a parsed lua expression AST back to formatted source. @@ -430,30 +418,28 @@ export const spaceluaApi = new LuaTable({ callback: (sf, expr: LuaExpression, opts?: LuaTable): string => { return prettyPrintExpression(expr, toPrintOptions(sf, opts)); }, - documentation: { - description: "Pretty-prints a parsed Lua expression AST.", - parameters: [ - { - name: "parsedExpr", - type: "table", - description: "Parsed expression AST.", - }, - { - name: "options", - type: "table", - description: - "Formatting options: `indentWidth`, `quote`, and `trailingComma`.", - optional: true, - }, - ], - returns: [{ type: "string", description: "Formatted Lua source." }], - examples: [ - { - code: 'local parsed = spacelua.parseExpression("{a=1,b=2}")\nprint(spacelua.prettyPrintExpression(parsed))', - }, - ], - see: "API/spacelua", - }, + description: "Pretty-prints a parsed Lua expression AST.", + parameters: [ + { + name: "parsedExpr", + type: "table", + description: "Parsed expression AST.", + }, + { + name: "options", + type: "table", + description: + "Formatting options: `indentWidth`, `quote`, and `trailingComma`.", + optional: true, + }, + ], + returns: [{ type: "string", description: "Formatted Lua source." }], + examples: [ + { + code: 'local parsed = spacelua.parseExpression("{a=1,b=2}")\nprint(spacelua.prettyPrintExpression(parsed))', + }, + ], + see: "API/spacelua", }), /** * Evaluates a parsed lua expression and returns the result. @@ -472,30 +458,28 @@ export const spaceluaApi = new LuaTable({ const env = createAugmentedEnv(sf, envAugmentation); return luaValueToJS(await evalExpression(parsedExpr, env, sf), sf); }, - documentation: { - description: - "Evaluates a parsed Lua expression, optionally with additional environment values.", - parameters: [ - { - name: "parsedExpr", - type: "table", - description: "Parsed expression AST.", - }, - { - name: "envAugmentation", - type: "table", - description: "Values added to the expression environment.", - optional: true, - }, - ], - returns: [{ description: "Evaluated result." }], - examples: [ - { - code: 'local parsed = spacelua.parseExpression("x + y")\nlocal result = spacelua.evalExpression(parsed, {x = 1, y = 2})\nprint(result)', - }, - ], - see: "API/spacelua", - }, + description: + "Evaluates a parsed Lua expression, optionally with additional environment values.", + parameters: [ + { + name: "parsedExpr", + type: "table", + description: "Parsed expression AST.", + }, + { + name: "envAugmentation", + type: "table", + description: "Values added to the expression environment.", + optional: true, + }, + ], + returns: [{ description: "Evaluated result." }], + examples: [ + { + code: 'local parsed = spacelua.parseExpression("x + y")\nlocal result = spacelua.evalExpression(parsed, {x = 1, y = 2})\nprint(result)', + }, + ], + see: "API/spacelua", }), /** * Interpolates a string with lua expressions and returns the result. @@ -507,30 +491,28 @@ export const spaceluaApi = new LuaTable({ } return interpolateLuaString(sf, template, envAugmentation); }, - documentation: { - description: - "Interpolates `${...}` Lua expressions in a string, optionally with additional environment values.", - parameters: [ - { - name: "template", - type: "string", - description: "Template containing `${...}` expressions.", - }, - { - name: "envAugmentation", - type: "table", - description: "Values added to the interpolation environment.", - optional: true, - }, - ], - returns: [{ type: "string", description: "Interpolated string." }], - examples: [ - { - code: 'local greeting = spacelua.interpolate("Hello ${name}!", {name = "Pete"})\nprint(greeting)', - }, - ], - see: "API/spacelua", - }, + description: + "Interpolates `${...}` Lua expressions in a string, optionally with additional environment values.", + parameters: [ + { + name: "template", + type: "string", + description: "Template containing `${...}` expressions.", + }, + { + name: "envAugmentation", + type: "table", + description: "Values added to the interpolation environment.", + optional: true, + }, + ], + returns: [{ type: "string", description: "Interpolated string." }], + examples: [ + { + code: 'local greeting = spacelua.interpolate("Hello ${name}!", {name = "Pete"})\nprint(greeting)', + }, + ], + see: "API/spacelua", }), /** * Returns your SilverBullet instance's base URL @@ -540,12 +522,10 @@ export const spaceluaApi = new LuaTable({ //NOTE: Removing trailing slash to stay compatible with original code: `location.protocol + "//" + location.host;` return document.baseURI.replace(/\/*$/, ""); }, - documentation: { - description: - "Returns the SilverBullet instance's base URL, or `nil` when run on the server.", - returns: [{ type: "string|nil" }], - examples: [{ code: "local url = spacelua.baseUrl()\nprint(url)" }], - see: "API/spacelua", - }, + description: + "Returns the SilverBullet instance's base URL, or `nil` when run on the server.", + returns: [{ type: "string|nil" }], + examples: [{ code: "local url = spacelua.baseUrl()\nprint(url)" }], + see: "API/spacelua", }), }); diff --git a/client/space_lua/stdlib/string.ts b/client/space_lua/stdlib/string.ts index 8ea4d845..e6ea64aa 100644 --- a/client/space_lua/stdlib/string.ts +++ b/client/space_lua/stdlib/string.ts @@ -40,24 +40,20 @@ export const stringApi = new LuaTable({ } return new LuaMultiRes(result); }, - documentation: { - description: - "Returns the numeric character codes in the inclusive range from `i` to `j`.", - parameters: [ - { name: "s", type: "string" }, - { name: "i", type: "integer", optional: true }, - { name: "j", type: "integer", optional: true }, - ], - returns: [{ type: "integer", description: "One result per character." }], - }, + description: + "Returns the numeric character codes in the inclusive range from `i` to `j`.", + parameters: [ + { name: "s", type: "string" }, + { name: "i", type: "integer", optional: true }, + { name: "j", type: "integer", optional: true }, + ], + returns: [{ type: "integer", description: "One result per character." }], }), char: new LuaBuiltinFunction({ callback: (_sf, ...args: number[]) => String.fromCharCode(...args), - documentation: { - description: "Creates a string from numeric character codes.", - signatures: ["string.char(...): string"], - returns: [{ type: "string" }], - }, + description: "Creates a string from numeric character codes.", + signatures: ["string.char(...): string"], + returns: [{ type: "string" }], }), find: new LuaBuiltinFunction({ callback: (_sf, s: string, pattern: string, init = 1, plain = false) => { @@ -69,20 +65,18 @@ export const stringApi = new LuaTable({ } return new LuaMultiRes(result); }, - documentation: { - description: - "Finds the first Lua-pattern match and returns its bounds followed by captures.", - parameters: [ - { name: "s", type: "string" }, - { name: "pattern", type: "string" }, - { name: "init", type: "integer", optional: true }, - { name: "plain", type: "boolean", optional: true }, - ], - returns: [ - { type: "integer|nil", description: "Start index or `nil`." }, - { type: "integer", description: "End index." }, - ], - }, + description: + "Finds the first Lua-pattern match and returns its bounds followed by captures.", + parameters: [ + { name: "s", type: "string" }, + { name: "pattern", type: "string" }, + { name: "init", type: "integer", optional: true }, + { name: "plain", type: "boolean", optional: true }, + ], + returns: [ + { type: "integer|nil", description: "Start index or `nil`." }, + { type: "integer", description: "End index." }, + ], }), format: new LuaBuiltinFunction({ callback: (_sf, format: string, ...args: any[]) => { @@ -91,21 +85,19 @@ export const stringApi = new LuaTable({ } return luaFormat(format, ...args); }, - documentation: { - description: "Formats values according to a C-style format string.", - signatures: ["string.format(format, ...): string"], - parameters: [ - { name: "format", type: "string" }, - { - name: "...", - description: "Values consumed by conversion specifiers.", - }, - ], - returns: [{ type: "string" }], - examples: [ - { code: 'print(string.format("Name: %s, score: %.1f", "Ada", 9.5))' }, - ], - }, + description: "Formats values according to a C-style format string.", + signatures: ["string.format(format, ...): string"], + parameters: [ + { name: "format", type: "string" }, + { + name: "...", + description: "Values consumed by conversion specifiers.", + }, + ], + returns: [{ type: "string" }], + examples: [ + { code: 'print(string.format("Name: %s, score: %.1f", "Ada", 9.5))' }, + ], }), gmatch: new LuaBuiltinFunction({ callback: (_sf, s: string, pattern: string, init = 1) => { @@ -116,21 +108,19 @@ export const stringApi = new LuaTable({ return capturesToLua(caps); }; }, - documentation: { - description: - "Returns an iterator over successive Lua-pattern matches and captures.", - parameters: [ - { name: "s", type: "string" }, - { name: "pattern", type: "string" }, - { name: "init", type: "integer", optional: true }, - ], - returns: [{ type: "function", description: "Match iterator." }], - examples: [ - { - code: 'for word in string.gmatch("hello world", "%w+") do\n print(word)\nend', - }, - ], - }, + description: + "Returns an iterator over successive Lua-pattern matches and captures.", + parameters: [ + { name: "s", type: "string" }, + { name: "pattern", type: "string" }, + { name: "init", type: "integer", optional: true }, + ], + returns: [{ type: "function", description: "Match iterator." }], + examples: [ + { + code: 'for word in string.gmatch("hello world", "%w+") do\n print(word)\nend', + }, + ], }), gsub: new LuaBuiltinFunction({ callback: async (sf, s: string, pattern: string, repl: any, n?: number) => { @@ -166,49 +156,41 @@ export const stringApi = new LuaTable({ const [result, count] = await patternGsub(s, pattern, callbacks, n); return new LuaMultiRes([result, count]); }, - documentation: { - description: - "Replaces Lua-pattern matches using a string, table, or function replacement.", - parameters: [ - { name: "s", type: "string" }, - { name: "pattern", type: "string" }, - { name: "replacement", type: "string|table|function" }, - { name: "n", type: "integer", optional: true }, - ], - returns: [ - { type: "string", description: "Result string." }, - { type: "integer", description: "Number of replacements." }, - ], - examples: [ - { - code: 'local result, count = string.gsub("hello hello", "hello", "hi", 1)\nprint(result, count) -- hi hello 1', - }, - ], - }, + description: + "Replaces Lua-pattern matches using a string, table, or function replacement.", + parameters: [ + { name: "s", type: "string" }, + { name: "pattern", type: "string" }, + { name: "replacement", type: "string|table|function" }, + { name: "n", type: "integer", optional: true }, + ], + returns: [ + { type: "string", description: "Result string." }, + { type: "integer", description: "Number of replacements." }, + ], + examples: [ + { + code: 'local result, count = string.gsub("hello hello", "hello", "hi", 1)\nprint(result, count) -- hi hello 1', + }, + ], }), len: new LuaBuiltinFunction({ callback: (_sf, s: string) => s.length, - documentation: { - description: "Returns the length of a string.", - parameters: [{ name: "s", type: "string" }], - returns: [{ type: "integer" }], - }, + description: "Returns the length of a string.", + parameters: [{ name: "s", type: "string" }], + returns: [{ type: "integer" }], }), lower: new LuaBuiltinFunction({ callback: (_sf, s: string) => luaToString(s.toLowerCase()), - documentation: { - description: "Returns a copy of a string converted to lowercase.", - parameters: [{ name: "s", type: "string" }], - returns: [{ type: "string" }], - }, + description: "Returns a copy of a string converted to lowercase.", + parameters: [{ name: "s", type: "string" }], + returns: [{ type: "string" }], }), upper: new LuaBuiltinFunction({ callback: (_sf, s: string) => luaToString(s.toUpperCase()), - documentation: { - description: "Returns a copy of a string converted to uppercase.", - parameters: [{ name: "s", type: "string" }], - returns: [{ type: "string" }], - }, + description: "Returns a copy of a string converted to uppercase.", + parameters: [{ name: "s", type: "string" }], + returns: [{ type: "string" }], }), match: new LuaBuiltinFunction({ callback: (_sf, s: string, pattern: string, init = 1) => { @@ -216,19 +198,17 @@ export const stringApi = new LuaTable({ if (!caps) return null; return capturesToLua(caps); }, - documentation: { - description: - "Returns captures from the first Lua-pattern match, or `nil` when none is found.", - parameters: [ - { name: "s", type: "string" }, - { name: "pattern", type: "string" }, - { name: "init", type: "integer", optional: true }, - ], - returns: [{ description: "Pattern captures, whole match, or `nil`." }], - examples: [ - { code: 'local year, month = string.match("2024-03", "(%d+)%-(%d+)")' }, - ], - }, + description: + "Returns captures from the first Lua-pattern match, or `nil` when none is found.", + parameters: [ + { name: "s", type: "string" }, + { name: "pattern", type: "string" }, + { name: "init", type: "integer", optional: true }, + ], + returns: [{ description: "Pattern captures, whole match, or `nil`." }], + examples: [ + { code: 'local year, month = string.match("2024-03", "(%d+)%-(%d+)")' }, + ], }), rep: new LuaBuiltinFunction({ callback: (_sf, s: string, n: number, sep?: string) => { @@ -240,24 +220,20 @@ export const stringApi = new LuaTable({ } return parts.join(sep); }, - documentation: { - description: - "Returns `n` copies of a string joined by an optional separator.", - parameters: [ - { name: "s", type: "string" }, - { name: "n", type: "integer" }, - { name: "sep", type: "string", optional: true }, - ], - returns: [{ type: "string" }], - }, + description: + "Returns `n` copies of a string joined by an optional separator.", + parameters: [ + { name: "s", type: "string" }, + { name: "n", type: "integer" }, + { name: "sep", type: "string", optional: true }, + ], + returns: [{ type: "string" }], }), reverse: new LuaBuiltinFunction({ callback: (_sf, s: string) => s.split("").reverse().join(""), - documentation: { - description: "Returns a string with its characters in reverse order.", - parameters: [{ name: "s", type: "string" }], - returns: [{ type: "string" }], - }, + description: "Returns a string with its characters in reverse order.", + parameters: [{ name: "s", type: "string" }], + returns: [{ type: "string" }], }), sub: new LuaBuiltinFunction({ callback: (_sf, s: string, i: number, j?: number) => { @@ -285,34 +261,30 @@ export const stringApi = new LuaTable({ } return ""; }, - documentation: { - description: - "Returns the substring from inclusive index `i` through `j`, supporting negative indices.", - parameters: [ - { name: "s", type: "string" }, - { name: "i", type: "integer" }, - { name: "j", type: "integer", optional: true }, - ], - returns: [{ type: "string" }], - }, + description: + "Returns the substring from inclusive index `i` through `j`, supporting negative indices.", + parameters: [ + { name: "s", type: "string" }, + { name: "i", type: "integer" }, + { name: "j", type: "integer", optional: true }, + ], + returns: [{ type: "string" }], }), split: new LuaBuiltinFunction({ callback: (_sf, s: string, sep: string) => s.split(sep), - documentation: { - description: - "Splits a string on a literal separator and returns the substrings.", - parameters: [ - { name: "s", type: "string" }, - { name: "sep", type: "string" }, - ], - returns: [{ type: "table" }], - examples: [ - { - code: 'for part in each(string.split("a,b,c", ",")) do\n print(part)\nend', - }, - ], - }, + description: + "Splits a string on a literal separator and returns the substrings.", + parameters: [ + { name: "s", type: "string" }, + { name: "sep", type: "string" }, + ], + returns: [{ type: "table" }], + examples: [ + { + code: 'for part in each(string.split("a,b,c", ",")) do\n print(part)\nend', + }, + ], }), pack: strPackFn, @@ -322,49 +294,39 @@ export const stringApi = new LuaTable({ // Non-standard extensions startsWith: new LuaBuiltinFunction({ callback: (_sf, s: string, prefix: string) => s.startsWith(prefix), - documentation: { - description: "Returns whether a string starts with a literal prefix.", - parameters: [ - { name: "s", type: "string" }, - { name: "prefix", type: "string" }, - ], - returns: [{ type: "boolean" }], - }, + description: "Returns whether a string starts with a literal prefix.", + parameters: [ + { name: "s", type: "string" }, + { name: "prefix", type: "string" }, + ], + returns: [{ type: "boolean" }], }), endsWith: new LuaBuiltinFunction({ callback: (_sf, s: string, suffix: string) => s.endsWith(suffix), - documentation: { - description: "Returns whether a string ends with a literal suffix.", - parameters: [ - { name: "s", type: "string" }, - { name: "suffix", type: "string" }, - ], - returns: [{ type: "boolean" }], - }, + description: "Returns whether a string ends with a literal suffix.", + parameters: [ + { name: "s", type: "string" }, + { name: "suffix", type: "string" }, + ], + returns: [{ type: "boolean" }], }), trim: new LuaBuiltinFunction({ callback: (_sf, s: string) => s.trim(), - documentation: { - description: "Removes whitespace from both ends of a string.", - parameters: [{ name: "s", type: "string" }], - returns: [{ type: "string" }], - }, + description: "Removes whitespace from both ends of a string.", + parameters: [{ name: "s", type: "string" }], + returns: [{ type: "string" }], }), trimStart: new LuaBuiltinFunction({ callback: (_sf, s: string) => s.trimStart(), - documentation: { - description: "Removes whitespace from the beginning of a string.", - parameters: [{ name: "s", type: "string" }], - returns: [{ type: "string" }], - }, + description: "Removes whitespace from the beginning of a string.", + parameters: [{ name: "s", type: "string" }], + returns: [{ type: "string" }], }), trimEnd: new LuaBuiltinFunction({ callback: (_sf, s: string) => s.trimEnd(), - documentation: { - description: "Removes whitespace from the end of a string.", - parameters: [{ name: "s", type: "string" }], - returns: [{ type: "string" }], - }, + description: "Removes whitespace from the end of a string.", + parameters: [{ name: "s", type: "string" }], + returns: [{ type: "string" }], }), matchRegex: new LuaBuiltinFunction({ callback: (_sf, s: string, pattern: string) => { @@ -372,20 +334,18 @@ export const stringApi = new LuaTable({ const result = s.match(regex); return jsToLuaValue(result); }, - documentation: { - description: - "Matches a string with a JavaScript regular expression and returns the match array.", - parameters: [ - { name: "s", type: "string" }, - { name: "pattern", type: "string" }, - ], - returns: [{ type: "table|nil" }], - examples: [ - { - code: 'local match = string.matchRegex("hello123", "([a-z]+)([0-9]+)")\nprint(match[1], match[2], match[3])', - }, - ], - }, + description: + "Matches a string with a JavaScript regular expression and returns the match array.", + parameters: [ + { name: "s", type: "string" }, + { name: "pattern", type: "string" }, + ], + returns: [{ type: "table|nil" }], + examples: [ + { + code: 'local match = string.matchRegex("hello123", "([a-z]+)([0-9]+)")\nprint(match[1], match[2], match[3])', + }, + ], }), matchRegexAll: new LuaBuiltinFunction({ callback: (_sf, s: string, pattern: string) => { @@ -398,21 +358,19 @@ export const stringApi = new LuaTable({ return jsToLuaValue(match); }; }, - documentation: { - description: - "Returns an iterator over all JavaScript regular-expression matches.", - parameters: [ - { name: "s", type: "string" }, - { name: "pattern", type: "string" }, - ], - returns: [ - { type: "function", description: "Iterator yielding match arrays." }, - ], - examples: [ - { - code: 'for match in string.matchRegexAll("a1b2", "([a-z])([0-9])") do\n print(match[1], match[2], match[3])\nend', - }, - ], - }, + description: + "Returns an iterator over all JavaScript regular-expression matches.", + parameters: [ + { name: "s", type: "string" }, + { name: "pattern", type: "string" }, + ], + returns: [ + { type: "function", description: "Iterator yielding match arrays." }, + ], + examples: [ + { + code: 'for match in string.matchRegexAll("a1b2", "([a-z])([0-9])") do\n print(match[1], match[2], match[3])\nend', + }, + ], }), }); diff --git a/client/space_lua/stdlib/string_pack.ts b/client/space_lua/stdlib/string_pack.ts index 0abf9c5a..1d501130 100644 --- a/client/space_lua/stdlib/string_pack.ts +++ b/client/space_lua/stdlib/string_pack.ts @@ -364,16 +364,14 @@ export const strPackFn = new LuaBuiltinFunction({ for (let i = 0; i < out.length; i++) result += String.fromCharCode(out[i]); return result; }, - documentation: { - description: - "Packs values into a binary string according to a Lua 5.4 format string.", - signatures: ["string.pack(format, ...): string"], - parameters: [ - { name: "format", type: "string", description: "Binary packing format." }, - { name: "...", description: "Values consumed by the format options." }, - ], - returns: [{ type: "string", description: "Packed binary string." }], - }, + description: + "Packs values into a binary string according to a Lua 5.4 format string.", + signatures: ["string.pack(format, ...): string"], + parameters: [ + { name: "format", type: "string", description: "Binary packing format." }, + { name: "...", description: "Values consumed by the format options." }, + ], + returns: [{ type: "string", description: "Packed binary string." }], }); export const strUnpackFn = new LuaBuiltinFunction({ @@ -478,27 +476,25 @@ export const strUnpackFn = new LuaBuiltinFunction({ results.push(pos + 1); return new LuaMultiRes(results); }, - documentation: { - description: - "Unpacks values from a binary string according to a Lua 5.4 format string.", - parameters: [ - { - name: "format", - type: "string", - description: "Binary unpacking format.", - }, - { name: "data", type: "string", description: "Packed binary string." }, - { - name: "init", - type: "integer", - description: "One-based starting position.", - optional: true, - }, - ], - returns: [ - { description: "Unpacked values followed by the next unread position." }, - ], - }, + description: + "Unpacks values from a binary string according to a Lua 5.4 format string.", + parameters: [ + { + name: "format", + type: "string", + description: "Binary unpacking format.", + }, + { name: "data", type: "string", description: "Packed binary string." }, + { + name: "init", + type: "integer", + description: "One-based starting position.", + optional: true, + }, + ], + returns: [ + { description: "Unpacked values followed by the next unread position." }, + ], }); export const strPackSizeFn = new LuaBuiltinFunction({ @@ -520,16 +516,14 @@ export const strPackSizeFn = new LuaBuiltinFunction({ return totalsize; }, - documentation: { - description: - "Returns the byte size of a fixed-length Lua 5.4 packing format.", - parameters: [ - { - name: "format", - type: "string", - description: "Fixed-length binary packing format.", - }, - ], - returns: [{ type: "integer", description: "Packed byte count." }], - }, + description: + "Returns the byte size of a fixed-length Lua 5.4 packing format.", + parameters: [ + { + name: "format", + type: "string", + description: "Fixed-length binary packing format.", + }, + ], + returns: [{ type: "integer", description: "Packed byte count." }], }); diff --git a/client/space_lua/stdlib/table.ts b/client/space_lua/stdlib/table.ts index 12ce3fa1..ed95ddda 100644 --- a/client/space_lua/stdlib/table.ts +++ b/client/space_lua/stdlib/table.ts @@ -114,17 +114,15 @@ export const tableApi = new LuaTable({ } return out.join(sep); }, - documentation: { - description: - "Concatenates table elements from `i` through `j` using an optional separator.", - parameters: [ - { name: "table", type: "table" }, - { name: "sep", type: "string", optional: true }, - { name: "i", type: "integer", optional: true }, - { name: "j", type: "integer", optional: true }, - ], - returns: [{ type: "string" }], - }, + description: + "Concatenates table elements from `i` through `j` using an optional separator.", + parameters: [ + { name: "table", type: "table" }, + { name: "sep", type: "string", optional: true }, + { name: "i", type: "integer", optional: true }, + { name: "j", type: "integer", optional: true }, + ], + returns: [{ type: "string" }], }), /** @@ -176,31 +174,29 @@ export const tableApi = new LuaTable({ await luaSet(tbl, pos, v, sf); }, - documentation: { - description: - "Inserts a value at a position, shifting later elements, or appends it when no position is supplied.", - signatures: [ - "table.insert(table, value)", - "table.insert(table, pos, value)", - ], - parameters: [ - { name: "table", type: "table" }, - { - name: "posOrValue", - description: "Insertion position or appended value.", - }, - { - name: "value", - description: "Value for positional insertion.", - optional: true, - }, - ], - examples: [ - { - code: 'local fruits = {"apple", "orange"}\ntable.insert(fruits, 2, "banana")\nprint(table.concat(fruits, ", "))', - }, - ], - }, + description: + "Inserts a value at a position, shifting later elements, or appends it when no position is supplied.", + signatures: [ + "table.insert(table, value)", + "table.insert(table, pos, value)", + ], + parameters: [ + { name: "table", type: "table" }, + { + name: "posOrValue", + description: "Insertion position or appended value.", + }, + { + name: "value", + description: "Value for positional insertion.", + optional: true, + }, + ], + examples: [ + { + code: 'local fruits = {"apple", "orange"}\ntable.insert(fruits, 2, "banana")\nprint(table.concat(fruits, ", "))', + }, + ], }), /** @@ -244,20 +240,18 @@ export const tableApi = new LuaTable({ return v; }, - documentation: { - description: - "Removes and returns an element, shifting later elements down.", - parameters: [ - { name: "table", type: "table" }, - { - name: "pos", - type: "integer", - description: "Position; defaults to the last element.", - optional: true, - }, - ], - returns: [{ description: "Removed value." }], - }, + description: + "Removes and returns an element, shifting later elements down.", + parameters: [ + { name: "table", type: "table" }, + { + name: "pos", + type: "integer", + description: "Position; defaults to the last element.", + optional: true, + }, + ], + returns: [{ description: "Removed value." }], }), /** @@ -308,23 +302,21 @@ export const tableApi = new LuaTable({ return a2; }, - documentation: { - description: - "Moves an inclusive element range to a destination table while handling overlaps.", - parameters: [ - { name: "a1", type: "table", description: "Source table." }, - { name: "f", type: "integer", description: "First source index." }, - { name: "e", type: "integer", description: "Last source index." }, - { name: "t", type: "integer", description: "Destination start index." }, - { - name: "a2", - type: "table", - description: "Destination table; defaults to `a1`.", - optional: true, - }, - ], - returns: [{ type: "table", description: "Destination table." }], - }, + description: + "Moves an inclusive element range to a destination table while handling overlaps.", + parameters: [ + { name: "a1", type: "table", description: "Source table." }, + { name: "f", type: "integer", description: "First source index." }, + { name: "e", type: "integer", description: "Last source index." }, + { name: "t", type: "integer", description: "Destination start index." }, + { + name: "a2", + type: "table", + description: "Destination table; defaults to `a1`.", + optional: true, + }, + ], + returns: [{ type: "table", description: "Destination table." }], }), /** @@ -384,22 +376,18 @@ export const tableApi = new LuaTable({ return tbl; }, - documentation: { - description: - "Sorts a table in place using ascending order or an optional comparison function.", - parameters: [ - { name: "table", type: "table" }, - { name: "comp", type: "function", optional: true }, - ], - returns: [ - { type: "table", description: "The sorted table in Space Lua." }, - ], - examples: [ - { - code: "local numbers = {3, 1, 2}\ntable.sort(numbers, function(a, b) return a > b end)", - }, - ], - }, + description: + "Sorts a table in place using ascending order or an optional comparison function.", + parameters: [ + { name: "table", type: "table" }, + { name: "comp", type: "function", optional: true }, + ], + returns: [{ type: "table", description: "The sorted table in Space Lua." }], + examples: [ + { + code: "local numbers = {3, 1, 2}\ntable.sort(numbers, function(a, b) return a > b end)", + }, + ], }), /** @@ -415,12 +403,10 @@ export const tableApi = new LuaTable({ } return Object.keys(tbl); }, - documentation: { - description: - "Returns an array containing all keys of a table or JavaScript object.", - parameters: [{ name: "table", type: "table" }], - returns: [{ type: "table", description: "Array of keys." }], - }, + description: + "Returns an array containing all keys of a table or JavaScript object.", + parameters: [{ name: "table", type: "table" }], + returns: [{ type: "table", description: "Array of keys." }], }), /** @@ -452,15 +438,13 @@ export const tableApi = new LuaTable({ sf, ); }, - documentation: { - description: - "Returns whether any table value is Lua-equal to a requested value.", - parameters: [ - { name: "table", type: "table" }, - { name: "value", description: "Value to find." }, - ], - returns: [{ type: "boolean" }], - }, + description: + "Returns whether any table value is Lua-equal to a requested value.", + parameters: [ + { name: "table", type: "table" }, + { name: "value", description: "Value to find." }, + ], + returns: [{ type: "boolean" }], }), /** @@ -493,27 +477,25 @@ export const tableApi = new LuaTable({ } return resultTable; }, - documentation: { - description: "Copies selected keys from a table into a new table.", - signatures: [ - "table.select(table, ...keys): table", - "table.select(table, keys): table", - ], - parameters: [ - { name: "table", type: "table" }, - { - name: "keys", - description: "Individual keys or one array-like table of keys.", - }, - ], - returns: [{ type: "table" }], - examples: [ - { - code: '${query[[\n from p = index.pages()\n limit 3\n select table.select(p, "name", "lastModified")\n]]}', - language: "markdown", - }, - ], - }, + description: "Copies selected keys from a table into a new table.", + signatures: [ + "table.select(table, ...keys): table", + "table.select(table, keys): table", + ], + parameters: [ + { name: "table", type: "table" }, + { + name: "keys", + description: "Individual keys or one array-like table of keys.", + }, + ], + returns: [{ type: "table" }], + examples: [ + { + code: '${query[[\n from p = index.pages()\n limit 3\n select table.select(p, "name", "lastModified")\n]]}', + language: "markdown", + }, + ], }), /** @@ -530,17 +512,15 @@ export const tableApi = new LuaTable({ void tbl.rawSet("n", n); return tbl; }, - documentation: { - description: - "Packs all arguments into a table with a count stored in field `n`.", - signatures: ["table.pack(...): table"], - returns: [ - { - type: "table", - description: "Arguments at integer keys plus field `n`.", - }, - ], - }, + description: + "Packs all arguments into a table with a count stored in field `n`.", + signatures: ["table.pack(...): table"], + returns: [ + { + type: "table", + description: "Arguments at integer keys plus field `n`.", + }, + ], }), /** @@ -569,19 +549,17 @@ export const tableApi = new LuaTable({ } return new LuaMultiRes(result); }, - documentation: { - description: - "Returns the table values from index `i` through `j` as separate results.", - parameters: [ - { name: "table", type: "table" }, - { name: "i", type: "integer", optional: true }, - { name: "j", type: "integer", optional: true }, - ], - returns: [{ description: "One result per selected element." }], - examples: [ - { code: 'local second, third = table.unpack({"a", "b", "c"}, 2, 3)' }, - ], - }, + description: + "Returns the table values from index `i` through `j` as separate results.", + parameters: [ + { name: "table", type: "table" }, + { name: "i", type: "integer", optional: true }, + { name: "j", type: "integer", optional: true }, + ], + returns: [{ description: "One result per selected element." }], + examples: [ + { code: 'local second, third = table.unpack({"a", "b", "c"}, 2, 3)' }, + ], }), // Non-standard Lua functions @@ -614,27 +592,25 @@ export const tableApi = new LuaTable({ } return null; }, - documentation: { - description: - "Finds the first array element accepted by a predicate and returns its index and value.", - parameters: [ - { name: "table", type: "table" }, - { - name: "criteriaFn", - type: "function", - description: "Predicate called with each value.", - }, - { name: "fromIndex", type: "integer", optional: true }, - ], - returns: [ - { type: "integer|nil", description: "Matching index or `nil`." }, - { description: "Matching value." }, - ], - examples: [ - { - code: "local index, value = table.find({1, 2, 3, 4}, function(n) return n % 2 == 0 end)", - }, - ], - }, + description: + "Finds the first array element accepted by a predicate and returns its index and value.", + parameters: [ + { name: "table", type: "table" }, + { + name: "criteriaFn", + type: "function", + description: "Predicate called with each value.", + }, + { name: "fromIndex", type: "integer", optional: true }, + ], + returns: [ + { type: "integer|nil", description: "Matching index or `nil`." }, + { description: "Matching value." }, + ], + examples: [ + { + code: "local index, value = table.find({1, 2, 3, 4}, function(n) return n % 2 == 0 end)", + }, + ], }), }); diff --git a/client/space_lua_api.test.ts b/client/space_lua_api.test.ts index 9afaaa14..7b8ed3ac 100644 --- a/client/space_lua_api.test.ts +++ b/client/space_lua_api.test.ts @@ -14,12 +14,10 @@ test("documented syscalls retain metadata when exposed to Lua", async () => { system.registerSyscalls([], { "example.greet": { callback: (_ctx, name: string) => `Hello ${name}`, - documentation: { - description: "Greets someone.", - parameters: [{ name: "name", type: "string" }], - returns: [{ type: "string" }], - see: "API/example", - }, + description: "Greets someone.", + parameters: [{ name: "name", type: "string" }], + returns: [{ type: "string" }], + see: "API/example", }, }); @@ -54,7 +52,7 @@ test("legacy syscall registrations get an API page reference", () => { system.registerSyscalls([], { "example.ping": () => "pong", }); - expect(system.registeredSyscalls.get("example.ping")?.documentation).toEqual({ - see: "API/example", - }); + expect(system.registeredSyscalls.get("example.ping")?.see).toBe( + "API/example", + ); }); diff --git a/client/space_lua_api.ts b/client/space_lua_api.ts index fd83b630..81bc8e63 100644 --- a/client/space_lua_api.ts +++ b/client/space_lua_api.ts @@ -36,23 +36,28 @@ export function exposeSyscalls(env: LuaEnv, system: System) { if (!env.has(ns)) { env.set(ns, new LuaTable(), nativeFs); } - const info = { + const { + callback: _callback, + requiredPermissions: _requiredPermissions, + ...metadata + } = syscall; + const definition = { kind: "syscall" as const, name: cleanSyscallName, - ...syscall.documentation, + ...metadata, }; const luaFn = isLuaNativeSyscall ? new LuaBuiltinFunction({ callback: (_sf, ...args) => { return system.localSyscall(syscallName, args); }, - documentation: info, + ...definition, }) : new LuaNativeJSFunction({ callback: (...args) => { return system.localSyscall(syscallName, args); }, - documentation: info, + ...definition, }); env.get(ns, nativeFs).set(fn, luaFn, nativeFs); } diff --git a/plug-api/types/index.ts b/plug-api/types/index.ts index c05a405f..b611f0d8 100644 --- a/plug-api/types/index.ts +++ b/plug-api/types/index.ts @@ -36,11 +36,10 @@ export type DocumentMeta = ObjectValue< extension: string; } & Record >; -export type SyscallMeta = { +export type SyscallMeta = LuaFunctionDocumentation & { name: string; requiredPermissions: string[]; argCount: number; - documentation?: LuaFunctionDocumentation; }; export type LuaFunctionParameterDocumentation = {