diff --git a/plugin/src/Types.lua b/plugin/src/Types.lua index f182d60a..3d866a1a 100644 --- a/plugin/src/Types.lua +++ b/plugin/src/Types.lua @@ -1,21 +1,68 @@ local t = require(script.Parent.Parent.t) local DevSettings = require(script.Parent.DevSettings) +local strict = require(script.Parent.strict) -local VirtualValue = t.interface({ +local RbxId = t.string + +local ApiValue = t.interface({ Type = t.string, Value = t.optional(t.any), }) -local VirtualMetadata = t.interface({ +local ApiInstanceMetadata = t.interface({ ignoreUnknownInstances = t.optional(t.boolean), }) -local VirtualInstance = t.interface({ +local ApiInstance = t.interface({ Name = t.string, ClassName = t.string, - Properties = t.map(t.string, VirtualValue), - Metadata = t.optional(VirtualMetadata) + Properties = t.map(t.string, ApiValue), + Metadata = t.optional(ApiInstanceMetadata), + Children = t.array(RbxId), +}) + +local ApiInstanceUpdate = t.interface({ + id = RbxId, + changedName = t.optional(t.string), + changedClassName = t.optional(t.string), + changedProperties = t.map(t.string, ApiValue), + changedMetadata = t.optional(ApiInstanceMetadata), +}) + +local ApiSubscribeMessage = t.interface({ + removedInstances = t.array(RbxId), + addedInstances = t.map(RbxId, ApiInstance), + updatedInstances = t.array(ApiInstanceUpdate), +}) + +local ApiInfoResponse = t.interface({ + sessionId = t.string, + serverVersion = t.string, + protocolVersion = t.number, + expectedPlaceIds = t.optional(t.array(t.number)), + rootInstanceId = RbxId, +}) + +local ApiReadResponse = t.interface({ + sessionId = t.string, + messageCursor = t.number, + instances = t.map(RbxId, ApiInstance), +}) + +local ApiSubscribeResponse = t.interface({ + sessionId = t.string, + messageCursor = t.number, + messages = t.array(ApiSubscribeMessage), +}) + +local ApiError = t.interface({ + kind = t.union( + t.literal("NotFound"), + t.literal("BadRequest"), + t.literal("InternalError") + ), + details = t.string, }) local function ifEnabled(innerCheck) @@ -28,9 +75,22 @@ local function ifEnabled(innerCheck) end end -return { +return strict("Types", { ifEnabled = ifEnabled, - VirtualInstance = VirtualInstance, - VirtualMetadata = VirtualMetadata, - VirtualValue = VirtualValue, -} \ No newline at end of file + + ApiInfoResponse = ApiInfoResponse, + ApiReadResponse = ApiReadResponse, + ApiSubscribeResponse = ApiSubscribeResponse, + ApiError = ApiError, + + ApiInstance = ApiInstance, + ApiInstanceMetadata = ApiInstanceMetadata, + ApiSubscribeMessage = ApiSubscribeMessage, + ApiValue = ApiValue, + RbxId = RbxId, + + -- Deprecated aliases during transition + VirtualInstance = ApiInstance, + VirtualMetadata = ApiInstanceMetadata, + VirtualValue = ApiValue, +}) \ No newline at end of file diff --git a/plugin/src/strict.lua b/plugin/src/strict.lua new file mode 100644 index 00000000..239c84a2 --- /dev/null +++ b/plugin/src/strict.lua @@ -0,0 +1,24 @@ +local function strictInner(name, target) + assert(type(name) == "string", "Argument #1 to `strict` must be a string or the table to modify") + assert(type(target) == "table", "Argument #2 to `strict` must be nil or the table to modify") + + setmetatable(target, { + __index = function(_, key) + error(("%q is not a valid member of strict table %q"):format(tostring(key), name), 2) + end, + + __newindex = function() + error(("Strict table %q is read-only"):format(name), 2) + end, + }) + + return target +end + +return function(nameOrTarget, target) + if type(nameOrTarget) == "string" then + return strictInner(nameOrTarget, target) + else + return strictInner("", target) + end +end \ No newline at end of file