alepha 0.9.4 → 0.10.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 -21
- package/README.md +47 -93
- package/batch.d.ts +491 -16
- package/bucket.d.ts +449 -12
- package/cache.d.ts +132 -1
- package/command.d.ts +32 -8
- package/core.d.ts +462 -369
- package/email.cjs +8 -0
- package/email.d.ts +328 -0
- package/email.js +1 -0
- package/lock.d.ts +412 -23
- package/logger.d.ts +83 -45
- package/package.json +62 -44
- package/postgres.d.ts +1731 -205
- package/queue/redis.d.ts +3 -3
- package/queue.d.ts +591 -8
- package/react/auth.d.ts +101 -112
- package/react/form.d.ts +14 -4
- package/react/head.d.ts +1 -1
- package/react/i18n.d.ts +13 -5
- package/react.d.ts +318 -180
- package/redis.d.ts +11 -11
- package/router.d.ts +1 -0
- package/security.d.ts +29 -29
- package/server/cache.d.ts +1 -0
- package/server/health.d.ts +6 -6
- package/server/links.d.ts +40 -29
- package/server/proxy.d.ts +192 -0
- package/server.d.ts +645 -88
- package/topic.d.ts +803 -12
- package/vite.d.ts +32 -4
package/server.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import { Alepha, AlephaError, Async, Descriptor, FileLike, KIND, Static, StreamLike, TObject, TSchema } from "alepha";
|
|
3
|
-
import * as
|
|
1
|
+
import * as _alepha_core11 from "alepha";
|
|
2
|
+
import { Alepha, AlephaError, Async, Descriptor, FileLike, KIND, Static, StreamLike, TArray, TFile, TObject, TRecord, TSchema, TStream, TString, TVoid } from "alepha";
|
|
3
|
+
import * as _alepha_logger3 from "alepha/logger";
|
|
4
4
|
import { Readable } from "node:stream";
|
|
5
5
|
import { ReadableStream } from "node:stream/web";
|
|
6
6
|
import { Route, RouterProvider } from "alepha/router";
|
|
7
7
|
import * as _alepha_cache0 from "alepha/cache";
|
|
8
8
|
import { IncomingMessage, ServerResponse as ServerResponse$1 } from "node:http";
|
|
9
9
|
import { DateTimeProvider, DurationLike } from "alepha/datetime";
|
|
10
|
-
import * as
|
|
10
|
+
import * as typebox0 from "typebox";
|
|
11
11
|
import * as http0 from "http";
|
|
12
12
|
|
|
13
13
|
//#region src/constants/routeMethods.d.ts
|
|
@@ -15,15 +15,31 @@ declare const routeMethods: readonly ["GET", "POST", "PUT", "PATCH", "DELETE", "
|
|
|
15
15
|
type RouteMethod = (typeof routeMethods)[number];
|
|
16
16
|
//#endregion
|
|
17
17
|
//#region src/helpers/ServerReply.d.ts
|
|
18
|
+
/**
|
|
19
|
+
* Helper for building server replies.
|
|
20
|
+
*/
|
|
18
21
|
declare class ServerReply {
|
|
19
22
|
headers: Record<string, string> & {
|
|
20
23
|
"set-cookie"?: string[];
|
|
21
24
|
};
|
|
22
25
|
status?: number;
|
|
23
26
|
body?: any;
|
|
27
|
+
/**
|
|
28
|
+
* Redirect to a given URL with optional status code (default 302).
|
|
29
|
+
*/
|
|
24
30
|
redirect(url: string, status?: number): void;
|
|
25
|
-
|
|
26
|
-
|
|
31
|
+
/**
|
|
32
|
+
* Set the response status code.
|
|
33
|
+
*/
|
|
34
|
+
setStatus(status: number): this;
|
|
35
|
+
/**
|
|
36
|
+
* Set a response header.
|
|
37
|
+
*/
|
|
38
|
+
setHeader(name: string, value: string): this;
|
|
39
|
+
/**
|
|
40
|
+
* Set the response body.
|
|
41
|
+
*/
|
|
42
|
+
setBody(body: any): this;
|
|
27
43
|
}
|
|
28
44
|
//#endregion
|
|
29
45
|
//#region src/services/UserAgentParser.d.ts
|
|
@@ -43,15 +59,17 @@ declare class UserAgentParser {
|
|
|
43
59
|
}
|
|
44
60
|
//#endregion
|
|
45
61
|
//#region src/interfaces/ServerRequest.d.ts
|
|
62
|
+
type TRequestBody = TObject | TString | TArray | TRecord | TStream;
|
|
63
|
+
type TResponseBody = TObject | TString | TRecord | TFile | TArray | TStream | TVoid;
|
|
46
64
|
interface RequestConfigSchema {
|
|
47
|
-
body?:
|
|
65
|
+
body?: TRequestBody;
|
|
48
66
|
params?: TObject;
|
|
49
67
|
query?: TObject;
|
|
50
68
|
headers?: TObject;
|
|
51
|
-
response?:
|
|
69
|
+
response?: TResponseBody;
|
|
52
70
|
}
|
|
53
71
|
interface ServerRequestConfig<TConfig extends RequestConfigSchema = RequestConfigSchema> {
|
|
54
|
-
body: TConfig["body"] extends
|
|
72
|
+
body: TConfig["body"] extends TRequestBody ? Static<TConfig["body"]> : any;
|
|
55
73
|
headers: TConfig["headers"] extends TObject ? Static<TConfig["headers"]> : Record<string, string>;
|
|
56
74
|
params: TConfig["params"] extends TObject ? Static<TConfig["params"]> : Record<string, string>;
|
|
57
75
|
query: TConfig["query"] extends TObject ? Static<TConfig["query"]> : Record<string, string>;
|
|
@@ -60,7 +78,16 @@ type ServerRequestConfigEntry<TConfig extends RequestConfigSchema = RequestConfi
|
|
|
60
78
|
interface ServerRequest<TConfig extends RequestConfigSchema = RequestConfigSchema> extends ServerRequestConfig<TConfig> {
|
|
61
79
|
method: RouteMethod;
|
|
62
80
|
url: URL;
|
|
81
|
+
requestId: string;
|
|
82
|
+
/**
|
|
83
|
+
* Client IP address.
|
|
84
|
+
* Will parse `X-Forwarded-For` header if present.
|
|
85
|
+
*/
|
|
63
86
|
ip?: string;
|
|
87
|
+
/**
|
|
88
|
+
* Value of the `Host` header sent by the client.
|
|
89
|
+
*/
|
|
90
|
+
host?: string;
|
|
64
91
|
/**
|
|
65
92
|
* Browser user agent information.
|
|
66
93
|
* Information are not guaranteed to be accurate. Use with caution.
|
|
@@ -69,10 +96,26 @@ interface ServerRequest<TConfig extends RequestConfigSchema = RequestConfigSchem
|
|
|
69
96
|
*/
|
|
70
97
|
userAgent: UserAgentInfo;
|
|
71
98
|
metadata: Record<string, any>;
|
|
99
|
+
/**
|
|
100
|
+
* Reply object to be used to send response.
|
|
101
|
+
*/
|
|
72
102
|
reply: ServerReply;
|
|
103
|
+
/**
|
|
104
|
+
* Raw request and response objects from platform.
|
|
105
|
+
* You should avoid using this property as much as possible to keep your code platform-agnostic.
|
|
106
|
+
*/
|
|
73
107
|
raw: {
|
|
108
|
+
/**
|
|
109
|
+
* Node.js request and response objects.
|
|
110
|
+
*/
|
|
74
111
|
node?: {
|
|
112
|
+
/**
|
|
113
|
+
* Node.js IncomingMessage object. (request)
|
|
114
|
+
*/
|
|
75
115
|
req: IncomingMessage;
|
|
116
|
+
/**
|
|
117
|
+
* Node.js ServerResponse object. (response)
|
|
118
|
+
*/
|
|
76
119
|
res: ServerResponse$1;
|
|
77
120
|
};
|
|
78
121
|
};
|
|
@@ -86,18 +129,18 @@ interface ServerRoute<TConfig extends RequestConfigSchema = RequestConfigSchema>
|
|
|
86
129
|
*/
|
|
87
130
|
silent?: boolean;
|
|
88
131
|
}
|
|
89
|
-
type ServerResponseBody<TConfig extends RequestConfigSchema = RequestConfigSchema> = TConfig["response"] extends
|
|
132
|
+
type ServerResponseBody<TConfig extends RequestConfigSchema = RequestConfigSchema> = TConfig["response"] extends TResponseBody ? Static<TConfig["response"]> : ResponseBodyType;
|
|
90
133
|
type ResponseKind = "json" | "text" | "void" | "file" | "any";
|
|
91
134
|
type ResponseBodyType = string | Buffer | StreamLike | undefined | null | void;
|
|
92
135
|
type ServerHandler<TConfig extends RequestConfigSchema = RequestConfigSchema> = (request: ServerRequest<TConfig>) => Async<ServerResponseBody<TConfig>>;
|
|
93
|
-
type ServerMiddlewareHandler<TConfig extends RequestConfigSchema = RequestConfigSchema> = (request: ServerRequest<TConfig>) => Async<ServerResponseBody<TConfig> | undefined>;
|
|
94
136
|
interface ServerResponse {
|
|
95
137
|
body: string | Buffer | ArrayBuffer | Readable | ReadableStream;
|
|
96
138
|
headers: Record<string, string>;
|
|
97
139
|
status: number;
|
|
98
140
|
}
|
|
141
|
+
type ServerRouteRequestHandler = (request: ServerRawRequest) => Promise<ServerResponse>;
|
|
99
142
|
interface ServerRouteMatcher extends Route {
|
|
100
|
-
handler:
|
|
143
|
+
handler: ServerRouteRequestHandler;
|
|
101
144
|
}
|
|
102
145
|
interface ServerRawRequest {
|
|
103
146
|
method: RouteMethod;
|
|
@@ -120,13 +163,26 @@ declare abstract class ServerProvider {
|
|
|
120
163
|
protected isViteNotFound(url?: string, route?: Route, params?: Record<string, string>): boolean;
|
|
121
164
|
}
|
|
122
165
|
//#endregion
|
|
166
|
+
//#region src/services/ServerRequestParser.d.ts
|
|
167
|
+
declare class ServerRequestParser {
|
|
168
|
+
protected readonly alepha: Alepha;
|
|
169
|
+
protected readonly userAgentParser: UserAgentParser;
|
|
170
|
+
createServerRequest(rawRequest: ServerRawRequest): ServerRequest;
|
|
171
|
+
getRequestId(request: ServerRawRequest): string | undefined;
|
|
172
|
+
getRequestUserAgent(request: ServerRawRequest): UserAgentInfo;
|
|
173
|
+
getRequestIp(request: ServerRawRequest): string | undefined;
|
|
174
|
+
}
|
|
175
|
+
//#endregion
|
|
123
176
|
//#region src/providers/ServerTimingProvider.d.ts
|
|
124
177
|
type TimingMap = Record<string, [number, number]>;
|
|
125
178
|
declare class ServerTimingProvider {
|
|
126
|
-
protected readonly log:
|
|
179
|
+
protected readonly log: _alepha_logger3.Logger;
|
|
127
180
|
protected readonly alepha: Alepha;
|
|
128
|
-
|
|
129
|
-
|
|
181
|
+
options: {
|
|
182
|
+
disabled: boolean;
|
|
183
|
+
};
|
|
184
|
+
readonly onRequest: _alepha_core11.HookDescriptor<"server:onRequest">;
|
|
185
|
+
readonly onResponse: _alepha_core11.HookDescriptor<"server:onResponse">;
|
|
130
186
|
protected get handlerName(): string;
|
|
131
187
|
beginTiming(name: string): void;
|
|
132
188
|
endTiming(name: string): void;
|
|
@@ -145,11 +201,9 @@ declare class ServerRouterProvider extends RouterProvider<ServerRouteMatcher> {
|
|
|
145
201
|
protected readonly alepha: Alepha;
|
|
146
202
|
protected readonly routes: ServerRoute[];
|
|
147
203
|
protected readonly serverTimingProvider: ServerTimingProvider;
|
|
148
|
-
protected readonly
|
|
204
|
+
protected readonly serverRequestParser: ServerRequestParser;
|
|
149
205
|
getRoutes(): ServerRoute[];
|
|
150
206
|
createRoute<TConfig extends RequestConfigSchema = RequestConfigSchema>(route: ServerRoute<TConfig>): void;
|
|
151
|
-
onRequest(route: ServerRoute, rawRequest: ServerRawRequest, responseKind: ResponseKind): Promise<ServerResponse>;
|
|
152
|
-
protected getClientIp(request: ServerRawRequest): string | undefined;
|
|
153
207
|
protected processRequest(request: ServerRequest, route: ServerRoute, responseKind: ResponseKind): Promise<{
|
|
154
208
|
status: number;
|
|
155
209
|
headers: Record<string, string> & {
|
|
@@ -168,16 +222,14 @@ declare class ServerRouterProvider extends RouterProvider<ServerRouteMatcher> {
|
|
|
168
222
|
//#endregion
|
|
169
223
|
//#region src/services/HttpClient.d.ts
|
|
170
224
|
declare class HttpClient {
|
|
171
|
-
protected readonly log:
|
|
225
|
+
protected readonly log: _alepha_logger3.Logger;
|
|
172
226
|
protected readonly alepha: Alepha;
|
|
173
227
|
readonly cache: _alepha_cache0.CacheDescriptorFn<HttpClientCache, any[]>;
|
|
174
228
|
protected readonly pendingRequests: HttpClientPendingRequests;
|
|
175
|
-
clear(): Promise<void>;
|
|
176
229
|
fetchAction(args: FetchActionArgs): Promise<FetchResponse>;
|
|
177
230
|
fetch<T>(url: string, request?: RequestInit,
|
|
178
231
|
// standard options
|
|
179
232
|
options?: FetchOptions): Promise<FetchResponse<T>>;
|
|
180
|
-
json<T = any>(url: string, options?: RequestInit): Promise<T>;
|
|
181
233
|
protected url(host: string, action: HttpAction, args: ServerRequestConfigEntry): string;
|
|
182
234
|
protected body(init: RequestInit, headers: Record<string, string>, action: HttpAction, args?: ServerRequestConfigEntry): Promise<void>;
|
|
183
235
|
protected responseData(response: Response, options: FetchOptions): Promise<any>;
|
|
@@ -234,28 +286,547 @@ interface HttpAction {
|
|
|
234
286
|
schema?: {
|
|
235
287
|
params?: TObject;
|
|
236
288
|
query?: TObject;
|
|
237
|
-
body?:
|
|
238
|
-
response?:
|
|
289
|
+
body?: TRequestBody;
|
|
290
|
+
response?: TResponseBody;
|
|
239
291
|
};
|
|
240
292
|
}
|
|
241
293
|
//#endregion
|
|
242
294
|
//#region src/descriptors/$action.d.ts
|
|
243
295
|
/**
|
|
244
|
-
*
|
|
296
|
+
* Creates a server action descriptor for defining type-safe HTTP endpoints.
|
|
297
|
+
*
|
|
298
|
+
* Server actions are the core building blocks for REST APIs in the Alepha framework. They provide
|
|
299
|
+
* a declarative way to define HTTP endpoints with full TypeScript type safety, automatic schema
|
|
300
|
+
* validation, and integrated security features. Actions automatically handle routing, request
|
|
301
|
+
* parsing, response serialization, and OpenAPI documentation generation.
|
|
302
|
+
*
|
|
303
|
+
* **Key Features**
|
|
304
|
+
*
|
|
305
|
+
* - **Type Safety**: Full TypeScript inference for request/response types
|
|
306
|
+
* - **Schema Validation**: Automatic validation using TypeBox schemas
|
|
307
|
+
* - **Auto-routing**: Convention-based URL generation with customizable paths
|
|
308
|
+
* - **Multiple Invocation**: Call directly (`run()`) or via HTTP (`fetch()`)
|
|
309
|
+
* - **OpenAPI Integration**: Automatic documentation generation
|
|
310
|
+
* - **Security Integration**: Built-in authentication and authorization support
|
|
311
|
+
* - **Content Type Detection**: Automatic handling of JSON, form-data, and plain text
|
|
312
|
+
*
|
|
313
|
+
* **URL Generation**
|
|
314
|
+
*
|
|
315
|
+
* By default, actions are prefixed with `/api` (configurable via `SERVER_API_PREFIX`):
|
|
316
|
+
* - Property name becomes the endpoint path
|
|
317
|
+
* - Path parameters are automatically detected from schema
|
|
318
|
+
* - HTTP method defaults to GET, or POST if body schema is provided
|
|
319
|
+
*
|
|
320
|
+
* **Use Cases**
|
|
321
|
+
*
|
|
322
|
+
* Perfect for building robust REST APIs:
|
|
323
|
+
* - CRUD operations with full type safety
|
|
324
|
+
* - File upload and download endpoints
|
|
325
|
+
* - Real-time data processing APIs
|
|
326
|
+
* - Integration with external services
|
|
327
|
+
* - Microservice communication
|
|
328
|
+
* - Admin and management interfaces
|
|
329
|
+
*
|
|
330
|
+
* @example
|
|
331
|
+
* **Basic CRUD operations:**
|
|
332
|
+
* ```ts
|
|
333
|
+
* import { $action } from "alepha/server";
|
|
334
|
+
* import { t } from "alepha";
|
|
335
|
+
*
|
|
336
|
+
* class UserController {
|
|
337
|
+
* // GET /api/users
|
|
338
|
+
* getUsers = $action({
|
|
339
|
+
* description: "Retrieve all users with pagination",
|
|
340
|
+
* schema: {
|
|
341
|
+
* query: t.object({
|
|
342
|
+
* page: t.optional(t.number({ default: 1 })),
|
|
343
|
+
* limit: t.optional(t.number({ default: 10, maximum: 100 })),
|
|
344
|
+
* search: t.optional(t.string())
|
|
345
|
+
* }),
|
|
346
|
+
* response: t.object({
|
|
347
|
+
* users: t.array(t.object({
|
|
348
|
+
* id: t.string(),
|
|
349
|
+
* name: t.string(),
|
|
350
|
+
* email: t.string(),
|
|
351
|
+
* createdAt: t.datetime()
|
|
352
|
+
* })),
|
|
353
|
+
* total: t.number(),
|
|
354
|
+
* hasMore: t.boolean()
|
|
355
|
+
* })
|
|
356
|
+
* },
|
|
357
|
+
* handler: async ({ query }) => {
|
|
358
|
+
* const { page, limit, search } = query;
|
|
359
|
+
* const users = await this.userService.findUsers({ page, limit, search });
|
|
360
|
+
*
|
|
361
|
+
* return {
|
|
362
|
+
* users: users.items,
|
|
363
|
+
* total: users.total,
|
|
364
|
+
* hasMore: (page * limit) < users.total
|
|
365
|
+
* };
|
|
366
|
+
* }
|
|
367
|
+
* });
|
|
368
|
+
*
|
|
369
|
+
* // POST /api/users
|
|
370
|
+
* createUser = $action({
|
|
371
|
+
* description: "Create a new user account",
|
|
372
|
+
* schema: {
|
|
373
|
+
* body: t.object({
|
|
374
|
+
* name: t.string({ minLength: 2, maxLength: 100 }),
|
|
375
|
+
* email: t.string({ format: "email" }),
|
|
376
|
+
* password: t.string({ minLength: 8 }),
|
|
377
|
+
* role: t.optional(t.enum(["user", "admin"]))
|
|
378
|
+
* }),
|
|
379
|
+
* response: t.object({
|
|
380
|
+
* id: t.string(),
|
|
381
|
+
* name: t.string(),
|
|
382
|
+
* email: t.string(),
|
|
383
|
+
* role: t.string(),
|
|
384
|
+
* createdAt: t.datetime()
|
|
385
|
+
* })
|
|
386
|
+
* },
|
|
387
|
+
* handler: async ({ body }) => {
|
|
388
|
+
* // Password validation and hashing
|
|
389
|
+
* await this.authService.validatePassword(body.password);
|
|
390
|
+
* const hashedPassword = await this.authService.hashPassword(body.password);
|
|
391
|
+
*
|
|
392
|
+
* // Create user with default role
|
|
393
|
+
* const user = await this.userService.create({
|
|
394
|
+
* ...body,
|
|
395
|
+
* password: hashedPassword,
|
|
396
|
+
* role: body.role || "user"
|
|
397
|
+
* });
|
|
398
|
+
*
|
|
399
|
+
* // Return user without password
|
|
400
|
+
* const { password, ...publicUser } = user;
|
|
401
|
+
* return publicUser;
|
|
402
|
+
* }
|
|
403
|
+
* });
|
|
404
|
+
*
|
|
405
|
+
* // GET /api/users/:id
|
|
406
|
+
* getUser = $action({
|
|
407
|
+
* description: "Retrieve user by ID",
|
|
408
|
+
* schema: {
|
|
409
|
+
* params: t.object({
|
|
410
|
+
* id: t.string()
|
|
411
|
+
* }),
|
|
412
|
+
* response: t.object({
|
|
413
|
+
* id: t.string(),
|
|
414
|
+
* name: t.string(),
|
|
415
|
+
* email: t.string(),
|
|
416
|
+
* role: t.string(),
|
|
417
|
+
* profile: t.optional(t.object({
|
|
418
|
+
* bio: t.string(),
|
|
419
|
+
* avatar: t.string({ format: "uri" }),
|
|
420
|
+
* location: t.string()
|
|
421
|
+
* }))
|
|
422
|
+
* })
|
|
423
|
+
* },
|
|
424
|
+
* handler: async ({ params }) => {
|
|
425
|
+
* const user = await this.userService.findById(params.id);
|
|
426
|
+
* if (!user) {
|
|
427
|
+
* throw new Error(`User not found: ${params.id}`);
|
|
428
|
+
* }
|
|
429
|
+
* return user;
|
|
430
|
+
* }
|
|
431
|
+
* });
|
|
432
|
+
*
|
|
433
|
+
* // PUT /api/users/:id
|
|
434
|
+
* updateUser = $action({
|
|
435
|
+
* method: "PUT",
|
|
436
|
+
* description: "Update user information",
|
|
437
|
+
* schema: {
|
|
438
|
+
* params: t.object({ id: t.string() }),
|
|
439
|
+
* body: t.object({
|
|
440
|
+
* name: t.optional(t.string({ minLength: 2 })),
|
|
441
|
+
* email: t.optional(t.string({ format: "email" })),
|
|
442
|
+
* profile: t.optional(t.object({
|
|
443
|
+
* bio: t.optional(t.string()),
|
|
444
|
+
* avatar: t.optional(t.string({ format: "uri" })),
|
|
445
|
+
* location: t.optional(t.string())
|
|
446
|
+
* }))
|
|
447
|
+
* }),
|
|
448
|
+
* response: t.object({
|
|
449
|
+
* id: t.string(),
|
|
450
|
+
* name: t.string(),
|
|
451
|
+
* email: t.string(),
|
|
452
|
+
* updatedAt: t.datetime()
|
|
453
|
+
* })
|
|
454
|
+
* },
|
|
455
|
+
* handler: async ({ params, body }) => {
|
|
456
|
+
* const updatedUser = await this.userService.update(params.id, body);
|
|
457
|
+
* return updatedUser;
|
|
458
|
+
* }
|
|
459
|
+
* });
|
|
460
|
+
* }
|
|
461
|
+
* ```
|
|
462
|
+
*
|
|
463
|
+
* @example
|
|
464
|
+
* **File upload with multipart form data:**
|
|
465
|
+
* ```ts
|
|
466
|
+
* class FileController {
|
|
467
|
+
* uploadAvatar = $action({
|
|
468
|
+
* method: "POST",
|
|
469
|
+
* description: "Upload user avatar image",
|
|
470
|
+
* schema: {
|
|
471
|
+
* body: t.object({
|
|
472
|
+
* file: t.file({
|
|
473
|
+
* maxSize: 5 * 1024 * 1024, // 5MB
|
|
474
|
+
* allowedMimeTypes: ["image/jpeg", "image/png", "image/webp"]
|
|
475
|
+
* }),
|
|
476
|
+
* userId: t.string()
|
|
477
|
+
* }),
|
|
478
|
+
* response: t.object({
|
|
479
|
+
* url: t.string({ format: "uri" }),
|
|
480
|
+
* size: t.number(),
|
|
481
|
+
* mimeType: t.string(),
|
|
482
|
+
* uploadedAt: t.datetime()
|
|
483
|
+
* })
|
|
484
|
+
* },
|
|
485
|
+
* handler: async ({ body }) => {
|
|
486
|
+
* const { file, userId } = body;
|
|
487
|
+
*
|
|
488
|
+
* // Validate file
|
|
489
|
+
* await this.fileService.validateImage(file);
|
|
490
|
+
*
|
|
491
|
+
* // Generate unique filename
|
|
492
|
+
* const filename = `avatars/${userId}/${Date.now()}-${file.name}`;
|
|
493
|
+
*
|
|
494
|
+
* // Upload to storage
|
|
495
|
+
* const uploadResult = await this.storageService.upload(filename, file);
|
|
496
|
+
*
|
|
497
|
+
* // Update user profile
|
|
498
|
+
* await this.userService.updateAvatar(userId, uploadResult.url);
|
|
245
499
|
*
|
|
246
|
-
*
|
|
247
|
-
*
|
|
248
|
-
*
|
|
500
|
+
* return {
|
|
501
|
+
* url: uploadResult.url,
|
|
502
|
+
* size: file.size,
|
|
503
|
+
* mimeType: file.type,
|
|
504
|
+
* uploadedAt: new Date().toISOString()
|
|
505
|
+
* };
|
|
506
|
+
* }
|
|
507
|
+
* });
|
|
508
|
+
*
|
|
509
|
+
* downloadFile = $action({
|
|
510
|
+
* method: "GET",
|
|
511
|
+
* description: "Download file by ID",
|
|
512
|
+
* schema: {
|
|
513
|
+
* params: t.object({ id: t.string() }),
|
|
514
|
+
* query: t.object({
|
|
515
|
+
* download: t.optional(t.boolean()),
|
|
516
|
+
* thumbnail: t.optional(t.boolean())
|
|
517
|
+
* }),
|
|
518
|
+
* response: t.file()
|
|
519
|
+
* },
|
|
520
|
+
* handler: async ({ params, query, reply, user }) => {
|
|
521
|
+
* const file = await this.fileService.findById(params.id);
|
|
522
|
+
* if (!file) {
|
|
523
|
+
* throw new Error("File not found");
|
|
524
|
+
* }
|
|
525
|
+
*
|
|
526
|
+
* // Check permissions
|
|
527
|
+
* await this.fileService.checkAccess(params.id, user.id);
|
|
528
|
+
*
|
|
529
|
+
* const fileBuffer = query.thumbnail
|
|
530
|
+
* ? await this.fileService.getThumbnail(file.id)
|
|
531
|
+
* : await this.fileService.getBuffer(file.path);
|
|
532
|
+
*
|
|
533
|
+
* // Set appropriate headers
|
|
534
|
+
* reply.header("Content-Type", file.mimeType);
|
|
535
|
+
* reply.header("Content-Length", fileBuffer.length);
|
|
536
|
+
*
|
|
537
|
+
* if (query.download) {
|
|
538
|
+
* reply.header("Content-Disposition", `attachment; filename="${file.name}"`);
|
|
539
|
+
* }
|
|
540
|
+
*
|
|
541
|
+
* return fileBuffer;
|
|
542
|
+
* }
|
|
543
|
+
* });
|
|
544
|
+
* }
|
|
545
|
+
* ```
|
|
249
546
|
*
|
|
250
547
|
* @example
|
|
548
|
+
* **Advanced API with custom paths and grouped operations:**
|
|
251
549
|
* ```ts
|
|
252
|
-
* class
|
|
253
|
-
*
|
|
254
|
-
*
|
|
255
|
-
*
|
|
550
|
+
* class OrderController {
|
|
551
|
+
* group = "orders"; // Groups all actions under "orders" tag
|
|
552
|
+
*
|
|
553
|
+
* // GET /api/orders/search
|
|
554
|
+
* searchOrders = $action({
|
|
555
|
+
* name: "search",
|
|
556
|
+
* path: "/orders/search", // Custom path
|
|
557
|
+
* description: "Advanced order search with filtering",
|
|
558
|
+
* schema: {
|
|
559
|
+
* query: t.object({
|
|
560
|
+
* status: t.optional(t.union([
|
|
561
|
+
* t.literal("pending"),
|
|
562
|
+
* t.literal("processing"),
|
|
563
|
+
* t.literal("shipped"),
|
|
564
|
+
* t.literal("delivered"),
|
|
565
|
+
* t.literal("cancelled")
|
|
566
|
+
* ])),
|
|
567
|
+
* customerId: t.optional(t.string()),
|
|
568
|
+
* dateFrom: t.optional(t.date()),
|
|
569
|
+
* dateTo: t.optional(t.date()),
|
|
570
|
+
* minAmount: t.optional(t.number({ minimum: 0 })),
|
|
571
|
+
* maxAmount: t.optional(t.number({ minimum: 0 })),
|
|
572
|
+
* sortBy: t.optional(t.union([
|
|
573
|
+
* t.literal("createdAt"),
|
|
574
|
+
* t.literal("amount"),
|
|
575
|
+
* t.literal("status")
|
|
576
|
+
* ])),
|
|
577
|
+
* sortOrder: t.optional(t.enum(["asc", "desc"]))
|
|
578
|
+
* }),
|
|
579
|
+
* response: t.object({
|
|
580
|
+
* orders: t.array(t.object({
|
|
581
|
+
* id: t.string(),
|
|
582
|
+
* orderNumber: t.string(),
|
|
583
|
+
* customerId: t.string(),
|
|
584
|
+
* customerName: t.string(),
|
|
585
|
+
* status: t.string(),
|
|
586
|
+
* totalAmount: t.number(),
|
|
587
|
+
* createdAt: t.datetime(),
|
|
588
|
+
* itemCount: t.number()
|
|
589
|
+
* })),
|
|
590
|
+
* pagination: t.object({
|
|
591
|
+
* page: t.number(),
|
|
592
|
+
* limit: t.number(),
|
|
593
|
+
* total: t.number(),
|
|
594
|
+
* hasMore: t.boolean()
|
|
595
|
+
* }),
|
|
596
|
+
* filters: t.object({
|
|
597
|
+
* appliedFilters: t.array(t.string()),
|
|
598
|
+
* availableStatuses: t.array(t.string())
|
|
599
|
+
* })
|
|
600
|
+
* })
|
|
601
|
+
* },
|
|
602
|
+
* handler: async ({ query }) => {
|
|
603
|
+
* // Build dynamic query based on filters
|
|
604
|
+
* const searchCriteria = this.orderService.buildSearchCriteria(query);
|
|
605
|
+
* const results = await this.orderService.searchOrders(searchCriteria);
|
|
606
|
+
*
|
|
607
|
+
* return {
|
|
608
|
+
* orders: results.orders,
|
|
609
|
+
* pagination: results.pagination,
|
|
610
|
+
* filters: {
|
|
611
|
+
* appliedFilters: Object.keys(query).filter(key => query[key] !== undefined),
|
|
612
|
+
* availableStatuses: await this.orderService.getAvailableStatuses()
|
|
613
|
+
* }
|
|
614
|
+
* };
|
|
615
|
+
* }
|
|
616
|
+
* });
|
|
617
|
+
*
|
|
618
|
+
* // POST /api/orders/:id/process
|
|
619
|
+
* processOrder = $action({
|
|
620
|
+
* method: "POST",
|
|
621
|
+
* path: "/orders/:id/process",
|
|
622
|
+
* description: "Process an order through the fulfillment workflow",
|
|
623
|
+
* schema: {
|
|
624
|
+
* params: t.object({ id: t.string() }),
|
|
625
|
+
* body: t.object({
|
|
626
|
+
* notes: t.optional(t.string()),
|
|
627
|
+
* priority: t.optional(t.union([
|
|
628
|
+
* t.literal("low"),
|
|
629
|
+
* t.literal("normal"),
|
|
630
|
+
* t.literal("high"),
|
|
631
|
+
* t.literal("urgent")
|
|
632
|
+
* ])),
|
|
633
|
+
* assignToWarehouse: t.optional(t.string())
|
|
634
|
+
* }),
|
|
635
|
+
* response: t.object({
|
|
636
|
+
* orderId: t.string(),
|
|
637
|
+
* status: t.string(),
|
|
638
|
+
* processedAt: t.datetime(),
|
|
639
|
+
* estimatedFulfillment: t.datetime(),
|
|
640
|
+
* trackingInfo: t.optional(t.object({
|
|
641
|
+
* trackingNumber: t.string(),
|
|
642
|
+
* carrier: t.string(),
|
|
643
|
+
* estimatedDelivery: t.date()
|
|
644
|
+
* }))
|
|
645
|
+
* })
|
|
646
|
+
* },
|
|
647
|
+
* handler: async ({ params, body, user }) => {
|
|
648
|
+
* // Validate order can be processed
|
|
649
|
+
* const order = await this.orderService.findById(params.id);
|
|
650
|
+
* if (!order || order.status !== "pending") {
|
|
651
|
+
* throw new Error("Order cannot be processed in current status");
|
|
652
|
+
* }
|
|
653
|
+
*
|
|
654
|
+
* // Check inventory availability
|
|
655
|
+
* const inventoryCheck = await this.inventoryService.checkAvailability(order.items);
|
|
656
|
+
* if (!inventoryCheck.available) {
|
|
657
|
+
* throw new Error(`Insufficient inventory: ${inventoryCheck.missingItems.join(", ")}`);
|
|
658
|
+
* }
|
|
659
|
+
*
|
|
660
|
+
* // Process the order
|
|
661
|
+
* const processResult = await this.fulfillmentService.processOrder({
|
|
662
|
+
* orderId: params.id,
|
|
663
|
+
* options: {
|
|
664
|
+
* notes: body.notes,
|
|
665
|
+
* priority: body.priority || "normal",
|
|
666
|
+
* warehouse: body.assignToWarehouse
|
|
667
|
+
* }
|
|
668
|
+
* });
|
|
669
|
+
*
|
|
670
|
+
* // Update order status
|
|
671
|
+
* await this.orderService.updateStatus(params.id, "processing", {
|
|
672
|
+
* processedBy: user.id,
|
|
673
|
+
* processedAt: new Date(),
|
|
674
|
+
* notes: body.notes
|
|
675
|
+
* });
|
|
676
|
+
*
|
|
677
|
+
* // Send notification
|
|
678
|
+
* await this.notificationService.sendOrderUpdate(order.customerId, {
|
|
679
|
+
* orderId: params.id,
|
|
680
|
+
* status: "processing",
|
|
681
|
+
* message: "Your order is now being processed"
|
|
682
|
+
* });
|
|
683
|
+
*
|
|
684
|
+
* return {
|
|
685
|
+
* orderId: params.id,
|
|
686
|
+
* status: "processing",
|
|
687
|
+
* processedAt: new Date().toISOString(),
|
|
688
|
+
* estimatedFulfillment: processResult.estimatedCompletion,
|
|
689
|
+
* trackingInfo: processResult.trackingInfo
|
|
690
|
+
* };
|
|
691
|
+
* }
|
|
692
|
+
* });
|
|
256
693
|
* }
|
|
257
|
-
* // GET /api/hello -> "Hello World"
|
|
258
694
|
* ```
|
|
695
|
+
*
|
|
696
|
+
* @example
|
|
697
|
+
* **Actions with security integration and role-based access:**
|
|
698
|
+
* ```ts
|
|
699
|
+
* class AdminController {
|
|
700
|
+
* group = "admin";
|
|
701
|
+
*
|
|
702
|
+
* // Only accessible to users with "admin:users:read" permission
|
|
703
|
+
* getUserStats = $action({
|
|
704
|
+
* description: "Get comprehensive user statistics",
|
|
705
|
+
* security: { permissions: ["admin:users:read"] },
|
|
706
|
+
* schema: {
|
|
707
|
+
* query: t.object({
|
|
708
|
+
* includeInactive: t.optional(t.boolean())
|
|
709
|
+
* }),
|
|
710
|
+
* response: t.object({
|
|
711
|
+
* totalUsers: t.number(),
|
|
712
|
+
* activeUsers: t.number(),
|
|
713
|
+
* newUsers: t.number(),
|
|
714
|
+
* userGrowth: t.number(),
|
|
715
|
+
* breakdown: t.object({
|
|
716
|
+
* byRole: t.record(t.string(), t.number()),
|
|
717
|
+
* byStatus: t.record(t.string(), t.number()),
|
|
718
|
+
* byRegistrationSource: t.record(t.string(), t.number())
|
|
719
|
+
* }),
|
|
720
|
+
* trends: t.array(t.object({
|
|
721
|
+
* date: t.date(),
|
|
722
|
+
* registrations: t.number(),
|
|
723
|
+
* activations: t.number()
|
|
724
|
+
* }))
|
|
725
|
+
* })
|
|
726
|
+
* },
|
|
727
|
+
* handler: async ({ query, user }) => {
|
|
728
|
+
* // user is available through security integration
|
|
729
|
+
* this.auditLogger.log({
|
|
730
|
+
* action: "admin.getUserStats",
|
|
731
|
+
* userId: user.id,
|
|
732
|
+
* userRole: user.role,
|
|
733
|
+
* timestamp: new Date()
|
|
734
|
+
* });
|
|
735
|
+
*
|
|
736
|
+
* const period = query.period || "month";
|
|
737
|
+
* const stats = await this.analyticsService.getUserStatistics({
|
|
738
|
+
* period,
|
|
739
|
+
* includeInactive: query.includeInactive || false
|
|
740
|
+
* });
|
|
741
|
+
*
|
|
742
|
+
* return stats;
|
|
743
|
+
* }
|
|
744
|
+
* });
|
|
745
|
+
*
|
|
746
|
+
* // Bulk operations with transaction support
|
|
747
|
+
* bulkUpdateUsers = $action({
|
|
748
|
+
* method: "POST",
|
|
749
|
+
* path: "/admin/users/bulk-update",
|
|
750
|
+
* description: "Bulk update user properties",
|
|
751
|
+
* security: { permissions: ["admin:users:write"] },
|
|
752
|
+
* schema: {
|
|
753
|
+
* body: t.object({
|
|
754
|
+
* userIds: t.array(t.string(), { minItems: 1, maxItems: 1000 }),
|
|
755
|
+
* updates: t.object({
|
|
756
|
+
* status: t.optional(t.union([t.literal("active"), t.literal("inactive")])),
|
|
757
|
+
* role: t.optional(t.string()),
|
|
758
|
+
* tags: t.optional(t.array(t.string())),
|
|
759
|
+
* customFields: t.optional(t.record(t.string(), t.any()))
|
|
760
|
+
* }),
|
|
761
|
+
* reason: t.string({ minLength: 10, maxLength: 500 })
|
|
762
|
+
* }),
|
|
763
|
+
* response: t.object({
|
|
764
|
+
* updated: t.number(),
|
|
765
|
+
* failed: t.number(),
|
|
766
|
+
* errors: t.array(t.object({
|
|
767
|
+
* userId: t.string(),
|
|
768
|
+
* error: t.string()
|
|
769
|
+
* })),
|
|
770
|
+
* auditLogId: t.string()
|
|
771
|
+
* })
|
|
772
|
+
* },
|
|
773
|
+
* handler: async ({ body, user }) => {
|
|
774
|
+
* const results = { updated: 0, failed: 0, errors: [] };
|
|
775
|
+
*
|
|
776
|
+
* // Create audit log entry
|
|
777
|
+
* const auditLogId = await this.auditService.logBulkOperation({
|
|
778
|
+
* operation: "bulk_user_update",
|
|
779
|
+
* initiatedBy: user.id,
|
|
780
|
+
* targetCount: body.userIds.length,
|
|
781
|
+
* reason: body.reason,
|
|
782
|
+
* changes: body.updates
|
|
783
|
+
* });
|
|
784
|
+
*
|
|
785
|
+
* // Process in batches to avoid overwhelming the database
|
|
786
|
+
* const batchSize = 50;
|
|
787
|
+
* for (let i = 0; i < body.userIds.length; i += batchSize) {
|
|
788
|
+
* const batch = body.userIds.slice(i, i + batchSize);
|
|
789
|
+
*
|
|
790
|
+
* try {
|
|
791
|
+
* const updateResult = await this.userService.bulkUpdate(batch, body.updates);
|
|
792
|
+
* results.updated += updateResult.success;
|
|
793
|
+
* results.failed += updateResult.failed;
|
|
794
|
+
* results.errors.push(...updateResult.errors);
|
|
795
|
+
* } catch (error) {
|
|
796
|
+
* // Log batch failure but continue processing
|
|
797
|
+
* this.logger.error(`Bulk update batch failed`, {
|
|
798
|
+
* batch: i / batchSize + 1,
|
|
799
|
+
* userIds: batch,
|
|
800
|
+
* error: error.message
|
|
801
|
+
* });
|
|
802
|
+
*
|
|
803
|
+
* results.failed += batch.length;
|
|
804
|
+
* results.errors.push(...batch.map(userId => ({
|
|
805
|
+
* userId,
|
|
806
|
+
* error: error.message
|
|
807
|
+
* })));
|
|
808
|
+
* }
|
|
809
|
+
* }
|
|
810
|
+
*
|
|
811
|
+
* // Update audit log with results
|
|
812
|
+
* await this.auditService.updateBulkOperationResults(auditLogId, results);
|
|
813
|
+
*
|
|
814
|
+
* return { ...results, auditLogId };
|
|
815
|
+
* }
|
|
816
|
+
* });
|
|
817
|
+
* }
|
|
818
|
+
* ```
|
|
819
|
+
*
|
|
820
|
+
* **Important Notes**:
|
|
821
|
+
* - Actions are automatically registered with the HTTP server when the service is initialized
|
|
822
|
+
* - Use `run()` for direct invocation (testing, internal calls, or remote services)
|
|
823
|
+
* - Use `fetch()` for explicit HTTP requests (client-side, external services)
|
|
824
|
+
* - Schema validation occurs automatically for all requests and responses
|
|
825
|
+
* - Path parameters are automatically extracted from schema definitions
|
|
826
|
+
* - Content-Type headers are automatically set based on schema types
|
|
827
|
+
* - Actions can be disabled via the `disabled` option for maintenance or feature flags
|
|
828
|
+
*
|
|
829
|
+
* @stability 2
|
|
259
830
|
*/
|
|
260
831
|
declare const $action: {
|
|
261
832
|
<TConfig extends RequestConfigSchema>(options: ActionDescriptorOptions<TConfig>): ActionDescriptor<TConfig>;
|
|
@@ -328,7 +899,7 @@ interface ActionDescriptorOptions<TConfig extends RequestConfigSchema> extends O
|
|
|
328
899
|
handler: ServerActionHandler<TConfig>;
|
|
329
900
|
}
|
|
330
901
|
declare class ActionDescriptor<TConfig extends RequestConfigSchema> extends Descriptor<ActionDescriptorOptions<TConfig>> {
|
|
331
|
-
protected readonly log:
|
|
902
|
+
protected readonly log: _alepha_logger3.Logger;
|
|
332
903
|
protected readonly env: {
|
|
333
904
|
SERVER_API_PREFIX: string;
|
|
334
905
|
};
|
|
@@ -362,7 +933,7 @@ declare class ActionDescriptor<TConfig extends RequestConfigSchema> extends Desc
|
|
|
362
933
|
* Call the action handler directly.
|
|
363
934
|
* There is no HTTP layer involved.
|
|
364
935
|
*/
|
|
365
|
-
run(config
|
|
936
|
+
run(config?: ClientRequestEntry<TConfig>, options?: ClientRequestOptions): Promise<ClientRequestResponse<TConfig>>;
|
|
366
937
|
/**
|
|
367
938
|
* Works like `run`, but always fetches (http request) the route.
|
|
368
939
|
*/
|
|
@@ -395,40 +966,35 @@ type ServerActionHandler<TConfig extends RequestConfigSchema = RequestConfigSche
|
|
|
395
966
|
*/
|
|
396
967
|
interface ServerActionRequest<TConfig extends RequestConfigSchema> extends ServerRequest<TConfig> {}
|
|
397
968
|
//#endregion
|
|
969
|
+
//#region src/schemas/errorSchema.d.ts
|
|
970
|
+
declare const errorSchema: typebox0.TObject<{
|
|
971
|
+
error: typebox0.TString;
|
|
972
|
+
status: typebox0.TInteger;
|
|
973
|
+
message: typebox0.TString;
|
|
974
|
+
details: typebox0.TOptional<typebox0.TString>;
|
|
975
|
+
requestId: typebox0.TOptional<typebox0.TString>;
|
|
976
|
+
cause: typebox0.TOptional<typebox0.TObject<{
|
|
977
|
+
name: typebox0.TString;
|
|
978
|
+
message: typebox0.TString;
|
|
979
|
+
}>>;
|
|
980
|
+
}>;
|
|
981
|
+
type ErrorSchema = Static<typeof errorSchema>;
|
|
982
|
+
//#endregion
|
|
398
983
|
//#region src/errors/HttpError.d.ts
|
|
399
984
|
declare const isHttpError: (error: unknown, status?: number) => error is HttpErrorLike;
|
|
400
985
|
declare class HttpError extends AlephaError {
|
|
401
986
|
name: string;
|
|
402
987
|
static is: (error: unknown, status?: number) => error is HttpErrorLike;
|
|
403
|
-
static toJSON(error: HttpError):
|
|
404
|
-
|
|
405
|
-
error: string | undefined;
|
|
406
|
-
message: string;
|
|
407
|
-
cause: {
|
|
408
|
-
name: string;
|
|
409
|
-
message: string;
|
|
410
|
-
};
|
|
411
|
-
} | {
|
|
412
|
-
status: number;
|
|
413
|
-
error: string | undefined;
|
|
414
|
-
message: string;
|
|
415
|
-
cause?: undefined;
|
|
416
|
-
};
|
|
988
|
+
static toJSON(error: HttpError): ErrorSchema;
|
|
989
|
+
readonly error: string;
|
|
417
990
|
readonly status: number;
|
|
418
|
-
readonly
|
|
991
|
+
readonly requestId?: string;
|
|
992
|
+
readonly details?: string;
|
|
419
993
|
readonly reason?: {
|
|
420
994
|
name: string;
|
|
421
995
|
message: string;
|
|
422
996
|
};
|
|
423
|
-
constructor(options:
|
|
424
|
-
error?: string;
|
|
425
|
-
message: string;
|
|
426
|
-
status: number;
|
|
427
|
-
cause?: {
|
|
428
|
-
name: string;
|
|
429
|
-
message: string;
|
|
430
|
-
} | unknown;
|
|
431
|
-
}, cause?: unknown);
|
|
997
|
+
constructor(options: Partial<ErrorSchema>, cause?: unknown);
|
|
432
998
|
}
|
|
433
999
|
declare const errorNameByStatus: Record<number, string>;
|
|
434
1000
|
interface HttpErrorLike extends Error {
|
|
@@ -485,35 +1051,26 @@ declare class ValidationError extends HttpError {
|
|
|
485
1051
|
}
|
|
486
1052
|
//#endregion
|
|
487
1053
|
//#region src/helpers/isMultipart.d.ts
|
|
1054
|
+
/**
|
|
1055
|
+
* Checks if the route has multipart/form-data request body.
|
|
1056
|
+
*/
|
|
488
1057
|
declare const isMultipart: (options: {
|
|
489
1058
|
schema?: RequestConfigSchema;
|
|
490
1059
|
requestBodyType?: string;
|
|
491
1060
|
}) => boolean;
|
|
492
1061
|
//#endregion
|
|
493
|
-
//#region src/schemas/errorSchema.d.ts
|
|
494
|
-
declare const errorSchema: _sinclair_typebox7.TObject<{
|
|
495
|
-
error: _sinclair_typebox7.TString;
|
|
496
|
-
status: _sinclair_typebox7.TNumber;
|
|
497
|
-
message: _sinclair_typebox7.TString;
|
|
498
|
-
details: _sinclair_typebox7.TOptional<_sinclair_typebox7.TString>;
|
|
499
|
-
cause: _sinclair_typebox7.TOptional<_sinclair_typebox7.TObject<{
|
|
500
|
-
name: _sinclair_typebox7.TString;
|
|
501
|
-
message: _sinclair_typebox7.TString;
|
|
502
|
-
}>>;
|
|
503
|
-
}>;
|
|
504
|
-
//#endregion
|
|
505
1062
|
//#region src/schemas/okSchema.d.ts
|
|
506
|
-
declare const okSchema:
|
|
507
|
-
ok:
|
|
508
|
-
id:
|
|
509
|
-
count:
|
|
1063
|
+
declare const okSchema: typebox0.TObject<{
|
|
1064
|
+
ok: typebox0.TBoolean;
|
|
1065
|
+
id: typebox0.TOptional<typebox0.TUnion<[typebox0.TString, typebox0.TInteger]>>;
|
|
1066
|
+
count: typebox0.TOptional<typebox0.TNumber>;
|
|
510
1067
|
}>;
|
|
511
1068
|
type Ok = Static<typeof okSchema>;
|
|
512
1069
|
//#endregion
|
|
513
1070
|
//#region src/providers/NodeHttpServerProvider.d.ts
|
|
514
|
-
declare const envSchema:
|
|
515
|
-
SERVER_PORT:
|
|
516
|
-
SERVER_HOST:
|
|
1071
|
+
declare const envSchema: _alepha_core11.TObject<{
|
|
1072
|
+
SERVER_PORT: _alepha_core11.TInteger;
|
|
1073
|
+
SERVER_HOST: _alepha_core11.TString;
|
|
517
1074
|
}>;
|
|
518
1075
|
declare module "alepha" {
|
|
519
1076
|
interface Env extends Partial<Static<typeof envSchema>> {}
|
|
@@ -521,31 +1078,31 @@ declare module "alepha" {
|
|
|
521
1078
|
declare class NodeHttpServerProvider extends ServerProvider {
|
|
522
1079
|
protected readonly alepha: Alepha;
|
|
523
1080
|
protected readonly dateTimeProvider: DateTimeProvider;
|
|
524
|
-
protected readonly log:
|
|
1081
|
+
protected readonly log: _alepha_logger3.Logger;
|
|
525
1082
|
protected readonly env: {
|
|
526
1083
|
SERVER_PORT: number;
|
|
527
1084
|
SERVER_HOST: string;
|
|
528
1085
|
};
|
|
529
1086
|
protected readonly router: ServerRouterProvider;
|
|
530
1087
|
protected readonly server: http0.Server<typeof IncomingMessage, typeof ServerResponse$1>;
|
|
531
|
-
protected readonly onNodeRequest:
|
|
1088
|
+
protected readonly onNodeRequest: _alepha_core11.HookDescriptor<"node:request">;
|
|
532
1089
|
handle(req: IncomingMessage, res: ServerResponse$1): Promise<void>;
|
|
533
1090
|
createRouterRequest(req: IncomingMessage, res: ServerResponse$1, params?: Record<string, string>): ServerRawRequest;
|
|
534
1091
|
getProtocol(req: IncomingMessage): "http" | "https";
|
|
535
1092
|
get hostname(): string;
|
|
536
|
-
readonly start:
|
|
537
|
-
protected readonly stop:
|
|
1093
|
+
readonly start: _alepha_core11.HookDescriptor<"start">;
|
|
1094
|
+
protected readonly stop: _alepha_core11.HookDescriptor<"stop">;
|
|
538
1095
|
protected listen(): Promise<void>;
|
|
539
1096
|
protected close(): Promise<void>;
|
|
540
1097
|
}
|
|
541
1098
|
//#endregion
|
|
542
1099
|
//#region src/providers/ServerLoggerProvider.d.ts
|
|
543
1100
|
declare class ServerLoggerProvider {
|
|
544
|
-
protected readonly log:
|
|
1101
|
+
protected readonly log: _alepha_logger3.Logger;
|
|
545
1102
|
protected readonly alepha: Alepha;
|
|
546
|
-
readonly onRequest:
|
|
547
|
-
readonly onError:
|
|
548
|
-
readonly onResponse:
|
|
1103
|
+
readonly onRequest: _alepha_core11.HookDescriptor<"server:onRequest">;
|
|
1104
|
+
readonly onError: _alepha_core11.HookDescriptor<"server:onError">;
|
|
1105
|
+
readonly onResponse: _alepha_core11.HookDescriptor<"server:onResponse">;
|
|
549
1106
|
}
|
|
550
1107
|
//#endregion
|
|
551
1108
|
//#region src/providers/ServerNotReadyProvider.d.ts
|
|
@@ -558,7 +1115,7 @@ declare class ServerLoggerProvider {
|
|
|
558
1115
|
*/
|
|
559
1116
|
declare class ServerNotReadyProvider {
|
|
560
1117
|
protected readonly alepha: Alepha;
|
|
561
|
-
readonly onRequest:
|
|
1118
|
+
readonly onRequest: _alepha_core11.HookDescriptor<"server:onRequest">;
|
|
562
1119
|
}
|
|
563
1120
|
//#endregion
|
|
564
1121
|
//#region src/index.d.ts
|
|
@@ -626,7 +1183,7 @@ declare module "alepha" {
|
|
|
626
1183
|
* @see {@link $action}
|
|
627
1184
|
* @module alepha.server
|
|
628
1185
|
*/
|
|
629
|
-
declare const AlephaServer:
|
|
1186
|
+
declare const AlephaServer: _alepha_core11.Service<_alepha_core11.Module>;
|
|
630
1187
|
//#endregion
|
|
631
|
-
export { $action, $route, ActionDescriptor, ActionDescriptorOptions, AlephaServer, BadRequestError, ClientRequestEntry, ClientRequestEntryContainer, ClientRequestOptions, ClientRequestResponse, ConflictError, FetchActionArgs, FetchOptions, FetchResponse, ForbiddenError, HttpAction, HttpClient, HttpClientPendingRequests, HttpError, HttpErrorLike, NodeHttpServerProvider, NotFoundError, Ok, RequestConfigSchema, ResponseBodyType, ResponseKind, RouteDescriptor, RouteDescriptorOptions, RouteMethod, ServerActionHandler, ServerActionRequest, ServerHandler, ServerLoggerProvider,
|
|
1188
|
+
export { $action, $route, ActionDescriptor, ActionDescriptorOptions, AlephaServer, BadRequestError, ClientRequestEntry, ClientRequestEntryContainer, ClientRequestOptions, ClientRequestResponse, ConflictError, ErrorSchema, FetchActionArgs, FetchOptions, FetchResponse, ForbiddenError, HttpAction, HttpClient, HttpClientPendingRequests, HttpError, HttpErrorLike, NodeHttpServerProvider, NotFoundError, Ok, RequestConfigSchema, ResponseBodyType, ResponseKind, RouteDescriptor, RouteDescriptorOptions, RouteMethod, ServerActionHandler, ServerActionRequest, ServerHandler, ServerLoggerProvider, ServerNotReadyProvider, ServerProvider, ServerRawRequest, ServerReply, ServerRequest, ServerRequestConfig, ServerRequestConfigEntry, ServerResponse, ServerResponseBody, ServerRoute, ServerRouteMatcher, ServerRouteRequestHandler, ServerRouterProvider, ServerTimingProvider, TRequestBody, TResponseBody, UnauthorizedError, ValidationError, errorNameByStatus, errorSchema, isHttpError, isMultipart, okSchema, routeMethods };
|
|
632
1189
|
//# sourceMappingURL=index.d.ts.map
|