kizlo 0.1.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 +21 -0
- package/README.md +74 -0
- package/dist/adapters/auth.d.ts +18 -0
- package/dist/adapters/auth.js +15 -0
- package/dist/adapters/captcha.d.ts +28 -0
- package/dist/adapters/captcha.js +86 -0
- package/dist/adapters/geo.d.ts +18 -0
- package/dist/adapters/geo.js +18 -0
- package/dist/adapters/geo.vercel.d.ts +6 -0
- package/dist/adapters/geo.vercel.js +41 -0
- package/dist/adapters/logger.d.ts +31 -0
- package/dist/adapters/logger.js +30 -0
- package/dist/cli/banner.js +26 -0
- package/dist/cli/commands/generate.js +34 -0
- package/dist/cli/commands/init.js +313 -0
- package/dist/cli/commands/test.js +68 -0
- package/dist/cli/commands/watch.js +53 -0
- package/dist/cli/commands/wp.js +66 -0
- package/dist/cli/daemon/config.js +87 -0
- package/dist/cli/daemon/generate.js +40 -0
- package/dist/cli/daemon/lock.js +31 -0
- package/dist/cli/daemon/logger.js +8 -0
- package/dist/cli/daemon/watch.js +37 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +22 -0
- package/dist/cli/presets/base.js +23 -0
- package/dist/cli/presets/index.js +16 -0
- package/dist/cli/presets/nextjs.js +39 -0
- package/dist/cli/utils.js +182 -0
- package/dist/cli/wp/bootstrap.js +114 -0
- package/dist/cli/wp/compose/docker-compose.yml +73 -0
- package/dist/cli/wp/constants.js +52 -0
- package/dist/cli/wp/docker.d.ts +24 -0
- package/dist/cli/wp/docker.js +69 -0
- package/dist/cli/wp/setup.js +39 -0
- package/dist/cli/wp/types.d.ts +72 -0
- package/dist/cli/wp/types.js +8 -0
- package/dist/cli/wp/utils.d.ts +39 -0
- package/dist/cli/wp/utils.js +105 -0
- package/dist/client.d.ts +24 -0
- package/dist/client.js +55 -0
- package/dist/comment/errors.js +47 -0
- package/dist/comment/index.js +138 -0
- package/dist/comment/schema.js +72 -0
- package/dist/comment/utils.js +35 -0
- package/dist/config.d.ts +39 -0
- package/dist/config.js +7 -0
- package/dist/context.d.ts +73 -0
- package/dist/context.js +145 -0
- package/dist/cookie.d.ts +19 -0
- package/dist/cookie.js +25 -0
- package/dist/email/service.d.ts +11 -0
- package/dist/email/service.interface.d.ts +8 -0
- package/dist/email/service.js +20 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.js +31 -0
- package/dist/integrations/nextjs/kizlo.client.d.ts +10 -0
- package/dist/integrations/nextjs/kizlo.client.js +13 -0
- package/dist/integrations/nextjs/kizlo.server.d.ts +12 -0
- package/dist/integrations/nextjs/kizlo.server.js +13 -0
- package/dist/integrations/nextjs/utils.js +11 -0
- package/dist/kizlo.d.ts +73 -0
- package/dist/kizlo.js +144 -0
- package/dist/menu/errors.js +16 -0
- package/dist/menu/fixture.d.ts +8 -0
- package/dist/menu/fixture.js +62 -0
- package/dist/menu/index.js +70 -0
- package/dist/menu/schema.js +70 -0
- package/dist/menu/utils.js +57 -0
- package/dist/nextjs/server.d.ts +2 -0
- package/dist/nextjs/server.js +3 -0
- package/dist/nextjs.d.ts +2 -0
- package/dist/nextjs.js +3 -0
- package/dist/package.js +5 -0
- package/dist/post/error.js +30 -0
- package/dist/post/fixture.d.ts +8 -0
- package/dist/post/fixture.js +71 -0
- package/dist/post/index.js +123 -0
- package/dist/post/schema.js +120 -0
- package/dist/post/utils.js +42 -0
- package/dist/post-type/service.js +48 -0
- package/dist/router.d.ts +624 -0
- package/dist/router.js +15 -0
- package/dist/seo/index.js +54 -0
- package/dist/seo/schema.d.ts +196 -0
- package/dist/seo/schema.js +96 -0
- package/dist/seo/types.d.ts +80 -0
- package/dist/seo/utils.js +44 -0
- package/dist/service.d.ts +17 -0
- package/dist/service.js +17 -0
- package/dist/shared/constants.js +10 -0
- package/dist/shared/contract.d.ts +21 -0
- package/dist/shared/contract.js +43 -0
- package/dist/shared/crypto.d.ts +28 -0
- package/dist/shared/crypto.js +34 -0
- package/dist/shared/error.d.ts +128 -0
- package/dist/shared/error.js +147 -0
- package/dist/shared/extension.d.ts +25 -0
- package/dist/shared/extension.js +7 -0
- package/dist/shared/identifier.d.ts +11 -0
- package/dist/shared/identifier.js +26 -0
- package/dist/shared/middleware.d.ts +29 -0
- package/dist/shared/procedure.d.ts +114 -0
- package/dist/shared/procedure.js +114 -0
- package/dist/shared/result.d.ts +24 -0
- package/dist/shared/result.js +49 -0
- package/dist/shared/router.d.ts +7 -0
- package/dist/shared/router.js +26 -0
- package/dist/shared/schema.d.ts +55 -0
- package/dist/shared/schema.js +43 -0
- package/dist/shared/serialize.d.ts +12 -0
- package/dist/shared/serialize.js +51 -0
- package/dist/shared/types.d.ts +35 -0
- package/dist/shared/utils.js +17 -0
- package/dist/test/auth.d.ts +7 -0
- package/dist/test/auth.js +15 -0
- package/dist/test/captcha.d.ts +7 -0
- package/dist/test/captcha.js +8 -0
- package/dist/test/client.d.ts +11 -0
- package/dist/test/client.js +14 -0
- package/dist/test/fixtures.d.ts +14 -0
- package/dist/test/fixtures.js +13 -0
- package/dist/test/server.d.ts +10 -0
- package/dist/test/server.js +32 -0
- package/dist/test/users.d.ts +14 -0
- package/dist/test/users.js +17 -0
- package/dist/test.d.ts +12 -0
- package/dist/test.js +13 -0
- package/dist/webhook/index.d.ts +38 -0
- package/dist/webhook/index.js +44 -0
- package/dist/webhook/schema.d.ts +45 -0
- package/dist/webhook/schema.js +72 -0
- package/dist/webhook/utils.js +21 -0
- package/dist/wordpress/comment/service.d.ts +28 -0
- package/dist/wordpress/comment/service.js +55 -0
- package/dist/wordpress/comment/types.d.ts +206 -0
- package/dist/wordpress/constants.d.ts +14 -0
- package/dist/wordpress/constants.js +13 -0
- package/dist/wordpress/error.d.ts +9 -0
- package/dist/wordpress/error.js +12 -0
- package/dist/wordpress/index.d.ts +15 -0
- package/dist/wordpress/menu/items/service.d.ts +28 -0
- package/dist/wordpress/menu/items/service.js +55 -0
- package/dist/wordpress/menu/items/types.d.ts +214 -0
- package/dist/wordpress/menu/service.d.ts +30 -0
- package/dist/wordpress/menu/service.js +58 -0
- package/dist/wordpress/menu/types.d.ts +115 -0
- package/dist/wordpress/post/service.d.ts +28 -0
- package/dist/wordpress/post/service.js +55 -0
- package/dist/wordpress/post/types.d.ts +290 -0
- package/dist/wordpress/service.d.ts +77 -0
- package/dist/wordpress/service.js +180 -0
- package/dist/wordpress/types.d.ts +67 -0
- package/dist/wordpress/user/service.d.ts +28 -0
- package/dist/wordpress/user/service.js +55 -0
- package/dist/wordpress/user/types.d.ts +221 -0
- package/dist/wordpress/utils.d.ts +7 -0
- package/dist/wordpress/utils.js +9 -0
- package/package.json +109 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { AnySchema, LiteralUnion, Metadata, SchemaInput, SchemaOutput } from "@kizlo/shared";
|
|
2
|
+
|
|
3
|
+
//#region src/shared/error.d.ts
|
|
4
|
+
declare const COMMON_ERRORS: {
|
|
5
|
+
BAD_REQUEST: {
|
|
6
|
+
status: number;
|
|
7
|
+
message: string;
|
|
8
|
+
};
|
|
9
|
+
UNAUTHORIZED: {
|
|
10
|
+
status: number;
|
|
11
|
+
message: string;
|
|
12
|
+
};
|
|
13
|
+
FORBIDDEN: {
|
|
14
|
+
status: number;
|
|
15
|
+
message: string;
|
|
16
|
+
};
|
|
17
|
+
NOT_FOUND: {
|
|
18
|
+
status: number;
|
|
19
|
+
message: string;
|
|
20
|
+
};
|
|
21
|
+
METHOD_NOT_SUPPORTED: {
|
|
22
|
+
status: number;
|
|
23
|
+
message: string;
|
|
24
|
+
};
|
|
25
|
+
NOT_ACCEPTABLE: {
|
|
26
|
+
status: number;
|
|
27
|
+
message: string;
|
|
28
|
+
};
|
|
29
|
+
TIMEOUT: {
|
|
30
|
+
status: number;
|
|
31
|
+
message: string;
|
|
32
|
+
};
|
|
33
|
+
CONFLICT: {
|
|
34
|
+
status: number;
|
|
35
|
+
message: string;
|
|
36
|
+
};
|
|
37
|
+
PRECONDITION_FAILED: {
|
|
38
|
+
status: number;
|
|
39
|
+
message: string;
|
|
40
|
+
};
|
|
41
|
+
PAYLOAD_TOO_LARGE: {
|
|
42
|
+
status: number;
|
|
43
|
+
message: string;
|
|
44
|
+
};
|
|
45
|
+
UNSUPPORTED_MEDIA_TYPE: {
|
|
46
|
+
status: number;
|
|
47
|
+
message: string;
|
|
48
|
+
};
|
|
49
|
+
UNPROCESSABLE_CONTENT: {
|
|
50
|
+
status: number;
|
|
51
|
+
message: string;
|
|
52
|
+
};
|
|
53
|
+
TOO_MANY_REQUESTS: {
|
|
54
|
+
status: number;
|
|
55
|
+
message: string;
|
|
56
|
+
};
|
|
57
|
+
CLIENT_CLOSED_REQUEST: {
|
|
58
|
+
status: number;
|
|
59
|
+
message: string;
|
|
60
|
+
};
|
|
61
|
+
INTERNAL_SERVER_ERROR: {
|
|
62
|
+
status: number;
|
|
63
|
+
message: string;
|
|
64
|
+
};
|
|
65
|
+
NOT_IMPLEMENTED: {
|
|
66
|
+
status: number;
|
|
67
|
+
message: string;
|
|
68
|
+
};
|
|
69
|
+
BAD_GATEWAY: {
|
|
70
|
+
status: number;
|
|
71
|
+
message: string;
|
|
72
|
+
};
|
|
73
|
+
SERVICE_UNAVAILABLE: {
|
|
74
|
+
status: number;
|
|
75
|
+
message: string;
|
|
76
|
+
};
|
|
77
|
+
GATEWAY_TIMEOUT: {
|
|
78
|
+
status: number;
|
|
79
|
+
message: string;
|
|
80
|
+
};
|
|
81
|
+
UNEXPECTED_ERROR: {
|
|
82
|
+
status: number;
|
|
83
|
+
message: string;
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
type CommonErrorMap = typeof COMMON_ERRORS;
|
|
87
|
+
type CommonErrorCode = keyof CommonErrorMap;
|
|
88
|
+
type CommonErrorLiteral = LiteralUnion<CommonErrorCode, string>;
|
|
89
|
+
type WithCommonErrorMap<TErrors extends DefinedErrorMapLike> = CommonErrorMap & { [K in keyof TErrors as string extends K ? never : K]: TErrors[K] };
|
|
90
|
+
interface KizloErrorOptions {
|
|
91
|
+
message?: string;
|
|
92
|
+
status?: number;
|
|
93
|
+
data?: unknown;
|
|
94
|
+
cause?: unknown;
|
|
95
|
+
}
|
|
96
|
+
declare class KizloError<TCode extends CommonErrorLiteral = CommonErrorLiteral, TData = unknown> extends Error {
|
|
97
|
+
readonly name = "KizloError";
|
|
98
|
+
readonly code: TCode;
|
|
99
|
+
readonly data: TData;
|
|
100
|
+
readonly status: number;
|
|
101
|
+
constructor(code: TCode, options?: KizloErrorOptions);
|
|
102
|
+
}
|
|
103
|
+
declare function isKizloError(value: unknown): value is KizloError;
|
|
104
|
+
declare function toKizloError(e: unknown): KizloError;
|
|
105
|
+
type DefinedErrorLike = {
|
|
106
|
+
status?: number;
|
|
107
|
+
message?: string;
|
|
108
|
+
data?: AnySchema;
|
|
109
|
+
};
|
|
110
|
+
declare function defineErrorMap<const T extends Partial<Record<CommonErrorLiteral, DefinedErrorLike>>>(map: T): T;
|
|
111
|
+
type DefinedErrorMapLike = Record<string, DefinedErrorLike>;
|
|
112
|
+
type ThrowableErrorFn<TCode extends string, T extends DefinedErrorLike> = T["data"] extends AnySchema ? undefined extends SchemaInput<T["data"]> ? (options?: {
|
|
113
|
+
status?: number;
|
|
114
|
+
message?: string;
|
|
115
|
+
data?: SchemaInput<T["data"]>;
|
|
116
|
+
}) => KizloError<TCode, SchemaOutput<T["data"]>> : (options: {
|
|
117
|
+
status?: number;
|
|
118
|
+
message?: string;
|
|
119
|
+
data: SchemaInput<T["data"]>;
|
|
120
|
+
}) => KizloError<TCode, SchemaOutput<T["data"]>> : (options?: {
|
|
121
|
+
status?: number;
|
|
122
|
+
message?: string;
|
|
123
|
+
data?: Metadata;
|
|
124
|
+
}) => KizloError<TCode, SchemaOutput<T["data"]>>;
|
|
125
|
+
type ThrowableErrorMap<T extends DefinedErrorMapLike> = { [K in Extract<keyof T, string>]: ThrowableErrorFn<K, T[K]> };
|
|
126
|
+
declare function createThrowableErrorMap<TError extends DefinedErrorMapLike>(errors: TError): ThrowableErrorMap<WithCommonErrorMap<TError>>;
|
|
127
|
+
//#endregion
|
|
128
|
+
export { COMMON_ERRORS, CommonErrorCode, CommonErrorLiteral, CommonErrorMap, DefinedErrorLike, DefinedErrorMapLike, KizloError, KizloErrorOptions, ThrowableErrorFn, ThrowableErrorMap, WithCommonErrorMap, createThrowableErrorMap, defineErrorMap, isKizloError, toKizloError };
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
//#region src/shared/error.ts
|
|
2
|
+
const COMMON_ERRORS = {
|
|
3
|
+
BAD_REQUEST: {
|
|
4
|
+
status: 400,
|
|
5
|
+
message: "Bad Request"
|
|
6
|
+
},
|
|
7
|
+
UNAUTHORIZED: {
|
|
8
|
+
status: 401,
|
|
9
|
+
message: "Unauthorized"
|
|
10
|
+
},
|
|
11
|
+
FORBIDDEN: {
|
|
12
|
+
status: 403,
|
|
13
|
+
message: "Forbidden"
|
|
14
|
+
},
|
|
15
|
+
NOT_FOUND: {
|
|
16
|
+
status: 404,
|
|
17
|
+
message: "Not Found"
|
|
18
|
+
},
|
|
19
|
+
METHOD_NOT_SUPPORTED: {
|
|
20
|
+
status: 405,
|
|
21
|
+
message: "Method Not Supported"
|
|
22
|
+
},
|
|
23
|
+
NOT_ACCEPTABLE: {
|
|
24
|
+
status: 406,
|
|
25
|
+
message: "Not Acceptable"
|
|
26
|
+
},
|
|
27
|
+
TIMEOUT: {
|
|
28
|
+
status: 408,
|
|
29
|
+
message: "Request Timeout"
|
|
30
|
+
},
|
|
31
|
+
CONFLICT: {
|
|
32
|
+
status: 409,
|
|
33
|
+
message: "Conflict"
|
|
34
|
+
},
|
|
35
|
+
PRECONDITION_FAILED: {
|
|
36
|
+
status: 412,
|
|
37
|
+
message: "Precondition Failed"
|
|
38
|
+
},
|
|
39
|
+
PAYLOAD_TOO_LARGE: {
|
|
40
|
+
status: 413,
|
|
41
|
+
message: "Payload Too Large"
|
|
42
|
+
},
|
|
43
|
+
UNSUPPORTED_MEDIA_TYPE: {
|
|
44
|
+
status: 415,
|
|
45
|
+
message: "Unsupported Media Type"
|
|
46
|
+
},
|
|
47
|
+
UNPROCESSABLE_CONTENT: {
|
|
48
|
+
status: 422,
|
|
49
|
+
message: "Unprocessable Content"
|
|
50
|
+
},
|
|
51
|
+
TOO_MANY_REQUESTS: {
|
|
52
|
+
status: 429,
|
|
53
|
+
message: "Too Many Requests"
|
|
54
|
+
},
|
|
55
|
+
CLIENT_CLOSED_REQUEST: {
|
|
56
|
+
status: 499,
|
|
57
|
+
message: "Client Closed Request"
|
|
58
|
+
},
|
|
59
|
+
INTERNAL_SERVER_ERROR: {
|
|
60
|
+
status: 500,
|
|
61
|
+
message: "Internal Server Error"
|
|
62
|
+
},
|
|
63
|
+
NOT_IMPLEMENTED: {
|
|
64
|
+
status: 501,
|
|
65
|
+
message: "Not Implemented"
|
|
66
|
+
},
|
|
67
|
+
BAD_GATEWAY: {
|
|
68
|
+
status: 502,
|
|
69
|
+
message: "Bad Gateway"
|
|
70
|
+
},
|
|
71
|
+
SERVICE_UNAVAILABLE: {
|
|
72
|
+
status: 503,
|
|
73
|
+
message: "Service Unavailable"
|
|
74
|
+
},
|
|
75
|
+
GATEWAY_TIMEOUT: {
|
|
76
|
+
status: 504,
|
|
77
|
+
message: "Gateway Timeout"
|
|
78
|
+
},
|
|
79
|
+
UNEXPECTED_ERROR: {
|
|
80
|
+
status: 500,
|
|
81
|
+
message: "An unexpected error occurred"
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
var KizloError = class extends Error {
|
|
85
|
+
name = "KizloError";
|
|
86
|
+
code;
|
|
87
|
+
data;
|
|
88
|
+
status;
|
|
89
|
+
constructor(code, options) {
|
|
90
|
+
const preset = COMMON_ERRORS[code];
|
|
91
|
+
const message = options?.message ?? preset?.message ?? String(code);
|
|
92
|
+
super(message, options?.cause ? { cause: options.cause } : void 0);
|
|
93
|
+
this.code = code;
|
|
94
|
+
this.status = options?.status ?? preset?.status ?? 500;
|
|
95
|
+
this.data = options?.data ?? null;
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
function isKizloError(value) {
|
|
99
|
+
if (value instanceof KizloError) return true;
|
|
100
|
+
if (typeof value !== "object" || value === null) return false;
|
|
101
|
+
const v = value;
|
|
102
|
+
return v.name === "KizloError" && typeof v.code === "string" && typeof v.message === "string";
|
|
103
|
+
}
|
|
104
|
+
function toKizloError(e) {
|
|
105
|
+
if (isKizloError(e)) return e;
|
|
106
|
+
if (typeof e === "object" && e !== null && "code" in e && typeof e.code === "string") {
|
|
107
|
+
const err = e;
|
|
108
|
+
return new KizloError(err.code, {
|
|
109
|
+
message: err.message,
|
|
110
|
+
status: err.status,
|
|
111
|
+
data: err.data
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
return new KizloError("INTERNAL_SERVER_ERROR", {
|
|
115
|
+
message: e instanceof Error ? e.message : String(e),
|
|
116
|
+
cause: e
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
function defineErrorMap(map) {
|
|
120
|
+
return map;
|
|
121
|
+
}
|
|
122
|
+
function createThrowableErrorMap(errors) {
|
|
123
|
+
return new Proxy({}, { get(_target, p) {
|
|
124
|
+
if (typeof p === "symbol") return void 0;
|
|
125
|
+
const preset = {
|
|
126
|
+
COMMON_ERRORS,
|
|
127
|
+
...errors
|
|
128
|
+
}[p];
|
|
129
|
+
return (options) => {
|
|
130
|
+
let data = options?.data;
|
|
131
|
+
if (preset?.data) {
|
|
132
|
+
const result = preset.data["~standard"].validate(options?.data);
|
|
133
|
+
if (result instanceof Promise) throw new TypeError(`Schema validation for error "${String(p)}" returned a Promise. Async validation is not supported here; use a synchronous schema.`);
|
|
134
|
+
if (result.issues) throw new TypeError(JSON.stringify(result.issues, null, 2));
|
|
135
|
+
data = result.value;
|
|
136
|
+
}
|
|
137
|
+
return new KizloError(p, {
|
|
138
|
+
status: options?.status ?? preset?.status,
|
|
139
|
+
message: options?.message ?? preset?.message,
|
|
140
|
+
data
|
|
141
|
+
});
|
|
142
|
+
};
|
|
143
|
+
} });
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
//#endregion
|
|
147
|
+
export { COMMON_ERRORS, KizloError, createThrowableErrorMap, defineErrorMap, isKizloError, toKizloError };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { EventHandler } from "../webhook/index.js";
|
|
2
|
+
import { AnyProcedureRouter } from "./procedure.js";
|
|
3
|
+
import { UnionToIntersection } from "@kizlo/shared";
|
|
4
|
+
|
|
5
|
+
//#region src/shared/extension.d.ts
|
|
6
|
+
interface ExtensionInitOptions {
|
|
7
|
+
context: {
|
|
8
|
+
something: string;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
interface ExtensionInitResult<TRouter extends AnyProcedureRouter> {
|
|
12
|
+
router?: TRouter;
|
|
13
|
+
events?: EventHandler[];
|
|
14
|
+
}
|
|
15
|
+
interface Extension<TId extends string, TRouter extends AnyProcedureRouter> {
|
|
16
|
+
id: TId;
|
|
17
|
+
init: ExtensionInitFn<TRouter>;
|
|
18
|
+
}
|
|
19
|
+
type AnyExtension = Extension<any, AnyProcedureRouter>;
|
|
20
|
+
type ExtensionInitFn<TRouter extends AnyProcedureRouter> = (context: ExtensionInitOptions) => ExtensionInitResult<TRouter>;
|
|
21
|
+
type ExtractExtensionRouter<TExt extends AnyExtension> = TExt extends Extension<infer Name, infer Router> ? [keyof Router] extends [never] ? never : string extends keyof Router ? never : Record<Name, Router> : never;
|
|
22
|
+
type InferExtensionRouter<TExt extends readonly AnyExtension[]> = TExt extends readonly [] ? Record<never, never> : ExtractExtensionRouter<TExt[number]> extends infer R ? [R] extends [never] ? Record<never, never> : UnionToIntersection<R> : never;
|
|
23
|
+
declare function createExtension<TId extends string, TRouter extends AnyProcedureRouter = AnyProcedureRouter>(extension: Extension<TId, TRouter>): Extension<TId, TRouter>;
|
|
24
|
+
//#endregion
|
|
25
|
+
export { AnyExtension, Extension, ExtensionInitFn, ExtensionInitOptions, ExtensionInitResult, ExtractExtensionRouter, InferExtensionRouter, createExtension };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
//#region src/shared/identifier.d.ts
|
|
2
|
+
type Identifier = {
|
|
3
|
+
type: "id";
|
|
4
|
+
value: number;
|
|
5
|
+
} | {
|
|
6
|
+
type: "email" | "other";
|
|
7
|
+
value: string;
|
|
8
|
+
};
|
|
9
|
+
declare function parseIdentifier(value: unknown, maxLength?: number): Identifier | null;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { Identifier, parseIdentifier };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
//#region src/shared/identifier.ts
|
|
2
|
+
function parseIdentifier(value, maxLength = 200) {
|
|
3
|
+
const input = String(value).trim();
|
|
4
|
+
if (input.length === 0) return null;
|
|
5
|
+
if (input.length > maxLength) return null;
|
|
6
|
+
if (/^\d+$/.test(input)) {
|
|
7
|
+
const num = Number(input);
|
|
8
|
+
if (num <= 0 || num > Number.MAX_SAFE_INTEGER) return null;
|
|
9
|
+
return {
|
|
10
|
+
type: "id",
|
|
11
|
+
value: num
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
if (/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/.test(input)) return {
|
|
15
|
+
type: "email",
|
|
16
|
+
value: input
|
|
17
|
+
};
|
|
18
|
+
if (!/^[a-zA-Z0-9._@-]+$/.test(input)) return null;
|
|
19
|
+
return {
|
|
20
|
+
type: "other",
|
|
21
|
+
value: input
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
//#endregion
|
|
26
|
+
export { parseIdentifier };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { AnyContext } from "./types.js";
|
|
2
|
+
import { DefinedErrorMapLike, ThrowableErrorMap } from "./error.js";
|
|
3
|
+
import { ServerContext } from "../context.js";
|
|
4
|
+
import { UnionToIntersection } from "@kizlo/shared";
|
|
5
|
+
|
|
6
|
+
//#region src/shared/middleware.d.ts
|
|
7
|
+
interface MiddlewareResult<TOutContext extends AnyContext, TOutput> {
|
|
8
|
+
output: TOutput;
|
|
9
|
+
context: TOutContext;
|
|
10
|
+
}
|
|
11
|
+
type MiddlewareNextFn<TOutput> = {
|
|
12
|
+
(): Promise<MiddlewareResult<AnyContext, TOutput>>;
|
|
13
|
+
<UOutContext extends AnyContext>(options: {
|
|
14
|
+
context: UOutContext;
|
|
15
|
+
}): Promise<MiddlewareResult<UOutContext, TOutput>>;
|
|
16
|
+
};
|
|
17
|
+
type MiddlewareOptions<TInput, TOutput, TError extends DefinedErrorMapLike> = {
|
|
18
|
+
input: TInput;
|
|
19
|
+
context: ServerContext;
|
|
20
|
+
next: MiddlewareNextFn<TOutput>;
|
|
21
|
+
errors: ThrowableErrorMap<TError>;
|
|
22
|
+
};
|
|
23
|
+
type MiddlewareHandler<TOutContext extends AnyContext, TInput, TOutput, TError extends DefinedErrorMapLike> = (options: MiddlewareOptions<TInput, TOutput, TError>) => Promise<MiddlewareResult<TOutContext, TOutput>>;
|
|
24
|
+
type Middleware<TOutContext extends AnyContext, TInput, TOutput, TError extends DefinedErrorMapLike> = MiddlewareHandler<TOutContext, TInput, TOutput, TError>;
|
|
25
|
+
type AnyMiddleware = Middleware<any, any, any, any>;
|
|
26
|
+
type ExtractMiddlewareContextOutput<M> = M extends Middleware<infer TOut, any, any, any> ? TOut : never;
|
|
27
|
+
type InferUses<T extends readonly AnyMiddleware[] | undefined> = T extends readonly [] ? object : T extends readonly AnyMiddleware[] ? UnionToIntersection<ExtractMiddlewareContextOutput<T[number]>> : object;
|
|
28
|
+
//#endregion
|
|
29
|
+
export { InferUses };
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { AnyContext } from "./types.js";
|
|
2
|
+
import { DefinedErrorMapLike, ThrowableErrorMap, WithCommonErrorMap } from "./error.js";
|
|
3
|
+
import { ServerContext } from "../context.js";
|
|
4
|
+
import { InferUses } from "./middleware.js";
|
|
5
|
+
import * as _orpc_contract0 from "@orpc/contract";
|
|
6
|
+
import { AnySchema, DeepMerge, Pathname, Prettify, Promisify, Schema, SchemaInput, SchemaOutput } from "@kizlo/shared";
|
|
7
|
+
import * as _orpc_server0 from "@orpc/server";
|
|
8
|
+
import { HTTPMethod } from "@orpc/server";
|
|
9
|
+
import { JsonifiedValue } from "@orpc/openapi-client";
|
|
10
|
+
|
|
11
|
+
//#region src/shared/procedure.d.ts
|
|
12
|
+
type AnyProcedureRouter = {
|
|
13
|
+
[K: string]: AnyProcedure | AnyProcedureRouter;
|
|
14
|
+
};
|
|
15
|
+
type RouterDepthTuple = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
|
16
|
+
type ExtractProcedureByScope<TRouter extends AnyProcedureRouter, TScope extends InvocationScope, TDepth extends number = 10> = TDepth extends 0 ? TRouter : { [K in keyof TRouter as TRouter[K] extends Procedure<infer Scope, infer _Input, infer _Output, infer _Errors> ? Scope extends TScope ? K : never : TRouter[K] extends AnyProcedureRouter ? keyof ExtractProcedureByScope<TRouter[K], TScope, RouterDepthTuple[TDepth]> extends never ? never : K : never]: TRouter[K] extends AnyProcedure ? TRouter[K] : TRouter[K] extends AnyProcedureRouter ? ExtractProcedureByScope<TRouter[K], TScope, RouterDepthTuple[TDepth]> : never };
|
|
17
|
+
interface MiddlewareResult<TOutContext extends AnyContext, TOutput> {
|
|
18
|
+
output: TOutput;
|
|
19
|
+
context: TOutContext;
|
|
20
|
+
}
|
|
21
|
+
type MiddlewareNextFn<TOutput> = {
|
|
22
|
+
(): Promise<MiddlewareResult<AnyContext, TOutput>>;
|
|
23
|
+
<UOutContext extends AnyContext>(options: {
|
|
24
|
+
context: UOutContext;
|
|
25
|
+
}): Promise<MiddlewareResult<UOutContext, TOutput>>;
|
|
26
|
+
};
|
|
27
|
+
type MiddlewareOptions<TInput, TOutput, TError extends DefinedErrorMapLike> = {
|
|
28
|
+
input: TInput;
|
|
29
|
+
context: ServerContext;
|
|
30
|
+
next: MiddlewareNextFn<TOutput>;
|
|
31
|
+
errors: ThrowableErrorMap<TError>;
|
|
32
|
+
};
|
|
33
|
+
type MiddlewareHandler<TInput, TOutput, TError extends DefinedErrorMapLike, TOutContext extends AnyContext> = (options: MiddlewareOptions<TInput, TOutput, TError>) => Promise<MiddlewareResult<TOutContext, TOutput>>;
|
|
34
|
+
type Middleware<TInput, TOutput, TError extends DefinedErrorMapLike = DefinedErrorMapLike, TOutContext extends AnyContext = AnyContext> = MiddlewareHandler<TInput, TOutput, TError, TOutContext>;
|
|
35
|
+
type AnyMiddleware = Middleware<any, any, any, any>;
|
|
36
|
+
type ExtractMiddlewareContextOutput<M> = M extends Middleware<infer TOut, any, any, any> ? TOut : never;
|
|
37
|
+
declare function createMiddleware<TInput = any, TOutput = any, TError extends DefinedErrorMapLike = DefinedErrorMapLike, TOutContext extends AnyContext = AnyContext>(handler: MiddlewareHandler<TInput, TOutput, TError, TOutContext>): Middleware<TInput, TOutput, TError, TOutContext>;
|
|
38
|
+
type InvocationScope = "internal" | "remote" | "api";
|
|
39
|
+
type ProcedureHandler<TInput, TOutput, TError extends DefinedErrorMapLike, TContext extends ServerContext> = (ctx: {
|
|
40
|
+
input: TInput;
|
|
41
|
+
context: TContext;
|
|
42
|
+
errors: ThrowableErrorMap<WithCommonErrorMap<TError>>;
|
|
43
|
+
}) => Promisify<TOutput>;
|
|
44
|
+
interface Procedure<TScope extends InvocationScope, TInput, TOutput, TError extends DefinedErrorMapLike = DefinedErrorMapLike> {
|
|
45
|
+
"~kizlo": {
|
|
46
|
+
uses: AnyMiddleware[];
|
|
47
|
+
handler: ProcedureHandler<TInput, TOutput, TError, ServerContext>;
|
|
48
|
+
options: {
|
|
49
|
+
scope: TScope;
|
|
50
|
+
errors?: TError;
|
|
51
|
+
output: AnySchema;
|
|
52
|
+
inputValidation?: boolean;
|
|
53
|
+
outputValidation?: boolean;
|
|
54
|
+
middlewares?: AnyMiddleware[];
|
|
55
|
+
} & ({
|
|
56
|
+
scope: "internal";
|
|
57
|
+
input?: AnySchema;
|
|
58
|
+
} | {
|
|
59
|
+
scope: "remote";
|
|
60
|
+
input?: AnySchema;
|
|
61
|
+
method?: HTTPMethod;
|
|
62
|
+
} | {
|
|
63
|
+
scope: "api";
|
|
64
|
+
method?: HTTPMethod;
|
|
65
|
+
path?: Pathname;
|
|
66
|
+
body?: AnySchema;
|
|
67
|
+
query?: AnySchema;
|
|
68
|
+
params?: AnySchema;
|
|
69
|
+
headers?: AnySchema;
|
|
70
|
+
});
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
type AnyProcedure = Procedure<InvocationScope, any, any, any>;
|
|
74
|
+
type ProcedureContext<TMiddlewares extends AnyMiddleware[]> = ServerContext & InferUses<TMiddlewares>;
|
|
75
|
+
type SchemaIO<TSchema, TMap extends "output" | "input"> = TMap extends "output" ? SchemaOutput<TSchema> : SchemaInput<TSchema>;
|
|
76
|
+
type OpenapiPart<TKey extends string, TSchema, TMap extends "output" | "input"> = [TSchema] extends [never] ? unknown : [TSchema] extends [Schema] ? undefined extends SchemaIO<TSchema, TMap> ? { [K in TKey]?: SchemaIO<TSchema, TMap> } : { [K in TKey]: SchemaIO<TSchema, TMap> } : unknown;
|
|
77
|
+
type ExtractParams<T extends string> = T extends `${string}{${infer Param}}${infer Rest}` ? { [K in Param | keyof ExtractParams<Rest>]: string } : object;
|
|
78
|
+
type ResolveParamsPart<TPathname, TParams, TMap extends "output" | "input"> = [TPathname] extends [never] ? OpenapiPart<"params", TParams, TMap> : TPathname extends string ? ExtractParams<TPathname> extends infer TPath extends object ? keyof TPath extends never ? OpenapiPart<"params", TParams, TMap> : [TParams] extends [never] ? {
|
|
79
|
+
params: TPath;
|
|
80
|
+
} : [TParams] extends [Schema] ? {
|
|
81
|
+
params: DeepMerge<TPath, TMap extends "output" ? SchemaOutput<TParams> : SchemaInput<TParams>>;
|
|
82
|
+
} : {
|
|
83
|
+
params: TPath;
|
|
84
|
+
} : OpenapiPart<"params", TParams, TMap> : OpenapiPart<"params", TParams, TMap>;
|
|
85
|
+
type ResolveOpenapi<TPathname, TBody, TParams, TQuery, THeaders, TMap extends "output" | "input"> = OpenapiPart<"body", TBody, TMap> & ResolveParamsPart<TPathname, TParams, TMap> & OpenapiPart<"query", TQuery, TMap> & OpenapiPart<"headers", THeaders, TMap>;
|
|
86
|
+
type ResolvedSchemaOutput<TScope, TPathname, TInput, TBody, TParams, TQuery, THeaders> = Prettify<TScope extends "api" ? ResolveOpenapi<TPathname, TBody, TParams, TQuery, THeaders, "output"> : [TInput] extends [Schema] ? SchemaOutput<TInput> : unknown>;
|
|
87
|
+
type ResolvedSchemaInput<TScope, TPathname, TInput, TBody, TParams, TQuery, THeaders> = Prettify<TScope extends "api" ? ResolveOpenapi<TPathname, TBody, TParams, TQuery, THeaders, "input"> : [TInput] extends [Schema] ? SchemaInput<TInput> : unknown>;
|
|
88
|
+
type ProcedureOptions<TScope extends InvocationScope, TPathname extends Pathname, TInput extends Schema | undefined, TBody extends Schema | undefined, TParams extends Schema | undefined, TQuery extends Schema | undefined, THeaders extends Schema | undefined, TOutput extends Schema, TError extends DefinedErrorMapLike, TMiddlewares extends Middleware<ResolvedSchemaOutput<TScope, TPathname, TInput, TBody, TParams, TQuery, THeaders>, SchemaOutput<TOutput>, TError>[]> = {
|
|
89
|
+
scope: TScope;
|
|
90
|
+
errors?: TError;
|
|
91
|
+
output: TOutput;
|
|
92
|
+
middlewares?: TMiddlewares;
|
|
93
|
+
inputValidation?: boolean;
|
|
94
|
+
outputValidation?: boolean;
|
|
95
|
+
} & (TScope extends "api" ? {
|
|
96
|
+
method?: HTTPMethod;
|
|
97
|
+
path?: TPathname;
|
|
98
|
+
body?: TBody;
|
|
99
|
+
query?: TQuery;
|
|
100
|
+
params?: TParams;
|
|
101
|
+
headers?: THeaders;
|
|
102
|
+
} : TScope extends "remote" ? {
|
|
103
|
+
input?: TInput;
|
|
104
|
+
method?: HTTPMethod;
|
|
105
|
+
} : {
|
|
106
|
+
input?: TInput;
|
|
107
|
+
});
|
|
108
|
+
declare function createProcedure<TScope extends InvocationScope, TPathname extends Pathname, TInput extends Schema | undefined = undefined, TBody extends Schema | undefined = undefined, TParams extends Schema | undefined = undefined, TQuery extends Schema | undefined = undefined, THeaders extends Schema | undefined = undefined, TOutput extends Schema = Schema, TError extends DefinedErrorMapLike = DefinedErrorMapLike, TMiddlewares extends Middleware<ResolvedSchemaOutput<TScope, TPathname, TInput, TBody, TParams, TQuery, THeaders>, SchemaOutput<TOutput>, TError>[] = Middleware<ResolvedSchemaOutput<TScope, TPathname, TInput, TBody, TParams, TQuery, THeaders>, SchemaOutput<TOutput>, TError>[], TContext extends ProcedureContext<TMiddlewares> = ProcedureContext<TMiddlewares>>(options: ProcedureOptions<TScope, TPathname, TInput, TBody, TParams, TQuery, THeaders, TOutput, TError, TMiddlewares>, handler: ProcedureHandler<ResolvedSchemaOutput<TScope, TPathname, TInput, TBody, TParams, TQuery, THeaders>, SchemaOutput<TOutput>, TError, TContext>): Procedure<TScope, ResolvedSchemaInput<TScope, TPathname, TInput, TBody, TParams, TQuery, THeaders>, TScope extends "api" ? JsonifiedValue<SchemaOutput<TOutput>> : SchemaOutput<TOutput>, TError>;
|
|
109
|
+
declare function schemaType<TInput, TOutput = TInput>(schema?: AnySchema): Schema<TInput, TOutput>;
|
|
110
|
+
declare function buildProcedure(procedure: AnyProcedure): _orpc_server0.DecoratedProcedure<_orpc_server0.Context & Record<never, never>, _orpc_server0.Context, _orpc_contract0.Schema<unknown, unknown>, _orpc_contract0.Schema<any, any>, Record<never, never>, Record<never, never>>;
|
|
111
|
+
declare function handleUnexpectedError(error: unknown, errors?: DefinedErrorMapLike): never;
|
|
112
|
+
declare function combineDetailed(parts: Record<string, AnySchema>): AnySchema;
|
|
113
|
+
//#endregion
|
|
114
|
+
export { AnyMiddleware, AnyProcedure, AnyProcedureRouter, ExtractMiddlewareContextOutput, ExtractParams, ExtractProcedureByScope, InvocationScope, Middleware, MiddlewareHandler, MiddlewareNextFn, MiddlewareOptions, MiddlewareResult, OpenapiPart, Procedure, ProcedureContext, ProcedureHandler, ProcedureOptions, ResolveParamsPart, ResolvedSchemaInput, ResolvedSchemaOutput, RouterDepthTuple, SchemaIO, buildProcedure, combineDetailed, createMiddleware, createProcedure, handleUnexpectedError, schemaType };
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { COMMON_ERRORS, KizloError, createThrowableErrorMap, isKizloError } from "./error.js";
|
|
2
|
+
import { os } from "@orpc/server";
|
|
3
|
+
|
|
4
|
+
//#region src/shared/procedure.ts
|
|
5
|
+
function createMiddleware(handler) {
|
|
6
|
+
return handler;
|
|
7
|
+
}
|
|
8
|
+
function createProcedure(options, handler) {
|
|
9
|
+
return { "~kizlo": {
|
|
10
|
+
options,
|
|
11
|
+
uses: options.middlewares ?? [],
|
|
12
|
+
handler: (ctx) => handler(ctx)
|
|
13
|
+
} };
|
|
14
|
+
}
|
|
15
|
+
function schemaType(schema) {
|
|
16
|
+
return schema ?? { "~standard": {
|
|
17
|
+
vendor: "custom",
|
|
18
|
+
version: 1,
|
|
19
|
+
async validate(value) {
|
|
20
|
+
return { value };
|
|
21
|
+
}
|
|
22
|
+
} };
|
|
23
|
+
}
|
|
24
|
+
function buildProcedure(procedure) {
|
|
25
|
+
const { handler, options, uses } = procedure["~kizlo"];
|
|
26
|
+
const errors = createThrowableErrorMap(options.errors ?? {});
|
|
27
|
+
const builder = os.$context().$config({
|
|
28
|
+
initialInputValidationIndex: options.inputValidation ?? true ? void 0 : NaN,
|
|
29
|
+
initialOutputValidationIndex: options.outputValidation ?? false ? void 0 : NaN
|
|
30
|
+
});
|
|
31
|
+
let chain = builder.meta({ scope: options.scope });
|
|
32
|
+
for (const middleware of uses) chain = chain.use(builder.middleware(async ({ next, context }, input) => {
|
|
33
|
+
try {
|
|
34
|
+
return await middleware({
|
|
35
|
+
input,
|
|
36
|
+
next,
|
|
37
|
+
context,
|
|
38
|
+
errors
|
|
39
|
+
});
|
|
40
|
+
} catch (error) {
|
|
41
|
+
handleUnexpectedError(error, options.errors);
|
|
42
|
+
}
|
|
43
|
+
}));
|
|
44
|
+
switch (options.scope) {
|
|
45
|
+
case "internal":
|
|
46
|
+
if (options.input) chain = chain.input(options.input);
|
|
47
|
+
break;
|
|
48
|
+
case "remote":
|
|
49
|
+
chain = chain.route({ method: options.method });
|
|
50
|
+
if (options.input) chain = chain.input(options.input);
|
|
51
|
+
break;
|
|
52
|
+
case "api": {
|
|
53
|
+
chain = chain.route({
|
|
54
|
+
path: options.path,
|
|
55
|
+
method: options.method,
|
|
56
|
+
inputStructure: "detailed"
|
|
57
|
+
});
|
|
58
|
+
const shape = {};
|
|
59
|
+
if (options.params) shape.params = options.params;
|
|
60
|
+
if (options.query) shape.query = options.query;
|
|
61
|
+
if (options.headers) shape.headers = options.headers;
|
|
62
|
+
if (options.body) shape.body = options.body;
|
|
63
|
+
if (Object.keys(shape).length > 0) chain = chain.input(combineDetailed(shape));
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (options.output) chain = chain.output(options.output);
|
|
68
|
+
return chain.handler(async ({ context, input }) => {
|
|
69
|
+
try {
|
|
70
|
+
return await handler({
|
|
71
|
+
context,
|
|
72
|
+
input,
|
|
73
|
+
errors
|
|
74
|
+
});
|
|
75
|
+
} catch (error) {
|
|
76
|
+
handleUnexpectedError(error, options.errors);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
function handleUnexpectedError(error, errors) {
|
|
81
|
+
const definedErrorMap = {
|
|
82
|
+
...COMMON_ERRORS,
|
|
83
|
+
...errors
|
|
84
|
+
};
|
|
85
|
+
if (isKizloError(error)) {
|
|
86
|
+
if (!definedErrorMap[error.code]) throw new KizloError("UNEXPECTED_ERROR", { cause: error });
|
|
87
|
+
}
|
|
88
|
+
throw error;
|
|
89
|
+
}
|
|
90
|
+
function combineDetailed(parts) {
|
|
91
|
+
return { "~standard": {
|
|
92
|
+
version: 1,
|
|
93
|
+
vendor: "kizlo",
|
|
94
|
+
validate: async (value) => {
|
|
95
|
+
if (typeof value !== "object" || value === null) return { issues: [{ message: "Expected object" }] };
|
|
96
|
+
const input = value;
|
|
97
|
+
const result = {};
|
|
98
|
+
const issues = [];
|
|
99
|
+
for (const [key, schema] of Object.entries(parts)) {
|
|
100
|
+
let r = schema["~standard"].validate(input[key]);
|
|
101
|
+
if (r instanceof Promise) r = await r;
|
|
102
|
+
if (r.issues) for (const issue of r.issues) issues.push({
|
|
103
|
+
...issue,
|
|
104
|
+
path: [key, ...issue.path ?? []]
|
|
105
|
+
});
|
|
106
|
+
else result[key] = r.value;
|
|
107
|
+
}
|
|
108
|
+
return issues.length ? { issues } : { value: result };
|
|
109
|
+
}
|
|
110
|
+
} };
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
//#endregion
|
|
114
|
+
export { buildProcedure, combineDetailed, createMiddleware, createProcedure, handleUnexpectedError, schemaType };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { DefinedErrorMapLike, KizloError, WithCommonErrorMap } from "./error.js";
|
|
2
|
+
import { AnyProcedureRouter, Procedure } from "./procedure.js";
|
|
3
|
+
import { NestedClient } from "@orpc/client";
|
|
4
|
+
import { SchemaOutput } from "@kizlo/shared";
|
|
5
|
+
|
|
6
|
+
//#region src/shared/result.d.ts
|
|
7
|
+
type MaybeCallerOptions<UInput> = unknown extends UInput ? [] : [UInput] extends [undefined] ? [] : object extends UInput ? [input?: UInput] : [input: UInput];
|
|
8
|
+
type ProcedureMethod<UInput, UOutput, TError extends DefinedErrorMapLike> = {
|
|
9
|
+
(...rest: MaybeCallerOptions<UInput>): Promise<KizloResult<UOutput, TError>>;
|
|
10
|
+
call: (...rest: MaybeCallerOptions<UInput>) => Promise<UOutput>;
|
|
11
|
+
};
|
|
12
|
+
type KizloErrorUnion<TErrors extends DefinedErrorMapLike> = { [K in Extract<keyof TErrors, string>]: KizloError<K, SchemaOutput<TErrors[K]["data"]>> }[Extract<keyof TErrors, string>];
|
|
13
|
+
type KizloResult<TOutput, TErrors extends DefinedErrorMapLike = DefinedErrorMapLike> = {
|
|
14
|
+
data: TOutput;
|
|
15
|
+
error: null;
|
|
16
|
+
success: true;
|
|
17
|
+
} | {
|
|
18
|
+
data: undefined;
|
|
19
|
+
error: KizloErrorUnion<WithCommonErrorMap<TErrors>>;
|
|
20
|
+
success: false;
|
|
21
|
+
};
|
|
22
|
+
type ResultClient<T extends AnyProcedureRouter> = { [K in keyof T]: T[K] extends Procedure<infer _Scope, infer Input, infer Output, infer Errors> ? ProcedureMethod<Input, Output, Errors> : T[K] extends AnyProcedureRouter ? ResultClient<T[K]> : never };
|
|
23
|
+
//#endregion
|
|
24
|
+
export { ResultClient };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { toKizloError } from "./error.js";
|
|
2
|
+
|
|
3
|
+
//#region src/shared/result.ts
|
|
4
|
+
function createResultClient(client) {
|
|
5
|
+
const cache = /* @__PURE__ */ new Map();
|
|
6
|
+
return new Proxy(typeof client === "function" ? client : () => {}, {
|
|
7
|
+
async apply(_, __, args) {
|
|
8
|
+
if (typeof client !== "function") throw new Error("This client node is not callable");
|
|
9
|
+
try {
|
|
10
|
+
return {
|
|
11
|
+
data: await client(...args),
|
|
12
|
+
error: null,
|
|
13
|
+
success: true
|
|
14
|
+
};
|
|
15
|
+
} catch (e) {
|
|
16
|
+
return {
|
|
17
|
+
data: void 0,
|
|
18
|
+
error: toKizloError(e),
|
|
19
|
+
success: false
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
get(_, prop, receiver) {
|
|
24
|
+
if (cache.has(prop)) return cache.get(prop);
|
|
25
|
+
if (prop === "call" && typeof client === "function") {
|
|
26
|
+
const unsafe = async (...args) => {
|
|
27
|
+
try {
|
|
28
|
+
return await client(...args);
|
|
29
|
+
} catch (e) {
|
|
30
|
+
throw toKizloError(e);
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
cache.set(prop, unsafe);
|
|
34
|
+
return unsafe;
|
|
35
|
+
}
|
|
36
|
+
const value = Reflect.get(client, prop, receiver);
|
|
37
|
+
if (typeof prop !== "string" || !isRecordLike(value)) return value;
|
|
38
|
+
const wrapped = createResultClient(value);
|
|
39
|
+
cache.set(prop, wrapped);
|
|
40
|
+
return wrapped;
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
function isRecordLike(value) {
|
|
45
|
+
return !!value && (typeof value === "object" || typeof value === "function");
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
//#endregion
|
|
49
|
+
export { createResultClient };
|