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