Closed Mustwey closed 2 weeks ago
here is the full script :
local ImportGlobals
local ClosureBindings = {function()local wax,script,require=ImportGlobals(1)local ImportGlobals return (function(...)
local TS = require(script.include.RuntimeLib)
local _Drawing = TS.import(script, script, "types", "wave", "libraries", "Drawing")
local Drawing = _Drawing.Drawing
local cleardrawcache = _Drawing.cleardrawcache
local setrenderproperty = _Drawing.setrenderproperty
local Janitor = TS.import(script, script, "include", "node_modules", "@rbxts", "janitor", "src").Janitor
local circle = Drawing.new("Circle")
circle.Radius = 50
circle.Color = Color3.fromRGB(255, 255, 255)
circle.Filled = false
circle.Position = Vector2.new(50, 50)
circle.Transparency = 0.9
local square = Drawing.new("Square")
square.Size = Vector2.new(100, 100)
square.Position = Vector2.new(150, 150)
square.Color = Color3.fromRGB(0, 255, 0)
square.Filled = true
square.Transparency = 0.8
local line = Drawing.new("Line")
line.PointA = Vector2.new(200, 200)
line.PointB = Vector2.new(300, 300)
line.Color = Color3.fromRGB(255, 0, 0)
line.Thickness = 2
line.Transparency = 1
local text = Drawing.new("Text")
text.Text = "Hello, Roblox!"
text.Position = Vector2.new(400, 400)
text.Font = Drawing.Fonts.Monospace
text.Size = 24
text.Color = Color3.fromRGB(255, 255, 0)
text.Outline = true
text.OutlineColor = Color3.fromRGB(0, 0, 0)
setrenderproperty(circle, "Transparency", 0.5)
setrenderproperty(square, "Color", Color3.fromRGB(0, 0, 255))
wait(5)
cleardrawcache()
local janitor = Janitor.new()
janitor:Add(circle, "Remove")
janitor:Add(square, "Remove")
janitor:Add(line, "Remove")
janitor:Add(text, "Remove")
return nil
end)() end,[5]=function()local wax,script,require=ImportGlobals(5)local ImportGlobals return (function(...)
local ERROR_NON_PROMISE_IN_LIST = "Non-promise value passed into %s at index %s"
local ERROR_NON_LIST = "Please pass a list of promises to %s"
local ERROR_NON_FUNCTION = "Please pass a handler function to %s!"
local MODE_KEY_METATABLE = { __mode = "k" }
local function isCallable(value)
if type(value) == "function" then
return true
end
if type(value) == "table" then
local metatable = getmetatable(value)
if metatable and type(rawget(metatable, "__call")) == "function" then
return true
end
end
return false
end
local function makeEnum(enumName, members)
local enum = {}
for _, memberName in ipairs(members) do
enum[memberName] = memberName
end
return setmetatable(enum, {
__index = function(_, k)
error(string.format("%s is not in %s!", k, enumName), 2)
end,
__newindex = function()
error(string.format("Creating new members in %s is not allowed!", enumName), 2)
end,
})
end
local Error
do
Error = {
Kind = makeEnum("Promise.Error.Kind", {
"ExecutionError",
"AlreadyCancelled",
"NotResolvedInTime",
"TimedOut",
}),
}
Error.__index = Error
function Error.new(options, parent)
options = options or {}
return setmetatable({
error = tostring(options.error) or "[This error has no error text.]",
trace = options.trace,
context = options.context,
kind = options.kind,
parent = parent,
createdTick = os.clock(),
createdTrace = debug.traceback(),
}, Error)
end
function Error.is(anything)
if type(anything) == "table" then
local metatable = getmetatable(anything)
if type(metatable) == "table" then
return rawget(anything, "error") ~= nil and type(rawget(metatable, "extend")) == "function"
end
end
return false
end
function Error.isKind(anything, kind)
assert(kind ~= nil, "Argument #2 to Promise.Error.isKind must not be nil")
return Error.is(anything) and anything.kind == kind
end
function Error:extend(options)
options = options or {}
options.kind = options.kind or self.kind
return Error.new(options, self)
end
function Error:getErrorChain()
local runtimeErrors = { self }
while runtimeErrors[#runtimeErrors].parent do
table.insert(runtimeErrors, runtimeErrors[#runtimeErrors].parent)
end
return runtimeErrors
end
function Error:__tostring()
local errorStrings = {
string.format("-- Promise.Error(%s) --", self.kind or "?"),
}
for _, runtimeError in ipairs(self:getErrorChain()) do
table.insert(
errorStrings,
table.concat({
runtimeError.trace or runtimeError.error,
runtimeError.context,
}, "\n")
)
end
return table.concat(errorStrings, "\n")
end
end
local function pack(...)
return select("#", ...), { ... }
end
local function packResult(success, ...)
return success, select("#", ...), { ... }
end
local function makeErrorHandler(traceback)
assert(traceback ~= nil, "traceback is nil")
return function(err)
if type(err) == "table" then
return err
end
return Error.new({
error = err,
kind = Error.Kind.ExecutionError,
trace = debug.traceback(tostring(err), 2),
context = "Promise created at:\n\n" .. traceback,
})
end
end
local function runExecutor(traceback, callback, ...)
return packResult(xpcall(callback, makeErrorHandler(traceback), ...))
end
local function createAdvancer(traceback, callback, resolve, reject)
return function(...)
local ok, resultLength, result = runExecutor(traceback, callback, ...)
if ok then
resolve(unpack(result, 1, resultLength))
else
reject(result[1])
end
end
end
local function isEmpty(t)
return next(t) == nil
end
local Promise = {
Error = Error,
Status = makeEnum("Promise.Status", { "Started", "Resolved", "Rejected", "Cancelled" }),
_getTime = os.clock,
_timeEvent = game:GetService("RunService").Heartbeat,
_unhandledRejectionCallbacks = {},
}
Promise.prototype = {}
Promise.__index = Promise.prototype
function Promise._new(traceback, callback, parent)
if parent ~= nil and not Promise.is(parent) then
error("Argument #2 to Promise.new must be a promise or nil", 2)
end
local self = {
_thread = nil,
_source = traceback,
_status = Promise.Status.Started,
_values = nil,
_valuesLength = -1,
_unhandledRejection = true,
_queuedResolve = {},
_queuedReject = {},
_queuedFinally = {},
_cancellationHook = nil,
_parent = parent,
_consumers = setmetatable({}, MODE_KEY_METATABLE),
}
if parent and parent._status == Promise.Status.Started then
parent._consumers[self] = true
end
setmetatable(self, Promise)
local function resolve(...)
self:_resolve(...)
end
local function reject(...)
self:_reject(...)
end
local function onCancel(cancellationHook)
if cancellationHook then
if self._status == Promise.Status.Cancelled then
cancellationHook()
else
self._cancellationHook = cancellationHook
end
end
return self._status == Promise.Status.Cancelled
end
self._thread = coroutine.create(function()
local ok, _, result = runExecutor(self._source, callback, resolve, reject, onCancel)
if not ok then
reject(result[1])
end
end)
task.spawn(self._thread)
return self
end
function Promise.new(executor)
return Promise._new(debug.traceback(nil, 2), executor)
end
function Promise:__tostring()
return string.format("Promise(%s)", self._status)
end
function Promise.defer(executor)
local traceback = debug.traceback(nil, 2)
local promise
promise = Promise._new(traceback, function(resolve, reject, onCancel)
local connection
connection = Promise._timeEvent:Connect(function()
connection:Disconnect()
local ok, _, result = runExecutor(traceback, executor, resolve, reject, onCancel)
if not ok then
reject(result[1])
end
end)
end)
return promise
end
Promise.async = Promise.defer
function Promise.resolve(...)
local length, values = pack(...)
return Promise._new(debug.traceback(nil, 2), function(resolve)
resolve(unpack(values, 1, length))
end)
end
function Promise.reject(...)
local length, values = pack(...)
return Promise._new(debug.traceback(nil, 2), function(_, reject)
reject(unpack(values, 1, length))
end)
end
function Promise._try(traceback, callback, ...)
local valuesLength, values = pack(...)
return Promise._new(traceback, function(resolve)
resolve(callback(unpack(values, 1, valuesLength)))
end)
end
function Promise.try(callback, ...)
return Promise._try(debug.traceback(nil, 2), callback, ...)
end
function Promise._all(traceback, promises, amount)
if type(promises) ~= "table" then
error(string.format(ERROR_NON_LIST, "Promise.all"), 3)
end
for i, promise in pairs(promises) do
if not Promise.is(promise) then
error(string.format(ERROR_NON_PROMISE_IN_LIST, "Promise.all", tostring(i)), 3)
end
end
if #promises == 0 or amount == 0 then
return Promise.resolve({})
end
return Promise._new(traceback, function(resolve, reject, onCancel)
local resolvedValues = {}
local newPromises = {}
local resolvedCount = 0
local rejectedCount = 0
local done = false
local function cancel()
for _, promise in ipairs(newPromises) do
promise:cancel()
end
end
local function resolveOne(i, ...)
if done then
return
end
resolvedCount = resolvedCount + 1
if amount == nil then
resolvedValues[i] = ...
else
resolvedValues[resolvedCount] = ...
end
if resolvedCount >= (amount or #promises) then
done = true
resolve(resolvedValues)
cancel()
end
end
onCancel(cancel)
for i, promise in ipairs(promises) do
newPromises[i] = promise:andThen(function(...)
resolveOne(i, ...)
end, function(...)
rejectedCount = rejectedCount + 1
if amount == nil or #promises - rejectedCount < amount then
cancel()
done = true
reject(...)
end
end)
end
if done then
cancel()
end
end)
end
function Promise.all(promises)
return Promise._all(debug.traceback(nil, 2), promises)
end
function Promise.fold(list, reducer, initialValue)
assert(type(list) == "table", "Bad argument #1 to Promise.fold: must be a table")
assert(isCallable(reducer), "Bad argument #2 to Promise.fold: must be a function")
local accumulator = Promise.resolve(initialValue)
return Promise.each(list, function(resolvedElement, i)
accumulator = accumulator:andThen(function(previousValueResolved)
return reducer(previousValueResolved, resolvedElement, i)
end)
end):andThen(function()
return accumulator
end)
end
function Promise.some(promises, count)
assert(type(count) == "number", "Bad argument #2 to Promise.some: must be a number")
return Promise._all(debug.traceback(nil, 2), promises, count)
end
function Promise.any(promises)
return Promise._all(debug.traceback(nil, 2), promises, 1):andThen(function(values)
return values[1]
end)
end
function Promise.allSettled(promises)
if type(promises) ~= "table" then
error(string.format(ERROR_NON_LIST, "Promise.allSettled"), 2)
end
for i, promise in pairs(promises) do
if not Promise.is(promise) then
error(string.format(ERROR_NON_PROMISE_IN_LIST, "Promise.allSettled", tostring(i)), 2)
end
end
if #promises == 0 then
return Promise.resolve({})
end
return Promise._new(debug.traceback(nil, 2), function(resolve, _, onCancel)
local fates = {}
local newPromises = {}
local finishedCount = 0
local function resolveOne(i, ...)
finishedCount = finishedCount + 1
fates[i] = ...
if finishedCount >= #promises then
resolve(fates)
end
end
onCancel(function()
for _, promise in ipairs(newPromises) do
promise:cancel()
end
end)
for i, promise in ipairs(promises) do
newPromises[i] = promise:finally(function(...)
resolveOne(i, ...)
end)
end
end)
end
function Promise.race(promises)
assert(type(promises) == "table", string.format(ERROR_NON_LIST, "Promise.race"))
for i, promise in pairs(promises) do
assert(Promise.is(promise), string.format(ERROR_NON_PROMISE_IN_LIST, "Promise.race", tostring(i)))
end
return Promise._new(debug.traceback(nil, 2), function(resolve, reject, onCancel)
local newPromises = {}
local finished = false
local function cancel()
for _, promise in ipairs(newPromises) do
promise:cancel()
end
end
local function finalize(callback)
return function(...)
cancel()
finished = true
return callback(...)
end
end
if onCancel(finalize(reject)) then
return
end
for i, promise in ipairs(promises) do
newPromises[i] = promise:andThen(finalize(resolve), finalize(reject))
end
if finished then
cancel()
end
end)
end
function Promise.each(list, predicate)
assert(type(list) == "table", string.format(ERROR_NON_LIST, "Promise.each"))
assert(isCallable(predicate), string.format(ERROR_NON_FUNCTION, "Promise.each"))
return Promise._new(debug.traceback(nil, 2), function(resolve, reject, onCancel)
local results = {}
local promisesToCancel = {}
local cancelled = false
local function cancel()
for _, promiseToCancel in ipairs(promisesToCancel) do
promiseToCancel:cancel()
end
end
onCancel(function()
cancelled = true
cancel()
end)
local preprocessedList = {}
for index, value in ipairs(list) do
if Promise.is(value) then
if value:getStatus() == Promise.Status.Cancelled then
cancel()
return reject(Error.new({
error = "Promise is cancelled",
kind = Error.Kind.AlreadyCancelled,
context = string.format(
"The Promise that was part of the array at index %d passed into Promise.each was already cancelled when Promise.each began.\n\nThat Promise was created at:\n\n%s",
index,
value._source
),
}))
elseif value:getStatus() == Promise.Status.Rejected then
cancel()
return reject(select(2, value:await()))
end
local ourPromise = value:andThen(function(...)
return ...
end)
table.insert(promisesToCancel, ourPromise)
preprocessedList[index] = ourPromise
else
preprocessedList[index] = value
end
end
for index, value in ipairs(preprocessedList) do
if Promise.is(value) then
local success
success, value = value:await()
if not success then
cancel()
return reject(value)
end
end
if cancelled then
return
end
local predicatePromise = Promise.resolve(predicate(value, index))
table.insert(promisesToCancel, predicatePromise)
local success, result = predicatePromise:await()
if not success then
cancel()
return reject(result)
end
results[index] = result
end
resolve(results)
end)
end
function Promise.is(object)
if type(object) ~= "table" then
return false
end
local objectMetatable = getmetatable(object)
if objectMetatable == Promise then
return true
elseif objectMetatable == nil then
return isCallable(object.andThen)
elseif
type(objectMetatable) == "table"
and type(rawget(objectMetatable, "__index")) == "table"
and isCallable(rawget(rawget(objectMetatable, "__index"), "andThen"))
then
return true
end
return false
end
function Promise.promisify(callback)
return function(...)
return Promise._try(debug.traceback(nil, 2), callback, ...)
end
end
do
local first
local connection
function Promise.delay(seconds)
assert(type(seconds) == "number", "Bad argument #1 to Promise.delay, must be a number.")
if not (seconds >= 1.6666666666666665E-2) or seconds == math.huge then
seconds = 1.6666666666666665E-2
end
return Promise._new(debug.traceback(nil, 2), function(resolve, _, onCancel)
local startTime = Promise._getTime()
local endTime = startTime + seconds
local node = {
resolve = resolve,
startTime = startTime,
endTime = endTime,
}
if connection == nil then
first = node
connection = Promise._timeEvent:Connect(function()
local threadStart = Promise._getTime()
while first ~= nil and first.endTime < threadStart do
local current = first
first = current.next
if first == nil then
connection:Disconnect()
connection = nil
else
first.previous = nil
end
current.resolve(Promise._getTime() - current.startTime)
end
end)
else
if first.endTime < endTime then
local current = first
local next = current.next
while next ~= nil and next.endTime < endTime do
current = next
next = current.next
end
current.next = node
node.previous = current
if next ~= nil then
node.next = next
next.previous = node
end
else
node.next = first
first.previous = node
first = node
end
end
onCancel(function()
local next = node.next
if first == node then
if next == nil then
connection:Disconnect()
connection = nil
else
next.previous = nil
end
first = next
else
local previous = node.previous
previous.next = next
if next ~= nil then
next.previous = previous
end
end
end)
end)
end
end
function Promise.prototype:timeout(seconds, rejectionValue)
local traceback = debug.traceback(nil, 2)
return Promise.race({
Promise.delay(seconds):andThen(function()
return Promise.reject(rejectionValue == nil and Error.new({
kind = Error.Kind.TimedOut,
error = "Timed out",
context = string.format(
"Timeout of %d seconds exceeded.\n:timeout() called at:\n\n%s",
seconds,
traceback
),
}) or rejectionValue)
end),
self,
})
end
function Promise.prototype:getStatus()
return self._status
end
function Promise.prototype:_andThen(traceback, successHandler, failureHandler)
self._unhandledRejection = false
if self._status == Promise.Status.Cancelled then
local promise = Promise.new(function() end)
promise:cancel()
return promise
end
return Promise._new(traceback, function(resolve, reject, onCancel)
local successCallback = resolve
if successHandler then
successCallback = createAdvancer(traceback, successHandler, resolve, reject)
end
local failureCallback = reject
if failureHandler then
failureCallback = createAdvancer(traceback, failureHandler, resolve, reject)
end
if self._status == Promise.Status.Started then
table.insert(self._queuedResolve, successCallback)
table.insert(self._queuedReject, failureCallback)
onCancel(function()
if self._status == Promise.Status.Started then
table.remove(self._queuedResolve, table.find(self._queuedResolve, successCallback))
table.remove(self._queuedReject, table.find(self._queuedReject, failureCallback))
end
end)
elseif self._status == Promise.Status.Resolved then
successCallback(unpack(self._values, 1, self._valuesLength))
elseif self._status == Promise.Status.Rejected then
failureCallback(unpack(self._values, 1, self._valuesLength))
end
end, self)
end
function Promise.prototype:andThen(successHandler, failureHandler)
assert(successHandler == nil or isCallable(successHandler), string.format(ERROR_NON_FUNCTION, "Promise:andThen"))
assert(failureHandler == nil or isCallable(failureHandler), string.format(ERROR_NON_FUNCTION, "Promise:andThen"))
return self:_andThen(debug.traceback(nil, 2), successHandler, failureHandler)
end
function Promise.prototype:catch(failureHandler)
assert(failureHandler == nil or isCallable(failureHandler), string.format(ERROR_NON_FUNCTION, "Promise:catch"))
return self:_andThen(debug.traceback(nil, 2), nil, failureHandler)
end
function Promise.prototype:tap(tapHandler)
assert(isCallable(tapHandler), string.format(ERROR_NON_FUNCTION, "Promise:tap"))
return self:_andThen(debug.traceback(nil, 2), function(...)
local callbackReturn = tapHandler(...)
if Promise.is(callbackReturn) then
local length, values = pack(...)
return callbackReturn:andThen(function()
return unpack(values, 1, length)
end)
end
return ...
end)
end
function Promise.prototype:andThenCall(callback, ...)
assert(isCallable(callback), string.format(ERROR_NON_FUNCTION, "Promise:andThenCall"))
local length, values = pack(...)
return self:_andThen(debug.traceback(nil, 2), function()
return callback(unpack(values, 1, length))
end)
end
function Promise.prototype:andThenReturn(...)
local length, values = pack(...)
return self:_andThen(debug.traceback(nil, 2), function()
return unpack(values, 1, length)
end)
end
function Promise.prototype:cancel()
if self._status ~= Promise.Status.Started then
return
end
self._status = Promise.Status.Cancelled
if self._cancellationHook then
self._cancellationHook()
end
coroutine.close(self._thread)
if self._parent then
self._parent:_consumerCancelled(self)
end
for child in pairs(self._consumers) do
child:cancel()
end
self:_finalize()
end
function Promise.prototype:_consumerCancelled(consumer)
if self._status ~= Promise.Status.Started then
return
end
self._consumers[consumer] = nil
if next(self._consumers) == nil then
self:cancel()
end
end
function Promise.prototype:_finally(traceback, finallyHandler)
self._unhandledRejection = false
local promise = Promise._new(traceback, function(resolve, reject, onCancel)
local handlerPromise
onCancel(function()
self:_consumerCancelled(self)
if handlerPromise then
handlerPromise:cancel()
end
end)
local finallyCallback = resolve
if finallyHandler then
finallyCallback = function(...)
local callbackReturn = finallyHandler(...)
if Promise.is(callbackReturn) then
handlerPromise = callbackReturn
callbackReturn
:finally(function(status)
if status ~= Promise.Status.Rejected then
resolve(self)
end
end)
:catch(function(...)
reject(...)
end)
else
resolve(self)
end
end
end
if self._status == Promise.Status.Started then
table.insert(self._queuedFinally, finallyCallback)
else
finallyCallback(self._status)
end
end)
return promise
end
function Promise.prototype:finally(finallyHandler)
assert(finallyHandler == nil or isCallable(finallyHandler), string.format(ERROR_NON_FUNCTION, "Promise:finally"))
return self:_finally(debug.traceback(nil, 2), finallyHandler)
end
function Promise.prototype:finallyCall(callback, ...)
assert(isCallable(callback), string.format(ERROR_NON_FUNCTION, "Promise:finallyCall"))
local length, values = pack(...)
return self:_finally(debug.traceback(nil, 2), function()
return callback(unpack(values, 1, length))
end)
end
function Promise.prototype:finallyReturn(...)
local length, values = pack(...)
return self:_finally(debug.traceback(nil, 2), function()
return unpack(values, 1, length)
end)
end
function Promise.prototype:awaitStatus()
self._unhandledRejection = false
if self._status == Promise.Status.Started then
local thread = coroutine.running()
self
:finally(function()
task.spawn(thread)
end)
:catch(
function() end
)
coroutine.yield()
end
if self._status == Promise.Status.Resolved then
return self._status, unpack(self._values, 1, self._valuesLength)
elseif self._status == Promise.Status.Rejected then
return self._status, unpack(self._values, 1, self._valuesLength)
end
return self._status
end
local function awaitHelper(status, ...)
return status == Promise.Status.Resolved, ...
end
function Promise.prototype:await()
return awaitHelper(self:awaitStatus())
end
local function expectHelper(status, ...)
if status ~= Promise.Status.Resolved then
error((...) == nil and "Expected Promise rejected with no value." or (...), 3)
end
return ...
end
function Promise.prototype:expect()
return expectHelper(self:awaitStatus())
end
Promise.prototype.awaitValue = Promise.prototype.expect
function Promise.prototype:_unwrap()
if self._status == Promise.Status.Started then
error("Promise has not resolved or rejected.", 2)
end
local success = self._status == Promise.Status.Resolved
return success, unpack(self._values, 1, self._valuesLength)
end
function Promise.prototype:_resolve(...)
if self._status ~= Promise.Status.Started then
if Promise.is((...)) then
(...):_consumerCancelled(self)
end
return
end
if Promise.is((...)) then
if select("#", ...) > 1 then
local message = string.format(
[[When returning a Promise from andThen, extra arguments are discarded! See:
%s]],
self._source
)
warn(message)
end
local chainedPromise = ...
local promise = chainedPromise:andThen(function(...)
self:_resolve(...)
end, function(...)
local maybeRuntimeError = chainedPromise._values[1]
if chainedPromise._error then
maybeRuntimeError = Error.new({
error = chainedPromise._error,
kind = Error.Kind.ExecutionError,
context = "[No stack trace available as this Promise originated from an older version of the Promise library (< v2)]",
})
end
if Error.isKind(maybeRuntimeError, Error.Kind.ExecutionError) then
return self:_reject(maybeRuntimeError:extend({
error = "This Promise was chained to a Promise that errored.",
trace = "",
context = string.format(
"The Promise at:\n\n%s\n...Rejected because it was chained to the following Promise, which encountered an error:\n",
self._source
),
}))
end
self:_reject(...)
end)
if promise._status == Promise.Status.Cancelled then
self:cancel()
elseif promise._status == Promise.Status.Started then
self._parent = promise
promise._consumers[self] = true
end
return
end
self._status = Promise.Status.Resolved
self._valuesLength, self._values = pack(...)
for _, callback in ipairs(self._queuedResolve) do
coroutine.wrap(callback)(...)
end
self:_finalize()
end
function Promise.prototype:_reject(...)
if self._status ~= Promise.Status.Started then
return
end
self._status = Promise.Status.Rejected
self._valuesLength, self._values = pack(...)
if not isEmpty(self._queuedReject) then
for _, callback in ipairs(self._queuedReject) do
coroutine.wrap(callback)(...)
end
else
local err = tostring((...))
coroutine.wrap(function()
Promise._timeEvent:Wait()
if not self._unhandledRejection then
return
end
local message = string.format("Unhandled Promise rejection:\n\n%s\n\n%s", err, self._source)
for _, callback in ipairs(Promise._unhandledRejectionCallbacks) do
task.spawn(callback, self, unpack(self._values, 1, self._valuesLength))
end
if Promise.TEST then
return
end
warn(message)
end)()
end
self:_finalize()
end
function Promise.prototype:_finalize()
for _, callback in ipairs(self._queuedFinally) do
coroutine.wrap(callback)(self._status)
end
self._queuedFinally = nil
self._queuedReject = nil
self._queuedResolve = nil
if not Promise.TEST then
self._parent = nil
self._consumers = nil
end
task.defer(coroutine.close, self._thread)
end
function Promise.prototype:now(rejectionValue)
local traceback = debug.traceback(nil, 2)
if self._status == Promise.Status.Resolved then
return self:_andThen(traceback, function(...)
return ...
end)
else
return Promise.reject(rejectionValue == nil and Error.new({
kind = Error.Kind.NotResolvedInTime,
error = "This Promise was not resolved in time for :now()",
context = ":now() was called at:\n\n" .. traceback,
}) or rejectionValue)
end
end
function Promise.retry(callback, times, ...)
assert(isCallable(callback), "Parameter #1 to Promise.retry must be a function")
assert(type(times) == "number", "Parameter #2 to Promise.retry must be a number")
local args, length = { ... }, select("#", ...)
return Promise.resolve(callback(...)):catch(function(...)
if times > 0 then
return Promise.retry(callback, times - 1, unpack(args, 1, length))
else
return Promise.reject(...)
end
end)
end
function Promise.retryWithDelay(callback, times, seconds, ...)
assert(isCallable(callback), "Parameter #1 to Promise.retry must be a function")
assert(type(times) == "number", "Parameter #2 (times) to Promise.retry must be a number")
assert(type(seconds) == "number", "Parameter #3 (seconds) to Promise.retry must be a number")
local args, length = { ... }, select("#", ...)
return Promise.resolve(callback(...)):catch(function(...)
if times > 0 then
Promise.delay(seconds):await()
return Promise.retryWithDelay(callback, times - 1, seconds, unpack(args, 1, length))
else
return Promise.reject(...)
end
end)
end
function Promise.fromEvent(event, predicate)
predicate = predicate or function()
return true
end
return Promise._new(debug.traceback(nil, 2), function(resolve, _, onCancel)
local connection
local shouldDisconnect = false
local function disconnect()
connection:Disconnect()
connection = nil
end
connection = event:Connect(function(...)
local callbackValue = predicate(...)
if callbackValue == true then
resolve(...)
if connection then
disconnect()
else
shouldDisconnect = true
end
elseif type(callbackValue) ~= "boolean" then
error("Promise.fromEvent predicate should always return a boolean")
end
end)
if shouldDisconnect and connection then
return disconnect()
end
onCancel(disconnect)
end)
end
function Promise.onUnhandledRejection(callback)
table.insert(Promise._unhandledRejectionCallbacks, callback)
return function()
local index = table.find(Promise._unhandledRejectionCallbacks, callback)
if index then
table.remove(Promise._unhandledRejectionCallbacks, index)
end
end
end
return Promise
end)() end,[6]=function()local wax,script,require=ImportGlobals(6)local ImportGlobals return (function(...)local Promise = require(script.Parent.Promise)
local RunService = game:GetService("RunService")
local OUTPUT_PREFIX = "roblox-ts: "
local NODE_MODULES = "node_modules"
local DEFAULT_SCOPE = "@rbxts"
local TS = {}
TS.Promise = Promise
local function isPlugin(context)
return RunService:IsStudio() and context:FindFirstAncestorWhichIsA("Plugin") ~= nil
end
function TS.getModule(context, scope, moduleName)
if moduleName == nil then
moduleName = scope
scope = DEFAULT_SCOPE
end
if RunService:IsRunning() and RunService:IsClient() and not isPlugin(context) and not game:IsLoaded() then
game.Loaded:Wait()
end
local object = context
repeat
local nodeModulesFolder = object:FindFirstChild(NODE_MODULES)
if nodeModulesFolder then
local scopeFolder = nodeModulesFolder:FindFirstChild(scope)
if scopeFolder then
local module = scopeFolder:FindFirstChild(moduleName)
if module then
return module
end
end
end
object = object.Parent
until object == nil
error(OUTPUT_PREFIX .. "Could not find module: " .. moduleName, 2)
end
local currentlyLoading = {}
local registeredLibraries = {}
function TS.import(context, module, ...)
for i = 1, select("#", ...) do
module = module:WaitForChild((select(i, ...)))
end
if module.ClassName ~= "ModuleScript" then
error(OUTPUT_PREFIX .. "Failed to import! Expected ModuleScript, got " .. module.ClassName, 2)
end
currentlyLoading[context] = module
local currentModule = module
local depth = 0
while currentModule do
depth = depth + 1
currentModule = currentlyLoading[currentModule]
if currentModule == module then
local str = currentModule.Name
for _ = 1, depth do
currentModule = currentlyLoading[currentModule]
str = str .. " ⇒ " .. currentModule.Name
end
error(OUTPUT_PREFIX .. "Failed to import! Detected a circular dependency chain: " .. str, 2)
end
end
if not registeredLibraries[module] then
if _G[module] then
error(
OUTPUT_PREFIX
.. "Invalid module access! Do you have multiple TS runtimes trying to import this? "
.. module:GetFullName(),
2
)
end
_G[module] = TS
registeredLibraries[module] = true
end
local data = require(module)
if currentlyLoading[context] == module then
currentlyLoading[context] = nil
end
return data
end
function TS.instanceof(obj, class)
if type(class) == "table" and type(class.instanceof) == "function" then
return class.instanceof(obj)
end
if type(obj) == "table" then
obj = getmetatable(obj)
while obj ~= nil do
if obj == class then
return true
end
local mt = getmetatable(obj)
if mt then
obj = mt.__index
else
obj = nil
end
end
end
return false
end
function TS.async(callback)
return function(...)
local n = select("#", ...)
local args = { ... }
return Promise.new(function(resolve, reject)
coroutine.wrap(function()
local ok, result = pcall(callback, unpack(args, 1, n))
if ok then
resolve(result)
else
reject(result)
end
end)()
end)
end
end
function TS.await(promise)
if not Promise.is(promise) then
return promise
end
local status, value = promise:awaitStatus()
if status == Promise.Status.Resolved then
return value
elseif status == Promise.Status.Rejected then
error(value, 2)
else
error("The awaited Promise was cancelled", 2)
end
end
local SIGN = 2147483648
local COMPLEMENT = 4294967296
local function bit_sign(num)
if bit32.btest(num, SIGN) then
return num - COMPLEMENT
else
return num
end
end
function TS.bit_lrsh(a, b)
return bit_sign(bit32.arshift(a, b))
end
TS.TRY_RETURN = 1
TS.TRY_BREAK = 2
TS.TRY_CONTINUE = 3
function TS.try(try, catch, finally)
local trySuccess, exitTypeOrTryError, returns = pcall(try)
local exitType, tryError
if trySuccess then
exitType = exitTypeOrTryError
else
tryError = exitTypeOrTryError
end
local catchSuccess = true
local catchError
if not trySuccess and catch then
local newExitTypeOrCatchError, newReturns
catchSuccess, newExitTypeOrCatchError, newReturns = pcall(catch, tryError)
local newExitType
if catchSuccess then
newExitType = newExitTypeOrCatchError
else
catchError = newExitTypeOrCatchError
end
if newExitType then
exitType, returns = newExitType, newReturns
end
end
if finally then
local newExitType, newReturns = finally()
if newExitType then
exitType, returns = newExitType, newReturns
end
end
if exitType ~= TS.TRY_RETURN and exitType ~= TS.TRY_BREAK and exitType ~= TS.TRY_CONTINUE then
if not catchSuccess then
error(catchError, 2)
end
if not trySuccess and not catch then
error(tryError, 2)
end
end
return exitType, returns
end
function TS.generator(callback)
local co = coroutine.create(callback)
return {
next = function(...)
if coroutine.status(co) == "dead" then
return { done = true }
else
local success, value = coroutine.resume(co, ...)
if success == false then
error(value, 2)
end
return {
value = value,
done = coroutine.status(co) == "dead",
}
end
end,
}
end
return TS
end)() end,[12]=function()local wax,script,require=ImportGlobals(12)local ImportGlobals return (function(...)
local Promise = require(script.Promise)
type Promise<T...> = Promise.TypedPromise<T...>
local LinkToInstanceIndex = setmetatable({}, {
__tostring = function()
return "LinkToInstanceIndex"
end;
})
local INVALID_METHOD_NAME =
"Object is a %* and as such expected `true?` for the method name and instead got %*. Traceback: %*"
local METHOD_NOT_FOUND_ERROR = "Object %* doesn't have method %*, are you sure you want to add it? Traceback: %*"
local NOT_A_PROMISE = "Invalid argument #1 to 'Janitor:AddPromise' (Promise expected, got %* (%*)) Traceback: %*"
export type Janitor = typeof(setmetatable(
{} :: {
CurrentlyCleaning: boolean,
SuppressInstanceReDestroy: boolean,
Add: <T>(self: Janitor, object: T, methodName: BooleanOrString?, index: any?) -> T,
AddObject: <T, A...>(
self: Janitor,
constructor: {new: (A...) -> T},
methodName: BooleanOrString?,
index: any?,
A...
) -> T,
AddPromise: <T...>(self: Janitor, promiseObject: Promise<T...>) -> Promise<T...>,
Remove: (self: Janitor, index: any) -> Janitor,
RemoveNoClean: (self: Janitor, index: any) -> Janitor,
RemoveList: (self: Janitor,...any) -> Janitor,
RemoveListNoClean: (self: Janitor,...any) -> Janitor,
Get: (self: Janitor, index: any) -> any?,
GetAll: (self: Janitor) -> {[any]: any},
Cleanup: (self: Janitor) -> (),
Destroy: (self: Janitor) -> (),
LinkToInstance: (self: Janitor, Object: Instance, allowMultiple: boolean?) -> RBXScriptConnection,
LinkToInstances: (self: Janitor,...Instance) -> Janitor
},
{} :: {__call: (self: Janitor) -> ()}
))
type Private = typeof(setmetatable(
{} :: {
CurrentlyCleaning: boolean,
SuppressInstanceReDestroy: boolean,
[any]: BooleanOrString,
Add: <T>(self: Private, object: T, methodName: BooleanOrString?, index: any?) -> T,
AddObject: <T, A...>(
self: Private,
constructor: {new: (A...) -> T},
methodName: BooleanOrString?,
index: any?,
A...
) -> T,
AddPromise: <T...>(self: Private, promiseObject: Promise<T...>) -> Promise<T...>,
Remove: (self: Private, index: any) -> Private,
RemoveNoClean: (self: Private, index: any) -> Private,
RemoveList: (self: Private,...any) -> Private,
RemoveListNoClean: (self: Private,...any) -> Private,
Get: (self: Private, index: any) -> any?,
GetAll: (self: Private) -> {[any]: any},
Cleanup: (self: Private) -> (),
Destroy: (self: Private) -> (),
LinkToInstance: (self: Private, object: Instance, allowMultiple: boolean?) -> RBXScriptConnection,
LinkToInstances: (self: Private,...Instance) -> Private
},
{} :: {__call: (self: Private) -> ()}
))
type Static = {
ClassName: "Janitor",
CurrentlyCleaning: boolean,
SuppressInstanceReDestroy: boolean,
new: () -> Janitor,
Is: (object: any) -> boolean,
instanceof: (object: any) -> boolean
}
type PrivateStatic = Static & {
__call: (self: Private) -> (),
__tostring: (self: Private) -> string
}
local Janitor = {} :: Janitor & Static
local Private = Janitor :: Private & PrivateStatic
Janitor.ClassName = "Janitor"
Janitor.CurrentlyCleaning = true
Janitor.SuppressInstanceReDestroy = false;
(Janitor :: any).__index = Janitor
local Janitors = setmetatable({} :: {[Private]: {[any]: any}}, {__mode = "k"})
local TYPE_DEFAULTS = {
["function"] = true;
thread = true;
RBXScriptConnection = "Disconnect";
}
function Janitor.new(): Janitor
return setmetatable({
CurrentlyCleaning = false;
}, Janitor) :: never
end
function Janitor.Is(object: any): boolean
return type(object) == "table" and getmetatable(object) == Janitor
end
Janitor.instanceof = Janitor.Is
local function Remove(self: Private, index: any)
local this = Janitors[self]
if this then
local object = this[index]
if not object then
return self
end
local methodName = self[object]
if methodName then
if methodName == true then
if type(object) == "function" then
object()
else
local wasCancelled: boolean = nil
if coroutine.running() ~= object then
wasCancelled = pcall(function()
task.cancel(object)
end)
end
if not wasCancelled then
local toCleanup = object
task.defer(function()
task.cancel(toCleanup)
end)
end
end
else
local objectMethod = object[methodName]
if objectMethod then
if self.SuppressInstanceReDestroy and methodName == "Destroy" and typeof(object) == "Instance" then
pcall(objectMethod, object)
else
objectMethod(object)
end
end
end
self[object] = nil
end
this[index] = nil
end
return self
end
type BooleanOrString = boolean | string
local function Add<T>(self: Private, object: T, methodName: BooleanOrString?, index: any?): T
if index then
Remove(self, index)
local this = Janitors[self]
if not this then
this = {}
Janitors[self] = this
end
this[index] = object
end
local typeOf = typeof(object)
local newMethodName = methodName or TYPE_DEFAULTS[typeOf] or "Destroy"
if typeOf == "function" or typeOf == "thread" then
if newMethodName ~= true then
warn(string.format(INVALID_METHOD_NAME, typeOf, tostring(newMethodName), debug.traceback(nil, 2)))
end
else
if not (object :: never)[newMethodName] then
warn(
string.format(
METHOD_NOT_FOUND_ERROR,
tostring(object),
tostring(newMethodName),
debug.traceback(nil, 2)
)
)
end
end
self[object] = newMethodName
return object
end
Private.Add = Add
function Janitor:AddObject<T, A...>(constructor: {new: (A...) -> T}, methodName: BooleanOrString?, index: any?, ...: A...): T
return Add(self, constructor.new(...), methodName, index)
end
function Janitor:AddPromise<T...>(promiseObject: Promise<T...>): Promise<T...>
if not Promise then
return promiseObject
end
if not Promise.is(promiseObject) then
error(string.format(NOT_A_PROMISE, typeof(promiseObject), tostring(promiseObject), debug.traceback(nil, 2)))
end
if promiseObject:getStatus() == Promise.Status.Started then
local uniqueId = newproxy(false)
local newPromise = Add(self, Promise.new(function(resolve, _, onCancel)
if onCancel(function()
promiseObject:cancel()
end) then
return
end
resolve(promiseObject)
end), "cancel", uniqueId)
newPromise:finally(function()
Remove(self, uniqueId)
end)
return newPromise :: never
end
return promiseObject
end
Private.Remove = Remove
function Private:RemoveNoClean(index: any)
local this = Janitors[self]
if this then
local object = this[index]
if object then
self[object] = nil
this[index] = nil
end
end
return self
end
function Janitor:RemoveList(...: any)
local this = Janitors[self]
if this then
local length = select("#", ...)
if length == 1 then
return Remove(self, ...)
end
if length == 2 then
local indexA, indexB = ...
Remove(self, indexA)
Remove(self, indexB)
return self
end
if length == 3 then
local indexA, indexB, indexC = ...
Remove(self, indexA)
Remove(self, indexB)
Remove(self, indexC)
return self
end
for selectIndex = 1, length do
local removeObject = select(selectIndex, ...)
Remove(self, removeObject)
end
end
return self
end
function Janitor:RemoveListNoClean(...: any)
local this = Janitors[self]
if this then
local length = select("#", ...)
if length == 1 then
local indexA = ...
local object = this[indexA]
if object then
self[object] = nil
this[indexA] = nil
end
return self
end
if length == 2 then
local indexA, indexB = ...
local objectA = this[indexA]
if objectA then
self[objectA] = nil
this[indexA] = nil
end
local objectB = this[indexB]
if objectB then
self[objectB] = nil
this[indexB] = nil
end
return self
end
if length == 3 then
local indexA, indexB, indexC = ...
local objectA = this[indexA]
if objectA then
self[objectA] = nil
this[indexA] = nil
end
local objectB = this[indexB]
if objectB then
self[objectB] = nil
this[indexB] = nil
end
local objectC = this[indexC]
if objectC then
self[objectC] = nil
this[indexC] = nil
end
return self
end
for selectIndex = 1, length do
local index = select(selectIndex, ...)
local object = this[index]
if object then
self[object] = nil
this[index] = nil
end
end
end
return self
end
function Janitor:Get(index: any): any?
local this = Janitors[self]
return if this then this[index] else nil
end
function Janitor:GetAll(): {[any]: any}
local this = Janitors[self]
return if this then table.freeze(table.clone(this)) else {}
end
local function GetFenv(self: Private): () -> (any, BooleanOrString)
return function(): ()
for object, methodName in next, self do
if object ~= "SuppressInstanceReDestroy" then
return object, methodName
end
end
end :: never
end
local function Cleanup(self: Private)
if not self.CurrentlyCleaning then
self.CurrentlyCleaning = nil :: never
local get = GetFenv(self)
local object, methodName = get()
while object and methodName do
if methodName == true then
if type(object) == "function" then
object()
elseif type(object) == "thread" then
local wasCancelled: boolean = nil
if coroutine.running() ~= object then
wasCancelled = pcall(function()
task.cancel(object)
end)
end
if not wasCancelled then
local toCleanup = object
task.defer(function()
task.cancel(toCleanup)
end)
end
end
else
local objectMethod = (object :: never)[methodName] :: (object: unknown) -> ()
if objectMethod then
if self.SuppressInstanceReDestroy and methodName == "Destroy" and typeof(object) == "Instance" then
pcall(objectMethod, object)
else
objectMethod(object)
end
end
end
self[object] = nil
object, methodName = get()
end
local this = Janitors[self]
if this then
table.clear(this)
Janitors[self] = nil
end
self.CurrentlyCleaning = false
end
end
Private.Cleanup = Cleanup
function Janitor:Destroy()
Cleanup(self)
table.clear(self :: never)
setmetatable(self :: any, nil)
end
Private.__call = Cleanup
local function LinkToInstance(self: Private, object: Instance, allowMultiple: boolean?): RBXScriptConnection
local indexToUse = if allowMultiple then newproxy(false) else LinkToInstanceIndex
return Add(self, object.Destroying:Connect(function()
Cleanup(self)
end), "Disconnect", indexToUse)
end
Private.LinkToInstance = LinkToInstance;
(Janitor :: never).LegacyLinkToInstance = LinkToInstance
function Janitor:LinkToInstances(...: Instance)
local manualCleanup = Janitor.new()
for index = 1, select("#", ...) do
local object = select(index, ...)
if typeof(object) ~= "Instance" then
continue
end
manualCleanup:Add(LinkToInstance(self, object, true), "Disconnect")
end
return manualCleanup
end
function Private:__tostring()
return "Janitor"
end
return table.freeze({
Janitor = Janitor :: Static
})
end)() end,[13]=function()local wax,script,require=ImportGlobals(13)local ImportGlobals return (function(...)
local Packages = script.Parent.Parent
local Promise = _G[script.Parent].Promise
export type Status = "Started" | "Resolved" | "Rejected" | "Cancelled"
export type ErrorKind = "ExecutionError" | "AlreadyCancelled" | "NotResolvedInTime" | "TimedOut"
type ErrorStaticAndShared = {
Kind: {
ExecutionError: "ExecutionError",
AlreadyCancelled: "AlreadyCancelled",
NotResolvedInTime: "NotResolvedInTime",
TimedOut: "TimedOut"
}
}
type ErrorOptions = {
error: string,
trace: string?,
context: string?,
kind: ErrorKind
}
export type Error = typeof(setmetatable(
{} :: ErrorStaticAndShared & {
error: string,
trace: string?,
context: string?,
kind: ErrorKind,
parent: Error?,
createdTick: number,
createdTrace: string,
extend: (self: Error, options: ErrorOptions?) -> Error,
getErrorChain: (self: Error) -> { Error }
},
{} :: { __tostring: (self: Error) -> string }
))
type ErrorStatic = ErrorStaticAndShared & {
new: (options: ErrorOptions?, parent: Error?) -> Error,
is: (anything: any) -> boolean,
isKind: (anything: any, kind: ErrorKind) -> boolean
}
export type Promise = {
andThen: (
self: Promise,
successHandler: (...any) -> ...any,
failureHandler: ((...any) -> ...any)?
) -> Promise,
andThenCall: <TArgs...>(self: Promise, callback: (TArgs...) -> ...any,TArgs...) -> any,
andThenReturn: (self: Promise,...any) -> Promise,
await: (self: Promise) -> (boolean, ...any),
awaitStatus: (self: Promise) -> (Status, ...any),
cancel: (self: Promise) -> (),
catch: (self: Promise, failureHandler: (...any) -> ...any) -> Promise,
expect: (self: Promise) -> ...any,
finally: (self: Promise, finallyHandler: (status: Status) -> ...any) -> Promise,
finallyCall: <TArgs...>(self: Promise, callback: (TArgs...) -> ...any,TArgs...) -> Promise,
finallyReturn: (self: Promise,...any) -> Promise,
getStatus: (self: Promise) -> Status,
now: (self: Promise, rejectionValue: any?) -> Promise,
tap: (self: Promise, tapHandler: (...any) -> ...any) -> Promise,
timeout: (self: Promise, seconds: number, rejectionValue: any?) -> Promise
}
export type TypedPromise<T...> = {
andThen: (self: Promise, successHandler: (T...) -> ...any, failureHandler: ((...any) -> ...any)?) -> Promise,
andThenCall: <TArgs...>(self: Promise, callback: (TArgs...) -> ...any,TArgs...) -> Promise,
andThenReturn: (self: Promise,...any) -> Promise,
await: (self: Promise) -> (boolean, T...),
awaitStatus: (self: Promise) -> (Status, T...),
cancel: (self: Promise) -> (),
catch: (self: Promise, failureHandler: (...any) -> ...any) -> Promise,
expect: (self: Promise) -> T...,
finally: (self: Promise, finallyHandler: (status: Status) -> ...any) -> Promise,
finallyCall: <TArgs...>(self: Promise, callback: (TArgs...) -> ...any,TArgs...) -> Promise,
finallyReturn: (self: Promise,...any) -> Promise,
getStatus: (self: Promise) -> Status,
now: (self: Promise, rejectionValue: any?) -> Promise,
tap: (self: Promise, tapHandler: (T...) -> ...any) -> Promise,
timeout: (self: Promise, seconds: number, rejectionValue: any?) -> TypedPromise<T...>
}
type Signal<T...> = {
Connect: (self: Signal<T...>, callback: (T...) -> ...any) -> SignalConnection
}
type SignalConnection = {
Disconnect: (self: SignalConnection) -> ...any,
[any]: any
}
export type PromiseStatic = {
Error: ErrorStatic,
Status: {
Started: "Started",
Resolved: "Resolved",
Rejected: "Rejected",
Cancelled: "Cancelled"
},
all: <T>(promises: { TypedPromise<T> }) -> TypedPromise<{ T }>,
allSettled: <T>(promise: { TypedPromise<T> }) -> TypedPromise<{ Status }>,
any: <T>(promise: { TypedPromise<T> }) -> TypedPromise<T>,
defer: <TReturn...>(
executor: (
resolve: (TReturn...) -> (),
reject: (...any) -> (),
onCancel: (abortHandler: (() -> ())?) -> boolean
) -> ()
) -> TypedPromise<TReturn...>,
delay: (seconds: number) -> TypedPromise<number>,
each: <T, TReturn>(
list: { T | TypedPromise<T> },
predicate: (value: T, index: number) -> TReturn | TypedPromise<TReturn>
) -> TypedPromise<{ TReturn }>,
fold: <T, TReturn>(
list: { T | TypedPromise<T> },
reducer: (accumulator: TReturn, value: T, index: number) -> TReturn | TypedPromise<TReturn>
) -> TypedPromise<TReturn>,
fromEvent: <TReturn...>(
event: Signal<TReturn...>,
predicate: ((TReturn...) -> boolean)?
) -> TypedPromise<TReturn...>,
is: (object: any) -> boolean,
new: <TReturn...>(
executor: (
resolve: (TReturn...) -> (),
reject: (...any) -> (),
onCancel: (abortHandler: (() -> ())?) -> boolean
) -> ()
) -> TypedPromise<TReturn...>,
onUnhandledRejection: (callback: (promise: TypedPromise<any>,...any) -> ()) -> () -> (),
promisify: <TArgs..., TReturn...>(callback: (TArgs...) -> TReturn...) -> (TArgs...) -> TypedPromise<TReturn...>,
race: <T>(promises: { TypedPromise<T> }) -> TypedPromise<T>,
reject: (...any) -> TypedPromise<...any>,
resolve: <TReturn...>(TReturn...) -> TypedPromise<TReturn...>,
retry: <TArgs..., TReturn...>(
callback: (TArgs...) -> TypedPromise<TReturn...>,
times: number,
TArgs...
) -> TypedPromise<TReturn...>,
retryWithDelay: <TArgs..., TReturn...>(
callback: (TArgs...) -> TypedPromise<TReturn...>,
times: number,
seconds: number,
TArgs...
) -> TypedPromise<TReturn...>,
some: <T>(promise: { TypedPromise<T> }, count: number) -> TypedPromise<{ T }>,
try: <TArgs..., TReturn...>(callback: (TArgs...) -> TReturn...,TArgs...) -> TypedPromise<TReturn...>
}
return Promise :: PromiseStatic?
end)() end,[15]=function()local wax,script,require=ImportGlobals(15)local ImportGlobals return (function(...)
local TS = _G[script]
local exports = {}
for _k, _v in TS.import(script, script, "logsnag") or {} do
exports[_k] = _v
end
return exports
end)() end,[16]=function()local wax,script,require=ImportGlobals(16)local ImportGlobals return (function(...)
local TS = _G[script]
local HttpService = TS.import(script, TS.getModule(script, "@rbxts", "services")).HttpService
local API
do
API = setmetatable({}, {
__tostring = function()
return "API"
end,
})
API.__index = API
function API.new(...)
local self = setmetatable({}, API)
return self:constructor(...) or self
end
function API:constructor(token, project)
self.token = token
self.project = project
end
function API:checkKebabCase(record)
if record == nil then
record = {}
end
for key in pairs(record) do
local _exp = string.split(key, "-")
local _arg0 = function(substr)
return #({ string.match(substr, "^%l+$") }) == 0
end
local _result = false
for _k, _v in _exp do
if _arg0(_v, _k - 1, _exp) then
_result = true
break
end
end
if _result then
return TS.Promise.reject('All tag and property keys must be in kebab-case, got "' .. (key .. '"'))
end
end
return TS.Promise.resolve()
end
function API:post(endpoint, body)
return self:request("POST", endpoint, body)
end
function API:patch(endpoint, body)
return self:request("PATCH", endpoint, body)
end
function API:request(method, endpoint, requestBody)
local _exp = TS.Promise.try(function()
local _fn = HttpService
local _object = {
project = self.project,
}
if type(requestBody) == "table" then
for _k, _v in requestBody do
_object[_k] = _v
end
end
local requestJson = _fn:JSONEncode(_object)
return HttpService:RequestAsync({
Url = "https://api.logsnag.com/v1/" .. endpoint,
Method = method,
Body = requestJson,
Headers = {
["Content-Type"] = "application/json",
Authorization = "Bearer " .. self.token,
},
})
end)
local _arg0 = function(response)
if response.Success then
return TS.Promise.resolve()
end
local httpError = "HTTP Error " .. (tostring(response.StatusCode) .. (": " .. response.StatusMessage))
local _exp_1 = TS.Promise.try(function()
return HttpService:JSONDecode(response.Body)
end)
local _arg0_1 = function(responseBody)
if responseBody.message == nil then
return TS.Promise.reject(httpError)
elseif responseBody.message ~= "Validation Error" then
return TS.Promise.reject(responseBody.message)
end
local validationErrors = {}
local _result = responseBody.validation
if _result ~= nil then
_result = _result.headers
if _result ~= nil then
local _arg0_2 = function(header)
local _message = header.message
table.insert(validationErrors, _message)
end
for _k, _v in _result do
_arg0_2(_v, _k - 1, _result)
end
end
end
local _result_1 = responseBody.validation
if _result_1 ~= nil then
_result_1 = _result_1.body
if _result_1 ~= nil then
local _arg0_2 = function(header)
local _message = header.message
table.insert(validationErrors, _message)
end
for _k, _v in _result_1 do
_arg0_2(_v, _k - 1, _result_1)
end
end
end
return TS.Promise.reject("Found " .. (tostring(#validationErrors) .. (" validation error" .. ((if #validationErrors == 1 then "" else "s") .. (":\n\t- " .. table.concat(validationErrors, "\n\t- "))))))
end
local _arg1 = function()
return TS.Promise.reject(httpError)
end
return _exp_1:andThen(_arg0_1, _arg1)
end
return _exp:andThen(_arg0)
end
end
return {
API = API,
}
end)() end,[17]=function()local wax,script,require=ImportGlobals(17)local ImportGlobals return (function(...)
local TS = _G[script]
local API = TS.import(script, script.Parent, "api").API
local Channel
do
Channel = setmetatable({}, {
__tostring = function()
return "Channel"
end,
})
Channel.__index = Channel
function Channel.new(...)
local self = setmetatable({}, Channel)
return self:constructor(...) or self
end
function Channel:constructor(api, name)
self.api = api
self.name = name
end
function Channel:getName()
return self.name
end
function Channel:log(event, options)
local _fn = API
local _result = options
if _result ~= nil then
_result = _result.tags
end
local _exp = _fn:checkKebabCase(_result)
local _arg0 = function()
local _fn_1 = self.api
local _object = {
channel = self.name,
event = event,
}
if type(options) == "table" then
for _k, _v in options do
_object[_k] = _v
end
end
return _fn_1:post("log", _object)
end
return _exp:andThen(_arg0)
end
end
return {
Channel = Channel,
}
end)() end,[18]=function()local wax,script,require=ImportGlobals(18)local ImportGlobals return (function(...)
local Insight
do
Insight = setmetatable({}, {
__tostring = function()
return "Insight"
end,
})
Insight.__index = Insight
function Insight.new(...)
local self = setmetatable({}, Insight)
return self:constructor(...) or self
end
function Insight:constructor(api, title, defaultIcon)
self.api = api
self.title = title
self.defaultIcon = defaultIcon
end
function Insight:getTitle()
return self.title
end
function Insight:set(value, icon)
local _fn = self.api
local _object = {
title = self.title,
}
local _left = "icon"
local _condition = icon
if _condition == nil then
_condition = self.defaultIcon
end
_object[_left] = _condition
_object.value = value
return _fn:post("insight", _object)
end
function Insight:increment(amount, icon)
local _fn = self.api
local _object = {
title = self.title,
}
local _left = "icon"
local _condition = icon
if _condition == nil then
_condition = self.defaultIcon
end
_object[_left] = _condition
_object.value = {
["$inc"] = amount,
}
return _fn:patch("insight", _object)
end
end
return {
Insight = Insight,
}
end)() end,[19]=function()local wax,script,require=ImportGlobals(19)local ImportGlobals return (function(...)
local TS = _G[script]
local Channel = TS.import(script, script.Parent, "channel").Channel
local Insight = TS.import(script, script.Parent, "insight").Insight
local API = TS.import(script, script.Parent, "api").API
local LogSnag
do
LogSnag = setmetatable({}, {
__tostring = function()
return "LogSnag"
end,
})
LogSnag.__index = LogSnag
function LogSnag.new(...)
local self = setmetatable({}, LogSnag)
return self:constructor(...) or self
end
function LogSnag:constructor(options)
self.api = API.new(options.token, options.project)
end
function LogSnag:getChannel(name)
return Channel.new(self.api, name)
end
function LogSnag:getInsight(title, defaultIcon)
return Insight.new(self.api, title, defaultIcon)
end
function LogSnag:identify(userId, properties)
local _exp = API:checkKebabCase(properties)
local _arg0 = function()
return self.api:post("identify", {
user_id = userId,
properties = properties,
})
end
return _exp:andThen(_arg0)
end
end
return {
LogSnag = LogSnag,
}
end)() end,[20]=function()local wax,script,require=ImportGlobals(20)local ImportGlobals return (function(...)
return nil
end)() end,[21]=function()local wax,script,require=ImportGlobals(21)local ImportGlobals return (function(...)local HttpService = game:GetService("HttpService")
local Object = {}
function Object.keys(object)
local result = table.create(#object)
for key in pairs(object) do
result[#result + 1] = key
end
return result
end
function Object.values(object)
local result = table.create(#object)
for _, value in pairs(object) do
result[#result + 1] = value
end
return result
end
function Object.entries(object)
local result = table.create(#object)
for key, value in pairs(object) do
result[#result + 1] = { key, value }
end
return result
end
function Object.assign(toObj, ...)
for i = 1, select("#", ...) do
local arg = select(i, ...)
if type(arg) == "table" then
for key, value in pairs(arg) do
toObj[key] = value
end
end
end
return toObj
end
function Object.copy(object)
local result = table.create(#object)
for k, v in pairs(object) do
result[k] = v
end
return result
end
local function deepCopyHelper(object, encountered)
local result = table.create(#object)
encountered[object] = result
for k, v in pairs(object) do
if type(k) == "table" then
k = encountered[k] or deepCopyHelper(k, encountered)
end
if type(v) == "table" then
v = encountered[v] or deepCopyHelper(v, encountered)
end
result[k] = v
end
return result
end
function Object.deepCopy(object)
return deepCopyHelper(object, {})
end
function Object.deepEquals(a, b)
for k in pairs(a) do
local av = a[k]
local bv = b[k]
if type(av) == "table" and type(bv) == "table" then
local result = Object.deepEquals(av, bv)
if not result then
return false
end
elseif av ~= bv then
return false
end
end
for k in pairs(b) do
if a[k] == nil then
return false
end
end
return true
end
function Object.toString(data)
return HttpService:JSONEncode(data)
end
function Object.isEmpty(object)
return next(object) == nil
end
function Object.fromEntries(entries)
local entriesLen = #entries
local result = table.create(entriesLen)
if entries then
for i = 1, entriesLen do
local pair = entries[i]
result[pair[1] ] = pair[2]
end
end
return result
end
return Object
end)() end,[23]=function()local wax,script,require=ImportGlobals(23)local ImportGlobals return (function(...)
local TS = _G[script]
local exports = {}
local _reflection_runtime = TS.import(script, TS.getModule(script, "@rbxts", "reflection-runtime").out)
local __GetType = _reflection_runtime.__GetType
local RegisterTypes = _reflection_runtime.RegisterTypes
for _k, _v in TS.import(script, TS.getModule(script, "@rbxts", "reflection-runtime").out) or {} do
exports[_k] = _v
end
RegisterTypes({
Name = "string",
FullName = "Primitive:string",
Assembly = "Global",
Value = nil,
Constructor = nil,
BaseType = nil,
Interfaces = {},
Properties = { {
Name = "_nominal_String",
Type = __GetType("@rbxts/compiler-types:types/String#_nominal_String"),
Optional = false,
AccessModifier = 2,
Readonly = true,
} },
Methods = {},
Kind = 1,
}, {
Name = "number",
FullName = "Primitive:number",
Assembly = "Global",
Value = nil,
Constructor = nil,
BaseType = nil,
Interfaces = {},
Properties = { {
Name = "_nominal_Number",
Type = __GetType("@rbxts/compiler-types:types/core#_nominal_Number"),
Optional = false,
AccessModifier = 2,
Readonly = true,
} },
Methods = {},
Kind = 1,
}, {
Name = "boolean",
FullName = "Primitive:boolean",
Assembly = "Global",
Value = nil,
Constructor = nil,
BaseType = nil,
Interfaces = {},
Properties = { {
Name = "_nominal_Boolean",
Type = __GetType("@rbxts/compiler-types:types/core#_nominal_Boolean"),
Optional = false,
AccessModifier = 2,
Readonly = true,
} },
Methods = {},
Kind = 1,
}, {
Name = "boolean",
FullName = "Primitive:boolean",
Assembly = "Global",
Value = nil,
Constructor = nil,
BaseType = nil,
Interfaces = {},
Properties = { {
Name = "_nominal_Boolean",
Type = __GetType("@rbxts/compiler-types:types/core#_nominal_Boolean"),
Optional = false,
AccessModifier = 2,
Readonly = true,
} },
Methods = {},
Kind = 1,
}, {
Name = "UnknownDeclaration",
FullName = "@rbxts/types:include/lua#thread",
Assembly = "@rbxts/types",
Value = nil,
Constructor = nil,
BaseType = nil,
Interfaces = {},
Properties = { {
Name = "_nominal_thread",
Type = __GetType("@rbxts/types:include/lua#_nominal_thread"),
Optional = false,
AccessModifier = 2,
Readonly = true,
} },
Methods = {},
Kind = nil,
})
return exports
end)() end,[25]=function()local wax,script,require=ImportGlobals(25)local ImportGlobals return (function(...)
local TS = _G[script]
local exports = {}
for _k, _v in TS.import(script, script, "declarations") or {} do
exports[_k] = _v
end
for _k, _v in TS.import(script, script, "macro") or {} do
exports[_k] = _v
end
for _k, _v in TS.import(script, script, "internal-usage") or {} do
exports[_k] = _v
end
for _k, _v in TS.import(script, script, "public-api") or {} do
exports[_k] = _v
end
for _k, _v in TS.import(script, script, "enums") or {} do
exports[_k] = _v
end
return exports
end)() end,[26]=function()local wax,script,require=ImportGlobals(26)local ImportGlobals return (function(...)
local TS = _G[script]
local TypeKind = TS.import(script, script.Parent, "enums").TypeKind
local GenerateValidator = TS.import(script, script.Parent, "validator-helper").GenerateValidator
local imported
local ScheduledTypes = {}
local function ImportInternalApi()
if imported then
return imported
end
imported = TS.Promise.new(function(resolve)
resolve(TS.import(script, script.Parent, "internal-usage"))
end):expect()
return imported
end
local Type
local Attribute
do
Attribute = setmetatable({}, {
__tostring = function()
return "Attribute"
end,
})
Attribute.__index = Attribute
function Attribute.new(...)
local self = setmetatable({}, Attribute)
return self:constructor(...) or self
end
function Attribute:constructor()
self.Attributes = {}
self.AttributesById = {}
end
function Attribute:GetAttributes()
return self.Attributes
end
function Attribute:Is(attributeData)
local attributeId = ImportInternalApi().GetGenericParameters()[1]
local casted = attributeData
if casted.__id == nil then
return false
end
return casted.__id == attributeId
end
function Attribute:findAttributeInherit(attributeId)
if not (TS.instanceof(self, Type)) then
return nil
end
local parent = self.BaseType
while parent do
local attribute = parent:getAttribute(attributeId)
if attribute ~= 0 and attribute == attribute and attribute ~= "" and attribute then
return attribute
end
parent = parent.BaseType
end
end
function Attribute:getAttribute(attributeId)
local _attributesById = self.AttributesById
local _attributeId = attributeId
return _attributesById[_attributeId]
end
function Attribute:GetAttribute(inherit)
if inherit == nil then
inherit = false
end
local attributeId = ImportInternalApi().GetGenericParameters()[1]
if not (attributeId ~= "" and attributeId) then
error("Attribute id is not set")
end
if inherit then
local attribute = self:findAttributeInherit(attributeId)
if attribute then
return attribute
end
end
return self:getAttribute(attributeId)
end
function Attribute:HaveAttribute(inherit)
if inherit == nil then
inherit = false
end
local attributeId = ImportInternalApi().GetGenericParameters()[1]
if not (attributeId ~= "" and attributeId) then
error("Attribute id is not set")
end
if inherit then
local attribute = self:findAttributeInherit(attributeId)
if attribute then
return true
end
end
return self:getAttribute(attributeId) ~= nil
end
end
do
local super = Attribute
Type = setmetatable({}, {
__tostring = function()
return "Type"
end,
__index = super,
})
Type.__index = Type
function Type.new(...)
local self = setmetatable({}, Type)
return self:constructor(...) or self
end
function Type:constructor()
super.constructor(self)
self.mapProperties = {}
self.mapMethods = {}
local _exp = self.Properties
local _callback = function(property)
local _mapProperties = self.mapProperties
local _name = property.Name
local _property = property
_mapProperties[_name] = _property
end
for _k, _v in _exp do
_callback(_v, _k - 1, _exp)
end
local _exp_1 = self.Methods
local _callback_1 = function(method)
local _mapMethods = self.mapMethods
local _name = method.Name
local _method = method
_mapMethods[_name] = _method
end
for _k, _v in _exp_1 do
_callback_1(_v, _k - 1, _exp_1)
end
if self.BaseType then
local _exp_2 = self.BaseType.Properties
local _callback_2 = function(property)
local _mapProperties = self.mapProperties
local _name = property.Name
local _property = property
_mapProperties[_name] = _property
end
for _k, _v in _exp_2 do
_callback_2(_v, _k - 1, _exp_2)
end
local _exp_3 = self.BaseType.Methods
local _callback_3 = function(method)
local _mapMethods = self.mapMethods
local _name = method.Name
local _method = method
_mapMethods[_name] = _method
end
for _k, _v in _exp_3 do
_callback_3(_v, _k - 1, _exp_3)
end
end
table.clear((self.Properties))
table.clear((self.Methods))
local _exp_2 = self.mapProperties
local _callback_2 = function(property)
local _exp_3 = (self.Properties)
local _property = property
table.insert(_exp_3, _property)
end
for _k, _v in _exp_2 do
_callback_2(_v, _k, _exp_2)
end
local _exp_3 = self.mapMethods
local _callback_3 = function(method)
local _exp_4 = (self.Methods)
local _method = method
table.insert(_exp_4, _method)
end
for _k, _v in _exp_3 do
_callback_3(_v, _k, _exp_3)
end
end
function Type:Validate(v)
local api = ImportInternalApi()
local generic = api.GetGenericParameters()[1]
if generic == nil then
error("Type generic is not set")
end
local _value = (string.find(generic, "RobloxInstance"))
if _value ~= 0 and _value == _value and _value then
local _type = api.__GetType("RobloxInstance:Instance")
return GenerateValidator(_type)(v)
end
local _type = api.__GetType(generic)
return GenerateValidator(_type)(v)
end
function Type:GenerateValidator()
local api = ImportInternalApi()
local generics = api.GetGenericParameters()
local _type = api.__GetType(generics[1])
return GenerateValidator(_type)
end
function Type:IsInterface()
return self.Kind == TypeKind.Interface
end
function Type:IsClass()
return self.Kind == TypeKind.Class
end
function Type:IsObject()
return self.Kind == TypeKind.Object
end
function Type:IsTypeParameter()
return self.Kind == TypeKind.TypeParameter
end
function Type:IsEnum()
return self.Kind == TypeKind.Enum
end
function Type:IsPrimitive()
return self.Kind == TypeKind.Primitive
end
function Type:GetProperty(name)
local _mapProperties = self.mapProperties
local _name = name
return _mapProperties[_name]
end
function Type:GetMethod(name)
local _mapMethods = self.mapMethods
local _name = name
return _mapMethods[_name]
end
end
local function WithAttributeProvider(instance, setMT)
if setMT == nil then
setMT = true
end
local template = Attribute.new()
for key, value in pairs(template) do
instance[key] = value
end
local _ = setMT and setmetatable(instance, Attribute)
return instance
end
local function GetDeferredConstructor(ctor, obj)
obj = setmetatable(obj or {}, ctor)
return { obj, function(...)
local args = { ... }
obj:constructor(unpack(args))
end }
end
local function Copy(target, source)
for key, value in pairs(source) do
target[key] = value
end
end
local Property, Method
local function ConvertTypeDescriptorInClass(descriptor, typeObject)
if getmetatable(descriptor) ~= nil then
return descriptor
end
if typeObject == nil then
local _fullName = descriptor.FullName
typeObject = ScheduledTypes[_fullName]
end
local _fullName = descriptor.FullName
ScheduledTypes[_fullName] = nil
local _binding = GetDeferredConstructor(Type, typeObject)
local template = _binding[1]
local ctor = _binding[2]
for key, value in pairs(descriptor) do
template[key] = value
end
local _exp = template.Properties
local _callback = function(property)
local template = Property.new()
Copy(property, template)
setmetatable(property, Property)
ConvertTypeDescriptorInClass(property.Type)
end
for _k, _v in _exp do
_callback(_v, _k - 1, _exp)
end
local _exp_1 = template.Methods
local _callback_1 = function(method)
local template = Method.new()
Copy(method, template)
setmetatable(method, Property)
ConvertTypeDescriptorInClass(method.ReturnType)
end
for _k, _v in _exp_1 do
_callback_1(_v, _k - 1, _exp_1)
end
ctor()
return template
end
do
local super = Attribute
Method = setmetatable({}, {
__tostring = function()
return "Method"
end,
__index = super,
})
Method.__index = Method
function Method.new(...)
local self = setmetatable({}, Method)
return self:constructor(...) or self
end
function Method:constructor(...)
super.constructor(self, ...)
end
end
local Parameter
do
local super = Attribute
Parameter = setmetatable({}, {
__tostring = function()
return "Parameter"
end,
__index = super,
})
Parameter.__index = Parameter
function Parameter.new(...)
local self = setmetatable({}, Parameter)
return self:constructor(...) or self
end
function Parameter:constructor(...)
super.constructor(self, ...)
end
end
do
local super = Attribute
Property = setmetatable({}, {
__tostring = function()
return "Property"
end,
__index = super,
})
Property.__index = Property
function Property.new(...)
local self = setmetatable({}, Property)
return self:constructor(...) or self
end
function Property:constructor(...)
super.constructor(self, ...)
end
function Property:Set(obj, value)
local _type = ImportInternalApi().__GetType(value)
if _type ~= self.Type then
error("Type mismatch")
end
obj[self.Name] = value
end
end
local ConstructorInfo
do
local super = Attribute
ConstructorInfo = setmetatable({}, {
__tostring = function()
return "ConstructorInfo"
end,
__index = super,
})
ConstructorInfo.__index = ConstructorInfo
function ConstructorInfo.new(...)
local self = setmetatable({}, ConstructorInfo)
return self:constructor(...) or self
end
function ConstructorInfo:constructor(...)
super.constructor(self, ...)
end
end
return {
WithAttributeProvider = WithAttributeProvider,
GetDeferredConstructor = GetDeferredConstructor,
ConvertTypeDescriptorInClass = ConvertTypeDescriptorInClass,
ScheduledTypes = ScheduledTypes,
Attribute = Attribute,
Type = Type,
Method = Method,
Parameter = Parameter,
Property = Property,
ConstructorInfo = ConstructorInfo,
}
end)() end,[27]=function()local wax,script,require=ImportGlobals(27)local ImportGlobals return (function(...)
local AccessModifier
do
local _inverse = {}
AccessModifier = setmetatable({}, {
__index = _inverse,
})
AccessModifier.Private = 0
_inverse[0] = "Private"
AccessModifier.Protected = 1
_inverse[1] = "Protected"
AccessModifier.Public = 2
_inverse[2] = "Public"
end
local TypeKind
do
local _inverse = {}
TypeKind = setmetatable({}, {
__index = _inverse,
})
TypeKind.Unknown = 0
_inverse[0] = "Unknown"
TypeKind.Primitive = 1
_inverse[1] = "Primitive"
TypeKind.Interface = 2
_inverse[2] = "Interface"
TypeKind.Object = 3
_inverse[3] = "Object"
TypeKind.Class = 4
_inverse[4] = "Class"
TypeKind.TypeParameter = 5
_inverse[5] = "TypeParameter"
TypeKind.Enum = 6
_inverse[6] = "Enum"
TypeKind.Instance = 7
_inverse[7] = "Instance"
end
return {
AccessModifier = AccessModifier,
TypeKind = TypeKind,
}
end)() end,[28]=function()local wax,script,require=ImportGlobals(28)local ImportGlobals return (function(...)
local TS = _G[script]
local _declarations = TS.import(script, script.Parent, "declarations")
local ConvertTypeDescriptorInClass = _declarations.ConvertTypeDescriptorInClass
local ScheduledTypes = _declarations.ScheduledTypes
local TypeKind = TS.import(script, script.Parent, "enums").TypeKind
local Metadata = TS.import(script, script.Parent, "metadata").Metadata
local _store = TS.import(script, script.Parent, "store")
local GlobalContext = _store.GlobalContext
local ReflectStore = _store.ReflectStore
local GENERIC_PARAMETERS = "__GENERIC_PARAMETERS__"
local ATTRIBUTE_KIND = "__ATTRIBUTE_KIND__"
local ATTRIBUTE_PARAMETERS = "__ATTRIBUTE_PARAMETERS__"
local metadataTypeReference = "__TYPE_REFERENSE__"
local UNKNOWN_TYPE = ConvertTypeDescriptorInClass({
Name = "unknown",
TypeParameters = {},
FullName = "unknown",
Assembly = "unknown",
BaseType = nil,
Interfaces = {},
Properties = {},
Methods = {},
Kind = TypeKind.Unknown,
})
local schedulingLocalTypes
local function DefineLocalType(id, _type)
local finalId = tostring(id)
if ReflectStore.LocalTypes[finalId] ~= nil then
error("Type already defined")
end
_type = ConvertTypeDescriptorInClass(_type, schedulingLocalTypes[finalId])
schedulingLocalTypes[finalId] = nil
local _localTypes = ReflectStore.LocalTypes
local __type = _type
_localTypes[finalId] = __type
end
schedulingLocalTypes = {}
local function GetLocalType(id, schedulingType)
if schedulingType == nil then
schedulingType = false
end
local finalId = tostring(id)
if schedulingType then
local finalId = tostring(id)
local typeReferense = schedulingLocalTypes[finalId] or {}
schedulingLocalTypes[finalId] = typeReferense
return typeReferense
end
if not (ReflectStore.LocalTypes[finalId] ~= nil) then
error("Type not found")
end
return ReflectStore.LocalTypes[finalId]
end
local function RegisterType(_typeRef)
local _store_1 = ReflectStore.Store
local _fullName = _typeRef.FullName
if _store_1[_fullName] ~= nil then
return nil
end
local _type = ConvertTypeDescriptorInClass(_typeRef)
local _typesByProjectName = ReflectStore.TypesByProjectName
local _assembly = _type.Assembly
local _condition = _typesByProjectName[_assembly]
if _condition == nil then
_condition = {}
end
local types = _condition
local _typesByProjectName_1 = ReflectStore.TypesByProjectName
local _assembly_1 = _type.Assembly
_typesByProjectName_1[_assembly_1] = types
local _assembliesSet = ReflectStore.AssembliesSet
local _assembly_2 = _type.Assembly
if not (_assembliesSet[_assembly_2] ~= nil) then
local _assemblies = ReflectStore.Assemblies
local _assembly_3 = _type.Assembly
table.insert(_assemblies, _assembly_3)
local _assembliesSet_1 = ReflectStore.AssembliesSet
local _assembly_4 = _type.Assembly
_assembliesSet_1[_assembly_4] = true
end
table.insert(types, _type)
local _exp = ReflectStore.Types
table.insert(_exp, _type)
local _store_2 = ReflectStore.Store
local _fullName_1 = _type.FullName
_store_2[_fullName_1] = _type
end
local function SetupKindForAttribute(kind, additionalParams)
GlobalContext[ATTRIBUTE_KIND] = kind
GlobalContext[ATTRIBUTE_PARAMETERS] = additionalParams
end
local function RegisterTypes(...)
local args = { ... }
local _callback = function(v)
return RegisterType(v)
end
for _k, _v in args do
_callback(_v, _k - 1, args)
end
end
local function RegisterDataType(instance, name)
Metadata.defineMetadata(instance, metadataTypeReference, name)
end
local function SetupGenericParameters(params)
GlobalContext[GENERIC_PARAMETERS] = params
end
local function SetupDefaultGenericParameters(defined, params)
if defined == nil then
return nil
end
local _callback = function(_param)
local index = _param[1]
local id = _param[2]
if defined[index + 1] ~= nil then
return nil
end
defined[index + 1] = id
end
for _k, _v in params do
_callback(_v, _k - 1, params)
end
end
local function GetGenericParameters()
local result = GlobalContext[GENERIC_PARAMETERS]
GlobalContext[GENERIC_PARAMETERS] = nil
return result or {}
end
local imported
local function ImportPublicApi()
if imported then
return imported
end
imported = TS.Promise.new(function(resolve)
resolve(TS.import(script, script.Parent, "public-api"))
end):expect()
return imported
end
local function __GetType(id, schedulingType)
if schedulingType == nil then
schedulingType = false
end
local _type = ImportPublicApi().GetType(id)
local _store_1 = ReflectStore.Store
local _id = id
local _condition = not (_store_1[_id] ~= nil)
if _condition then
_condition = schedulingType
end
if _condition then
local _id_1 = id
local _condition_1 = ScheduledTypes[_id_1]
if _condition_1 == nil then
_condition_1 = {}
end
local typeReferense = _condition_1
local _id_2 = id
ScheduledTypes[_id_2] = typeReferense
return typeReferense
end
return _type
end
local function GetMethodCallback(ctor, methodName)
local casted = ctor
return casted[methodName]
end
local function GetConstructorCallback(ctor)
local casted = ctor
return casted.constructor
end
return {
DefineLocalType = DefineLocalType,
GetLocalType = GetLocalType,
RegisterType = RegisterType,
SetupKindForAttribute = SetupKindForAttribute,
RegisterTypes = RegisterTypes,
RegisterDataType = RegisterDataType,
SetupGenericParameters = SetupGenericParameters,
SetupDefaultGenericParameters = SetupDefaultGenericParameters,
GetGenericParameters = GetGenericParameters,
__GetType = __GetType,
GetMethodCallback = GetMethodCallback,
GetConstructorCallback = GetConstructorCallback,
ATTRIBUTE_KIND = ATTRIBUTE_KIND,
ATTRIBUTE_PARAMETERS = ATTRIBUTE_PARAMETERS,
metadataTypeReference = metadataTypeReference,
UNKNOWN_TYPE = UNKNOWN_TYPE,
}
end)() end,[29]=function()local wax,script,require=ImportGlobals(29)local ImportGlobals return (function(...)return {}
end)() end,[30]=function()local wax,script,require=ImportGlobals(30)local ImportGlobals return (function(...)
local Metadata = {}
do
local _container = Metadata
local metadata = {}
_container.metadata = metadata
local idToObj = {}
_container.idToObj = idToObj
local objToId = {}
_container.objToId = objToId
local NO_PROP_MARKER = {}
local function getObjMetadata(obj, prop, create)
local _condition = prop
if _condition == nil then
_condition = NO_PROP_MARKER
end
local realProp = _condition
if create then
local _obj = obj
local objMetadata = metadata[_obj]
if not objMetadata then
objMetadata = {}
local _obj_1 = obj
local _objMetadata = objMetadata
metadata[_obj_1] = _objMetadata
end
local propMetadata = objMetadata[realProp]
if not propMetadata then
propMetadata = {}
local _objMetadata = objMetadata
local _propMetadata = propMetadata
_objMetadata[realProp] = _propMetadata
end
return propMetadata
end
local _obj = obj
local _result = metadata[_obj]
if _result ~= nil then
_result = _result[realProp]
end
return _result
end
local function getParentConstructor(obj)
local metatable = getmetatable(obj)
if metatable and type(metatable) == "table" then
return rawget(metatable, "__index")
end
end
local function defineMetadata(obj, key, value, property)
local metadata = getObjMetadata(obj, property, true)
local _key = key
local _value = value
metadata[_key] = _value
end
_container.defineMetadata = defineMetadata
local function defineMetadataBatch(obj, list, property)
local metadata = getObjMetadata(obj, property, true)
for key, value in pairs(list) do
metadata[key] = value
end
end
_container.defineMetadataBatch = defineMetadataBatch
local function deleteMetadata(obj, key, property)
local metadata = getObjMetadata(obj, property)
local _result = metadata
if _result ~= nil then
local _key = key
_result[_key] = nil
end
end
_container.deleteMetadata = deleteMetadata
local function getOwnMetadata(obj, key, property)
local metadata = getObjMetadata(obj, property)
local _result = metadata
if _result ~= nil then
local _key = key
_result = _result[_key]
end
return _result
end
_container.getOwnMetadata = getOwnMetadata
local function hasOwnMetadata(obj, key, property)
local metadata = getObjMetadata(obj, property)
local _result = metadata
if _result ~= nil then
local _key = key
_result = _result[_key] ~= nil
end
local _condition = _result
if _condition == nil then
_condition = false
end
return _condition
end
_container.hasOwnMetadata = hasOwnMetadata
local function getOwnMetadataKeys(obj, property)
local metadata = getObjMetadata(obj, property)
local keys = {}
if metadata ~= nil then
for key in metadata do
table.insert(keys, key)
end
end
return keys
end
_container.getOwnMetadataKeys = getOwnMetadataKeys
local function getOwnProperties(obj)
local _obj = obj
local properties = metadata[_obj]
if not properties then
return {}
end
local keys = {}
for key in properties do
if key ~= NO_PROP_MARKER then
table.insert(keys, key)
end
end
return keys
end
_container.getOwnProperties = getOwnProperties
local function getMetadatas(obj, key, property)
local values = {}
local value = getOwnMetadata(obj, key, property)
if value ~= nil then
table.insert(values, value)
end
local parent = getParentConstructor(obj)
if parent then
for _, value in getMetadatas(parent, key, property) do
table.insert(values, value)
end
end
return values
end
_container.getMetadatas = getMetadatas
local function getMetadata(obj, key, property)
local value = getOwnMetadata(obj, key, property)
if value ~= nil then
return value
end
local parent = getParentConstructor(obj)
if parent then
return getMetadata(parent, key, property)
end
end
_container.getMetadata = getMetadata
local function hasMetadata(obj, key, property)
local value = hasOwnMetadata(obj, key, property)
if value then
return value
end
local parent = getParentConstructor(obj)
if parent then
return hasMetadata(parent, key, property)
end
return false
end
_container.hasMetadata = hasMetadata
local function getMetadataKeys(obj, property)
local _set = {}
for _, _v in getOwnMetadataKeys(obj, property) do
_set[_v] = true
end
local keys = _set
local parent = getParentConstructor(obj)
if parent then
for _, key in getMetadataKeys(parent, property) do
keys[key] = true
end
end
local _array = {}
local _length = #_array
for _v in keys do
_length += 1
_array[_length] = _v
end
return _array
end
_container.getMetadataKeys = getMetadataKeys
local function getProperties(obj)
local _set = {}
for _, _v in getOwnProperties(obj) do
_set[_v] = true
end
local keys = _set
local parent = getParentConstructor(obj)
if parent then
for _, key in getProperties(parent) do
keys[key] = true
end
end
local _array = {}
local _length = #_array
for _v in keys do
_length += 1
_array[_length] = _v
end
return _array
end
_container.getProperties = getProperties
end
return {
Metadata = Metadata,
}
end)() end,[31]=function()local wax,script,require=ImportGlobals(31)local ImportGlobals return (function(...)
local TS = _G[script]
local _declarations = TS.import(script, script.Parent, "declarations")
local Attribute = _declarations.Attribute
local WithAttributeProvider = _declarations.WithAttributeProvider
local _internal_usage = TS.import(script, script.Parent, "internal-usage")
local __GetType = _internal_usage.__GetType
local ATTRIBUTE_KIND = _internal_usage.ATTRIBUTE_KIND
local ATTRIBUTE_PARAMETERS = _internal_usage.ATTRIBUTE_PARAMETERS
local metadataTypeReference = _internal_usage.metadataTypeReference
local UNKNOWN_TYPE = _internal_usage.UNKNOWN_TYPE
local Metadata = TS.import(script, script.Parent, "metadata").Metadata
local _store = TS.import(script, script.Parent, "store")
local GlobalContext = _store.GlobalContext
local ReflectStore = _store.ReflectStore
local CurrentAssembly = {
_special = "CurrentAssembly",
}
local function GetPrimitiveTypeId(value)
local _value = value
if type(_value) == "table" then
local _condition = Metadata.getMetadata(value, metadataTypeReference)
if _condition == nil then
_condition = "__UNKNOWN__"
end
return _condition
end
local _value_1 = value
local name = typeof(_value_1)
return `Primitive:{name}`
end
local function GetAllTypes()
return ReflectStore.Types
end
local function GetAllAssemblies()
return ReflectStore.Assemblies
end
local function GetTypes(assembly)
if assembly == CurrentAssembly then
error("Transformer missing CurrentAssembly marker")
end
local _typesByProjectName = ReflectStore.TypesByProjectName
local _assembly = assembly
local _condition = (_typesByProjectName[_assembly])
if _condition == nil then
_condition = {}
end
return _condition
end
local cachedRobloxInstanceTypes = {}
local function GetType(instance)
local _type
local _instance = instance
if type(_instance) == "string" then
local _store_1 = ReflectStore.Store
local _instance_1 = instance
_type = _store_1[_instance_1]
end
if _type == nil then
local _store_1 = ReflectStore.Store
local _arg0 = GetPrimitiveTypeId(instance)
_type = _store_1[_arg0]
end
if _type == nil then
local _store_1 = ReflectStore.Store
local _instance_1 = instance
local _arg0 = `@rbxts/types:include/roblox#{typeof(_instance_1)}`
_type = _store_1[_arg0]
end
local _condition = _type == nil
if _condition then
local _instance_1 = instance
_condition = typeof(_instance_1) == "Instance"
end
if _condition then
local _store_1 = ReflectStore.Store
local _arg0 = `RobloxInstance:{instance.ClassName}`
_type = _store_1[_arg0]
if _type == nil then
local _className = instance.ClassName
if cachedRobloxInstanceTypes[_className] ~= nil then
local _className_1 = instance.ClassName
return cachedRobloxInstanceTypes[_className_1]
end
_type = ReflectStore.Store["RobloxInstance:Instance"]
local clone = table.clone(_type)
clone.RobloxInstanceType = instance.ClassName
clone.FullName = `RobloxInstance:{instance.ClassName}`
local _className_1 = instance.ClassName
cachedRobloxInstanceTypes[_className_1] = clone
return clone
end
end
if _type == nil then
return UNKNOWN_TYPE
end
return _type
end
local function AddAttributeData(attributeInstance, attributeId, data)
if not (TS.instanceof(attributeInstance, Attribute)) then
WithAttributeProvider(attributeInstance)
end
data.__id = attributeId
local _attributesById = attributeInstance.AttributesById
local _attributeId = attributeId
local _data = data
_attributesById[_attributeId] = _data
local _attributes = attributeInstance.Attributes
local _data_1 = data
table.insert(_attributes, _data_1)
end
local function CreateAttribute(attributeClass, attributeId)
if attributeId == nil then
error("Attribute id is not set")
end
local callableSignature = function(t, ...)
local params = { ... }
local kind = GlobalContext[ATTRIBUTE_KIND]
if kind == nil then
error("Attribute kind is not set")
end
local _condition = GlobalContext[ATTRIBUTE_PARAMETERS]
if _condition == nil then
_condition = {}
end
local additional = _condition
return function(ctor, ...)
local args = { ... }
local attr = attributeClass.new(unpack(params))
local _type = __GetType(ctor)
if kind == "class" then
AddAttributeData(_type, attributeId, attr)
return nil
end
if kind == "method" then
local _binding = args
local methodName = _binding[1]
local _exp = _type.Methods
local _callback = function(v)
return v.Name == methodName
end
local _result
for _i, _v in _exp do
if _callback(_v, _i - 1, _exp) == true then
_result = _v
break
end
end
local provider = _result
if not provider then
return nil
end
AddAttributeData(provider, attributeId, attr)
return nil
end
if kind == "property" then
local _binding = args
local propertyName = _binding[1]
local _exp = _type.Properties
local _callback = function(v)
return v.Name == propertyName
end
local _result
for _i, _v in _exp do
if _callback(_v, _i - 1, _exp) == true then
_result = _v
break
end
end
local provider = _result
if not provider then
return nil
end
AddAttributeData(provider, attributeId, attr)
return nil
end
if kind == "parameter" then
local methodName = additional[1]
local _binding = args
local _ = _binding[1]
local index = _binding[2]
local _exp = _type.Methods
local _callback = function(v)
return v.Name == methodName
end
local _result
for _i, _v in _exp do
if _callback(_v, _i - 1, _exp) == true then
_result = _v
break
end
end
local _provider = _result
if _provider ~= nil then
_provider = _provider.Parameters[index + 1]
end
local provider = _provider
if not provider then
return nil
end
AddAttributeData(provider, attributeId, attr)
return nil
end
end
end
local mt = getmetatable(attributeClass)
mt.__call = callableSignature
return attributeClass
end
return {
GetAllTypes = GetAllTypes,
GetAllAssemblies = GetAllAssemblies,
GetTypes = GetTypes,
GetType = GetType,
CreateAttribute = CreateAttribute,
CurrentAssembly = CurrentAssembly,
}
end)() end,[32]=function()local wax,script,require=ImportGlobals(32)local ImportGlobals return (function(...)
local ReflectStoreTemplate = {
Store = {},
LocalTypes = {},
Assemblies = {},
AssembliesSet = {},
Types = {},
TypesByProjectName = {},
}
local KEY = "__REFLECT_STORE"
local GlobalContext = _G
local ReflectStore = (GlobalContext[KEY]) or ReflectStoreTemplate
for key, value in pairs(ReflectStoreTemplate) do
if ReflectStore[key] ~= nil then
continue
end
ReflectStore[key] = value
end
GlobalContext[KEY] = ReflectStore
return {
GlobalContext = GlobalContext,
ReflectStore = ReflectStore,
}
end)() end,[33]=function()local wax,script,require=ImportGlobals(33)local ImportGlobals return (function(...)
local TS = _G[script]
local t = TS.import(script, TS.getModule(script, "@rbxts", "t").lib.ts).t
local TypeKind = TS.import(script, script.Parent, "enums").TypeKind
local function GenerateClassValidator(_type)
if not _type:IsClass() then
error("Not a class")
end
return function(v)
local _v = v
if not (type(_v) == "table") then
return false
end
local mt = getmetatable(v)
if not (mt ~= 0 and mt == mt and mt ~= "" and mt) or _type.Value ~= mt then
return false
end
return TS.instanceof(v, (_type.Value))
end
end
local imported
local function ImportPublicApi()
if imported then
return imported
end
imported = TS.Promise.new(function(resolve)
resolve(TS.import(script, script.Parent, "public-api"))
end):expect()
return imported
end
local function GenerateValidator(_type)
local typeName = _type.Name
if _type.Kind == TypeKind.Instance and _type.RobloxInstanceType then
return function(v)
local _v = v
if not (typeof(_v) == "Instance") then
return false
end
local anotherType = ImportPublicApi().GetType(v)
if not anotherType.RobloxInstanceType then
return false
end
return t.instanceIsA(anotherType.RobloxInstanceType)(v)
end
end
if t[typeName] ~= nil then
return t[typeName]
end
if _type.Kind == TypeKind.Object or _type.Kind == TypeKind.Interface then
local _interface = {}
local _exp = _type.Properties
local _callback = function(property)
_interface[property.Name] = GenerateValidator(property.Type)
end
for _k, _v in _exp do
_callback(_v, _k - 1, _exp)
end
return t.interface(_interface)
end
if _type.Kind == TypeKind.Class then
return GenerateClassValidator(_type)
end
error(`Cannot find validator for type {_type.Name}, kind: {_type.Kind}, id: {_type.FullName}`)
end
return {
GenerateValidator = GenerateValidator,
}
end)() end,[34]=function()local wax,script,require=ImportGlobals(34)local ImportGlobals return (function(...)return setmetatable({}, {
__index = function(self, serviceName)
local service = game:GetService(serviceName)
self[serviceName] = service
return service
end,
})
end)() end,[37]=function()local wax,script,require=ImportGlobals(37)local ImportGlobals return (function(...)
local t = {}
function t.type(typeName)
return function(value)
local valueType = type(value)
if valueType == typeName then
return true
else
return false
end
end
end
function t.typeof(typeName)
return function(value)
local valueType = typeof(value)
if valueType == typeName then
return true
else
return false
end
end
end
function t.any(value)
if value ~= nil then
return true
else
return false
end
end
t.boolean = t.typeof("boolean")
t.buffer = t.typeof("buffer")
t.thread = t.typeof("thread")
t.callback = t.typeof("function")
t["function"] = t.callback
t.none = t.typeof("nil")
t["nil"] = t.none
t.string = t.typeof("string")
t.table = t.typeof("table")
t.userdata = t.type("userdata")
t.vector = t.type("vector")
function t.number(value)
local valueType = typeof(value)
if valueType == "number" then
if value == value then
return true
else
return false
end
else
return false
end
end
function t.nan(value)
local valueType = typeof(value)
if valueType == "number" then
if value ~= value then
return true
else
return false
end
else
return false
end
end
t.Axes = t.typeof("Axes")
t.BrickColor = t.typeof("BrickColor")
t.CatalogSearchParams = t.typeof("CatalogSearchParams")
t.CFrame = t.typeof("CFrame")
t.Color3 = t.typeof("Color3")
t.ColorSequence = t.typeof("ColorSequence")
t.ColorSequenceKeypoint = t.typeof("ColorSequenceKeypoint")
t.DateTime = t.typeof("DateTime")
t.DockWidgetPluginGuiInfo = t.typeof("DockWidgetPluginGuiInfo")
t.Enum = t.typeof("Enum")
t.EnumItem = t.typeof("EnumItem")
t.Enums = t.typeof("Enums")
t.Faces = t.typeof("Faces")
t.FloatCurveKey = t.typeof("FloatCurveKey")
t.Font = t.typeof("Font")
t.Instance = t.typeof("Instance")
t.NumberRange = t.typeof("NumberRange")
t.NumberSequence = t.typeof("NumberSequence")
t.NumberSequenceKeypoint = t.typeof("NumberSequenceKeypoint")
t.OverlapParams = t.typeof("OverlapParams")
t.PathWaypoint = t.typeof("PathWaypoint")
t.PhysicalProperties = t.typeof("PhysicalProperties")
t.Random = t.typeof("Random")
t.Ray = t.typeof("Ray")
t.RaycastParams = t.typeof("RaycastParams")
t.RaycastResult = t.typeof("RaycastResult")
t.RBXScriptConnection = t.typeof("RBXScriptConnection")
t.RBXScriptSignal = t.typeof("RBXScriptSignal")
t.Rect = t.typeof("Rect")
t.Region3 = t.typeof("Region3")
t.Region3int16 = t.typeof("Region3int16")
t.TweenInfo = t.typeof("TweenInfo")
t.UDim = t.typeof("UDim")
t.UDim2 = t.typeof("UDim2")
t.Vector2 = t.typeof("Vector2")
t.Vector2int16 = t.typeof("Vector2int16")
t.Vector3 = t.typeof("Vector3")
t.Vector3int16 = t.typeof("Vector3int16")
function t.literal(...)
local size = select("#", ...)
if size == 1 then
local literal = ...
return function(value)
if value ~= literal then
return false
end
return true
end
else
local literals = {}
for i = 1, size do
local value = select(i, ...)
literals[i] = t.literal(value)
end
return t.union(table.unpack(literals, 1, size))
end
end
t.exactly = t.literal
function t.keyOf(keyTable)
local keys = {}
local length = 0
for key in pairs(keyTable) do
length = length + 1
keys[length] = key
end
return t.literal(table.unpack(keys, 1, length))
end
function t.valueOf(valueTable)
local values = {}
local length = 0
for _, value in pairs(valueTable) do
length = length + 1
values[length] = value
end
return t.literal(table.unpack(values, 1, length))
end
function t.integer(value)
local success = t.number(value)
if not success then
return false
end
if value % 1 == 0 then
return true
else
return false
end
end
function t.numberMin(min)
return function(value)
local success = t.number(value)
if not success then
return false
end
if value >= min then
return true
else
return false
end
end
end
function t.numberMax(max)
return function(value)
local success = t.number(value)
if not success then
return false
end
if value <= max then
return true
else
return false
end
end
end
function t.numberMinExclusive(min)
return function(value)
local success = t.number(value)
if not success then
return false
end
if min < value then
return true
else
return false
end
end
end
function t.numberMaxExclusive(max)
return function(value)
local success = t.number(value)
if not success then
return false
end
if value < max then
return true
else
return false
end
end
end
t.numberPositive = t.numberMinExclusive(0)
t.numberNegative = t.numberMaxExclusive(0)
function t.numberConstrained(min, max)
assert(t.number(min))
assert(t.number(max))
local minCheck = t.numberMin(min)
local maxCheck = t.numberMax(max)
return function(value)
local minSuccess = minCheck(value)
if not minSuccess then
return false
end
local maxSuccess = maxCheck(value)
if not maxSuccess then
return false
end
return true
end
end
function t.numberConstrainedExclusive(min, max)
assert(t.number(min))
assert(t.number(max))
local minCheck = t.numberMinExclusive(min)
local maxCheck = t.numberMaxExclusive(max)
return function(value)
local minSuccess = minCheck(value)
if not minSuccess then
return false
end
local maxSuccess = maxCheck(value)
if not maxSuccess then
return false
end
return true
end
end
function t.match(pattern)
assert(t.string(pattern))
return function(value)
local stringSuccess = t.string(value)
if not stringSuccess then
return false
end
if string.match(value, pattern) == nil then
return false
end
return true
end
end
function t.optional(check)
assert(t.callback(check))
return function(value)
if value == nil then
return true
end
local success = check(value)
if success then
return true
else
return false
end
end
end
function t.tuple(...)
local checks = { ... }
return function(...)
local args = { ... }
for i, check in ipairs(checks) do
local success = check(args[i])
if success == false then
return false
end
end
return true
end
end
function t.keys(check)
assert(t.callback(check))
return function(value)
local tableSuccess = t.table(value)
if tableSuccess == false then
return false
end
for key in pairs(value) do
local success = check(key)
if success == false then
return false
end
end
return true
end
end
function t.values(check)
assert(t.callback(check))
return function(value)
local tableSuccess = t.table(value)
if tableSuccess == false then
return false
end
for _, val in pairs(value) do
local success = check(val)
if success == false then
return false
end
end
return true
end
end
function t.map(keyCheck, valueCheck)
assert(t.callback(keyCheck))
assert(t.callback(valueCheck))
local keyChecker = t.keys(keyCheck)
local valueChecker = t.values(valueCheck)
return function(value)
local keySuccess = keyChecker(value)
if not keySuccess then
return false
end
local valueSuccess = valueChecker(value)
if not valueSuccess then
return false
end
return true
end
end
function t.set(valueCheck)
return t.map(valueCheck, t.literal(true))
end
do
local arrayKeysCheck = t.keys(t.integer)
function t.array(check)
assert(t.callback(check))
local valuesCheck = t.values(check)
return function(value)
local keySuccess = arrayKeysCheck(value)
if keySuccess == false then
return false
end
local arraySize = 0
for _ in ipairs(value) do
arraySize = arraySize + 1
end
for key in pairs(value) do
if key < 1 or key > arraySize then
return false
end
end
local valueSuccess = valuesCheck(value)
if not valueSuccess then
return false
end
return true
end
end
function t.strictArray(...)
local valueTypes = { ... }
assert(t.array(t.callback)(valueTypes))
return function(value)
local keySuccess = arrayKeysCheck(value)
if keySuccess == false then
return false
end
if #valueTypes < #value then
return false
end
for idx, typeFn in pairs(valueTypes) do
local typeSuccess = typeFn(value[idx])
if not typeSuccess then
return false
end
end
return true
end
end
end
do
local callbackArray = t.array(t.callback)
function t.union(...)
local checks = { ... }
assert(callbackArray(checks))
return function(value)
for _, check in ipairs(checks) do
if check(value) then
return true
end
end
return false
end
end
t.some = t.union
function t.intersection(...)
local checks = { ... }
assert(callbackArray(checks))
return function(value)
for _, check in ipairs(checks) do
local success = check(value)
if not success then
return false
end
end
return true
end
end
t.every = t.intersection
end
do
local checkInterface = t.map(t.any, t.callback)
function t.interface(checkTable)
assert(checkInterface(checkTable))
return function(value)
local tableSuccess = t.table(value)
if tableSuccess == false then
return false
end
for key, check in pairs(checkTable) do
local success = check(value[key])
if success == false then
return false
end
end
return true
end
end
function t.strictInterface(checkTable)
assert(checkInterface(checkTable))
return function(value)
local tableSuccess = t.table(value)
if tableSuccess == false then
return false
end
for key, check in pairs(checkTable) do
local success = check(value[key])
if success == false then
return false
end
end
for key in pairs(value) do
if not checkTable[key] then
return false
end
end
return true
end
end
end
function t.instanceOf(className, childTable)
assert(t.string(className))
local childrenCheck
if childTable ~= nil then
childrenCheck = t.children(childTable)
end
return function(value)
local instanceSuccess = t.Instance(value)
if not instanceSuccess then
return false
end
if value.ClassName ~= className then
return false
end
if childrenCheck then
local childrenSuccess = childrenCheck(value)
if not childrenSuccess then
return false
end
end
return true
end
end
t.instance = t.instanceOf
function t.instanceIsA(className, childTable)
assert(t.string(className))
local childrenCheck
if childTable ~= nil then
childrenCheck = t.children(childTable)
end
return function(value)
local instanceSuccess = t.Instance(value)
if not instanceSuccess then
return false
end
if not value:IsA(className) then
return false
end
if childrenCheck then
local childrenSuccess = childrenCheck(value)
if not childrenSuccess then
return false
end
end
return true
end
end
function t.enum(enum)
assert(t.Enum(enum))
return function(value)
local enumItemSuccess = t.EnumItem(value)
if not enumItemSuccess then
return false
end
if value.EnumType == enum then
return true
else
return false
end
end
end
do
local checkWrap = t.tuple(t.callback, t.callback)
function t.wrap(callback, checkArgs)
assert(checkWrap(callback, checkArgs))
return function(...)
assert(checkArgs(...))
return callback(...)
end
end
end
function t.strict(check)
return function(...)
assert(check(...))
end
end
do
local checkChildren = t.map(t.string, t.callback)
function t.children(checkTable)
assert(checkChildren(checkTable))
return function(value)
local instanceSuccess = t.Instance(value)
if not instanceSuccess then
return false
end
local childrenByName = {}
for _, child in ipairs(value:GetChildren()) do
local name = child.Name
if checkTable[name] then
if childrenByName[name] then
return false
end
childrenByName[name] = child
end
end
for name, check in pairs(checkTable) do
local success = check(childrenByName[name])
if not success then
return false
end
end
return true
end
end
end
return { t = t }
end)() end,[39]=function()local wax,script,require=ImportGlobals(39)local ImportGlobals return (function(...)local Expectation = require(script.Expectation)
local TestBootstrap = require(script.TestBootstrap)
local TestEnum = require(script.TestEnum)
local TestPlan = require(script.TestPlan)
local TestPlanner = require(script.TestPlanner)
local TestResults = require(script.TestResults)
local TestRunner = require(script.TestRunner)
local TestSession = require(script.TestSession)
local TextReporter = require(script.Reporters.TextReporter)
local TextReporterQuiet = require(script.Reporters.TextReporterQuiet)
local TeamCityReporter = require(script.Reporters.TeamCityReporter)
local function run(testRoot, callback)
local modules = TestBootstrap:getModules(testRoot)
local plan = TestPlanner.createPlan(modules)
local results = TestRunner.runPlan(plan)
callback(results)
end
local TestEZ = {
run = run,
Expectation = Expectation,
TestBootstrap = TestBootstrap,
TestEnum = TestEnum,
TestPlan = TestPlan,
TestPlanner = TestPlanner,
TestResults = TestResults,
TestRunner = TestRunner,
TestSession = TestSession,
Reporters = {
TextReporter = TextReporter,
TextReporterQuiet = TextReporterQuiet,
TeamCityReporter = TeamCityReporter,
},
}
return TestEZ
end)() end,[40]=function()local wax,script,require=ImportGlobals(40)local ImportGlobals return (function(...)
local Context = {}
function Context.new(parent)
local meta = {}
local index = {}
meta.__index = index
if parent then
for key, value in pairs(getmetatable(parent).__index) do
index[key] = value
end
end
function meta.__newindex(_obj, key, value)
assert(index[key] == nil, string.format("Cannot reassign %s in context", tostring(key)))
index[key] = value
end
return setmetatable({}, meta)
end
return Context
end)() end,[41]=function()local wax,script,require=ImportGlobals(41)local ImportGlobals return (function(...)
local Expectation = {}
local SELF_KEYS = {
to = true,
be = true,
been = true,
have = true,
was = true,
at = true,
}
local NEGATION_KEYS = {
never = true,
}
local function assertLevel(condition, message, level)
message = message or "Assertion failed!"
level = level or 1
if not condition then
error(message, level + 1)
end
end
local function bindSelf(self, method)
return function(firstArg, ...)
if firstArg == self then
return method(self, ...)
else
return method(self, firstArg, ...)
end
end
end
local function formatMessage(result, trueMessage, falseMessage)
if result then
return trueMessage
else
return falseMessage
end
end
function Expectation.new(value)
local self = {
value = value,
successCondition = true,
condition = false,
matchers = {},
_boundMatchers = {},
}
setmetatable(self, Expectation)
self.a = bindSelf(self, self.a)
self.an = self.a
self.ok = bindSelf(self, self.ok)
self.equal = bindSelf(self, self.equal)
self.throw = bindSelf(self, self.throw)
self.near = bindSelf(self, self.near)
return self
end
function Expectation.checkMatcherNameCollisions(name)
if SELF_KEYS[name] or NEGATION_KEYS[name] or Expectation[name] then
return false
end
return true
end
function Expectation:extend(matchers)
self.matchers = matchers or {}
for name, implementation in pairs(self.matchers) do
self._boundMatchers[name] = bindSelf(self, function(_self, ...)
local result = implementation(self.value, ...)
local pass = result.pass == self.successCondition
assertLevel(pass, result.message, 3)
self:_resetModifiers()
return self
end)
end
return self
end
function Expectation.__index(self, key)
if SELF_KEYS[key] then
return self
end
if NEGATION_KEYS[key] then
local newExpectation = Expectation.new(self.value):extend(self.matchers)
newExpectation.successCondition = not self.successCondition
return newExpectation
end
if self._boundMatchers[key] then
return self._boundMatchers[key]
end
return Expectation[key]
end
function Expectation:_resetModifiers()
self.successCondition = true
end
function Expectation:a(typeName)
local result = (typeof(self.value) == typeName) == self.successCondition
local message = formatMessage(self.successCondition,
("Expected value of type %q, got value %q of type %s"):format(
typeName,
tostring(self.value),
type(self.value)
),
("Expected value not of type %q, got value %q of type %s"):format(
typeName,
tostring(self.value),
type(self.value)
)
)
assertLevel(result, message, 3)
self:_resetModifiers()
return self
end
Expectation.an = Expectation.a
function Expectation:ok()
local result = (self.value ~= nil) == self.successCondition
local message = formatMessage(self.successCondition,
("Expected value %q to be non-nil"):format(
tostring(self.value)
),
("Expected value %q to be nil"):format(
tostring(self.value)
)
)
assertLevel(result, message, 3)
self:_resetModifiers()
return self
end
function Expectation:equal(otherValue)
local result = (self.value == otherValue) == self.successCondition
local message = formatMessage(self.successCondition,
("Expected value %q (%s), got %q (%s) instead"):format(
tostring(otherValue),
type(otherValue),
tostring(self.value),
type(self.value)
),
("Expected anything but value %q (%s)"):format(
tostring(otherValue),
type(otherValue)
)
)
assertLevel(result, message, 3)
self:_resetModifiers()
return self
end
function Expectation:near(otherValue, limit)
assert(type(self.value) == "number", "Expectation value must be a number to use 'near'")
assert(type(otherValue) == "number", "otherValue must be a number")
assert(type(limit) == "number" or limit == nil, "limit must be a number or nil")
limit = limit or 1e-7
local result = (math.abs(self.value - otherValue) <= limit) == self.successCondition
local message = formatMessage(self.successCondition,
("Expected value to be near %f (within %f) but got %f instead"):format(
otherValue,
limit,
self.value
),
("Expected value to not be near %f (within %f) but got %f instead"):format(
otherValue,
limit,
self.value
)
)
assertLevel(result, message, 3)
self:_resetModifiers()
return self
end
function Expectation:throw(messageSubstring)
local ok, err = pcall(self.value)
local result = ok ~= self.successCondition
if messageSubstring and not ok then
if self.successCondition then
result = err:find(messageSubstring, 1, true) ~= nil
else
result = err:find(messageSubstring, 1, true) == nil
end
end
local message
if messageSubstring then
message = formatMessage(self.successCondition,
("Expected function to throw an error containing %q, but it %s"):format(
messageSubstring,
err and ("threw: %s"):format(err) or "did not throw."
),
("Expected function to never throw an error containing %q, but it threw: %s"):format(
messageSubstring,
tostring(err)
)
)
else
message = formatMessage(self.successCondition,
"Expected function to throw an error, but it did not throw.",
("Expected function to succeed, but it threw an error: %s"):format(
tostring(err)
)
)
end
assertLevel(result, message, 3)
self:_resetModifiers()
return self
end
return Expectation
end)() end,[42]=function()local wax,script,require=ImportGlobals(42)local ImportGlobals return (function(...)local Expectation = require(script.Parent.Expectation)
local checkMatcherNameCollisions = Expectation.checkMatcherNameCollisions
local function copy(t)
local result = {}
for key, value in pairs(t) do
result[key] = value
end
return result
end
local ExpectationContext = {}
ExpectationContext.__index = ExpectationContext
function ExpectationContext.new(parent)
local self = {
_extensions = parent and copy(parent._extensions) or {},
}
return setmetatable(self, ExpectationContext)
end
function ExpectationContext:startExpectationChain(...)
return Expectation.new(...):extend(self._extensions)
end
function ExpectationContext:extend(config)
for key, value in pairs(config) do
assert(self._extensions[key] == nil, string.format("Cannot reassign %q in expect.extend", key))
assert(checkMatcherNameCollisions(key), string.format("Cannot overwrite matcher %q; it already exists", key))
self._extensions[key] = value
end
end
return ExpectationContext
end)() end,[43]=function()local wax,script,require=ImportGlobals(43)local ImportGlobals return (function(...)local TestEnum = require(script.Parent.TestEnum)
local LifecycleHooks = {}
LifecycleHooks.__index = LifecycleHooks
function LifecycleHooks.new()
local self = {
_stack = {},
}
return setmetatable(self, LifecycleHooks)
end
function LifecycleHooks:getBeforeEachHooks()
local key = TestEnum.NodeType.BeforeEach
local hooks = {}
for _, level in ipairs(self._stack) do
for _, hook in ipairs(level[key]) do
table.insert(hooks, hook)
end
end
return hooks
end
function LifecycleHooks:getAfterEachHooks()
local key = TestEnum.NodeType.AfterEach
local hooks = {}
for _, level in ipairs(self._stack) do
for _, hook in ipairs(level[key]) do
table.insert(hooks, 1, hook)
end
end
return hooks
end
function LifecycleHooks:popHooks()
table.remove(self._stack, #self._stack)
end
function LifecycleHooks:pushHooksFrom(planNode)
assert(planNode ~= nil)
table.insert(self._stack, {
[TestEnum.NodeType.BeforeAll] = self:_getHooksOfType(planNode.children, TestEnum.NodeType.BeforeAll),
[TestEnum.NodeType.AfterAll] = self:_getHooksOfType(planNode.children, TestEnum.NodeType.AfterAll),
[TestEnum.NodeType.BeforeEach] = self:_getHooksOfType(planNode.children, TestEnum.NodeType.BeforeEach),
[TestEnum.NodeType.AfterEach] = self:_getHooksOfType(planNode.children, TestEnum.NodeType.AfterEach),
})
end
function LifecycleHooks:getBeforeAllHooks()
return self._stack[#self._stack][TestEnum.NodeType.BeforeAll]
end
function LifecycleHooks:getAfterAllHooks()
return self._stack[#self._stack][TestEnum.NodeType.AfterAll]
end
function LifecycleHooks:_getHooksOfType(nodes, key)
local hooks = {}
for _, node in ipairs(nodes) do
if node.type == key then
table.insert(hooks, node.callback)
end
end
return hooks
end
return LifecycleHooks
end)() end,[45]=function()local wax,script,require=ImportGlobals(45)local ImportGlobals return (function(...)local TestService = game:GetService("TestService")
local TestEnum = require(script.Parent.Parent.TestEnum)
local TeamCityReporter = {}
local function teamCityEscape(str)
str = string.gsub(str, "([]|'[])","|%1")
str = string.gsub(str, "\r", "|r")
str = string.gsub(str, "\n", "|n")
return str
end
local function teamCityEnterSuite(suiteName)
return string.format("##teamcity[testSuiteStarted name='%s']", teamCityEscape(suiteName))
end
local function teamCityLeaveSuite(suiteName)
return string.format("##teamcity[testSuiteFinished name='%s']", teamCityEscape(suiteName))
end
local function teamCityEnterCase(caseName)
return string.format("##teamcity[testStarted name='%s']", teamCityEscape(caseName))
end
local function teamCityLeaveCase(caseName)
return string.format("##teamcity[testFinished name='%s']", teamCityEscape(caseName))
end
local function teamCityFailCase(caseName, errorMessage)
return string.format("##teamcity[testFailed name='%s' message='%s']",
teamCityEscape(caseName), teamCityEscape(errorMessage))
end
local function reportNode(node, buffer, level)
buffer = buffer or {}
level = level or 0
if node.status == TestEnum.TestStatus.Skipped then
return buffer
end
if node.planNode.type == TestEnum.NodeType.Describe then
table.insert(buffer, teamCityEnterSuite(node.planNode.phrase))
for _, child in ipairs(node.children) do
reportNode(child, buffer, level + 1)
end
table.insert(buffer, teamCityLeaveSuite(node.planNode.phrase))
else
table.insert(buffer, teamCityEnterCase(node.planNode.phrase))
if node.status == TestEnum.TestStatus.Failure then
table.insert(buffer, teamCityFailCase(node.planNode.phrase, table.concat(node.errors,"\n")))
end
table.insert(buffer, teamCityLeaveCase(node.planNode.phrase))
end
end
local function reportRoot(node)
local buffer = {}
for _, child in ipairs(node.children) do
reportNode(child, buffer, 0)
end
return buffer
end
local function report(root)
local buffer = reportRoot(root)
return table.concat(buffer, "\n")
end
function TeamCityReporter.report(results)
local resultBuffer = {
"Test results:",
report(results),
("%d passed, %d failed, %d skipped"):format(
results.successCount,
results.failureCount,
results.skippedCount
)
}
print(table.concat(resultBuffer, "\n"))
if results.failureCount > 0 then
print(("%d test nodes reported failures."):format(results.failureCount))
end
if #results.errors > 0 then
print("Errors reported by tests:")
print("")
for _, message in ipairs(results.errors) do
TestService:Error(message)
print("")
end
end
end
return TeamCityReporter
end)() end,[46]=function()local wax,script,require=ImportGlobals(46)local ImportGlobals return (function(...)
local TestService = game:GetService("TestService")
local TestEnum = require(script.Parent.Parent.TestEnum)
local INDENT = (" "):rep(3)
local STATUS_SYMBOLS = {
[TestEnum.TestStatus.Success] = "+",
[TestEnum.TestStatus.Failure] = "-",
[TestEnum.TestStatus.Skipped] = "~"
}
local UNKNOWN_STATUS_SYMBOL = "?"
local TextReporter = {}
local function compareNodes(a, b)
return a.planNode.phrase:lower() < b.planNode.phrase:lower()
end
local function reportNode(node, buffer, level)
buffer = buffer or {}
level = level or 0
if node.status == TestEnum.TestStatus.Skipped then
return buffer
end
local line
if node.status then
local symbol = STATUS_SYMBOLS[node.status] or UNKNOWN_STATUS_SYMBOL
line = ("%s[%s] %s"):format(
INDENT:rep(level),
symbol,
node.planNode.phrase
)
else
line = ("%s%s"):format(
INDENT:rep(level),
node.planNode.phrase
)
end
table.insert(buffer, line)
table.sort(node.children, compareNodes)
for _, child in ipairs(node.children) do
reportNode(child, buffer, level + 1)
end
return buffer
end
local function reportRoot(node)
local buffer = {}
table.sort(node.children, compareNodes)
for _, child in ipairs(node.children) do
reportNode(child, buffer, 0)
end
return buffer
end
local function report(root)
local buffer = reportRoot(root)
return table.concat(buffer, "\n")
end
function TextReporter.report(results)
local resultBuffer = {
"Test results:",
report(results),
("%d passed, %d failed, %d skipped"):format(
results.successCount,
results.failureCount,
results.skippedCount
)
}
print(table.concat(resultBuffer, "\n"))
if results.failureCount > 0 then
print(("%d test nodes reported failures."):format(results.failureCount))
end
if #results.errors > 0 then
print("Errors reported by tests:")
print("")
for _, message in ipairs(results.errors) do
TestService:Error(message)
print("")
end
end
end
return TextReporter
end)() end,[47]=function()local wax,script,require=ImportGlobals(47)local ImportGlobals return (function(...)
local TestService = game:GetService("TestService")
local TestEnum = require(script.Parent.Parent.TestEnum)
local INDENT = (" "):rep(3)
local STATUS_SYMBOLS = {
[TestEnum.TestStatus.Success] = "+",
[TestEnum.TestStatus.Failure] = "-",
[TestEnum.TestStatus.Skipped] = "~"
}
local UNKNOWN_STATUS_SYMBOL = "?"
local TextReporterQuiet = {}
local function reportNode(node, buffer, level)
buffer = buffer or {}
level = level or 0
if node.status == TestEnum.TestStatus.Skipped then
return buffer
end
local line
if node.status ~= TestEnum.TestStatus.Success then
local symbol = STATUS_SYMBOLS[node.status] or UNKNOWN_STATUS_SYMBOL
line = ("%s[%s] %s"):format(
INDENT:rep(level),
symbol,
node.planNode.phrase
)
end
table.insert(buffer, line)
for _, child in ipairs(node.children) do
reportNode(child, buffer, level + 1)
end
return buffer
end
local function reportRoot(node)
local buffer = {}
for _, child in ipairs(node.children) do
reportNode(child, buffer, 0)
end
return buffer
end
local function report(root)
local buffer = reportRoot(root)
return table.concat(buffer, "\n")
end
function TextReporterQuiet.report(results)
local resultBuffer = {
"Test results:",
report(results),
("%d passed, %d failed, %d skipped"):format(
results.successCount,
results.failureCount,
results.skippedCount
)
}
print(table.concat(resultBuffer, "\n"))
if results.failureCount > 0 then
print(("%d test nodes reported failures."):format(results.failureCount))
end
if #results.errors > 0 then
print("Errors reported by tests:")
print("")
for _, message in ipairs(results.errors) do
TestService:Error(message)
print("")
end
end
end
return TextReporterQuiet
end)() end,[48]=function()local wax,script,require=ImportGlobals(48)local ImportGlobals return (function(...)
local TestPlanner = require(script.Parent.TestPlanner)
local TestRunner = require(script.Parent.TestRunner)
local TextReporter = require(script.Parent.Reporters.TextReporter)
local TestBootstrap = {}
local function stripSpecSuffix(name)
return (name:gsub("%.spec$", ""))
end
local function isSpecScript(aScript)
return aScript:IsA("ModuleScript") and aScript.Name:match("%.spec$")
end
local function getPath(module, root)
root = root or game
local path = {}
local last = module
if last.Name == "init.spec" then
last = last.Parent
end
while last ~= nil and last ~= root do
table.insert(path, stripSpecSuffix(last.Name))
last = last.Parent
end
table.insert(path, stripSpecSuffix(root.Name))
return path
end
local function toStringPath(tablePath)
local stringPath = ""
local first = true
for _, element in ipairs(tablePath) do
if first then
stringPath = element
first = false
else
stringPath = element .. " " .. stringPath
end
end
return stringPath
end
function TestBootstrap:getModulesImpl(root, modules, current)
modules = modules or {}
current = current or root
if isSpecScript(current) then
local method = require(current)
local path = getPath(current, root)
local pathString = toStringPath(path)
table.insert(modules, {
method = method,
path = path,
pathStringForSorting = pathString:lower()
})
end
end
function TestBootstrap:getModules(root)
local modules = {}
self:getModulesImpl(root, modules)
for _, child in ipairs(root:GetDescendants()) do
self:getModulesImpl(root, modules, child)
end
return modules
end
function TestBootstrap:run(roots, reporter, otherOptions)
reporter = reporter or TextReporter
otherOptions = otherOptions or {}
local showTimingInfo = otherOptions["showTimingInfo"] or false
local testNamePattern = otherOptions["testNamePattern"]
local extraEnvironment = otherOptions["extraEnvironment"] or {}
if type(roots) ~= "table" then
error(("Bad argument #1 to TestBootstrap:run. Expected table, got %s"):format(typeof(roots)), 2)
end
local startTime = tick()
local modules = {}
for _, subRoot in ipairs(roots) do
local newModules = self:getModules(subRoot)
for _, newModule in ipairs(newModules) do
table.insert(modules, newModule)
end
end
local afterModules = tick()
local plan = TestPlanner.createPlan(modules, testNamePattern, extraEnvironment)
local afterPlan = tick()
local results = TestRunner.runPlan(plan)
local afterRun = tick()
reporter.report(results)
local afterReport = tick()
if showTimingInfo then
local timing = {
("Took %f seconds to locate test modules"):format(afterModules - startTime),
("Took %f seconds to create test plan"):format(afterPlan - afterModules),
("Took %f seconds to run tests"):format(afterRun - afterPlan),
("Took %f seconds to report tests"):format(afterReport - afterRun),
}
print(table.concat(timing, "\n"))
end
return results
end
return TestBootstrap
end)() end,[49]=function()local wax,script,require=ImportGlobals(49)local ImportGlobals return (function(...)
local TestEnum = {}
TestEnum.TestStatus = {
Success = "Success",
Failure = "Failure",
Skipped = "Skipped"
}
TestEnum.NodeType = {
Describe = "Describe",
It = "It",
BeforeAll = "BeforeAll",
AfterAll = "AfterAll",
BeforeEach = "BeforeEach",
AfterEach = "AfterEach"
}
TestEnum.NodeModifier = {
None = "None",
Skip = "Skip",
Focus = "Focus"
}
return TestEnum
end)() end,[50]=function()local wax,script,require=ImportGlobals(50)local ImportGlobals return (function(...)
local TestEnum = require(script.Parent.TestEnum)
local Expectation = require(script.Parent.Expectation)
local function newEnvironment(currentNode, extraEnvironment)
local env = {}
if extraEnvironment then
if type(extraEnvironment) ~= "table" then
error(("Bad argument #2 to newEnvironment. Expected table, got %s"):format(
typeof(extraEnvironment)), 2)
end
for key, value in pairs(extraEnvironment) do
env[key] = value
end
end
local function addChild(phrase, callback, nodeType, nodeModifier)
local node = currentNode:addChild(phrase, nodeType, nodeModifier)
node.callback = callback
if nodeType == TestEnum.NodeType.Describe then
node:expand()
end
return node
end
function env.describeFOCUS(phrase, callback)
addChild(phrase, callback, TestEnum.NodeType.Describe, TestEnum.NodeModifier.Focus)
end
function env.describeSKIP(phrase, callback)
addChild(phrase, callback, TestEnum.NodeType.Describe, TestEnum.NodeModifier.Skip)
end
function env.describe(phrase, callback, nodeModifier)
addChild(phrase, callback, TestEnum.NodeType.Describe, TestEnum.NodeModifier.None)
end
function env.itFOCUS(phrase, callback)
addChild(phrase, callback, TestEnum.NodeType.It, TestEnum.NodeModifier.Focus)
end
function env.itSKIP(phrase, callback)
addChild(phrase, callback, TestEnum.NodeType.It, TestEnum.NodeModifier.Skip)
end
function env.itFIXME(phrase, callback)
local node = addChild(phrase, callback, TestEnum.NodeType.It, TestEnum.NodeModifier.Skip)
warn("FIXME: broken test", node:getFullName())
end
function env.it(phrase, callback, nodeModifier)
addChild(phrase, callback, TestEnum.NodeType.It, TestEnum.NodeModifier.None)
end
local lifecyclePhaseId = 0
local lifecycleHooks = {
[TestEnum.NodeType.BeforeAll] = "beforeAll",
[TestEnum.NodeType.AfterAll] = "afterAll",
[TestEnum.NodeType.BeforeEach] = "beforeEach",
[TestEnum.NodeType.AfterEach] = "afterEach"
}
for nodeType, name in pairs(lifecycleHooks) do
env[name] = function(callback)
addChild(name .. "_" .. tostring(lifecyclePhaseId), callback, nodeType, TestEnum.NodeModifier.None)
lifecyclePhaseId = lifecyclePhaseId + 1
end
end
function env.FIXME(optionalMessage)
warn("FIXME: broken test", currentNode:getFullName(), optionalMessage or "")
currentNode.modifier = TestEnum.NodeModifier.Skip
end
function env.FOCUS()
currentNode.modifier = TestEnum.NodeModifier.Focus
end
function env.SKIP()
currentNode.modifier = TestEnum.NodeModifier.Skip
end
function env.HACK_NO_XPCALL()
warn([[HACK_NO_XPCALL is deprecated. It is now safe to yield in an xpcall, so this is no longer necessary. It can be safely deleted.]]
)
end
env.fit = env.itFOCUS
env.xit = env.itSKIP
env.fdescribe = env.describeFOCUS
env.xdescribe = env.describeSKIP
env.expect = setmetatable({
extend = function(...)
error("Cannot call \"expect.extend\" from within a \"describe\" node.")
end,
}, {
__call = function(_self, ...)
return Expectation.new(...)
end,
})
return env
end
local TestNode = {}
TestNode.__index = TestNode
function TestNode.new(plan, phrase, nodeType, nodeModifier)
nodeModifier = nodeModifier or TestEnum.NodeModifier.None
local node = {
plan = plan,
phrase = phrase,
type = nodeType,
modifier = nodeModifier,
children = {},
callback = nil,
parent = nil,
}
node.environment = newEnvironment(node, plan.extraEnvironment)
return setmetatable(node, TestNode)
end
local function getModifier(name, pattern, modifier)
if pattern and (modifier == nil or modifier == TestEnum.NodeModifier.None) then
if name:match(pattern) then
return TestEnum.NodeModifier.Focus
else
return TestEnum.NodeModifier.Skip
end
end
return modifier
end
function TestNode:addChild(phrase, nodeType, nodeModifier)
if nodeType == TestEnum.NodeType.It then
for _, child in pairs(self.children) do
if child.phrase == phrase then
error("Duplicate it block found: " .. child:getFullName())
end
end
end
local childName = self:getFullName() .. " " .. phrase
nodeModifier = getModifier(childName, self.plan.testNamePattern, nodeModifier)
local child = TestNode.new(self.plan, phrase, nodeType, nodeModifier)
child.parent = self
table.insert(self.children, child)
return child
end
function TestNode:getFullName()
if self.parent then
local parentPhrase = self.parent:getFullName()
if parentPhrase then
return parentPhrase .. " " .. self.phrase
end
end
return self.phrase
end
function TestNode:expand()
local originalEnv = getfenv(self.callback)
local callbackEnv = setmetatable({}, { __index = originalEnv })
for key, value in pairs(self.environment) do
callbackEnv[key] = value
end
callbackEnv.script = originalEnv.script
setfenv(self.callback, callbackEnv)
local success, result = xpcall(self.callback, function(message)
return debug.traceback(tostring(message), 2)
end)
if not success then
self.loadError = result
end
end
local TestPlan = {}
TestPlan.__index = TestPlan
function TestPlan.new(testNamePattern, extraEnvironment)
local plan = {
children = {},
testNamePattern = testNamePattern,
extraEnvironment = extraEnvironment,
}
return setmetatable(plan, TestPlan)
end
function TestPlan:addChild(phrase, nodeType, nodeModifier)
nodeModifier = getModifier(phrase, self.testNamePattern, nodeModifier)
local child = TestNode.new(self, phrase, nodeType, nodeModifier)
table.insert(self.children, child)
return child
end
function TestPlan:addRoot(path, method)
local curNode = self
for i = #path, 1, -1 do
local nextNode = nil
for _, child in ipairs(curNode.children) do
if child.phrase == path[i] then
nextNode = child
break
end
end
if nextNode == nil then
nextNode = curNode:addChild(path[i], TestEnum.NodeType.Describe)
end
curNode = nextNode
end
curNode.callback = method
curNode:expand()
end
function TestPlan:visitAllNodes(callback, root, level)
root = root or self
level = level or 0
for _, child in ipairs(root.children) do
callback(child, level)
self:visitAllNodes(callback, child, level + 1)
end
end
function TestPlan:visualize()
local buffer = {}
self:visitAllNodes(function(node, level)
table.insert(buffer, (" "):rep(3 * level) .. node.phrase)
end)
return table.concat(buffer, "\n")
end
function TestPlan:findNodes(callback)
local results = {}
self:visitAllNodes(function(node)
if callback(node) then
table.insert(results, node)
end
end)
return results
end
return TestPlan
end)() end,[51]=function()local wax,script,require=ImportGlobals(51)local ImportGlobals return (function(...)
local TestPlan = require(script.Parent.TestPlan)
local TestPlanner = {}
function TestPlanner.createPlan(modulesList, testNamePattern, extraEnvironment)
local plan = TestPlan.new(testNamePattern, extraEnvironment)
table.sort(modulesList, function(a, b)
return a.pathStringForSorting < b.pathStringForSorting
end)
for _, module in ipairs(modulesList) do
plan:addRoot(module.path, module.method)
end
return plan
end
return TestPlanner
end)() end,[52]=function()local wax,script,require=ImportGlobals(52)local ImportGlobals return (function(...)
local TestEnum = require(script.Parent.TestEnum)
local STATUS_SYMBOLS = {
[TestEnum.TestStatus.Success] = "+",
[TestEnum.TestStatus.Failure] = "-",
[TestEnum.TestStatus.Skipped] = "~"
}
local TestResults = {}
TestResults.__index = TestResults
function TestResults.new(plan)
local self = {
successCount = 0,
failureCount = 0,
skippedCount = 0,
planNode = plan,
children = {},
errors = {}
}
setmetatable(self, TestResults)
return self
end
function TestResults.createNode(planNode)
local node = {
planNode = planNode,
children = {},
errors = {},
status = nil
}
return node
end
function TestResults:visitAllNodes(callback, root)
root = root or self
for _, child in ipairs(root.children) do
callback(child)
self:visitAllNodes(callback, child)
end
end
function TestResults:visualize(root, level)
root = root or self
level = level or 0
local buffer = {}
for _, child in ipairs(root.children) do
if child.planNode.type == TestEnum.NodeType.It then
local symbol = STATUS_SYMBOLS[child.status] or "?"
local str = ("%s[%s] %s"):format(
(" "):rep(3 * level),
symbol,
child.planNode.phrase
)
if child.messages and #child.messages > 0 then
str = str .. "\n " .. (" "):rep(3 * level) .. table.concat(child.messages, "\n " .. (" "):rep(3 * level))
end
table.insert(buffer, str)
else
local str = ("%s%s"):format(
(" "):rep(3 * level),
child.planNode.phrase or ""
)
if child.status then
str = str .. (" (%s)"):format(child.status)
end
table.insert(buffer, str)
if #child.children > 0 then
local text = self:visualize(child, level + 1)
table.insert(buffer, text)
end
end
end
return table.concat(buffer, "\n")
end
return TestResults
end)() end,[53]=function()local wax,script,require=ImportGlobals(53)local ImportGlobals return (function(...)
local TestEnum = require(script.Parent.TestEnum)
local TestSession = require(script.Parent.TestSession)
local LifecycleHooks = require(script.Parent.LifecycleHooks)
local RUNNING_GLOBAL = "__TESTEZ_RUNNING_TEST__"
local TestRunner = {
environment = {}
}
local function wrapExpectContextWithPublicApi(expectationContext)
return setmetatable({
extend = function(...)
expectationContext:extend(...)
end,
}, {
__call = function(_self, ...)
return expectationContext:startExpectationChain(...)
end,
})
end
function TestRunner.runPlan(plan)
local session = TestSession.new(plan)
local lifecycleHooks = LifecycleHooks.new()
local exclusiveNodes = plan:findNodes(function(node)
return node.modifier == TestEnum.NodeModifier.Focus
end)
session.hasFocusNodes = #exclusiveNodes > 0
TestRunner.runPlanNode(session, plan, lifecycleHooks)
return session:finalize()
end
function TestRunner.runPlanNode(session, planNode, lifecycleHooks)
local function runCallback(callback, messagePrefix)
local success = true
local errorMessage
_G[RUNNING_GLOBAL] = true
messagePrefix = messagePrefix or ""
local testEnvironment = getfenv(callback)
for key, value in pairs(TestRunner.environment) do
testEnvironment[key] = value
end
testEnvironment.fail = function(message)
if message == nil then
message = "fail() was called."
end
success = false
errorMessage = messagePrefix .. debug.traceback(tostring(message), 2)
end
testEnvironment.expect = wrapExpectContextWithPublicApi(session:getExpectationContext())
local context = session:getContext()
local nodeSuccess, nodeResult = xpcall(
function()
callback(context)
end,
function(message)
return messagePrefix .. debug.traceback(tostring(message), 2)
end
)
if not nodeSuccess then
success = false
errorMessage = nodeResult
end
_G[RUNNING_GLOBAL] = nil
return success, errorMessage
end
local function runNode(childPlanNode)
for _, hook in ipairs(lifecycleHooks:getBeforeEachHooks()) do
local success, errorMessage = runCallback(hook, "beforeEach hook: ")
if not success then
return false, errorMessage
end
end
local testSuccess, testErrorMessage = runCallback(childPlanNode.callback)
for _, hook in ipairs(lifecycleHooks:getAfterEachHooks()) do
local success, errorMessage = runCallback(hook, "afterEach hook: ")
if not success then
if not testSuccess then
return false, testErrorMessage .. "\nWhile cleaning up the failed test another error was found:\n" .. errorMessage
end
return false, errorMessage
end
end
if not testSuccess then
return false, testErrorMessage
end
return true, nil
end
lifecycleHooks:pushHooksFrom(planNode)
local halt = false
for _, hook in ipairs(lifecycleHooks:getBeforeAllHooks()) do
local success, errorMessage = runCallback(hook, "beforeAll hook: ")
if not success then
session:addDummyError("beforeAll", errorMessage)
halt = true
end
end
if not halt then
for _, childPlanNode in ipairs(planNode.children) do
if childPlanNode.type == TestEnum.NodeType.It then
session:pushNode(childPlanNode)
if session:shouldSkip() then
session:setSkipped()
else
local success, errorMessage = runNode(childPlanNode)
if success then
session:setSuccess()
else
session:setError(errorMessage)
end
end
session:popNode()
elseif childPlanNode.type == TestEnum.NodeType.Describe then
session:pushNode(childPlanNode)
TestRunner.runPlanNode(session, childPlanNode, lifecycleHooks)
if childPlanNode.loadError then
local message = "Error during planning: " .. childPlanNode.loadError
session:setError(message)
else
session:setStatusFromChildren()
end
session:popNode()
end
end
end
for _, hook in ipairs(lifecycleHooks:getAfterAllHooks()) do
local success, errorMessage = runCallback(hook, "afterAll hook: ")
if not success then
session:addDummyError("afterAll", errorMessage)
end
end
lifecycleHooks:popHooks()
end
return TestRunner
end)() end,[54]=function()local wax,script,require=ImportGlobals(54)local ImportGlobals return (function(...)
local TestEnum = require(script.Parent.TestEnum)
local TestResults = require(script.Parent.TestResults)
local Context = require(script.Parent.Context)
local ExpectationContext = require(script.Parent.ExpectationContext)
local TestSession = {}
TestSession.__index = TestSession
function TestSession.new(plan)
local self = {
results = TestResults.new(plan),
nodeStack = {},
contextStack = {},
expectationContextStack = {},
hasFocusNodes = false
}
setmetatable(self, TestSession)
return self
end
function TestSession:calculateTotals()
local results = self.results
results.successCount = 0
results.failureCount = 0
results.skippedCount = 0
results:visitAllNodes(function(node)
local status = node.status
local nodeType = node.planNode.type
if nodeType == TestEnum.NodeType.It then
if status == TestEnum.TestStatus.Success then
results.successCount = results.successCount + 1
elseif status == TestEnum.TestStatus.Failure then
results.failureCount = results.failureCount + 1
elseif status == TestEnum.TestStatus.Skipped then
results.skippedCount = results.skippedCount + 1
end
end
end)
end
function TestSession:gatherErrors()
local results = self.results
results.errors = {}
results:visitAllNodes(function(node)
if #node.errors > 0 then
for _, message in ipairs(node.errors) do
table.insert(results.errors, message)
end
end
end)
end
function TestSession:finalize()
if #self.nodeStack ~= 0 then
error("Cannot finalize TestResults with nodes still on the stack!", 2)
end
self:calculateTotals()
self:gatherErrors()
return self.results
end
function TestSession:pushNode(planNode)
local node = TestResults.createNode(planNode)
local lastNode = self.nodeStack[#self.nodeStack] or self.results
table.insert(lastNode.children, node)
table.insert(self.nodeStack, node)
local lastContext = self.contextStack[#self.contextStack]
local context = Context.new(lastContext)
table.insert(self.contextStack, context)
local lastExpectationContext = self.expectationContextStack[#self.expectationContextStack]
local expectationContext = ExpectationContext.new(lastExpectationContext)
table.insert(self.expectationContextStack, expectationContext)
end
function TestSession:popNode()
assert(#self.nodeStack > 0, "Tried to pop from an empty node stack!")
table.remove(self.nodeStack, #self.nodeStack)
table.remove(self.contextStack, #self.contextStack)
table.remove(self.expectationContextStack, #self.expectationContextStack)
end
function TestSession:getContext()
assert(#self.contextStack > 0, "Tried to get context from an empty stack!")
return self.contextStack[#self.contextStack]
end
function TestSession:getExpectationContext()
assert(#self.expectationContextStack > 0, "Tried to get expectationContext from an empty stack!")
return self.expectationContextStack[#self.expectationContextStack]
end
function TestSession:shouldSkip()
if self.hasFocusNodes then
for i = #self.nodeStack, 1, -1 do
local node = self.nodeStack[i]
if node.planNode.modifier == TestEnum.NodeModifier.Skip then
return true
end
if node.planNode.modifier == TestEnum.NodeModifier.Focus then
return false
end
end
return true
else
for i = #self.nodeStack, 1, -1 do
local node = self.nodeStack[i]
if node.planNode.modifier == TestEnum.NodeModifier.Skip then
return true
end
end
end
return false
end
function TestSession:setSuccess()
assert(#self.nodeStack > 0, "Attempting to set success status on empty stack")
self.nodeStack[#self.nodeStack].status = TestEnum.TestStatus.Success
end
function TestSession:setSkipped()
assert(#self.nodeStack > 0, "Attempting to set skipped status on empty stack")
self.nodeStack[#self.nodeStack].status = TestEnum.TestStatus.Skipped
end
function TestSession:setError(message)
assert(#self.nodeStack > 0, "Attempting to set error status on empty stack")
local last = self.nodeStack[#self.nodeStack]
last.status = TestEnum.TestStatus.Failure
table.insert(last.errors, message)
end
function TestSession:addDummyError(phrase, message)
self:pushNode({type = TestEnum.NodeType.It, phrase = phrase})
self:setError(message)
self:popNode()
self.nodeStack[#self.nodeStack].status = TestEnum.TestStatus.Failure
end
function TestSession:setStatusFromChildren()
assert(#self.nodeStack > 0, "Attempting to set status from children on empty stack")
local last = self.nodeStack[#self.nodeStack]
local status = TestEnum.TestStatus.Success
local skipped = true
for _, child in ipairs(last.children) do
if child.status ~= TestEnum.TestStatus.Skipped then
skipped = false
if child.status == TestEnum.TestStatus.Failure then
status = TestEnum.TestStatus.Failure
end
end
end
if skipped then
status = TestEnum.TestStatus.Skipped
end
last.status = status
end
return TestSession
end)() end}
local ObjectTree = {{1,2,{"roblox-ts-model"},{{3,1,{"modules"}},{4,1,{"include"},{{5,2,{"Promise"}},{6,2,{"RuntimeLib"}},{7,1,{"node_modules"},{{8,1,{"@rbxts"},{{34,2,{"services"}},{22,1,{"reflection"},{{23,2,{"out"}}}},{35,1,{"t"},{{36,1,{"lib"},{{37,2,{"ts"}}}}}},{14,1,{"logsnag"},{{15,2,{"out"},{{16,2,{"api"}},{17,2,{"channel"}},{18,2,{"insight"}},{20,2,{"types"}},{19,2,{"logsnag"}}}}}},{24,1,{"reflection-runtime"},{{25,2,{"out"},{{29,2,{"macro"}},{32,2,{"store"}},{30,2,{"metadata"}},{26,2,{"declarations"}},{31,2,{"public-api"}},{33,2,{"validator-helper"}},{27,2,{"enums"}},{28,2,{"internal-usage"}}}}}},{55,1,{"types"},{{56,1,{"include"},{{57,1,{"generated"}}}}}},{38,1,{"testez"},{{39,2,{"src"},{{49,2,{"TestEnum"}},{44,1,{"Reporters"},{{45,2,{"TeamCityReporter"}},{46,2,{"TextReporter"}},{47,2,{"TextReporterQuiet"}}}},{40,2,{"Context"}},{41,2,{"Expectation"}},{50,2,{"TestPlan"}},{43,2,{"LifecycleHooks"}},{51,2,{"TestPlanner"}},{54,2,{"TestSession"}},{53,2,{"TestRunner"}},{52,2,{"TestResults"}},{48,2,{"TestBootstrap"}},{42,2,{"ExpectationContext"}}}}}},{11,1,{"janitor"},{{12,2,{"src"},{{13,2,{"Promise"}}}}}},{9,1,{"compiler-types"},{{10,1,{"types"}}}},{21,2,{"object-utils"}}}}}}}},{2,1,{"data"}}}}}
local LineOffsets = nil
local WaxVersion = "0.4.1"
local EnvName = "WaxRuntime"
local string, task, setmetatable, error, next, table, unpack, coroutine, script, type, require, pcall, tostring, tonumber, _VERSION =
string, task, setmetatable, error, next, table, unpack, coroutine, script, type, require, pcall, tostring, tonumber, _VERSION
-- Table operations
local table_insert = function(t, pos, value)
if value then
-- Insert at position
for i = #t, pos, -1 do
t[i + 1] = t[i]
end
t[pos] = value
else
-- Append to end
t[#t + 1] = pos
end
return t
end
local table_remove = function(t, pos)
pos = pos or #t
local value = t[pos]
if pos < #t then
for i = pos, #t - 1 do
t[i] = t[i + 1]
end
end
t[#t] = nil
return value
end
local table_freeze = (function()
return function(t)
if type(t) ~= "table" then return t end
local mt = {
__newindex = function() error("Cannot modify frozen table", 2) end,
__metatable = false
}
for k, v in pairs(t) do
if type(v) == "table" then
t[k] = table_freeze(v)
end
end
return setmetatable(t, mt)
end
end)()
local coroutine_wrap = coroutine.wrap
local string_sub = string.sub
local string_match = string.match
local string_gmatch = string.gmatch
if _VERSION and string_sub(_VERSION, 1, 4) == "Lune" then
local RequireSuccess, LuneTaskLib = pcall(require, "@lune/task")
if RequireSuccess and LuneTaskLib then
task = LuneTaskLib
end
end
local task_defer = task and task.defer
local Defer = task_defer or function(f, ...)
coroutine_wrap(f)(...)
end
local ClassNameIdBindings = {
[1] = "Folder",
[2] = "ModuleScript",
[3] = "Script",
[4] = "LocalScript",
[5] = "StringValue",
}
local RefBindings = {}
local ScriptClosures = {}
local ScriptClosureRefIds = {}
local StoredModuleValues = {}
local ScriptsToRun = {}
local SharedEnvironment = {}
local RefChildren = {}
local InstanceMethods = {
GetFullName = { {}, function(self)
local Path = self.Name
local ObjectPointer = self.Parent
while ObjectPointer do
Path = ObjectPointer.Name .. "." .. Path
ObjectPointer = ObjectPointer.Parent
end
return Path
end},
GetChildren = { {}, function(self)
local ReturnArray = {}
for Child in next, RefChildren[self] do
table_insert(ReturnArray, Child)
end
return ReturnArray
end},
GetDescendants = { {}, function(self)
local ReturnArray = {}
for Child in next, RefChildren[self] do
table_insert(ReturnArray, Child)
for _, Descendant in next, Child:GetDescendants() do
table_insert(ReturnArray, Descendant)
end
end
return ReturnArray
end},
FindFirstChild = { {"string", "boolean?"}, function(self, name, recursive)
local Children = RefChildren[self]
for Child in next, Children do
if Child.Name == name then
return Child
end
end
if recursive then
for Child in next, Children do
return Child:FindFirstChild(name, true)
end
end
end},
FindFirstAncestor = { {"string"}, function(self, name)
local RefPointer = self.Parent
while RefPointer do
if RefPointer.Name == name then
return RefPointer
end
RefPointer = RefPointer.Parent
end
end},
WaitForChild = { {"string", "number?"}, function(self, name)
return self:FindFirstChild(name)
end},
}
local InstanceMethodProxies = {}
for MethodName, MethodObject in next, InstanceMethods do
local Types = MethodObject[1]
local Method = MethodObject[2]
local EvaluatedTypeInfo = {}
for ArgIndex, TypeInfo in next, Types do
local ExpectedType, IsOptional = string_match(TypeInfo, "^([^%?]+)(%??)")
EvaluatedTypeInfo[ArgIndex] = {ExpectedType, IsOptional}
end
InstanceMethodProxies[MethodName] = function(self, ...)
if not RefChildren[self] then
error("Expected ':' not '.' calling member function " .. MethodName, 2)
end
local Args = {...}
for ArgIndex, TypeInfo in next, EvaluatedTypeInfo do
local RealArg = Args[ArgIndex]
local RealArgType = type(RealArg)
local ExpectedType, IsOptional = TypeInfo[1], TypeInfo[2]
if RealArg == nil and not IsOptional then
error("Argument " .. RealArg .. " missing or nil", 3)
end
if ExpectedType ~= "any" and RealArgType ~= ExpectedType and not (RealArgType == "nil" and IsOptional) then
error("Argument " .. ArgIndex .. " expects type \"" .. ExpectedType .. "\", got \"" .. RealArgType .. "\"", 2)
end
end
return Method(self, ...)
end
end
local function CreateRef(className, name, parent)
local StringValue_Value
local Children = setmetatable({}, {__mode = "k"})
local function InvalidMember(member)
error(member .. " is not a valid (virtual) member of " .. className .. " \"" .. name .. "\"", 3)
end
local function ReadOnlyProperty(property)
error("Unable to assign (virtual) property " .. property .. ". Property is read only", 3)
end
local Ref = {}
local RefMetatable = {}
RefMetatable.__metatable = false
RefMetatable.__index = function(_, index)
if index == "ClassName" then
return className
elseif index == "Name" then
return name
elseif index == "Parent" then
return parent
elseif className == "StringValue" and index == "Value" then
return StringValue_Value
else
local InstanceMethod = InstanceMethodProxies[index]
if InstanceMethod then
return InstanceMethod
end
end
for Child in next, Children do
if Child.Name == index then
return Child
end
end
InvalidMember(index)
end
RefMetatable.__newindex = function(_, index, value)
if index == "ClassName" then
ReadOnlyProperty(index)
elseif index == "Name" then
name = value
elseif index == "Parent" then
if value == Ref then
return
end
if parent ~= nil then
RefChildren[parent][Ref] = nil
end
parent = value
if value ~= nil then
RefChildren[value][Ref] = true
end
elseif className == "StringValue" and index == "Value" then
StringValue_Value = value
else
InvalidMember(index)
end
end
RefMetatable.__tostring = function()
return name
end
setmetatable(Ref, RefMetatable)
RefChildren[Ref] = Children
if parent ~= nil then
RefChildren[parent][Ref] = true
end
return Ref
end
local function CreateRefFromObject(object, parent)
local RefId = object[1]
local ClassNameId = object[2]
local Properties = object[3]
local Children = object[4]
local ClassName = ClassNameIdBindings[ClassNameId]
local Name = Properties and table_remove(Properties, 1) or ClassName
local Ref = CreateRef(ClassName, Name, parent)
RefBindings[RefId] = Ref
if Properties then
for PropertyName, PropertyValue in next, Properties do
Ref[PropertyName] = PropertyValue
end
end
if Children then
for _, ChildObject in next, Children do
CreateRefFromObject(ChildObject, Ref)
end
end
return Ref
end
local RealObjectRoot = CreateRef("Folder", "[" .. EnvName .. "]")
for _, Object in next, ObjectTree do
CreateRefFromObject(Object, RealObjectRoot)
end
for RefId, Closure in next, ClosureBindings do
local Ref = RefBindings[RefId]
ScriptClosures[Ref] = Closure
ScriptClosureRefIds[Ref] = RefId
local ClassName = Ref.ClassName
if ClassName == "LocalScript" or ClassName == "Script" then
table_insert(ScriptsToRun, Ref)
end
end
local function LoadScript(scriptRef)
local ScriptClassName = scriptRef.ClassName
local StoredModuleValue = StoredModuleValues[scriptRef]
if StoredModuleValue and ScriptClassName == "ModuleScript" then
return unpack(StoredModuleValue)
end
local Closure = ScriptClosures[scriptRef]
local function FormatError(originalErrorMessage)
originalErrorMessage = tostring(originalErrorMessage)
local VirtualFullName = scriptRef:GetFullName()
local OriginalErrorLine, BaseErrorMessage = string_match(originalErrorMessage, "[^:]+:(%d+): (.+)")
if not OriginalErrorLine or not LineOffsets then
return VirtualFullName .. ":*: " .. (BaseErrorMessage or originalErrorMessage)
end
OriginalErrorLine = tonumber(OriginalErrorLine)
local RefId = ScriptClosureRefIds[scriptRef]
local LineOffset = LineOffsets[RefId]
local RealErrorLine = OriginalErrorLine - LineOffset + 1
if RealErrorLine < 0 then
RealErrorLine = "?"
end
return VirtualFullName .. ":" .. RealErrorLine .. ": " .. BaseErrorMessage
end
if ScriptClassName == "LocalScript" or ScriptClassName == "Script" then
local RunSuccess, ErrorMessage = pcall(Closure)
if not RunSuccess then
error(FormatError(ErrorMessage), 0)
end
else
local PCallReturn = {pcall(Closure)}
local RunSuccess = table_remove(PCallReturn, 1)
if not RunSuccess then
local ErrorMessage = table_remove(PCallReturn, 1)
error(FormatError(ErrorMessage), 0)
end
StoredModuleValues[scriptRef] = PCallReturn
return unpack(PCallReturn)
end
end
function ImportGlobals(refId)
local ScriptRef = RefBindings[refId]
local function RealCall(f, ...)
local PCallReturn = {pcall(f, ...)}
local CallSuccess = table_remove(PCallReturn, 1)
if not CallSuccess then
error(PCallReturn[1], 3)
end
return unpack(PCallReturn)
end
local WaxShared = table_freeze(setmetatable({}, {
__index = SharedEnvironment,
__newindex = function(_, index, value)
SharedEnvironment[index] = value
end,
__len = function()
return #SharedEnvironment
end,
__iter = function()
return next, SharedEnvironment
end,
}))
local Global_wax = table_freeze({
version = WaxVersion,
envname = EnvName,
shared = WaxShared,
script = script,
require = require,
})
local Global_script = ScriptRef
local function Global_require(module, ...)
local ModuleArgType = type(module)
local ErrorNonModuleScript = "Attempted to call require with a non-ModuleScript"
local ErrorSelfRequire = "Attempted to call require with self"
if ModuleArgType == "table" and RefChildren[module] then
if module.ClassName ~= "ModuleScript" then
error(ErrorNonModuleScript, 2)
elseif module == ScriptRef then
error(ErrorSelfRequire, 2)
end
return LoadScript(module)
elseif ModuleArgType == "string" and string_sub(module, 1, 1) ~= "@" then
if #module == 0 then
error("Attempted to call require with empty string", 2)
end
local CurrentRefPointer = ScriptRef
if string_sub(module, 1, 1) == "/" then
CurrentRefPointer = RealObjectRoot
elseif string_sub(module, 1, 2) == "./" then
module = string_sub(module, 3)
end
local PreviousPathMatch
for PathMatch in string_gmatch(module, "([^/]*)/?") do
local RealIndex = PathMatch
if PathMatch == ".." then
RealIndex = "Parent"
end
if RealIndex ~= "" then
local ResultRef = CurrentRefPointer:FindFirstChild(RealIndex)
if not ResultRef then
local CurrentRefParent = CurrentRefPointer.Parent
if CurrentRefParent then
ResultRef = CurrentRefParent:FindFirstChild(RealIndex)
end
end
if ResultRef then
CurrentRefPointer = ResultRef
elseif PathMatch ~= PreviousPathMatch and PathMatch ~= "init" and PathMatch ~= "init.server" and PathMatch ~= "init.client" then
error("Virtual script path \"" .. module .. "\" not found", 2)
end
end
PreviousPathMatch = PathMatch
end
if CurrentRefPointer.ClassName ~= "ModuleScript" then
error(ErrorNonModuleScript, 2)
elseif CurrentRefPointer == ScriptRef then
error(ErrorSelfRequire, 2)
end
return LoadScript(CurrentRefPointer)
end
return RealCall(require, module, ...)
end
return Global_wax, Global_script, Global_require
end
for _, ScriptRef in next, ScriptsToRun do
Defer(LoadScript, ScriptRef)
end
return LoadScript(RealObjectRoot:GetChildren()[1])```