alepha 0.9.4 → 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/server/links.d.ts CHANGED
@@ -7,26 +7,26 @@ import * as _alepha_logger0 from "alepha/logger";
7
7
  import * as _alepha_retry0 from "alepha/retry";
8
8
  import { ProxyDescriptorOptions, ServerProxyProvider } from "alepha/server/proxy";
9
9
  import { ServiceAccountDescriptor, UserAccountToken } from "alepha/security";
10
- import * as _sinclair_typebox19 from "@sinclair/typebox";
10
+ import * as _sinclair_typebox0 from "@sinclair/typebox";
11
11
 
12
12
  //#region src/schemas/apiLinksResponseSchema.d.ts
13
- declare const apiLinkSchema: _sinclair_typebox19.TObject<{
14
- name: _sinclair_typebox19.TString;
15
- group: _sinclair_typebox19.TOptional<_sinclair_typebox19.TString>;
16
- path: _sinclair_typebox19.TString;
17
- method: _sinclair_typebox19.TOptional<_sinclair_typebox19.TString>;
18
- requestBodyType: _sinclair_typebox19.TOptional<_sinclair_typebox19.TString>;
19
- service: _sinclair_typebox19.TOptional<_sinclair_typebox19.TString>;
13
+ declare const apiLinkSchema: _sinclair_typebox0.TObject<{
14
+ name: _sinclair_typebox0.TString;
15
+ group: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
16
+ path: _sinclair_typebox0.TString;
17
+ method: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
18
+ requestBodyType: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
19
+ service: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
20
20
  }>;
21
- declare const apiLinksResponseSchema: _sinclair_typebox19.TObject<{
22
- prefix: _sinclair_typebox19.TOptional<_sinclair_typebox19.TString>;
23
- links: _sinclair_typebox19.TArray<_sinclair_typebox19.TObject<{
24
- name: _sinclair_typebox19.TString;
25
- group: _sinclair_typebox19.TOptional<_sinclair_typebox19.TString>;
26
- path: _sinclair_typebox19.TString;
27
- method: _sinclair_typebox19.TOptional<_sinclair_typebox19.TString>;
28
- requestBodyType: _sinclair_typebox19.TOptional<_sinclair_typebox19.TString>;
29
- service: _sinclair_typebox19.TOptional<_sinclair_typebox19.TString>;
21
+ declare const apiLinksResponseSchema: _sinclair_typebox0.TObject<{
22
+ prefix: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
23
+ links: _sinclair_typebox0.TArray<_sinclair_typebox0.TObject<{
24
+ name: _sinclair_typebox0.TString;
25
+ group: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
26
+ path: _sinclair_typebox0.TString;
27
+ method: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
28
+ requestBodyType: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
29
+ service: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
30
30
  }>>;
31
31
  }>;
32
32
  type ApiLinksResponse = Static<typeof apiLinksResponseSchema>;
@@ -257,15 +257,15 @@ declare class ServerLinksProvider {
257
257
  * This is based on the user's permissions.
258
258
  */
259
259
  readonly links: _alepha_server0.RouteDescriptor<{
260
- response: _sinclair_typebox19.TObject<{
261
- prefix: _sinclair_typebox19.TOptional<_sinclair_typebox19.TString>;
262
- links: _sinclair_typebox19.TArray<_sinclair_typebox19.TObject<{
263
- name: _sinclair_typebox19.TString;
264
- group: _sinclair_typebox19.TOptional<_sinclair_typebox19.TString>;
265
- path: _sinclair_typebox19.TString;
266
- method: _sinclair_typebox19.TOptional<_sinclair_typebox19.TString>;
267
- requestBodyType: _sinclair_typebox19.TOptional<_sinclair_typebox19.TString>;
268
- service: _sinclair_typebox19.TOptional<_sinclair_typebox19.TString>;
260
+ response: _sinclair_typebox0.TObject<{
261
+ prefix: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
262
+ links: _sinclair_typebox0.TArray<_sinclair_typebox0.TObject<{
263
+ name: _sinclair_typebox0.TString;
264
+ group: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
265
+ path: _sinclair_typebox0.TString;
266
+ method: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
267
+ requestBodyType: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
268
+ service: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
269
269
  }>>;
270
270
  }>;
271
271
  }>;
@@ -276,10 +276,10 @@ declare class ServerLinksProvider {
276
276
  * I mean for 150+ links, you got 50ms of serialization time.
277
277
  */
278
278
  readonly schema: _alepha_server0.RouteDescriptor<{
279
- params: _sinclair_typebox19.TObject<{
280
- name: _sinclair_typebox19.TString;
279
+ params: _sinclair_typebox0.TObject<{
280
+ name: _sinclair_typebox0.TString;
281
281
  }>;
282
- response: _sinclair_typebox19.TRecord<_sinclair_typebox19.TString, _sinclair_typebox19.TAny>;
282
+ response: _sinclair_typebox0.TRecord<_sinclair_typebox0.TString, _sinclair_typebox0.TAny>;
283
283
  }>;
284
284
  getSchemaByName(name: string, options?: GetApiLinksOptions): Promise<RequestConfigSchema>;
285
285
  /**
@@ -299,6 +299,17 @@ declare module "alepha" {
299
299
  api?: ApiLinksResponse;
300
300
  }
301
301
  }
302
+ /**
303
+ * Provides server-side link management and remote capabilities for client-server interactions.
304
+ *
305
+ * The server-links module enables declarative link definitions using `$remote` and `$client` descriptors,
306
+ * facilitating seamless API endpoint management and client-server communication. It integrates with server
307
+ * security features to ensure safe and controlled access to resources.
308
+ *
309
+ * @see {@link $remote}
310
+ * @see {@link $client}
311
+ * @module alepha.server.links
312
+ */
302
313
  declare const AlephaServerLinks: _alepha_core2.Service<_alepha_core2.Module>;
303
314
  //#endregion
304
315
  export { $client, $remote, AlephaServerLinks, ApiLink, ApiLinksResponse, ClientScope, FetchLinksOptions, GetApiLinksOptions, HttpClientLink, HttpVirtualClient, LinkProvider, RemoteDescriptor, RemoteDescriptorOptions, RemoteDescriptorProvider, ServerLinksProvider, ServerRemote, VirtualAction, apiLinkSchema, apiLinksResponseSchema };
package/server/proxy.d.ts CHANGED
@@ -4,16 +4,208 @@ import { ServerHandler, ServerRequest, ServerRouterProvider } from "alepha/serve
4
4
  import * as _alepha_logger0 from "alepha/logger";
5
5
 
6
6
  //#region src/descriptors/$proxy.d.ts
7
+
8
+ /**
9
+ * Creates a proxy descriptor to forward requests to another server.
10
+ *
11
+ * This descriptor enables you to create reverse proxy functionality, allowing your Alepha server
12
+ * to forward requests to other services while maintaining a unified API surface. It's particularly
13
+ * useful for microservice architectures, API gateways, or when you need to aggregate multiple
14
+ * services behind a single endpoint.
15
+ *
16
+ * **Key Features**
17
+ *
18
+ * - **Path-based routing**: Match specific paths or patterns to proxy
19
+ * - **Dynamic targets**: Support both static and dynamic target resolution
20
+ * - **Request/Response hooks**: Modify requests before forwarding and responses after receiving
21
+ * - **URL rewriting**: Transform URLs before forwarding to the target
22
+ * - **Conditional proxying**: Enable/disable proxies based on environment or conditions
23
+ *
24
+ * @example
25
+ * **Basic proxy setup:**
26
+ * ```ts
27
+ * import { $proxy } from "alepha/server-proxy";
28
+ *
29
+ * class ApiGateway {
30
+ * // Forward all /api/* requests to external service
31
+ * api = $proxy({
32
+ * path: "/api/*",
33
+ * target: "https://api.example.com"
34
+ * });
35
+ * }
36
+ * ```
37
+ *
38
+ * @example
39
+ * **Dynamic target with environment-based routing:**
40
+ * ```ts
41
+ * class ApiGateway {
42
+ * // Route to different environments based on configuration
43
+ * api = $proxy({
44
+ * path: "/api/*",
45
+ * target: () => process.env.NODE_ENV === "production"
46
+ * ? "https://api.prod.example.com"
47
+ * : "https://api.dev.example.com"
48
+ * });
49
+ * }
50
+ * ```
51
+ *
52
+ * @example
53
+ * **Advanced proxy with request/response modification:**
54
+ * ```ts
55
+ * class SecureProxy {
56
+ * secure = $proxy({
57
+ * path: "/secure/*",
58
+ * target: "https://secure-api.example.com",
59
+ * beforeRequest: async (request, proxyRequest) => {
60
+ * // Add authentication headers
61
+ * proxyRequest.headers = {
62
+ * ...proxyRequest.headers,
63
+ * 'Authorization': `Bearer ${await getServiceToken()}`,
64
+ * 'X-Forwarded-For': request.headers['x-forwarded-for'] || request.ip
65
+ * };
66
+ * },
67
+ * afterResponse: async (request, proxyResponse) => {
68
+ * // Log response for monitoring
69
+ * console.log(`Proxied ${request.url} -> ${proxyResponse.status}`);
70
+ * },
71
+ * rewrite: (url) => {
72
+ * // Remove /secure prefix when forwarding
73
+ * url.pathname = url.pathname.replace('/secure', '');
74
+ * }
75
+ * });
76
+ * }
77
+ * ```
78
+ *
79
+ * @example
80
+ * **Conditional proxy based on feature flags:**
81
+ * ```ts
82
+ * class FeatureProxy {
83
+ * newApi = $proxy({
84
+ * path: "/v2/*",
85
+ * target: "https://new-api.example.com",
86
+ * disabled: !process.env.ENABLE_V2_API // Disable if feature flag is off
87
+ * });
88
+ * }
89
+ * ```
90
+ */
7
91
  declare const $proxy: {
8
92
  (options: ProxyDescriptorOptions): ProxyDescriptor;
9
93
  [KIND]: typeof ProxyDescriptor;
10
94
  };
11
95
  type ProxyDescriptorOptions = {
96
+ /**
97
+ * Path pattern to match for proxying requests.
98
+ *
99
+ * Supports wildcards and path parameters:
100
+ * - `/api/*` - Matches all paths starting with `/api/`
101
+ * - `/api/v1/*` - Matches all paths starting with `/api/v1/`
102
+ * - `/users/:id` - Matches `/users/123`, `/users/abc`, etc.
103
+ *
104
+ * @example "/api/*"
105
+ * @example "/secure/admin/*"
106
+ * @example "/users/:id/posts"
107
+ */
12
108
  path: string;
109
+ /**
110
+ * Target URL to which matching requests should be forwarded.
111
+ *
112
+ * Can be either:
113
+ * - **Static string**: A fixed URL like `"https://api.example.com"`
114
+ * - **Dynamic function**: A function that returns the URL, enabling runtime target resolution
115
+ *
116
+ * The target URL will be combined with the remaining path from the original request.
117
+ *
118
+ * @example "https://api.example.com"
119
+ * @example () => process.env.API_URL || "http://localhost:3001"
120
+ */
13
121
  target: string | (() => string);
122
+ /**
123
+ * Whether this proxy is disabled.
124
+ *
125
+ * When `true`, requests matching the path will not be proxied and will be handled
126
+ * by other routes or return 404. Useful for feature toggles or conditional proxying.
127
+ *
128
+ * @default false
129
+ * @example !process.env.ENABLE_PROXY
130
+ */
14
131
  disabled?: boolean;
132
+ /**
133
+ * Hook called before forwarding the request to the target server.
134
+ *
135
+ * Use this to:
136
+ * - Add authentication headers
137
+ * - Modify request headers or body
138
+ * - Add request tracking/logging
139
+ * - Transform the request before forwarding
140
+ *
141
+ * @param request - The original incoming server request
142
+ * @param proxyRequest - The request that will be sent to the target (modifiable)
143
+ *
144
+ * @example
145
+ * ```ts
146
+ * beforeRequest: async (request, proxyRequest) => {
147
+ * proxyRequest.headers = {
148
+ * ...proxyRequest.headers,
149
+ * 'Authorization': `Bearer ${await getToken()}`,
150
+ * 'X-Request-ID': generateRequestId()
151
+ * };
152
+ * }
153
+ * ```
154
+ */
15
155
  beforeRequest?: (request: ServerRequest, proxyRequest: RequestInit) => Async<void>;
156
+ /**
157
+ * Hook called after receiving the response from the target server.
158
+ *
159
+ * Use this to:
160
+ * - Log response details for monitoring
161
+ * - Add custom headers to the response
162
+ * - Transform response data
163
+ * - Handle error responses
164
+ *
165
+ * @param request - The original incoming server request
166
+ * @param proxyResponse - The response received from the target server
167
+ *
168
+ * @example
169
+ * ```ts
170
+ * afterResponse: async (request, proxyResponse) => {
171
+ * console.log(`Proxy ${request.method} ${request.url} -> ${proxyResponse.status}`);
172
+ *
173
+ * if (!proxyResponse.ok) {
174
+ * await logError(`Proxy error: ${proxyResponse.status}`, { request, response: proxyResponse });
175
+ * }
176
+ * }
177
+ * ```
178
+ */
16
179
  afterResponse?: (request: ServerRequest, proxyResponse: Response) => Async<void>;
180
+ /**
181
+ * Function to rewrite the URL before sending to the target server.
182
+ *
183
+ * Use this to:
184
+ * - Remove or add path prefixes
185
+ * - Transform path parameters
186
+ * - Modify query parameters
187
+ * - Change the URL structure entirely
188
+ *
189
+ * The function receives a mutable URL object and should modify it in-place.
190
+ *
191
+ * @param url - The URL object to modify (mutable)
192
+ *
193
+ * @example
194
+ * ```ts
195
+ * // Remove /api prefix when forwarding
196
+ * rewrite: (url) => {
197
+ * url.pathname = url.pathname.replace('/api', '');
198
+ * }
199
+ * ```
200
+ *
201
+ * @example
202
+ * ```ts
203
+ * // Add version prefix
204
+ * rewrite: (url) => {
205
+ * url.pathname = `/v2${url.pathname}`;
206
+ * }
207
+ * ```
208
+ */
17
209
  rewrite?: (url: URL) => void;
18
210
  };
19
211
  declare class ProxyDescriptor extends Descriptor<ProxyDescriptorOptions> {}