plugin: Add API interface for strongly typing responses

This commit is contained in:
Lucien Greathouse
2019-10-01 16:55:45 -07:00
parent c62a5d15ad
commit 0dbbf44ab2
2 changed files with 94 additions and 10 deletions

View File

@@ -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,
}
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,
})

24
plugin/src/strict.lua Normal file
View File

@@ -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("<unnamed table>", target)
end
end