rbxts-trpc 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,15 @@
1
+ ISC License
2
+
3
+ Copyright (c) 2026 Mergemat
4
+
5
+ Permission to use, copy, modify, and/or distribute this software for any
6
+ purpose with or without fee is hereby granted, provided that the above
7
+ copyright notice and this permission notice appear in all copies.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
10
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
12
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
14
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15
+ PERFORMANCE OF THIS SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,56 @@
1
+ # rbxts-trpc
2
+
3
+ Type-safe tRPC-style procedures and events for Roblox TS, built on top of `@rbxts/remo`.
4
+
5
+ ## Docs
6
+
7
+ - Live docs: https://rbxts-trpc.vercel.app
8
+ - Source docs app: `docs/`
9
+
10
+ Everything else (guides, API reference, React usage, events/procedures, and LLM endpoints) lives in the docs site.
11
+
12
+ ## Install
13
+
14
+ ```sh
15
+ bun add rbxts-trpc @rbxts/remo @rbxts/t
16
+ ```
17
+
18
+ If you use React helpers, also install `@rbxts/react`.
19
+
20
+ ## Quick Example
21
+
22
+ ```ts
23
+ import { t as v } from "@rbxts/t";
24
+ import { createClient, createServer, initTRPC } from "rbxts-trpc";
25
+
26
+ const trpc = initTRPC()
27
+ .context<{ player?: Player }>()
28
+ .create({
29
+ createContext: ({ player }) => ({ player }),
30
+ });
31
+
32
+ const appRouter = trpc.router({
33
+ todos: trpc.router({
34
+ list: trpc.procedure
35
+ .intent("query")
36
+ .output<string[]>(v.array(v.string))
37
+ .resolve(() => ["Milk", "Eggs"]),
38
+ add: trpc.procedure.input<string>(v.string).resolve(({ input }) => input.size() > 0),
39
+ changed: trpc.event.client.input<string[]>(v.array(v.string)).create(),
40
+ }),
41
+ });
42
+
43
+ const server = createServer({ t: trpc, router: appRouter });
44
+ server.events.todos.changed.emitAll(["Milk", "Eggs", "Bread"]);
45
+
46
+ const client = createClient({ t: trpc, router: appRouter });
47
+ client.todos.list.query(undefined).then((todos) => print(todos.size()));
48
+ ```
49
+
50
+ ## Develop
51
+
52
+ ```sh
53
+ bun run build
54
+ bun run lint
55
+ bun run docs:dev
56
+ ```
package/index.d.ts ADDED
@@ -0,0 +1 @@
1
+ export * from "./out/index";
@@ -0,0 +1,11 @@
1
+ import type { TRPCFactory } from "../core/initTRPC";
2
+ import type { ClientEvent, ClientEventProxy, Procedure, ProcedureCallProxy, Router, RouterShape, ServerEvent, ServerEventProxy } from "../core/types";
3
+ type ClientShapeFromRouter<TRouter extends Router<any, RouterShape<any>>> = ClientShapeFromNodes<TRouter["_def"]["shape"]>;
4
+ type ClientShapeFromNodes<TShape> = {
5
+ [K in keyof TShape]: TShape[K] extends Router<any, any> ? ClientShapeFromNodes<TShape[K]["_def"]["shape"]> : TShape[K] extends Procedure<any, infer TInput, infer TOutput, infer TIntent> ? ProcedureCallProxy<TInput, TOutput, TIntent> : TShape[K] extends ServerEvent<any, infer TInput> ? ServerEventProxy<TInput> : TShape[K] extends ClientEvent<any, infer TInput> ? ClientEventProxy<TInput> : never;
6
+ };
7
+ export declare function createClient<TContext, TRouter extends Router<TContext, RouterShape<TContext>>>(options: {
8
+ t: TRPCFactory<TContext>;
9
+ router: TRouter;
10
+ }): ClientShapeFromRouter<TRouter>;
11
+ export {};
@@ -0,0 +1,135 @@
1
+ -- Compiled with roblox-ts v3.0.0
2
+ local TS = _G[script]
3
+ local createRemotes = TS.import(script, TS.getModule(script, "@rbxts", "remo").src).createRemotes
4
+ local _errors = TS.import(script, script.Parent.Parent, "core", "errors")
5
+ local TRPCClientError = _errors.TRPCClientError
6
+ local toErrorShape = _errors.toErrorShape
7
+ local _execute = TS.import(script, script.Parent.Parent, "runtime", "execute")
8
+ local formatError = _execute.formatError
9
+ local runClientEvent = _execute.runClientEvent
10
+ local _schema = TS.import(script, script.Parent.Parent, "runtime", "schema")
11
+ local buildRemoSchema = _schema.buildRemoSchema
12
+ local joinPath = _schema.joinPath
13
+ local function isRouterNode(node)
14
+ return node._def.kind == "router"
15
+ end
16
+ local function isProcedureNode(node)
17
+ return node._def.kind == "procedure"
18
+ end
19
+ local function isServerEventNode(node)
20
+ return node._def.kind == "event" and node._def.direction == "server"
21
+ end
22
+ local function isClientEventNode(node)
23
+ return node._def.kind == "event" and node._def.direction == "client"
24
+ end
25
+ local function createClient(options)
26
+ local schema = buildRemoSchema(options.router)
27
+ local remotes = createRemotes(schema)
28
+ local listenersByPath = {}
29
+ local addListener = function(path, listener)
30
+ local listeners = listenersByPath[path] or {}
31
+ local _listener = listener
32
+ table.insert(listeners, _listener)
33
+ listenersByPath[path] = listeners
34
+ return function()
35
+ local current = listenersByPath[path]
36
+ if not current then
37
+ return nil
38
+ end
39
+ local _listener_1 = listener
40
+ local index = (table.find(current, _listener_1) or 0) - 1
41
+ if index >= 0 then
42
+ table.remove(current, index + 1)
43
+ end
44
+ end
45
+ end
46
+ local walk
47
+ walk = function(shape, remoteShape, target, parent)
48
+ for key, rawNode in pairs(shape) do
49
+ local keyName = key
50
+ local node = rawNode
51
+ local path = joinPath(parent, keyName)
52
+ local remoteNode = remoteShape[keyName]
53
+ if isRouterNode(node) then
54
+ local nested = {}
55
+ target[keyName] = nested
56
+ walk(node._def.shape, remoteNode, nested, path)
57
+ continue
58
+ end
59
+ if isProcedureNode(node) then
60
+ local execute = TS.async(function(input)
61
+ local requestRemote = remoteNode
62
+ local result
63
+ TS.try(function()
64
+ result = TS.await(requestRemote.request(requestRemote, input))
65
+ end, function(caught)
66
+ local shape = formatError(options.t._config, caught)
67
+ error(TRPCClientError.new(shape))
68
+ end)
69
+ if not result.ok then
70
+ error(TRPCClientError.new(result.error))
71
+ end
72
+ return result.data
73
+ end)
74
+ local _object = {
75
+ __kind = "procedure",
76
+ __path = path,
77
+ __intent = node._def.intent,
78
+ }
79
+ for _k, _v in (if node._def.intent == "query" then {
80
+ query = execute,
81
+ } else {
82
+ mutate = execute,
83
+ }) do
84
+ _object[_k] = _v
85
+ end
86
+ target[keyName] = _object
87
+ continue
88
+ end
89
+ if isServerEventNode(node) then
90
+ target[keyName] = {
91
+ __kind = "serverEvent",
92
+ __path = path,
93
+ emit = function(input)
94
+ local fireRemote = remoteNode
95
+ fireRemote.fire(fireRemote, input)
96
+ end,
97
+ }
98
+ continue
99
+ end
100
+ if isClientEventNode(node) then
101
+ local connectRemote = remoteNode
102
+ connectRemote.connect(connectRemote, function(input)
103
+ task.spawn(TS.async(function()
104
+ local listeners = listenersByPath[path] or {}
105
+ TS.try(function()
106
+ TS.await(runClientEvent({
107
+ config = options.t._config,
108
+ path = path,
109
+ input = input,
110
+ inputValidator = node._def.inputValidator,
111
+ middlewares = node._def.middlewares,
112
+ listeners = listeners,
113
+ }))
114
+ end, function(caught)
115
+ warn(`[rbxts-trpc] client event error on '{path}':`, toErrorShape(caught))
116
+ end)
117
+ end))
118
+ end)
119
+ target[keyName] = {
120
+ __kind = "clientEvent",
121
+ __path = path,
122
+ on = function(listener)
123
+ return addListener(path, listener)
124
+ end,
125
+ }
126
+ end
127
+ end
128
+ end
129
+ local client = {}
130
+ walk(options.router._def.shape, remotes, client)
131
+ return client
132
+ end
133
+ return {
134
+ createClient = createClient,
135
+ }
@@ -0,0 +1,15 @@
1
+ import type { ErrorShape, TRPCErrorCode } from "./types";
2
+ export declare class TRPCError {
3
+ readonly name = "TRPCError";
4
+ readonly code: TRPCErrorCode;
5
+ readonly message: string;
6
+ readonly data?: unknown;
7
+ constructor(code: TRPCErrorCode, message: string, data?: unknown);
8
+ }
9
+ export declare class TRPCClientError {
10
+ readonly name = "TRPCClientError";
11
+ readonly message: string;
12
+ readonly shape: ErrorShape;
13
+ constructor(shape: ErrorShape);
14
+ }
15
+ export declare function toErrorShape(caught: unknown): ErrorShape;
@@ -0,0 +1,69 @@
1
+ -- Compiled with roblox-ts v3.0.0
2
+ local TRPCError
3
+ do
4
+ TRPCError = setmetatable({}, {
5
+ __tostring = function()
6
+ return "TRPCError"
7
+ end,
8
+ })
9
+ TRPCError.__index = TRPCError
10
+ function TRPCError.new(...)
11
+ local self = setmetatable({}, TRPCError)
12
+ return self:constructor(...) or self
13
+ end
14
+ function TRPCError:constructor(code, message, data)
15
+ self.name = "TRPCError"
16
+ self.code = code
17
+ self.message = message
18
+ self.data = data
19
+ end
20
+ end
21
+ local TRPCClientError
22
+ do
23
+ TRPCClientError = setmetatable({}, {
24
+ __tostring = function()
25
+ return "TRPCClientError"
26
+ end,
27
+ })
28
+ TRPCClientError.__index = TRPCClientError
29
+ function TRPCClientError.new(...)
30
+ local self = setmetatable({}, TRPCClientError)
31
+ return self:constructor(...) or self
32
+ end
33
+ function TRPCClientError:constructor(shape)
34
+ self.name = "TRPCClientError"
35
+ self.shape = shape
36
+ self.message = shape.message
37
+ end
38
+ end
39
+ local function toErrorShape(caught)
40
+ local _caught = caught
41
+ if type(_caught) == "table" then
42
+ local maybeError = caught
43
+ local _code = maybeError.code
44
+ local _condition = type(_code) == "string"
45
+ if _condition then
46
+ local _message = maybeError.message
47
+ _condition = type(_message) == "string"
48
+ end
49
+ if _condition then
50
+ return {
51
+ code = maybeError.code,
52
+ message = maybeError.message,
53
+ data = maybeError.data,
54
+ }
55
+ end
56
+ end
57
+ local _object = {
58
+ code = "INTERNAL_SERVER_ERROR",
59
+ }
60
+ local _left = "message"
61
+ local _caught_1 = caught
62
+ _object[_left] = if type(_caught_1) == "string" then caught else "Internal server error"
63
+ return _object
64
+ end
65
+ return {
66
+ toErrorShape = toErrorShape,
67
+ TRPCError = TRPCError,
68
+ TRPCClientError = TRPCClientError,
69
+ }
@@ -0,0 +1,23 @@
1
+ import type { ClientEvent, EventHandler, EventMiddleware, ServerEvent, Validator } from "./types";
2
+ export declare class ServerEventBuilder<TContext, TInput> {
3
+ private readonly currentInputValidator?;
4
+ private readonly currentMiddlewares;
5
+ constructor(options?: {
6
+ inputValidator?: Validator<TInput>;
7
+ middlewares?: ReadonlyArray<EventMiddleware<TContext, TInput>>;
8
+ });
9
+ input<TNextInput>(validator: Validator<TNextInput>): ServerEventBuilder<TContext, TNextInput>;
10
+ use(middleware: EventMiddleware<TContext, TInput>): ServerEventBuilder<TContext, TInput>;
11
+ handle(handler: EventHandler<TContext, TInput>): ServerEvent<TContext, TInput>;
12
+ }
13
+ export declare class ClientEventBuilder<TContext, TInput> {
14
+ private readonly currentInputValidator?;
15
+ private readonly currentMiddlewares;
16
+ constructor(options?: {
17
+ inputValidator?: Validator<TInput>;
18
+ middlewares?: ReadonlyArray<EventMiddleware<TContext, TInput>>;
19
+ });
20
+ input<TNextInput>(validator: Validator<TNextInput>): ClientEventBuilder<TContext, TNextInput>;
21
+ use(middleware: EventMiddleware<TContext, TInput>): ClientEventBuilder<TContext, TInput>;
22
+ create(): ClientEvent<TContext, TInput>;
23
+ }
@@ -0,0 +1,154 @@
1
+ -- Compiled with roblox-ts v3.0.0
2
+ local ServerEventImpl
3
+ do
4
+ ServerEventImpl = setmetatable({}, {
5
+ __tostring = function()
6
+ return "ServerEventImpl"
7
+ end,
8
+ })
9
+ ServerEventImpl.__index = ServerEventImpl
10
+ function ServerEventImpl.new(...)
11
+ local self = setmetatable({}, ServerEventImpl)
12
+ return self:constructor(...) or self
13
+ end
14
+ function ServerEventImpl:constructor(def)
15
+ self._def = def
16
+ end
17
+ end
18
+ local ClientEventImpl
19
+ do
20
+ ClientEventImpl = setmetatable({}, {
21
+ __tostring = function()
22
+ return "ClientEventImpl"
23
+ end,
24
+ })
25
+ ClientEventImpl.__index = ClientEventImpl
26
+ function ClientEventImpl.new(...)
27
+ local self = setmetatable({}, ClientEventImpl)
28
+ return self:constructor(...) or self
29
+ end
30
+ function ClientEventImpl:constructor(def)
31
+ self._def = def
32
+ end
33
+ end
34
+ local ServerEventBuilder
35
+ do
36
+ ServerEventBuilder = setmetatable({}, {
37
+ __tostring = function()
38
+ return "ServerEventBuilder"
39
+ end,
40
+ })
41
+ ServerEventBuilder.__index = ServerEventBuilder
42
+ function ServerEventBuilder.new(...)
43
+ local self = setmetatable({}, ServerEventBuilder)
44
+ return self:constructor(...) or self
45
+ end
46
+ function ServerEventBuilder:constructor(options)
47
+ local _result = options
48
+ if _result ~= nil then
49
+ _result = _result.inputValidator
50
+ end
51
+ self.currentInputValidator = _result
52
+ local _result_1 = options
53
+ if _result_1 ~= nil then
54
+ _result_1 = _result_1.middlewares
55
+ end
56
+ local _condition = _result_1
57
+ if _condition == nil then
58
+ _condition = {}
59
+ end
60
+ self.currentMiddlewares = _condition
61
+ end
62
+ function ServerEventBuilder:input(validator)
63
+ return ServerEventBuilder.new({
64
+ inputValidator = validator,
65
+ middlewares = self.currentMiddlewares,
66
+ })
67
+ end
68
+ function ServerEventBuilder:use(middleware)
69
+ local _object = {
70
+ inputValidator = self.currentInputValidator,
71
+ }
72
+ local _left = "middlewares"
73
+ local _array = {}
74
+ local _length = #_array
75
+ local _array_1 = self.currentMiddlewares
76
+ local _Length = #_array_1
77
+ table.move(_array_1, 1, _Length, _length + 1, _array)
78
+ _length += _Length
79
+ _array[_length + 1] = middleware
80
+ _object[_left] = _array
81
+ return ServerEventBuilder.new(_object)
82
+ end
83
+ function ServerEventBuilder:handle(handler)
84
+ return ServerEventImpl.new({
85
+ kind = "event",
86
+ direction = "server",
87
+ inputValidator = self.currentInputValidator,
88
+ middlewares = self.currentMiddlewares,
89
+ handle = handler,
90
+ })
91
+ end
92
+ end
93
+ local ClientEventBuilder
94
+ do
95
+ ClientEventBuilder = setmetatable({}, {
96
+ __tostring = function()
97
+ return "ClientEventBuilder"
98
+ end,
99
+ })
100
+ ClientEventBuilder.__index = ClientEventBuilder
101
+ function ClientEventBuilder.new(...)
102
+ local self = setmetatable({}, ClientEventBuilder)
103
+ return self:constructor(...) or self
104
+ end
105
+ function ClientEventBuilder:constructor(options)
106
+ local _result = options
107
+ if _result ~= nil then
108
+ _result = _result.inputValidator
109
+ end
110
+ self.currentInputValidator = _result
111
+ local _result_1 = options
112
+ if _result_1 ~= nil then
113
+ _result_1 = _result_1.middlewares
114
+ end
115
+ local _condition = _result_1
116
+ if _condition == nil then
117
+ _condition = {}
118
+ end
119
+ self.currentMiddlewares = _condition
120
+ end
121
+ function ClientEventBuilder:input(validator)
122
+ return ClientEventBuilder.new({
123
+ inputValidator = validator,
124
+ middlewares = self.currentMiddlewares,
125
+ })
126
+ end
127
+ function ClientEventBuilder:use(middleware)
128
+ local _object = {
129
+ inputValidator = self.currentInputValidator,
130
+ }
131
+ local _left = "middlewares"
132
+ local _array = {}
133
+ local _length = #_array
134
+ local _array_1 = self.currentMiddlewares
135
+ local _Length = #_array_1
136
+ table.move(_array_1, 1, _Length, _length + 1, _array)
137
+ _length += _Length
138
+ _array[_length + 1] = middleware
139
+ _object[_left] = _array
140
+ return ClientEventBuilder.new(_object)
141
+ end
142
+ function ClientEventBuilder:create()
143
+ return ClientEventImpl.new({
144
+ kind = "event",
145
+ direction = "client",
146
+ inputValidator = self.currentInputValidator,
147
+ middlewares = self.currentMiddlewares,
148
+ })
149
+ end
150
+ end
151
+ return {
152
+ ServerEventBuilder = ServerEventBuilder,
153
+ ClientEventBuilder = ClientEventBuilder,
154
+ }
@@ -0,0 +1,28 @@
1
+ import { ClientEventBuilder, ServerEventBuilder } from "./event";
2
+ import { ProcedureBuilder } from "./procedure";
3
+ import type { InitTRPCConfig, Router, RouterShape } from "./types";
4
+ export interface TRPCFactory<TContext> {
5
+ readonly _config: InitTRPCConfig<TContext>;
6
+ readonly procedure: ProcedureBuilder<TContext, undefined, unknown, "mutation">;
7
+ readonly event: {
8
+ readonly server: ServerEventBuilder<TContext, undefined>;
9
+ readonly client: ClientEventBuilder<TContext, undefined>;
10
+ };
11
+ router<TShape extends RouterShape<TContext>>(shape: TShape): Router<TContext, TShape>;
12
+ }
13
+ declare class FactoryImpl<TContext> implements TRPCFactory<TContext> {
14
+ readonly _config: InitTRPCConfig<TContext>;
15
+ readonly procedure: ProcedureBuilder<TContext, undefined, unknown, "mutation">;
16
+ readonly event: {
17
+ server: ServerEventBuilder<TContext, undefined>;
18
+ client: ClientEventBuilder<TContext, undefined>;
19
+ };
20
+ constructor(config: InitTRPCConfig<TContext>);
21
+ router<TShape extends RouterShape<TContext>>(shape: TShape): Router<TContext, TShape>;
22
+ }
23
+ export declare function initTRPC(): {
24
+ context<TContext>(): {
25
+ create(config?: InitTRPCConfig<TContext>): FactoryImpl<TContext>;
26
+ };
27
+ };
28
+ export {};
@@ -0,0 +1,48 @@
1
+ -- Compiled with roblox-ts v3.0.0
2
+ local TS = _G[script]
3
+ local _event = TS.import(script, script.Parent, "event")
4
+ local ClientEventBuilder = _event.ClientEventBuilder
5
+ local ServerEventBuilder = _event.ServerEventBuilder
6
+ local ProcedureBuilder = TS.import(script, script.Parent, "procedure").ProcedureBuilder
7
+ local createRouter = TS.import(script, script.Parent, "router").createRouter
8
+ local FactoryImpl
9
+ do
10
+ FactoryImpl = setmetatable({}, {
11
+ __tostring = function()
12
+ return "FactoryImpl"
13
+ end,
14
+ })
15
+ FactoryImpl.__index = FactoryImpl
16
+ function FactoryImpl.new(...)
17
+ local self = setmetatable({}, FactoryImpl)
18
+ return self:constructor(...) or self
19
+ end
20
+ function FactoryImpl:constructor(config)
21
+ self.procedure = ProcedureBuilder.new()
22
+ self.event = {
23
+ server = ServerEventBuilder.new(),
24
+ client = ClientEventBuilder.new(),
25
+ }
26
+ self._config = config
27
+ end
28
+ function FactoryImpl:router(shape)
29
+ return createRouter(shape)
30
+ end
31
+ end
32
+ local function initTRPC()
33
+ return {
34
+ context = function(self)
35
+ return {
36
+ create = function(self, config)
37
+ if config == nil then
38
+ config = {}
39
+ end
40
+ return FactoryImpl.new(config)
41
+ end,
42
+ }
43
+ end,
44
+ }
45
+ end
46
+ return {
47
+ initTRPC = initTRPC,
48
+ }
@@ -0,0 +1,18 @@
1
+ import type { Procedure, ProcedureIntent, ProcedureMiddleware, ProcedureResolver, Validator } from "./types";
2
+ export declare class ProcedureBuilder<TContext, TInput, TOutput, TIntent extends ProcedureIntent = "mutation"> {
3
+ private readonly inputValidator?;
4
+ private readonly outputValidator?;
5
+ private readonly middlewares;
6
+ private readonly currentIntent;
7
+ constructor(options?: {
8
+ inputValidator?: Validator<TInput>;
9
+ outputValidator?: Validator<TOutput>;
10
+ middlewares?: ReadonlyArray<ProcedureMiddleware<TContext, TInput, TOutput>>;
11
+ intent?: TIntent;
12
+ });
13
+ input<TNextInput>(validator: Validator<TNextInput>): ProcedureBuilder<TContext, TNextInput, TOutput, TIntent>;
14
+ output<TNextOutput>(validator: Validator<TNextOutput>): ProcedureBuilder<TContext, TInput, TNextOutput, TIntent>;
15
+ use(middleware: ProcedureMiddleware<TContext, TInput, TOutput>): ProcedureBuilder<TContext, TInput, TOutput, TIntent>;
16
+ intent<TNextIntent extends ProcedureIntent>(intent: TNextIntent): ProcedureBuilder<TContext, TInput, TOutput, TNextIntent>;
17
+ resolve<TResolvedOutput extends TOutput>(resolve: ProcedureResolver<TContext, TInput, TResolvedOutput>): Procedure<TContext, TInput, TResolvedOutput, TIntent>;
18
+ }
@@ -0,0 +1,115 @@
1
+ -- Compiled with roblox-ts v3.0.0
2
+ local ProcedureImpl
3
+ do
4
+ ProcedureImpl = setmetatable({}, {
5
+ __tostring = function()
6
+ return "ProcedureImpl"
7
+ end,
8
+ })
9
+ ProcedureImpl.__index = ProcedureImpl
10
+ function ProcedureImpl.new(...)
11
+ local self = setmetatable({}, ProcedureImpl)
12
+ return self:constructor(...) or self
13
+ end
14
+ function ProcedureImpl:constructor(def)
15
+ self._def = def
16
+ end
17
+ end
18
+ local ProcedureBuilder
19
+ do
20
+ ProcedureBuilder = setmetatable({}, {
21
+ __tostring = function()
22
+ return "ProcedureBuilder"
23
+ end,
24
+ })
25
+ ProcedureBuilder.__index = ProcedureBuilder
26
+ function ProcedureBuilder.new(...)
27
+ local self = setmetatable({}, ProcedureBuilder)
28
+ return self:constructor(...) or self
29
+ end
30
+ function ProcedureBuilder:constructor(options)
31
+ local _result = options
32
+ if _result ~= nil then
33
+ _result = _result.inputValidator
34
+ end
35
+ self.inputValidator = _result
36
+ local _result_1 = options
37
+ if _result_1 ~= nil then
38
+ _result_1 = _result_1.outputValidator
39
+ end
40
+ self.outputValidator = _result_1
41
+ local _result_2 = options
42
+ if _result_2 ~= nil then
43
+ _result_2 = _result_2.middlewares
44
+ end
45
+ local _condition = _result_2
46
+ if _condition == nil then
47
+ _condition = {}
48
+ end
49
+ self.middlewares = _condition
50
+ local _result_3 = options
51
+ if _result_3 ~= nil then
52
+ _result_3 = _result_3.intent
53
+ end
54
+ local _condition_1 = _result_3
55
+ if _condition_1 == nil then
56
+ _condition_1 = "mutation"
57
+ end
58
+ self.currentIntent = _condition_1
59
+ end
60
+ function ProcedureBuilder:input(validator)
61
+ return ProcedureBuilder.new({
62
+ inputValidator = validator,
63
+ outputValidator = self.outputValidator,
64
+ middlewares = self.middlewares,
65
+ intent = self.currentIntent,
66
+ })
67
+ end
68
+ function ProcedureBuilder:output(validator)
69
+ return ProcedureBuilder.new({
70
+ inputValidator = self.inputValidator,
71
+ outputValidator = validator,
72
+ middlewares = self.middlewares,
73
+ intent = self.currentIntent,
74
+ })
75
+ end
76
+ function ProcedureBuilder:use(middleware)
77
+ local _object = {
78
+ inputValidator = self.inputValidator,
79
+ outputValidator = self.outputValidator,
80
+ }
81
+ local _left = "middlewares"
82
+ local _array = {}
83
+ local _length = #_array
84
+ local _array_1 = self.middlewares
85
+ local _Length = #_array_1
86
+ table.move(_array_1, 1, _Length, _length + 1, _array)
87
+ _length += _Length
88
+ _array[_length + 1] = middleware
89
+ _object[_left] = _array
90
+ _object.intent = self.currentIntent
91
+ return ProcedureBuilder.new(_object)
92
+ end
93
+ function ProcedureBuilder:intent(intent)
94
+ return ProcedureBuilder.new({
95
+ inputValidator = self.inputValidator,
96
+ outputValidator = self.outputValidator,
97
+ middlewares = self.middlewares,
98
+ intent = intent,
99
+ })
100
+ end
101
+ function ProcedureBuilder:resolve(resolve)
102
+ local def = {
103
+ kind = "procedure",
104
+ intent = self.currentIntent,
105
+ inputValidator = self.inputValidator,
106
+ outputValidator = self.outputValidator,
107
+ middlewares = self.middlewares,
108
+ resolve = resolve,
109
+ }
110
+ return ProcedureImpl.new(def)
111
+ end
112
+ end
113
+ return {
114
+ ProcedureBuilder = ProcedureBuilder,
115
+ }