@kibinrpc/server 0.0.2 → 0.0.3
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/dist/index.d.mts +26 -8
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +69 -26
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -12,13 +12,6 @@ declare class KibinError extends Error {
|
|
|
12
12
|
declare function serverAction<T extends (...args: never[]) => unknown>(fn: T): T;
|
|
13
13
|
declare function defineActions<T extends Record<string, (...args: never[]) => unknown>>(actions: T): T;
|
|
14
14
|
//#endregion
|
|
15
|
-
//#region src/router.d.ts
|
|
16
|
-
type Services = Record<string, object>;
|
|
17
|
-
declare function createRouter<T extends Services>(services: T): {
|
|
18
|
-
services: T;
|
|
19
|
-
handler: (request: Request) => Promise<Response>;
|
|
20
|
-
};
|
|
21
|
-
//#endregion
|
|
22
15
|
//#region src/types.d.ts
|
|
23
16
|
interface RpcRequest {
|
|
24
17
|
namespace: string;
|
|
@@ -32,6 +25,31 @@ interface RpcResponse<T = unknown> {
|
|
|
32
25
|
message: string;
|
|
33
26
|
};
|
|
34
27
|
}
|
|
28
|
+
interface ActionCtx {
|
|
29
|
+
namespace: string;
|
|
30
|
+
method: string;
|
|
31
|
+
args: unknown[];
|
|
32
|
+
request: Request;
|
|
33
|
+
}
|
|
34
|
+
interface AfterActionCtx extends ActionCtx {
|
|
35
|
+
result: unknown;
|
|
36
|
+
}
|
|
37
|
+
interface ActionErrorCtx extends ActionCtx {
|
|
38
|
+
error: unknown;
|
|
39
|
+
}
|
|
40
|
+
interface RouterInterceptors {
|
|
41
|
+
beforeAction?: (ctx: ActionCtx) => void | Promise<void>;
|
|
42
|
+
afterAction?: (ctx: AfterActionCtx) => unknown | Promise<unknown>;
|
|
43
|
+
onError?: (ctx: ActionErrorCtx) => void | Promise<void>;
|
|
44
|
+
}
|
|
45
|
+
//#endregion
|
|
46
|
+
//#region src/router.d.ts
|
|
47
|
+
type Services = Record<string, object>;
|
|
48
|
+
declare function createRouter<T extends Services>(services: T, interceptors?: RouterInterceptors): {
|
|
49
|
+
services: T;
|
|
50
|
+
handler: (request: Request) => Promise<Response>;
|
|
51
|
+
batchHandler: (request: Request) => Promise<Response>;
|
|
52
|
+
};
|
|
35
53
|
//#endregion
|
|
36
|
-
export { KibinError, type RpcRequest, type RpcResponse, ServerAction, createRouter, defineActions, serverAction };
|
|
54
|
+
export { type ActionCtx, type ActionErrorCtx, type AfterActionCtx, KibinError, type RouterInterceptors, type RpcRequest, type RpcResponse, ServerAction, createRouter, defineActions, serverAction };
|
|
37
55
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/decorator.ts","../src/errors.ts","../src/fn.ts","../src/
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/decorator.ts","../src/errors.ts","../src/fn.ts","../src/types.ts","../src/router.ts"],"mappings":";iBAEgB,YAAA,CAAA,0CAEd,MAAA,GAAS,IAAA,EAAM,IAAA,KAAS,IAAA,EAAM,IAAA,KAAS,MAAA,EACvC,OAAA,EAAS,2BAAA,CAA4B,IAAA,GAAO,IAAA,EAAM,IAAA,KAAS,IAAA,EAAM,IAAA,KAAS,MAAA,OAAO,IAAA,EADlE,IAAA,KAAI,IAAA,EAAW,IAAA,KAAS,MAAA;;;cCJ5B,UAAA,SAAmB,KAAK;EAAA,SAC3B,IAAA;EAAA,SACA,UAAA;cAEG,IAAA,UAAc,OAAA,UAAiB,UAAA;AAAA;;;iBCF5B,YAAA,eAA2B,IAAA,sBAAA,CAA2B,EAAA,EAAI,CAAA,GAAI,CAAC;AAAA,iBAK/D,aAAA,WAAwB,MAAA,aAAmB,IAAA,uBAAA,CAC1D,OAAA,EAAS,CAAA,GACP,CAAA;;;UCTc,UAAA;EAChB,SAAA;EACA,MAAA;EACA,IAAA;AAAA;AAAA,UAGgB,WAAA;EAChB,IAAA,GAAO,CAAC;EACR,KAAA;IAAU,IAAA;IAAc,OAAA;EAAA;AAAA;AAAA,UAGR,SAAA;EAChB,SAAA;EACA,MAAA;EACA,IAAA;EACA,OAAA,EAAS,OAAO;AAAA;AAAA,UAGA,cAAA,SAAuB,SAAS;EAChD,MAAM;AAAA;AAAA,UAGU,cAAA,SAAuB,SAAS;EAChD,KAAK;AAAA;AAAA,UAGW,kBAAA;EAChB,YAAA,IAAgB,GAAA,EAAK,SAAA,YAAqB,OAAA;EAC1C,WAAA,IAAe,GAAA,EAAK,cAAA,eAA6B,OAAA;EACjD,OAAA,IAAW,GAAA,EAAK,cAAA,YAA0B,OAAA;AAAA;;;KCzBtC,QAAA,GAAW,MAAM;AAAA,iBAwEN,YAAA,WAAuB,QAAA,CAAA,CAAU,QAAA,EAAU,CAAA,EAAG,YAAA,GAAe,kBAAA;;qBAC5C,OAAA,KAAU,OAAA,CAAQ,QAAA;0BAYb,OAAA,KAAU,OAAA,CAAQ,QAAA;AAAA"}
|
package/dist/index.mjs
CHANGED
|
@@ -48,7 +48,62 @@ function jsonResponse(body, status) {
|
|
|
48
48
|
headers: { "Content-Type": "application/json" }
|
|
49
49
|
});
|
|
50
50
|
}
|
|
51
|
-
function
|
|
51
|
+
function statusFromResponse(result) {
|
|
52
|
+
if (!result.error) return 200;
|
|
53
|
+
if (result.error.code === "NOT_FOUND" || result.error.code === "METHOD_NOT_FOUND") return 404;
|
|
54
|
+
if (result.error.code === "BAD_REQUEST") return 400;
|
|
55
|
+
return 500;
|
|
56
|
+
}
|
|
57
|
+
async function executeRpcCall(body, request, services, interceptors) {
|
|
58
|
+
const { namespace, method, args } = body;
|
|
59
|
+
const service = services[namespace];
|
|
60
|
+
if (!service) return { error: {
|
|
61
|
+
code: "NOT_FOUND",
|
|
62
|
+
message: `Namespace "${namespace}" not found`
|
|
63
|
+
} };
|
|
64
|
+
const fn = service[method];
|
|
65
|
+
if (!(getRegisteredActions(service).has(method) || isBrandedAction(fn))) return { error: {
|
|
66
|
+
code: "METHOD_NOT_FOUND",
|
|
67
|
+
message: `"${method}" is not a registered server action`
|
|
68
|
+
} };
|
|
69
|
+
if (typeof fn !== "function") return { error: {
|
|
70
|
+
code: "METHOD_NOT_FOUND",
|
|
71
|
+
message: `Method "${method}" not found`
|
|
72
|
+
} };
|
|
73
|
+
const ctx = {
|
|
74
|
+
namespace,
|
|
75
|
+
method,
|
|
76
|
+
args,
|
|
77
|
+
request
|
|
78
|
+
};
|
|
79
|
+
try {
|
|
80
|
+
if (interceptors?.beforeAction) await interceptors.beforeAction(ctx);
|
|
81
|
+
const result = await fn.apply(service, args);
|
|
82
|
+
let finalResult = result;
|
|
83
|
+
if (interceptors?.afterAction) {
|
|
84
|
+
const transformed = await interceptors.afterAction({
|
|
85
|
+
...ctx,
|
|
86
|
+
result
|
|
87
|
+
});
|
|
88
|
+
if (transformed !== void 0) finalResult = transformed;
|
|
89
|
+
}
|
|
90
|
+
return { data: finalResult };
|
|
91
|
+
} catch (error) {
|
|
92
|
+
if (interceptors?.onError) await interceptors.onError({
|
|
93
|
+
...ctx,
|
|
94
|
+
error
|
|
95
|
+
});
|
|
96
|
+
if (error instanceof KibinError) return { error: {
|
|
97
|
+
code: error.code,
|
|
98
|
+
message: error.message
|
|
99
|
+
} };
|
|
100
|
+
return { error: {
|
|
101
|
+
code: "INTERNAL_ERROR",
|
|
102
|
+
message: "Internal server error"
|
|
103
|
+
} };
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
function createRouter(services, interceptors) {
|
|
52
107
|
async function handler(request) {
|
|
53
108
|
let body;
|
|
54
109
|
try {
|
|
@@ -59,37 +114,25 @@ function createRouter(services) {
|
|
|
59
114
|
message: "Invalid JSON body"
|
|
60
115
|
} }, 400);
|
|
61
116
|
}
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
} }, 404);
|
|
68
|
-
const fn = service[method];
|
|
69
|
-
if (!(getRegisteredActions(service).has(method) || isBrandedAction(fn))) return jsonResponse({ error: {
|
|
70
|
-
code: "METHOD_NOT_FOUND",
|
|
71
|
-
message: `"${method}" is not a registered server action`
|
|
72
|
-
} }, 404);
|
|
73
|
-
if (typeof fn !== "function") return jsonResponse({ error: {
|
|
74
|
-
code: "METHOD_NOT_FOUND",
|
|
75
|
-
message: `Method "${method}" not found`
|
|
76
|
-
} }, 404);
|
|
117
|
+
const result = await executeRpcCall(body, request, services, interceptors);
|
|
118
|
+
return jsonResponse(result, statusFromResponse(result));
|
|
119
|
+
}
|
|
120
|
+
async function batchHandler(request) {
|
|
121
|
+
let bodies;
|
|
77
122
|
try {
|
|
78
|
-
|
|
79
|
-
} catch
|
|
80
|
-
if (error instanceof KibinError) return jsonResponse({ error: {
|
|
81
|
-
code: error.code,
|
|
82
|
-
message: error.message
|
|
83
|
-
} }, error.statusCode);
|
|
123
|
+
bodies = await request.json();
|
|
124
|
+
} catch {
|
|
84
125
|
return jsonResponse({ error: {
|
|
85
|
-
code: "
|
|
86
|
-
message: "
|
|
87
|
-
} },
|
|
126
|
+
code: "BAD_REQUEST",
|
|
127
|
+
message: "Invalid JSON body"
|
|
128
|
+
} }, 400);
|
|
88
129
|
}
|
|
130
|
+
return jsonResponse(await Promise.all(bodies.map((body) => executeRpcCall(body, request, services, interceptors))), 200);
|
|
89
131
|
}
|
|
90
132
|
return {
|
|
91
133
|
services,
|
|
92
|
-
handler
|
|
134
|
+
handler,
|
|
135
|
+
batchHandler
|
|
93
136
|
};
|
|
94
137
|
}
|
|
95
138
|
//#endregion
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../src/registry.ts","../src/decorator.ts","../src/errors.ts","../src/fn.ts","../src/router.ts"],"sourcesContent":["export const SERVER_ACTIONS_KEY = Symbol('serverActions');\nexport const FUNCTION_ACTION_KEY = Symbol('functionAction');\n\nexport function getRegisteredActions(instance: object): Set<string> {\n\treturn (Reflect.get(instance, SERVER_ACTIONS_KEY) as Set<string> | undefined) ?? new Set();\n}\n\nexport function isBrandedAction(fn: unknown): boolean {\n\treturn typeof fn === 'function' && Reflect.get(fn, FUNCTION_ACTION_KEY) === true;\n}\n","import { SERVER_ACTIONS_KEY } from './registry.js';\n\nexport function ServerAction() {\n\treturn <This, Args extends unknown[], Return>(\n\t\ttarget: (this: This, ...args: Args) => Return,\n\t\tcontext: ClassMethodDecoratorContext<This, (this: This, ...args: Args) => Return>,\n\t) => {\n\t\tcontext.addInitializer(function (this: This) {\n\t\t\tif (!Reflect.has(this as object, SERVER_ACTIONS_KEY)) {\n\t\t\t\tReflect.set(this as object, SERVER_ACTIONS_KEY, new Set<string>());\n\t\t\t}\n\t\t\t(Reflect.get(this as object, SERVER_ACTIONS_KEY) as Set<string>).add(String(context.name));\n\t\t});\n\t\treturn target;\n\t};\n}\n","export class KibinError extends Error {\n\treadonly code: string;\n\treadonly statusCode: number;\n\n\tconstructor(code: string, message: string, statusCode = 400) {\n\t\tsuper(message);\n\t\tthis.name = 'KibinError';\n\t\tthis.code = code;\n\t\tthis.statusCode = statusCode;\n\t}\n}\n","import { FUNCTION_ACTION_KEY } from './registry.js';\n\nexport function serverAction<T extends (...args: never[]) => unknown>(fn: T): T {\n\tReflect.set(fn, FUNCTION_ACTION_KEY, true);\n\treturn fn;\n}\n\nexport function defineActions<T extends Record<string, (...args: never[]) => unknown>>(\n\tactions: T,\n): T {\n\tfor (const key of Object.keys(actions)) {\n\t\tserverAction(actions[key]);\n\t}\n\treturn actions;\n}\n","import { KibinError } from './errors.js';\nimport { getRegisteredActions, isBrandedAction } from './registry.js';\nimport type { RpcRequest, RpcResponse } from './types.js';\n\ntype Services = Record<string, object>;\n\nfunction jsonResponse(body: RpcResponse, status: number): Response {\n\treturn new Response(JSON.stringify(body), {\n\t\tstatus,\n\t\theaders: { 'Content-Type': 'application/json' },\n\t});\n}\n\
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/registry.ts","../src/decorator.ts","../src/errors.ts","../src/fn.ts","../src/router.ts"],"sourcesContent":["export const SERVER_ACTIONS_KEY = Symbol('serverActions');\nexport const FUNCTION_ACTION_KEY = Symbol('functionAction');\n\nexport function getRegisteredActions(instance: object): Set<string> {\n\treturn (Reflect.get(instance, SERVER_ACTIONS_KEY) as Set<string> | undefined) ?? new Set();\n}\n\nexport function isBrandedAction(fn: unknown): boolean {\n\treturn typeof fn === 'function' && Reflect.get(fn, FUNCTION_ACTION_KEY) === true;\n}\n","import { SERVER_ACTIONS_KEY } from './registry.js';\n\nexport function ServerAction() {\n\treturn <This, Args extends unknown[], Return>(\n\t\ttarget: (this: This, ...args: Args) => Return,\n\t\tcontext: ClassMethodDecoratorContext<This, (this: This, ...args: Args) => Return>,\n\t) => {\n\t\tcontext.addInitializer(function (this: This) {\n\t\t\tif (!Reflect.has(this as object, SERVER_ACTIONS_KEY)) {\n\t\t\t\tReflect.set(this as object, SERVER_ACTIONS_KEY, new Set<string>());\n\t\t\t}\n\t\t\t(Reflect.get(this as object, SERVER_ACTIONS_KEY) as Set<string>).add(String(context.name));\n\t\t});\n\t\treturn target;\n\t};\n}\n","export class KibinError extends Error {\n\treadonly code: string;\n\treadonly statusCode: number;\n\n\tconstructor(code: string, message: string, statusCode = 400) {\n\t\tsuper(message);\n\t\tthis.name = 'KibinError';\n\t\tthis.code = code;\n\t\tthis.statusCode = statusCode;\n\t}\n}\n","import { FUNCTION_ACTION_KEY } from './registry.js';\n\nexport function serverAction<T extends (...args: never[]) => unknown>(fn: T): T {\n\tReflect.set(fn, FUNCTION_ACTION_KEY, true);\n\treturn fn;\n}\n\nexport function defineActions<T extends Record<string, (...args: never[]) => unknown>>(\n\tactions: T,\n): T {\n\tfor (const key of Object.keys(actions)) {\n\t\tserverAction(actions[key]);\n\t}\n\treturn actions;\n}\n","import { KibinError } from './errors.js';\nimport { getRegisteredActions, isBrandedAction } from './registry.js';\nimport type { RouterInterceptors, RpcRequest, RpcResponse } from './types.js';\n\ntype Services = Record<string, object>;\n\nfunction jsonResponse(body: RpcResponse | RpcResponse[], status: number): Response {\n\treturn new Response(JSON.stringify(body), {\n\t\tstatus,\n\t\theaders: { 'Content-Type': 'application/json' },\n\t});\n}\n\nfunction statusFromResponse(result: RpcResponse): number {\n\tif (!result.error) return 200;\n\tif (result.error.code === 'NOT_FOUND' || result.error.code === 'METHOD_NOT_FOUND') return 404;\n\tif (result.error.code === 'BAD_REQUEST') return 400;\n\treturn 500;\n}\n\nasync function executeRpcCall(\n\tbody: RpcRequest,\n\trequest: Request,\n\tservices: Services,\n\tinterceptors: RouterInterceptors | undefined,\n): Promise<RpcResponse> {\n\tconst { namespace, method, args } = body;\n\n\tconst service = services[namespace];\n\tif (!service) {\n\t\treturn { error: { code: 'NOT_FOUND', message: `Namespace \"${namespace}\" not found` } };\n\t}\n\n\tconst fn = (service as Record<string, unknown>)[method];\n\tconst isAllowed = getRegisteredActions(service).has(method) || isBrandedAction(fn);\n\tif (!isAllowed) {\n\t\treturn {\n\t\t\terror: {\n\t\t\t\tcode: 'METHOD_NOT_FOUND',\n\t\t\t\tmessage: `\"${method}\" is not a registered server action`,\n\t\t\t},\n\t\t};\n\t}\n\n\tif (typeof fn !== 'function') {\n\t\treturn { error: { code: 'METHOD_NOT_FOUND', message: `Method \"${method}\" not found` } };\n\t}\n\n\tconst ctx = { namespace, method, args, request };\n\n\ttry {\n\t\tif (interceptors?.beforeAction) {\n\t\t\tawait interceptors.beforeAction(ctx);\n\t\t}\n\n\t\tconst result = await fn.apply(service, args);\n\n\t\tlet finalResult = result;\n\t\tif (interceptors?.afterAction) {\n\t\t\tconst transformed = await interceptors.afterAction({ ...ctx, result });\n\t\t\tif (transformed !== undefined) finalResult = transformed;\n\t\t}\n\n\t\treturn { data: finalResult };\n\t} catch (error) {\n\t\tif (interceptors?.onError) {\n\t\t\tawait interceptors.onError({ ...ctx, error });\n\t\t}\n\n\t\tif (error instanceof KibinError) {\n\t\t\treturn { error: { code: error.code, message: error.message } };\n\t\t}\n\t\treturn { error: { code: 'INTERNAL_ERROR', message: 'Internal server error' } };\n\t}\n}\n\nexport function createRouter<T extends Services>(services: T, interceptors?: RouterInterceptors) {\n\tasync function handler(request: Request): Promise<Response> {\n\t\tlet body: RpcRequest;\n\t\ttry {\n\t\t\tbody = (await request.json()) as RpcRequest;\n\t\t} catch {\n\t\t\treturn jsonResponse({ error: { code: 'BAD_REQUEST', message: 'Invalid JSON body' } }, 400);\n\t\t}\n\n\t\tconst result = await executeRpcCall(body, request, services, interceptors);\n\t\treturn jsonResponse(result, statusFromResponse(result));\n\t}\n\n\tasync function batchHandler(request: Request): Promise<Response> {\n\t\tlet bodies: RpcRequest[];\n\t\ttry {\n\t\t\tbodies = (await request.json()) as RpcRequest[];\n\t\t} catch {\n\t\t\treturn jsonResponse({ error: { code: 'BAD_REQUEST', message: 'Invalid JSON body' } }, 400);\n\t\t}\n\n\t\tconst results = await Promise.all(\n\t\t\tbodies.map((body) => executeRpcCall(body, request, services, interceptors)),\n\t\t);\n\t\treturn jsonResponse(results, 200);\n\t}\n\n\treturn { services, handler, batchHandler };\n}\n"],"mappings":"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"}
|