@kunk/server 3.0.2 → 3.0.5

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.
@@ -0,0 +1,520 @@
1
+ import { ContextData, ContextData as ContextData$1, Generator, Generator as Generator$1, I, I as I$1, ICommand, ICommand as ICommand$1, IError, IThrowable, Logger, Logger as Logger$1, StandardSchemaV1, StandardSchemaV1 as StandardSchemaV1$1, Validator } from "@kunk/api";
2
+ import { InferInsertModel, InferSelectModel, SQL, Table } from "drizzle-orm";
3
+ import pino from "pino";
4
+ import * as DrizzleQuery from "drizzle-orm/sql/expressions";
5
+ import { BindToFluentSyntax, Container, Container as IContainer, ServiceIdentifier as IService } from "inversify";
6
+ import * as elysia from "elysia";
7
+ import Elysia from "elysia";
8
+ import { StandardSchemaV1 as StandardSchemaV1$2 } from "@standard-schema/spec";
9
+ import { IndexColumn, PgColumn } from "drizzle-orm/pg-core";
10
+ import * as elysia_types0 from "elysia/types";
11
+ import * as elysia_universal_server0 from "elysia/universal/server";
12
+ import * as elysia_cookies0 from "elysia/cookies";
13
+
14
+ //#region src/utils/config.d.ts
15
+ declare class Config<T extends StandardSchemaV1$2> {
16
+ private readonly schema;
17
+ private values;
18
+ private constructor();
19
+ get(): I$1.Output<T>;
20
+ set(values: I$1.Input<T>): Promise<void>;
21
+ static create<T extends StandardSchemaV1$2>(options: {
22
+ name: string;
23
+ schema: T;
24
+ }): Promise<Config<T>>;
25
+ static set<T extends StandardSchemaV1$2>(config: Config<T>, values: I$1.Input<T>): void;
26
+ }
27
+ //#endregion
28
+ //#region src/configs/DatabaseConfig.d.ts
29
+ declare const DatabaseConfig: Config<any>;
30
+ //#endregion
31
+ //#region src/contracts/Auth.d.ts
32
+ declare abstract class Auth {
33
+ abstract getSession(): Promise<Auth.Session>;
34
+ abstract signInEmail(data: Auth.SignInEmail.Input): Promise<Auth.SignInEmail.Output>;
35
+ abstract signOut(): Promise<void>;
36
+ abstract signUpEmail(data: Auth.SignUpEmail.Input): Promise<Auth.SignUpEmail.Output>;
37
+ }
38
+ declare namespace Auth {
39
+ type User = {
40
+ id: string;
41
+ email: string;
42
+ name: string;
43
+ image: string | null | undefined;
44
+ emailVerified: boolean;
45
+ createdAt: Date;
46
+ updatedAt: Date;
47
+ };
48
+ type Session = {
49
+ redirect: boolean;
50
+ token: string;
51
+ url: string | undefined;
52
+ user: User;
53
+ };
54
+ type SignUpEmailResponse = {
55
+ redirect: boolean;
56
+ token: string;
57
+ url: string | undefined;
58
+ user: User;
59
+ };
60
+ namespace SignUpEmail {
61
+ type Input = {
62
+ email: string;
63
+ password: string;
64
+ name: string;
65
+ rememberMe?: boolean;
66
+ callbackURL?: string;
67
+ image?: string;
68
+ };
69
+ type Output = {
70
+ token: string | null;
71
+ user: User;
72
+ };
73
+ }
74
+ namespace SignInEmail {
75
+ type Input = {
76
+ email: string;
77
+ password: string;
78
+ };
79
+ type Output = {
80
+ redirect: boolean;
81
+ token: string;
82
+ url: string | undefined;
83
+ user: User;
84
+ };
85
+ }
86
+ }
87
+ //#endregion
88
+ //#region src/contracts/Database.d.ts
89
+ declare abstract class Database {
90
+ abstract commit(): Promise<void>;
91
+ abstract create<T extends Table, V extends InferInsertModel<T> | InferInsertModel<T>[]>(entity: T, values: V): Promise<V extends InferInsertModel<T>[] ? { [K in keyof V]: NonNullable<InferSelectModel<T>> } : NonNullable<InferSelectModel<T>>>;
92
+ abstract update<T extends Table>(entity: T, id: string, values: Partial<InferInsertModel<T>>): Promise<InferSelectModel<T>>;
93
+ abstract upsert<T extends Table>(entity: T, options: {
94
+ target: IndexColumn | IndexColumn[];
95
+ values: InferInsertModel<T>;
96
+ }): Promise<InferSelectModel<T>>;
97
+ abstract delete<T extends Table>(entity: T, id: string): Promise<void>;
98
+ abstract findMany<T extends Table>(entity: T, options?: {
99
+ where?: SQL;
100
+ limit?: number;
101
+ offset?: number;
102
+ orderBy?: (PgColumn | SQL | SQL.Aliased)[];
103
+ }): Promise<InferSelectModel<T>[]>;
104
+ abstract findOne<T extends Table>(entity: T, options?: {
105
+ where?: SQL;
106
+ }): Promise<InferSelectModel<T> | null>;
107
+ abstract get<T extends Table>(entity: T, id: string): Promise<InferSelectModel<T>>;
108
+ }
109
+ //#endregion
110
+ //#region src/contracts/Query.d.ts
111
+ type Query = typeof DrizzleQuery;
112
+ //#endregion
113
+ //#region src/interfaces/IApplication.d.ts
114
+ interface IApplication {
115
+ bind<T>(serviceIdentifier: IService<T>): BindToFluentSyntax<T>;
116
+ }
117
+ //#endregion
118
+ //#region src/interfaces/IContext.d.ts
119
+ type Executor = {
120
+ <T extends Promise<{
121
+ default: ICommand$1<any, any>;
122
+ }>>(command: () => T, input: I$1.Input<Awaited<T>['default']>): Promise<I$1.Output<Awaited<T>['default']>>;
123
+ <IN extends StandardSchemaV1$1, OUT extends StandardSchemaV1$1>(command: ICommand$1<IN, OUT>, input: I$1.Input<IN>): Promise<I$1.Output<OUT>>;
124
+ };
125
+ type Prepare = {
126
+ <T extends Promise<{
127
+ default: ICommand$1<any, any>;
128
+ }>>(command: () => T, input: I$1.Input<Awaited<T>['default']>): {
129
+ input: I$1.Input<Awaited<T>['default']>;
130
+ execute: () => Promise<I$1.Output<Awaited<T>['default']>>;
131
+ };
132
+ <IN extends StandardSchemaV1$1, OUT extends StandardSchemaV1$1>(command: ICommand$1<IN, OUT>, input: I$1.Input<IN>): {
133
+ input: I$1.Input<IN>;
134
+ execute: () => Promise<I$1.Output<OUT>>;
135
+ };
136
+ };
137
+ interface IContext {
138
+ db: Database;
139
+ Q: Query;
140
+ gen: Generator;
141
+ logger: Logger;
142
+ prepare: Prepare;
143
+ execute: Executor;
144
+ get: <T>(serviceIdentifier: IService<T>) => T;
145
+ getAsync: <T>(serviceIdentifier: IService<T>) => Promise<T>;
146
+ }
147
+ //#endregion
148
+ //#region src/interfaces/IContextCommand.d.ts
149
+ interface IContextCommand<IN extends StandardSchemaV1$1 = StandardSchemaV1$1, OUT extends StandardSchemaV1$1 = StandardSchemaV1$1> extends IContext {
150
+ readonly command: ICommand$1<IN, OUT>;
151
+ readonly input: I$1.Output<IN>;
152
+ }
153
+ //#endregion
154
+ //#region src/interfaces/IContextHandler.d.ts
155
+ interface ICommandHandler<IN extends StandardSchemaV1$1, OUT extends StandardSchemaV1$1> {
156
+ (context: IContextCommand<IN, OUT>): Promise<I$1.Output<OUT>>;
157
+ }
158
+ //#endregion
159
+ //#region src/interfaces/IMiddleware.d.ts
160
+ type IMiddleware = (ctx: {
161
+ next: any;
162
+ container: Container;
163
+ }) => any;
164
+ //#endregion
165
+ //#region src/services/BunGenerator.d.ts
166
+ declare class BunGenerator extends Generator$1 {
167
+ get id(): string;
168
+ code(length: number): string;
169
+ }
170
+ //#endregion
171
+ //#region src/services/PinoLogger.d.ts
172
+ declare class PinoLogger implements Logger$1 {
173
+ private logger;
174
+ constructor(logger?: pino.Logger);
175
+ info(message: string): void;
176
+ warn(message: string): void;
177
+ error(error: any): void;
178
+ fork(name: string): Logger$1;
179
+ }
180
+ //#endregion
181
+ //#region src/services/DizzleDatabase.d.ts
182
+ declare class DizzleDatabase extends Database {
183
+ private readonly sql;
184
+ private readonly session;
185
+ private released;
186
+ private constructor();
187
+ static create(sql: Bun.SQL, contextData: ContextData$1): Promise<DizzleDatabase>;
188
+ create<T extends Table, V extends InferInsertModel<T> | InferInsertModel<T>[]>(entity: T, values: V): Promise<V extends InferInsertModel<T>[] ? { [K in keyof V]: NonNullable<InferSelectModel<T>> } : NonNullable<InferSelectModel<T>>>;
189
+ update<T extends Table>(entity: T, id: string, values: Partial<InferInsertModel<T>>): Promise<InferSelectModel<T>>;
190
+ upsert<T extends Table>(entity: T, options: {
191
+ target: IndexColumn | IndexColumn[];
192
+ values: InferInsertModel<T>;
193
+ }): Promise<InferSelectModel<T>>;
194
+ findMany<T extends Table>(entity: T, options?: {
195
+ where?: SQL;
196
+ limit?: number;
197
+ offset?: number;
198
+ orderBy?: (PgColumn | SQL | SQL.Aliased)[];
199
+ }): Promise<InferSelectModel<T>[]>;
200
+ findOne<T extends Table>(entity: T, options?: {
201
+ where?: SQL;
202
+ }): Promise<InferSelectModel<T> | null>;
203
+ get<T extends Table>(entity: T, id: string): Promise<InferSelectModel<T>>;
204
+ delete<T extends Table>(entity: T, id: string): Promise<void>;
205
+ commit(): Promise<void>;
206
+ }
207
+ //#endregion
208
+ //#region src/utils/SERVER_ERROR.d.ts
209
+ declare namespace SERVER_ERROR {
210
+ function RESOURCE_ID_NOT_FOUND(resource: string, id: string): any;
211
+ function RESOURCE_NOT_FOUND(resource: string): any;
212
+ function BAD_REQUEST(type: string, args: Record<string, any>): any;
213
+ function RESOURCE_ID_ALREADY_EXISTS(resource: string, id: string): any;
214
+ function VALIDATION(...issues: IThrowable[]): any;
215
+ function SCHEMA_VALIDATION(issues: readonly StandardSchemaV1$2.Issue[]): any;
216
+ function UNEXPECTED(type: string, args: Record<string, any>): any;
217
+ const FORWARD: any;
218
+ function GET_ENTITY_NOT_FOUND<T extends Table>(entity: T, id: string): any;
219
+ }
220
+ //#endregion
221
+ //#region src/context.d.ts
222
+ declare class Context implements IContext {
223
+ private readonly container;
224
+ readonly db: Database;
225
+ readonly gen: Generator;
226
+ readonly logger: Logger;
227
+ constructor(container: IContainer, db: Database);
228
+ static create(contextData?: ContextData): Promise<Context>;
229
+ readonly Q: typeof DrizzleQuery;
230
+ execute: IContext["execute"];
231
+ prepare: IContext["prepare"];
232
+ get: <T>(service: IService<T>) => T;
233
+ getAsync: <T>(service: IService<T>) => Promise<T>;
234
+ [Symbol.dispose]: () => Promise<void>;
235
+ }
236
+ //#endregion
237
+ //#region src/command.d.ts
238
+ declare class Command<IN extends StandardSchemaV1, OUT extends StandardSchemaV1> implements ICommand<IN, OUT> {
239
+ readonly name: string;
240
+ readonly visibility: "PUBLIC" | "PROTECTED" | "PRIVATE";
241
+ input: IN;
242
+ output: OUT;
243
+ middlewares: IMiddleware[];
244
+ handler: ICommandHandler<IN, OUT>;
245
+ readonly "~type": "kunk:command";
246
+ private constructor();
247
+ private static create;
248
+ static PUBLIC: <IN_1 extends StandardSchemaV1 = StandardSchemaV1, OUT_1 extends StandardSchemaV1 = StandardSchemaV1>(setup: {
249
+ name: string;
250
+ input: IN_1;
251
+ output: OUT_1;
252
+ middlewares?: IMiddleware[];
253
+ }, handler: ICommandHandler<IN_1, OUT_1>) => Command<IN_1, OUT_1>;
254
+ static PROTECTED: <IN_1 extends StandardSchemaV1 = StandardSchemaV1, OUT_1 extends StandardSchemaV1 = StandardSchemaV1>(setup: {
255
+ name: string;
256
+ input: IN_1;
257
+ output: OUT_1;
258
+ middlewares?: IMiddleware[];
259
+ }, handler: ICommandHandler<IN_1, OUT_1>) => Command<IN_1, OUT_1>;
260
+ static PRIVATE: <IN_1 extends StandardSchemaV1 = StandardSchemaV1, OUT_1 extends StandardSchemaV1 = StandardSchemaV1>(setup: {
261
+ name: string;
262
+ input: IN_1;
263
+ output: OUT_1;
264
+ middlewares?: IMiddleware[];
265
+ }, handler: ICommandHandler<IN_1, OUT_1>) => Command<IN_1, OUT_1>;
266
+ internalCall(context: IContextCommand<IN, OUT>): Promise<I.Output<OUT>>;
267
+ call(context: IContextCommand<IN, OUT>): Promise<I.Output<OUT>>;
268
+ }
269
+ //#endregion
270
+ //#region src/middleware.d.ts
271
+ declare function middleware<T extends (...args: any[]) => any>(fn: T, middlewares: IMiddleware[]): T;
272
+ //#endregion
273
+ //#region src/server.d.ts
274
+ declare const Server: Elysia<"", {
275
+ decorator: {};
276
+ store: {};
277
+ derive: {};
278
+ resolve: {};
279
+ }, {
280
+ typebox: {};
281
+ error: {};
282
+ } & {
283
+ typebox: {};
284
+ error: {};
285
+ }, {
286
+ schema: {};
287
+ standaloneSchema: {};
288
+ macro: {};
289
+ macroFn: {};
290
+ parser: {};
291
+ response: {};
292
+ } & {
293
+ schema: {};
294
+ standaloneSchema: {};
295
+ macro: {};
296
+ macroFn: {};
297
+ parser: {};
298
+ response: {};
299
+ }, {}, {
300
+ derive: {};
301
+ resolve: {};
302
+ schema: {};
303
+ standaloneSchema: {};
304
+ response: {};
305
+ }, {
306
+ derive: {};
307
+ resolve: {};
308
+ schema: {};
309
+ standaloneSchema: {};
310
+ response: {
311
+ 200: Response;
312
+ };
313
+ }>;
314
+ declare function route<K extends string, CMD extends ICommand<any, any>>(path: K, commandImport: Promise<{
315
+ default: CMD;
316
+ }>): Promise<Elysia<"", {
317
+ decorator: {};
318
+ store: {};
319
+ derive: {};
320
+ resolve: {};
321
+ }, {
322
+ typebox: {};
323
+ error: {};
324
+ }, {
325
+ schema: {};
326
+ standaloneSchema: {};
327
+ macro: {};
328
+ macroFn: {};
329
+ parser: {};
330
+ response: {};
331
+ }, {} & elysia.CreateEden<elysia_types0.JoinPath<"", K>, {
332
+ post: {
333
+ body: elysia_types0.IntersectIfObject<elysia.UnwrapBodySchema<CMD["input"], {}>, unknown>;
334
+ params: elysia_types0.IsNever<keyof elysia_types0.IntersectIfObject<elysia.ResolvePath<elysia_types0.JoinPath<"", K>>, unknown>> extends true ? elysia.ResolvePath<K> : elysia_types0.IntersectIfObject<elysia.ResolvePath<elysia_types0.JoinPath<"", K>>, unknown>;
335
+ query: unknown;
336
+ headers: any;
337
+ response: elysia.ComposeElysiaResponse<elysia_types0.IntersectIfObjectSchema<elysia.UnwrapRoute<{
338
+ body: CMD["input"];
339
+ response: CMD["output"];
340
+ headers: any;
341
+ detail: {
342
+ summary: string;
343
+ };
344
+ tags: string[];
345
+ }, {}, elysia_types0.JoinPath<"", K>>, {}>, ({
346
+ headers,
347
+ body
348
+ }: {
349
+ body: elysia_types0.IntersectIfObject<elysia.UnwrapBodySchema<CMD["input"], {}>, unknown> extends infer T_1 ? T_1 extends elysia_types0.IntersectIfObject<elysia.UnwrapBodySchema<CMD["input"], {}>, unknown> ? T_1 extends object ? { [K_2 in keyof T_1]: T_1[K_2] } : T_1 : never : never;
350
+ query: Record<string, string>;
351
+ params: undefined extends elysia_types0.IntersectIfObject<elysia.ResolvePath<elysia_types0.JoinPath<"", K>>, unknown> ? Record<string, string> : elysia_types0.IntersectIfObject<elysia.ResolvePath<elysia_types0.JoinPath<"", K>>, unknown> extends infer T_2 ? T_2 extends elysia_types0.IntersectIfObject<elysia.ResolvePath<elysia_types0.JoinPath<"", K>>, unknown> ? T_2 extends object ? { [K_3 in keyof T_2]: T_2[K_3] } : T_2 : never : never;
352
+ headers: any;
353
+ cookie: Record<string, elysia.Cookie<unknown>>;
354
+ server: elysia_universal_server0.Server | null;
355
+ redirect: elysia.redirect;
356
+ set: {
357
+ headers: elysia.HTTPHeaders;
358
+ status?: number | keyof elysia.StatusMap;
359
+ redirect?: string;
360
+ cookie?: Record<string, elysia_cookies0.ElysiaCookie>;
361
+ };
362
+ path: string;
363
+ route: string;
364
+ request: Request;
365
+ store: {};
366
+ status: {} extends elysia_types0.IntersectIfObject<CMD["output"] extends string | elysia_types0.FastAnySchema ? {
367
+ 200: elysia.UnwrapSchema<CMD["output"], {}> extends infer A ? A extends File ? elysia.ElysiaFile | File : A : unknown;
368
+ } : CMD["output"] extends {
369
+ [x: number]: string | elysia_types0.FastAnySchema;
370
+ } ? { [k in keyof CMD["output"]]: elysia.UnwrapSchema<CMD["output"][k], {}> extends infer A_1 ? A_1 extends File ? elysia.ElysiaFile | File : A_1 : unknown } : unknown, unknown> ? <const Code extends number | keyof elysia.StatusMap, const T_3 = (Code extends 100 | 101 | 102 | 103 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 300 | 301 | 302 | 303 | 304 | 307 | 308 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 428 | 429 | 431 | 451 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 510 | 511 ? {
371
+ readonly 100: "Continue";
372
+ readonly 101: "Switching Protocols";
373
+ readonly 102: "Processing";
374
+ readonly 103: "Early Hints";
375
+ readonly 200: "OK";
376
+ readonly 201: "Created";
377
+ readonly 202: "Accepted";
378
+ readonly 203: "Non-Authoritative Information";
379
+ readonly 204: "No Content";
380
+ readonly 205: "Reset Content";
381
+ readonly 206: "Partial Content";
382
+ readonly 207: "Multi-Status";
383
+ readonly 208: "Already Reported";
384
+ readonly 300: "Multiple Choices";
385
+ readonly 301: "Moved Permanently";
386
+ readonly 302: "Found";
387
+ readonly 303: "See Other";
388
+ readonly 304: "Not Modified";
389
+ readonly 307: "Temporary Redirect";
390
+ readonly 308: "Permanent Redirect";
391
+ readonly 400: "Bad Request";
392
+ readonly 401: "Unauthorized";
393
+ readonly 402: "Payment Required";
394
+ readonly 403: "Forbidden";
395
+ readonly 404: "Not Found";
396
+ readonly 405: "Method Not Allowed";
397
+ readonly 406: "Not Acceptable";
398
+ readonly 407: "Proxy Authentication Required";
399
+ readonly 408: "Request Timeout";
400
+ readonly 409: "Conflict";
401
+ readonly 410: "Gone";
402
+ readonly 411: "Length Required";
403
+ readonly 412: "Precondition Failed";
404
+ readonly 413: "Payload Too Large";
405
+ readonly 414: "URI Too Long";
406
+ readonly 415: "Unsupported Media Type";
407
+ readonly 416: "Range Not Satisfiable";
408
+ readonly 417: "Expectation Failed";
409
+ readonly 418: "I'm a teapot";
410
+ readonly 420: "Enhance Your Calm";
411
+ readonly 421: "Misdirected Request";
412
+ readonly 422: "Unprocessable Content";
413
+ readonly 423: "Locked";
414
+ readonly 424: "Failed Dependency";
415
+ readonly 425: "Too Early";
416
+ readonly 426: "Upgrade Required";
417
+ readonly 428: "Precondition Required";
418
+ readonly 429: "Too Many Requests";
419
+ readonly 431: "Request Header Fields Too Large";
420
+ readonly 451: "Unavailable For Legal Reasons";
421
+ readonly 500: "Internal Server Error";
422
+ readonly 501: "Not Implemented";
423
+ readonly 502: "Bad Gateway";
424
+ readonly 503: "Service Unavailable";
425
+ readonly 504: "Gateway Timeout";
426
+ readonly 505: "HTTP Version Not Supported";
427
+ readonly 506: "Variant Also Negotiates";
428
+ readonly 507: "Insufficient Storage";
429
+ readonly 508: "Loop Detected";
430
+ readonly 510: "Not Extended";
431
+ readonly 511: "Network Authentication Required";
432
+ }[Code] : Code)>(code: Code, response?: T_3) => elysia.ElysiaCustomStatusResponse<Code, T_3, Code extends "Continue" | "Switching Protocols" | "Processing" | "Early Hints" | "OK" | "Created" | "Accepted" | "Non-Authoritative Information" | "No Content" | "Reset Content" | "Partial Content" | "Multi-Status" | "Already Reported" | "Multiple Choices" | "Moved Permanently" | "Found" | "See Other" | "Not Modified" | "Temporary Redirect" | "Permanent Redirect" | "Bad Request" | "Unauthorized" | "Payment Required" | "Forbidden" | "Not Found" | "Method Not Allowed" | "Not Acceptable" | "Proxy Authentication Required" | "Request Timeout" | "Conflict" | "Gone" | "Length Required" | "Precondition Failed" | "Payload Too Large" | "URI Too Long" | "Unsupported Media Type" | "Range Not Satisfiable" | "Expectation Failed" | "I'm a teapot" | "Enhance Your Calm" | "Misdirected Request" | "Unprocessable Content" | "Locked" | "Failed Dependency" | "Too Early" | "Upgrade Required" | "Precondition Required" | "Too Many Requests" | "Request Header Fields Too Large" | "Unavailable For Legal Reasons" | "Internal Server Error" | "Not Implemented" | "Bad Gateway" | "Service Unavailable" | "Gateway Timeout" | "HTTP Version Not Supported" | "Variant Also Negotiates" | "Insufficient Storage" | "Loop Detected" | "Not Extended" | "Network Authentication Required" ? {
433
+ readonly Continue: 100;
434
+ readonly "Switching Protocols": 101;
435
+ readonly Processing: 102;
436
+ readonly "Early Hints": 103;
437
+ readonly OK: 200;
438
+ readonly Created: 201;
439
+ readonly Accepted: 202;
440
+ readonly "Non-Authoritative Information": 203;
441
+ readonly "No Content": 204;
442
+ readonly "Reset Content": 205;
443
+ readonly "Partial Content": 206;
444
+ readonly "Multi-Status": 207;
445
+ readonly "Already Reported": 208;
446
+ readonly "Multiple Choices": 300;
447
+ readonly "Moved Permanently": 301;
448
+ readonly Found: 302;
449
+ readonly "See Other": 303;
450
+ readonly "Not Modified": 304;
451
+ readonly "Temporary Redirect": 307;
452
+ readonly "Permanent Redirect": 308;
453
+ readonly "Bad Request": 400;
454
+ readonly Unauthorized: 401;
455
+ readonly "Payment Required": 402;
456
+ readonly Forbidden: 403;
457
+ readonly "Not Found": 404;
458
+ readonly "Method Not Allowed": 405;
459
+ readonly "Not Acceptable": 406;
460
+ readonly "Proxy Authentication Required": 407;
461
+ readonly "Request Timeout": 408;
462
+ readonly Conflict: 409;
463
+ readonly Gone: 410;
464
+ readonly "Length Required": 411;
465
+ readonly "Precondition Failed": 412;
466
+ readonly "Payload Too Large": 413;
467
+ readonly "URI Too Long": 414;
468
+ readonly "Unsupported Media Type": 415;
469
+ readonly "Range Not Satisfiable": 416;
470
+ readonly "Expectation Failed": 417;
471
+ readonly "I'm a teapot": 418;
472
+ readonly "Enhance Your Calm": 420;
473
+ readonly "Misdirected Request": 421;
474
+ readonly "Unprocessable Content": 422;
475
+ readonly Locked: 423;
476
+ readonly "Failed Dependency": 424;
477
+ readonly "Too Early": 425;
478
+ readonly "Upgrade Required": 426;
479
+ readonly "Precondition Required": 428;
480
+ readonly "Too Many Requests": 429;
481
+ readonly "Request Header Fields Too Large": 431;
482
+ readonly "Unavailable For Legal Reasons": 451;
483
+ readonly "Internal Server Error": 500;
484
+ readonly "Not Implemented": 501;
485
+ readonly "Bad Gateway": 502;
486
+ readonly "Service Unavailable": 503;
487
+ readonly "Gateway Timeout": 504;
488
+ readonly "HTTP Version Not Supported": 505;
489
+ readonly "Variant Also Negotiates": 506;
490
+ readonly "Insufficient Storage": 507;
491
+ readonly "Loop Detected": 508;
492
+ readonly "Not Extended": 510;
493
+ readonly "Network Authentication Required": 511;
494
+ }[Code] : Code> : elysia.SelectiveStatus<elysia_types0.IntersectIfObject<CMD["output"] extends string | elysia_types0.FastAnySchema ? {
495
+ 200: elysia.UnwrapSchema<CMD["output"], {}> extends infer A ? A extends File ? elysia.ElysiaFile | File : A : unknown;
496
+ } : CMD["output"] extends {
497
+ [x: number]: string | elysia_types0.FastAnySchema;
498
+ } ? { [k in keyof CMD["output"]]: elysia.UnwrapSchema<CMD["output"][k], {}> extends infer A_1 ? A_1 extends File ? elysia.ElysiaFile | File : A_1 : unknown } : unknown, unknown>>;
499
+ }) => Promise<Response>, {}> extends infer T ? { [K_1 in keyof T]: T[K_1] } : never;
500
+ };
501
+ }>, {
502
+ derive: {};
503
+ resolve: {};
504
+ schema: {};
505
+ standaloneSchema: {};
506
+ response: {};
507
+ }, {
508
+ derive: {};
509
+ resolve: {};
510
+ schema: {};
511
+ standaloneSchema: {};
512
+ response: {};
513
+ }>>;
514
+ //#endregion
515
+ //#region src/registry.d.ts
516
+ declare const registry: Container;
517
+ declare function gen(): unknown;
518
+ declare const Q: typeof DrizzleQuery;
519
+ //#endregion
520
+ export { Auth, BunGenerator, Command, Config, Context, ContextData, Database, DatabaseConfig, DizzleDatabase, DrizzleQuery, Generator, type I, IApplication, type ICommand, ICommandHandler, type IContainer, IContext, IContextCommand, type IError, IMiddleware, type IService, Logger, PinoLogger, Q, Query, SERVER_ERROR, Server, type StandardSchemaV1, Validator, gen, middleware, registry, route };
package/dist/index.mjs ADDED
@@ -0,0 +1 @@
1
+ import{ContextData,Generator,Generator as Generator$1,Logger,Throwable,Validator}from"@kunk/api";import{eq,getTableUniqueName}from"drizzle-orm";import*as path from"path";import{T}from"@kunk/model";import pino from"pino";import{drizzle}from"drizzle-orm/bun-sql";import*as DrizzleQuery from"drizzle-orm/sql/expressions";import{Container}from"inversify";import openapi,{fromTypes}from"@elysiajs/openapi";import Elysia,{ValidationError}from"elysia";let SERVER_ERROR;(function(e){function t(e,t){return Throwable.create(`RESOURCE_ID_NOT_FOUND`,404,{resource:e,id:t})}e.RESOURCE_ID_NOT_FOUND=t;function n(e){return Throwable.create(`RESOURCE_NOT_FOUND`,404,{resource:e})}e.RESOURCE_NOT_FOUND=n;function r(e,t){return Throwable.create(e,400,t)}e.BAD_REQUEST=r;function a(e,t){return Throwable.create(`RESOURCE_ID_ALREADY_EXISTS`,400,{resource:e,id:t})}e.RESOURCE_ID_ALREADY_EXISTS=a;function o(...e){return Throwable.create(`VALIDATION_ERROR`,422,{issues:e})}e.VALIDATION=o;function c(e){return Throwable.create(`SCHEMA_VALIDATION_ERROR`,422,{issues:e})}e.SCHEMA_VALIDATION=c;function l(e,t){return Throwable.create(e,500,t)}e.UNEXPECTED=l,e.FORWARD=Throwable.forward;function u(e,t){return SERVER_ERROR.RESOURCE_ID_NOT_FOUND(getTableUniqueName(e),t)}e.GET_ENTITY_NOT_FOUND=u})(SERVER_ERROR||={});function interpolateEnvVars(e){if(typeof e==`string`)return e.replace(/\${([^:-]+)(?:-([^}]+))?}/g,(e,t,n)=>Bun.env[t]||n||``);if(typeof e==`object`&&e){let t=Array.isArray(e)?[]:{};for(let n in e)t[n]=interpolateEnvVars(e[n]);return t}return e}async function loadFromFile(e,t){let n={},r=path.resolve(process.cwd(),`./config/${e}.yaml`);await Bun.file(r).exists()&&(n=await import(r).then(e=>e.default?.[Bun.env.NODE_ENV||`local`]));let i=await t[`~standard`].validate(n);if(i.issues)throw SERVER_ERROR.SCHEMA_VALIDATION(i.issues);return interpolateEnvVars(i.value)}var Config=class e{constructor(e,t){this.schema=e,this.values=t}get(){return this.values}async set(e){let t=await this.schema[`~standard`].validate(e);if(t.issues)throw SERVER_ERROR.SCHEMA_VALIDATION(t.issues);this.values=t.value}static async create(t){let n=await loadFromFile(t.name,t.schema);return new e(t.schema,n)}static set(e,t){e.set(t)}};const DatabaseConfig=await Config.create({name:`database`,schema:T.object({uri:T.string().default("${DATABASE_URI}"),idleTimeout:T.number().default(5),connectionTimeout:T.number().default(30),maxPoolSize:T.number().default(30)})});var Auth=class{},Database=class{},BunGenerator=class extends Generator$1{get id(){return Bun.randomUUIDv7()}code(e){return Bun.randomUUIDv7().replace(/-/g,``).slice(0,e)}};const rootLogger=pino({name:`app`,transport:{target:`pino-pretty`,options:{colorize:!0,translateTime:`SYS:standard`,ignore:`pid,hostname`}}});var PinoLogger=class e{constructor(e=rootLogger){this.logger=e}info(e){this.logger.info(e)}warn(e){this.logger.warn(e)}error(e){this.logger.error(e)}fork(t){return new e(this.logger.child({name:t}))}},DizzleDatabase=class e extends Database{released=!1;constructor(e,t){super(),this.sql=e,this.session=t}static async create(t,n){let r=await t.reserve();return n.tenantId&&await r`SELECT set_config('app.tenant_id', ${n.tenantId}, false);`,new e(drizzle({client:r}),r)}async create(e,t){let n=e,r=await this.sql.insert(n).values(t).returning(),i=Array.isArray(t)?t.length:1;if(r.length!==i)throw SERVER_ERROR.UNEXPECTED(`FAILED_TO_INSERT_ENTITY`,{});return Array.isArray(t)?r:r[0]}async update(e,t,n){let r=e,[i]=await this.sql.update(r).set(n).where(eq(r.id,t)).returning();if(!i)throw SERVER_ERROR.UNEXPECTED(`FAILED_TO_UPDATE_ENTITY`,{});return i}async upsert(e,t){let n=e,[r]=await this.sql.insert(n).values(t.values).onConflictDoUpdate({target:t.target,set:t.values}).returning();if(!r)throw SERVER_ERROR.UNEXPECTED(`FAILED_TO_UPSERT_ENTITY`,{});return r}async findMany(e,t){let n=e,r=await this.sql.select().from(n).where(t?.where).limit(t?.limit??1e3).offset(t?.offset??0).orderBy(...t?.orderBy??[]).execute();if(!r)throw SERVER_ERROR.UNEXPECTED(`FAILED_TO_GET_MANY_ENTITIES`,{});return r}async findOne(e,t){let n=e,[r]=await this.sql.select().from(n).where(t?.where).limit(1).execute();return r||null}async get(e,t){let n=e,[r]=await this.sql.select().from(n).where(eq(n.id,t)).limit(1).execute();if(!r)throw SERVER_ERROR.GET_ENTITY_NOT_FOUND(n,t);return r}async delete(e,t){let n=e;await this.sql.delete(n).where(eq(n.id,t))}async commit(){this.released||(this.released=!0,this.session.release())}};const registry=new Container({defaultScope:`Singleton`});function gen(){return registry.get(Generator$1)}const Q=DrizzleQuery;var Context=class n{gen;logger;constructor(e,n){this.container=e,this.db=n,this.gen=e.get(Generator),this.logger=e.get(Logger)}static async create(t={}){let r=new Container({defaultScope:`Singleton`,parent:registry});return r.bind(ContextData).toConstantValue(t),new n(r,await r.getAsync(Database))}Q=DrizzleQuery;execute=async(e,t)=>{let n=e;n instanceof Function&&(n=e()),n instanceof Promise&&(n=await n.then(e=>e.default));let r=t;if(n.input){let e=await n.input[`~standard`].validate(t);if(e.issues)throw SERVER_ERROR.SCHEMA_VALIDATION(e.issues);r=e.value}let i={...this,command:n,input:r},a=null;try{return await(()=>n.call(i))(i,this)}catch(e){throw a=SERVER_ERROR.FORWARD(e),a}};prepare=(e,t)=>({input:t,execute:()=>this.execute(e,t)});get=e=>this.container.get(e);getAsync=async e=>await this.container.getAsync(e);[Symbol.dispose]=async()=>{await this.db.commit()}};function middleware(e,t){return t.reduceRight((e,t)=>(n=>t({...n,next:e})),e)}var Command=class e{"~type"=`kunk:command`;constructor(e,t,n,r,i,a){this.name=e,this.visibility=t,this.input=n,this.output=r,this.middlewares=i,this.handler=a}static create=t=>(n,r)=>new e(n.name,t,n.input,n.output,n.middlewares||[],r);static PUBLIC=this.create(`PUBLIC`);static PROTECTED=this.create(`PROTECTED`);static PRIVATE=this.create(`PRIVATE`);async internalCall(e){if(!this.handler)throw SERVER_ERROR.UNEXPECTED(`HANDLER_NOT_SET`,{command:this.name});return this.handler(e)}async call(e){return middleware(()=>this.internalCall(e),this.middlewares)(e)}};registry.bind(Logger).to(PinoLogger),registry.bind(Generator).to(BunGenerator),registry.bind(Bun.SQL).toDynamicValue(()=>{let e=DatabaseConfig.get();return new Bun.SQL({url:e.uri,max:e.maxPoolSize,idleTimeout:e.idleTimeout,connectionTimeout:e.connectionTimeout})}).inSingletonScope(),registry.bind(Database).toDynamicValue(async t=>await DizzleDatabase.create(t.get(Bun.SQL),t.get(ContextData))).inRequestScope();const Server=new Elysia().use(openapi({references:fromTypes(),mapJsonSchema:{zod:T.toJSONSchema},documentation:{servers:[{url:`/`,description:`The base URL of the API`,variables:{tenant_id:{default:`test`}}}]}})).onError(({error:e})=>Throwable.is(e)?Response.json(e):e instanceof T.ModelError?Response.json(Throwable.forward(e)):e instanceof ValidationError||e instanceof Error?Response.json(e):Response.json(Throwable.forward(e)));async function route(e,t){let n=e.split(`/`),r=n.slice(0,-1).join(`.`),i=n.pop(),a=(await t).default,o=a.input?.type===`void`?null:a.input,s=a.output?.type===`void`?null:a.output;return console.info(`command loaded:`,e),new Elysia().post(e,async({headers:e,body:t})=>{let n=e[`x-tenant-id`];using r=await Context.create({tenantId:n});let i=await r.execute(a,t);return Response.json(i)},{body:o,response:s,headers:T.object({"x-tenant-id":T.string().default(`{{tenant_id}}`).optional()}),detail:{summary:i},tags:[r]})}export{Auth,BunGenerator,Command,Config,Context,ContextData,Database,DatabaseConfig,DizzleDatabase,DrizzleQuery,Generator,Logger,PinoLogger,Q,SERVER_ERROR,Server,Validator,gen,middleware,registry,route};
package/package.json CHANGED
@@ -1,15 +1,25 @@
1
1
  {
2
2
  "name": "@kunk/server",
3
- "version": "3.0.2",
3
+ "version": "3.0.5",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "./src/index.ts",
7
7
  "module": "./src/index.ts",
8
+ "files": [
9
+ "dist"
10
+ ],
8
11
  "scripts": {
9
12
  "build": "tsdown",
10
13
  "version:patch": "bun pm version patch",
11
14
  "deploy": "bun publish"
12
15
  },
16
+ "exports": {
17
+ ".": {
18
+ "types": "./dist/index.d.ts",
19
+ "import": "./dist/index.js",
20
+ "default": "./dist/index.js"
21
+ }
22
+ },
13
23
  "dependencies": {
14
24
  "@kunk/api": "3.0.0",
15
25
  "@kunk/tsconfig": "3.0.0",
File without changes
@@ -1,4 +0,0 @@
1
-
2
- $ bun pm version patch
3
- [0.04ms] ".env"
4
- v3.0.2
package/CHANGELOG.md DELETED
@@ -1,13 +0,0 @@
1
- # @kunk/server
2
-
3
- ## 3.0.0
4
-
5
- ### Major Changes
6
-
7
- - version 2
8
-
9
- ### Patch Changes
10
-
11
- - Updated dependencies
12
- - @kunk/tsconfig@3.0.0
13
- - @kunk/api@3.0.0
package/src/command.ts DELETED
@@ -1,57 +0,0 @@
1
- import type { StandardSchemaV1 } from "@standard-schema/spec"
2
- import type { I, ICommand, ICommandHandler, IContextCommand, IMiddleware } from "@/interfaces/+"
3
- import { SERVER_ERROR } from "@/utils/+"
4
- import { middleware } from "./middleware"
5
-
6
- export class Command<IN extends StandardSchemaV1, OUT extends StandardSchemaV1> implements ICommand<IN, OUT> {
7
-
8
- public readonly "~type": "kunk:command" = "kunk:command"
9
-
10
- private constructor(
11
- public readonly name: string,
12
- public readonly visibility: "PUBLIC" | "PROTECTED" | "PRIVATE",
13
- public input: IN,
14
- public output: OUT,
15
- public middlewares: IMiddleware[],
16
- public handler: ICommandHandler<IN, OUT>,
17
- ) {}
18
-
19
- private static create = (visibility: "PUBLIC" | "PROTECTED" | "PRIVATE") => <IN extends StandardSchemaV1 = StandardSchemaV1, OUT extends StandardSchemaV1 = StandardSchemaV1>(
20
- setup: {
21
- name: string,
22
- input: IN
23
- output: OUT
24
- middlewares?: IMiddleware[]
25
- },
26
- handler: ICommandHandler<IN, OUT>,
27
- ) => {
28
- return new Command<IN, OUT>(
29
- setup.name,
30
- visibility,
31
- setup.input,
32
- setup.output,
33
- setup.middlewares || [],
34
- handler
35
- )
36
- }
37
-
38
- public static PUBLIC = this.create("PUBLIC")
39
- public static PROTECTED = this.create("PROTECTED")
40
- public static PRIVATE = this.create("PRIVATE")
41
-
42
-
43
- async internalCall(context: IContextCommand<IN, OUT>): Promise<I.Output<OUT>> {
44
- if (!this.handler) {
45
- throw SERVER_ERROR.UNEXPECTED("HANDLER_NOT_SET", {
46
- command: this.name
47
- })
48
- }
49
- return this.handler(context)
50
- }
51
-
52
- async call(context: IContextCommand<IN, OUT>): Promise<I.Output<OUT>> {
53
- const caller = () => this.internalCall(context)
54
- const handler: any = middleware(caller, this.middlewares)
55
- return handler(context)
56
- }
57
- }
package/src/configs/+.ts DELETED
@@ -1 +0,0 @@
1
- export * from "./DatabaseConfig"
@@ -1,12 +0,0 @@
1
- import { Config } from "@/utils/config"
2
- import { T } from "@kunk/model"
3
-
4
- export const DatabaseConfig = await Config.create({
5
- name: "database",
6
- schema: T.object({
7
- uri: T.string().default("${DATABASE_URI}"),
8
- idleTimeout: T.number().default(5),
9
- connectionTimeout: T.number().default(30),
10
- maxPoolSize: T.number().default(30),
11
- })
12
- })