webspresso 0.0.90 → 0.0.93
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/README.md +98 -2509
- package/bin/commands/admin-password.js +8 -2
- package/bin/commands/api.js +7 -1
- package/bin/commands/favicon-generate.js +6 -4
- package/bin/commands/mcp.js +162 -0
- package/bin/commands/new.js +7 -1
- package/bin/commands/page.js +7 -1
- package/bin/commands/seed.js +7 -1
- package/bin/commands/service.js +199 -0
- package/bin/commands/skill.js +7 -1
- package/bin/webspresso.js +4 -0
- package/core/auth/middleware.js +9 -0
- package/core/compileSchema.js +1 -5
- package/core/compression/compressible.js +63 -0
- package/core/compression/compression-stream.js +59 -0
- package/core/compression/index.js +25 -0
- package/core/compression/middleware.js +310 -0
- package/core/compression/negotiate.js +165 -0
- package/core/errors/base.js +31 -0
- package/core/errors/domain.js +193 -0
- package/core/errors/http.js +133 -0
- package/core/errors/index.js +77 -0
- package/core/errors/middleware.js +162 -0
- package/core/errors/normalize.js +171 -0
- package/core/kernel/app.js +2 -1
- package/core/kernel/index.js +5 -1
- package/core/orm/cache/fingerprint.js +23 -5
- package/core/orm/complexity.js +120 -0
- package/core/orm/eager-loader.js +54 -9
- package/core/orm/events.js +64 -14
- package/core/orm/index.js +83 -12
- package/core/orm/model.js +13 -2
- package/core/orm/query-builder.js +30 -4
- package/core/orm/repository.js +57 -25
- package/core/orm/transaction.js +39 -5
- package/core/orm/utils.js +6 -3
- package/core/queue/adapters/database.js +317 -0
- package/core/queue/adapters/memory.js +176 -0
- package/core/queue/adapters/redis.js +357 -0
- package/core/queue/index.js +21 -0
- package/core/queue/job.js +103 -0
- package/core/queue/manager.js +413 -0
- package/core/realtime/adapters/redis.js +431 -0
- package/core/realtime/adapters/socket-io.js +203 -0
- package/core/realtime/adapters/sse.js +210 -0
- package/core/realtime/adapters/websocket.js +337 -0
- package/core/realtime/auth-manager.js +140 -0
- package/core/realtime/core.js +359 -0
- package/core/realtime/emitter.js +98 -0
- package/core/realtime/errors.js +71 -0
- package/core/realtime/index.js +79 -0
- package/core/realtime/reconnect-manager.js +118 -0
- package/core/realtime/registry.js +243 -0
- package/core/shutdown/http-adapter.js +134 -0
- package/core/shutdown/index.js +12 -0
- package/core/shutdown/shutdown-manager.js +312 -0
- package/core/ssr/index.js +13 -0
- package/core/ssr/stream.js +174 -0
- package/core/validation/index.js +70 -0
- package/index.d.ts +924 -53
- package/index.js +110 -1
- package/package.json +30 -2
- package/plugins/admin-panel/api.js +37 -4
- package/plugins/admin-panel/app.js +57 -17
- package/plugins/admin-panel/client/parts/01-state-api-breadcrumb.js +10 -2
- package/plugins/admin-panel/client/parts/04-field-renderers.js +102 -58
- package/plugins/admin-panel/client/parts/05-rich-text-file-helpers.js +51 -27
- package/plugins/admin-panel/client/parts/07-model-list.js +9 -4
- package/plugins/admin-panel/client/parts/08-record-list.js +37 -26
- package/plugins/admin-panel/client/parts/09-record-form.js +168 -19
- package/plugins/admin-panel/core/admin-module.js +2 -2
- package/plugins/admin-panel/core/api-extensions.js +149 -0
- package/plugins/admin-panel/field-renderers/rich-text.js +3 -2
- package/plugins/admin-panel/index.js +155 -23
- package/plugins/admin-panel/modules/bulk-actions.js +9 -2
- package/plugins/admin-panel/modules/custom-pages.js +144 -45
- package/plugins/admin-panel/modules/dashboard.js +8 -1
- package/plugins/admin-panel/modules/menu.js +85 -0
- package/plugins/admin-panel/modules/user-management.js +5 -2
- package/plugins/admin-panel/vendor/mithril.min.js +1 -0
- package/plugins/admin-panel/vendor/quill.min.js +7 -0
- package/plugins/admin-panel/vendor/quill.snow.min.css +945 -0
- package/plugins/admin-panel/vendor/tailwind.min.js +65 -0
- package/plugins/basic-auth/index.js +293 -0
- package/plugins/data-exchange/export-xlsx.js +28 -2
- package/plugins/data-exchange/import.js +55 -16
- package/plugins/data-exchange/index.js +19 -0
- package/plugins/data-exchange/parse-table.js +14 -5
- package/plugins/data-exchange/record-selection.js +2 -0
- package/plugins/email/index.js +14 -1
- package/plugins/index.js +33 -0
- package/plugins/mcp/auth.js +104 -0
- package/plugins/mcp/discovery.js +88 -0
- package/plugins/mcp/index.js +208 -0
- package/plugins/mcp/prompts.js +149 -0
- package/plugins/mcp/providers/orm.js +325 -0
- package/plugins/mcp/providers/services.js +190 -0
- package/plugins/mcp/providers/system.js +87 -0
- package/plugins/mcp/server.js +472 -0
- package/plugins/mcp/transports/sse.js +139 -0
- package/plugins/mcp/transports/stdio.js +108 -0
- package/plugins/queue/index.js +108 -0
- package/plugins/realtime/index.js +150 -0
- package/plugins/recaptcha/index.js +11 -0
- package/plugins/redirect/index.js +9 -1
- package/plugins/rest-resources/index.js +280 -11
- package/plugins/upload/index.js +16 -0
- package/src/app-context.js +46 -6
- package/src/file-router.js +366 -130
- package/src/helpers.js +20 -2
- package/src/njk-frontmatter.js +24 -14
- package/src/plugin-manager.js +124 -4
- package/src/server.js +332 -54
- package/src/services/builtins/auth.js +273 -0
- package/src/services/builtins/exchange.js +229 -0
- package/src/services/builtins/mail.js +134 -0
- package/src/services/builtins/media.js +196 -0
- package/src/services/builtins/system.js +221 -0
- package/src/services/discovery.js +141 -0
- package/src/services/executor.js +292 -0
- package/src/services/index.js +70 -0
- package/src/services/memoize.js +256 -0
- package/src/services/registry.js +290 -0
- package/src/services/validator.js +230 -0
- package/templates/skills/webspresso-usage/REFERENCE-framework.md +6 -4
package/index.d.ts
CHANGED
|
@@ -34,7 +34,21 @@ export interface CreateAppOptions {
|
|
|
34
34
|
version?: string;
|
|
35
35
|
manifestPath?: string;
|
|
36
36
|
prefix?: string;
|
|
37
|
-
|
|
37
|
+
publicDir?: string;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* If truthy, route load() return values for stylesheets and scripts are promoted to pageHead
|
|
41
|
+
*/
|
|
42
|
+
pageAssets?:
|
|
43
|
+
| boolean
|
|
44
|
+
| {
|
|
45
|
+
enabled?: boolean;
|
|
46
|
+
stylesheets?: boolean;
|
|
47
|
+
scripts?: boolean;
|
|
48
|
+
};
|
|
49
|
+
/** Trust proxy configuration (default: 1) */
|
|
50
|
+
trustProxy?: boolean | number | string;
|
|
51
|
+
/**
|
|
38
52
|
* Custom 404 / 500 / 503 handlers. File-based route errors are forwarded with `next(err)` and hit `serverError` / `timeout`.
|
|
39
53
|
* When `serverError` / `timeout` is a template path, it is not used for paths under `/api` (default JSON instead).
|
|
40
54
|
*/
|
|
@@ -48,15 +62,235 @@ export interface CreateAppOptions {
|
|
|
48
62
|
timeout?: string | false;
|
|
49
63
|
auth?: unknown;
|
|
50
64
|
db?: DatabaseInstance | null;
|
|
65
|
+
/** HTTP response compression options */
|
|
66
|
+
compression?: boolean | CompressionOptions;
|
|
67
|
+
/** Shutdown and lifecycle configuration */
|
|
68
|
+
shutdown?: ShutdownOptions;
|
|
69
|
+
server?: {
|
|
70
|
+
port?: number;
|
|
71
|
+
shutdown?: ShutdownOptions;
|
|
72
|
+
compression?: boolean | CompressionOptions;
|
|
73
|
+
trustProxy?: boolean | number | string;
|
|
74
|
+
[key: string]: unknown;
|
|
75
|
+
};
|
|
51
76
|
/** Opt-in Alpine / swup assets under `/__webspresso/client-runtime/*`. Env: WEBSPRESSO_ALPINE, WEBSPRESSO_SWUP. */
|
|
52
77
|
clientRuntime?: {
|
|
53
78
|
alpine?: boolean | Record<string, unknown>;
|
|
54
79
|
swup?: boolean | Record<string, unknown>;
|
|
55
80
|
};
|
|
81
|
+
/** Path to services directory (auto-discovered) */
|
|
82
|
+
servicesDir?: string;
|
|
83
|
+
services?: {
|
|
84
|
+
dir?: string;
|
|
85
|
+
};
|
|
56
86
|
setupRoutes?: (app: Application, ctx: SetupRoutesContext) => void;
|
|
57
87
|
[key: string]: unknown;
|
|
58
88
|
}
|
|
59
89
|
|
|
90
|
+
export interface ServiceContext {
|
|
91
|
+
req?: Request;
|
|
92
|
+
res?: Response;
|
|
93
|
+
db?: DatabaseInstance | null;
|
|
94
|
+
fsy?: Record<string, unknown>;
|
|
95
|
+
locale?: string;
|
|
96
|
+
t?: unknown;
|
|
97
|
+
service?: {
|
|
98
|
+
<T = unknown>(name: string, input?: unknown, options?: unknown): Promise<T>;
|
|
99
|
+
invalidate?: (name: string, input?: unknown, ctx?: unknown) => boolean;
|
|
100
|
+
clearCache?: (name?: string) => boolean;
|
|
101
|
+
};
|
|
102
|
+
[key: string]: unknown;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export type ServiceHandler<TInput = unknown, TOutput = unknown> = (
|
|
106
|
+
input: TInput,
|
|
107
|
+
ctx: ServiceContext
|
|
108
|
+
) => Promise<TOutput> | TOutput;
|
|
109
|
+
|
|
110
|
+
export interface ServiceDefinition<TInput = unknown, TOutput = unknown> {
|
|
111
|
+
schema?: import('zod').ZodType<any> | Record<string, unknown> | ((input: unknown) => unknown) | null;
|
|
112
|
+
handler: ServiceHandler<TInput, TOutput>;
|
|
113
|
+
metadata?: Record<string, unknown>;
|
|
114
|
+
auth?: boolean | string | string[] | ((user: unknown, ctx: ServiceContext) => boolean | Promise<boolean>);
|
|
115
|
+
cache?:
|
|
116
|
+
| boolean
|
|
117
|
+
| string
|
|
118
|
+
| number
|
|
119
|
+
| {
|
|
120
|
+
ttl?: string | number;
|
|
121
|
+
key?: string | ((input: unknown, ctx: ServiceContext) => string);
|
|
122
|
+
};
|
|
123
|
+
timeout?: number | string;
|
|
124
|
+
transaction?: boolean;
|
|
125
|
+
[key: string]: unknown;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export class ServiceRegistry {
|
|
129
|
+
constructor(options?: { servicesDir?: string; isDev?: boolean; logger?: unknown });
|
|
130
|
+
readonly services: Map<string, ServiceDefinition>;
|
|
131
|
+
load(): this;
|
|
132
|
+
register(name: string, definition: ServiceDefinition | ServiceHandler): this;
|
|
133
|
+
get(name: string): ServiceDefinition | undefined;
|
|
134
|
+
has(name: string): boolean;
|
|
135
|
+
list(): string[];
|
|
136
|
+
invalidate(name: string, input?: unknown, ctx?: unknown): boolean;
|
|
137
|
+
clearCache(name?: string): boolean;
|
|
138
|
+
call<T = unknown>(name: string, input?: unknown, ctx?: unknown, options?: unknown): Promise<T>;
|
|
139
|
+
reload(): this;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export function createServiceRegistry(options?: {
|
|
143
|
+
servicesDir?: string;
|
|
144
|
+
isDev?: boolean;
|
|
145
|
+
logger?: unknown;
|
|
146
|
+
autoLoad?: boolean;
|
|
147
|
+
}): ServiceRegistry;
|
|
148
|
+
|
|
149
|
+
export type InferServiceInput<T> = T extends ServiceDefinition<infer TInput, any>
|
|
150
|
+
? TInput
|
|
151
|
+
: T extends { schema: import('zod').ZodType<infer TInput> }
|
|
152
|
+
? TInput
|
|
153
|
+
: T extends (input: infer TInput, ...args: any[]) => any
|
|
154
|
+
? TInput
|
|
155
|
+
: unknown;
|
|
156
|
+
|
|
157
|
+
export type InferServiceOutput<T> = T extends ServiceDefinition<any, infer TOutput>
|
|
158
|
+
? TOutput
|
|
159
|
+
: T extends (...args: any[]) => Promise<infer TOutput>
|
|
160
|
+
? TOutput
|
|
161
|
+
: T extends (...args: any[]) => infer TOutput
|
|
162
|
+
? TOutput
|
|
163
|
+
: unknown;
|
|
164
|
+
|
|
165
|
+
export function defineService<TInput = unknown, TOutput = unknown>(
|
|
166
|
+
definition: ServiceDefinition<TInput, TOutput> | ServiceHandler<TInput, TOutput>
|
|
167
|
+
): ServiceDefinition<TInput, TOutput>;
|
|
168
|
+
|
|
169
|
+
export const service: typeof defineService;
|
|
170
|
+
|
|
171
|
+
export interface MemoizeOptions {
|
|
172
|
+
ttl?: string | number | boolean;
|
|
173
|
+
maxSize?: number;
|
|
174
|
+
key?: (input: unknown, ctx?: unknown) => string;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export interface MemoizedFunction<TArgs extends unknown[], TReturn> {
|
|
178
|
+
(...args: TArgs): Promise<TReturn>;
|
|
179
|
+
invalidate(...args: TArgs): boolean;
|
|
180
|
+
delete(...args: TArgs): boolean;
|
|
181
|
+
clear(): void;
|
|
182
|
+
has(...args: TArgs): boolean;
|
|
183
|
+
readonly size: number;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export function memoize<TArgs extends unknown[], TReturn>(
|
|
187
|
+
fn: (...args: TArgs) => Promise<TReturn> | TReturn,
|
|
188
|
+
options?: MemoizeOptions
|
|
189
|
+
): MemoizedFunction<TArgs, TReturn>;
|
|
190
|
+
|
|
191
|
+
export function parseTtlMs(ttl: string | number | boolean): number;
|
|
192
|
+
|
|
193
|
+
export function stableCacheKey(input: unknown): string;
|
|
194
|
+
|
|
195
|
+
export function sanitizeInput<T = unknown>(input: T): T;
|
|
196
|
+
|
|
197
|
+
export function maskSensitiveData<T = unknown>(data: T, customRedactKeys?: string[]): T;
|
|
198
|
+
|
|
199
|
+
export function discoverServices(
|
|
200
|
+
servicesDir: string
|
|
201
|
+
): Array<{ name: string; aliases: string[]; filePath: string; relativePath: string }>;
|
|
202
|
+
|
|
203
|
+
export function filePathToServiceName(relativePath: string): { name: string; aliases: string[] };
|
|
204
|
+
|
|
205
|
+
export function toCamelCase(str: string): string;
|
|
206
|
+
|
|
207
|
+
export function createAuthServices(options?: {
|
|
208
|
+
userModel?: string;
|
|
209
|
+
fields?: Record<string, string>;
|
|
210
|
+
}): Record<string, ServiceDefinition>;
|
|
211
|
+
|
|
212
|
+
export function createMailServices(options?: {
|
|
213
|
+
emailService: unknown;
|
|
214
|
+
registry?: unknown;
|
|
215
|
+
db?: unknown;
|
|
216
|
+
tableName?: string;
|
|
217
|
+
}): Record<string, ServiceDefinition>;
|
|
218
|
+
|
|
219
|
+
export function createMediaServices(options?: {
|
|
220
|
+
provider?: unknown;
|
|
221
|
+
destDir?: string;
|
|
222
|
+
publicBasePath?: string;
|
|
223
|
+
}): Record<string, ServiceDefinition>;
|
|
224
|
+
|
|
225
|
+
export function createSystemServices(options?: {
|
|
226
|
+
db?: unknown;
|
|
227
|
+
serviceRegistry?: unknown;
|
|
228
|
+
pluginManager?: unknown;
|
|
229
|
+
}): Record<string, ServiceDefinition>;
|
|
230
|
+
|
|
231
|
+
export function createExchangeServices(options?: {
|
|
232
|
+
db?: unknown;
|
|
233
|
+
}): Record<string, ServiceDefinition>;
|
|
234
|
+
|
|
235
|
+
export function validateServiceInput(schema: unknown, input: unknown, serviceName: string): unknown;
|
|
236
|
+
|
|
237
|
+
export function executeService(
|
|
238
|
+
registry: ServiceRegistry,
|
|
239
|
+
name: string,
|
|
240
|
+
input?: unknown,
|
|
241
|
+
ctx?: unknown,
|
|
242
|
+
options?: unknown
|
|
243
|
+
): Promise<unknown>;
|
|
244
|
+
|
|
245
|
+
export interface CompressionOptions {
|
|
246
|
+
enabled?: boolean;
|
|
247
|
+
threshold?: number;
|
|
248
|
+
level?: number;
|
|
249
|
+
encodings?: string[];
|
|
250
|
+
filter?: (req: Request, res: Response) => boolean;
|
|
251
|
+
brotli?: Record<string, unknown>;
|
|
252
|
+
gzip?: Record<string, unknown>;
|
|
253
|
+
deflate?: Record<string, unknown>;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
export interface ShutdownOptions {
|
|
257
|
+
enabled?: boolean;
|
|
258
|
+
mode?: 'graceful' | 'force';
|
|
259
|
+
timeout?: number;
|
|
260
|
+
signals?: string[];
|
|
261
|
+
logger?: unknown;
|
|
262
|
+
exitOnSignal?: boolean;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
export interface ServerAdapter {
|
|
266
|
+
close(): Promise<void>;
|
|
267
|
+
forceClose?(): void;
|
|
268
|
+
closeIdleConnections?(): void;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
export class NodeHttpAdapter implements ServerAdapter {
|
|
272
|
+
constructor(server: unknown);
|
|
273
|
+
close(): Promise<void>;
|
|
274
|
+
forceClose(): void;
|
|
275
|
+
closeIdleConnections(): void;
|
|
276
|
+
destroy(): void;
|
|
277
|
+
readonly isListening: boolean;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
export class ShutdownManager {
|
|
281
|
+
constructor(options?: ShutdownOptions);
|
|
282
|
+
readonly isShuttingDown: boolean;
|
|
283
|
+
readonly isClosed: boolean;
|
|
284
|
+
mode: 'graceful' | 'force';
|
|
285
|
+
timeout: number;
|
|
286
|
+
onShutdown(fn: () => Promise<void> | void): this;
|
|
287
|
+
registerDisposer(nameOrFn: string | (() => Promise<void> | void), maybeFn?: () => Promise<void> | void): this;
|
|
288
|
+
registerAdapter(adapter: ServerAdapter): this;
|
|
289
|
+
enableShutdownHooks(): this;
|
|
290
|
+
disableShutdownHooks(): this;
|
|
291
|
+
close(reason?: string): Promise<void>;
|
|
292
|
+
}
|
|
293
|
+
|
|
60
294
|
export interface SetupRoutesContext {
|
|
61
295
|
nunjucksEnv: unknown;
|
|
62
296
|
authMiddleware?: RequestHandler;
|
|
@@ -65,15 +299,97 @@ export interface SetupRoutesContext {
|
|
|
65
299
|
clientRuntime: { alpine: boolean; swup: boolean };
|
|
66
300
|
}
|
|
67
301
|
|
|
302
|
+
export interface WebspressoApplication extends Application {
|
|
303
|
+
server?: unknown;
|
|
304
|
+
readonly isShuttingDown: boolean;
|
|
305
|
+
shutdownManager: ShutdownManager;
|
|
306
|
+
serviceRegistry: ServiceRegistry;
|
|
307
|
+
onShutdown(fn: () => Promise<void> | void): this;
|
|
308
|
+
close(reason?: string): Promise<void>;
|
|
309
|
+
enableShutdownHooks(): this;
|
|
310
|
+
disableShutdownHooks(): this;
|
|
311
|
+
setErrorHandler(handler: (error: unknown, req: Request, res: Response, next: NextFunction) => Promise<unknown> | unknown): this;
|
|
312
|
+
}
|
|
313
|
+
|
|
68
314
|
export interface CreateAppResult {
|
|
69
|
-
app:
|
|
315
|
+
app: WebspressoApplication;
|
|
70
316
|
nunjucksEnv: unknown;
|
|
71
317
|
pluginManager: PluginManager;
|
|
72
318
|
authMiddleware?: RequestHandler;
|
|
319
|
+
shutdownManager: ShutdownManager;
|
|
73
320
|
}
|
|
74
321
|
|
|
75
322
|
export function createApp(options?: CreateAppOptions): CreateAppResult;
|
|
76
323
|
|
|
324
|
+
// --- Exceptions & Errors ---
|
|
325
|
+
|
|
326
|
+
export interface ErrorOptions {
|
|
327
|
+
code?: string;
|
|
328
|
+
details?: unknown;
|
|
329
|
+
cause?: unknown;
|
|
330
|
+
status?: number;
|
|
331
|
+
headers?: Record<string, string>;
|
|
332
|
+
expose?: boolean;
|
|
333
|
+
[key: string]: unknown;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
export class WebspressoError extends Error {
|
|
337
|
+
name: string;
|
|
338
|
+
code?: string;
|
|
339
|
+
details?: unknown;
|
|
340
|
+
cause?: unknown;
|
|
341
|
+
status?: number;
|
|
342
|
+
constructor(message: string, options?: ErrorOptions);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
export class HttpError extends WebspressoError {
|
|
346
|
+
status: number;
|
|
347
|
+
headers: Record<string, string>;
|
|
348
|
+
expose: boolean;
|
|
349
|
+
constructor(status?: number, message?: string, options?: ErrorOptions);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
export class BadRequestError extends HttpError { constructor(message?: string, options?: ErrorOptions); }
|
|
353
|
+
export class UnauthorizedError extends HttpError { constructor(message?: string, options?: ErrorOptions); }
|
|
354
|
+
export class ForbiddenError extends HttpError { constructor(message?: string, options?: ErrorOptions); }
|
|
355
|
+
export class NotFoundError extends HttpError { constructor(message?: string, options?: ErrorOptions); }
|
|
356
|
+
export class MethodNotAllowedError extends HttpError { constructor(message?: string, options?: ErrorOptions); }
|
|
357
|
+
export class ConflictError extends HttpError { constructor(message?: string, options?: ErrorOptions); }
|
|
358
|
+
export class PayloadTooLargeError extends HttpError { constructor(message?: string, options?: ErrorOptions); }
|
|
359
|
+
export class UnsupportedMediaTypeError extends HttpError { constructor(message?: string, options?: ErrorOptions); }
|
|
360
|
+
export class UnprocessableEntityError extends HttpError { constructor(message?: string, options?: ErrorOptions); }
|
|
361
|
+
export class TooManyRequestsError extends HttpError { constructor(message?: string, options?: ErrorOptions); }
|
|
362
|
+
|
|
363
|
+
export class ValidationError extends HttpError {
|
|
364
|
+
fields: Record<string, string[] | string>;
|
|
365
|
+
constructor(message?: string, options?: ErrorOptions & { fields?: Record<string, string[] | string> });
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
export class ConfigurationError extends WebspressoError { constructor(message: string, options?: ErrorOptions); }
|
|
369
|
+
export class PluginError extends WebspressoError { plugin?: string | null; constructor(message: string, options?: ErrorOptions & { plugin?: string }); }
|
|
370
|
+
export class SecurityError extends HttpError { constructor(message?: string, options?: ErrorOptions); }
|
|
371
|
+
export class RequestError extends HttpError { constructor(status?: number, message?: string, options?: ErrorOptions); }
|
|
372
|
+
export class RequestAbortedError extends RequestError { constructor(message?: string, options?: ErrorOptions); }
|
|
373
|
+
export class RouterError extends WebspressoError { constructor(message: string, options?: ErrorOptions); }
|
|
374
|
+
export class RouteNotFoundError extends NotFoundError { path?: string; constructor(pathOrMessage?: string, options?: ErrorOptions); }
|
|
375
|
+
export class RouteGenerationError extends RouterError { constructor(message: string, options?: ErrorOptions); }
|
|
376
|
+
|
|
377
|
+
export function normalizeError(err: unknown, isDev?: boolean): HttpError | WebspressoError;
|
|
378
|
+
export function toErrorResponseObject(error: unknown, isDev?: boolean): Record<string, unknown>;
|
|
379
|
+
|
|
380
|
+
export function createCompressionMiddleware(options?: CompressionOptions): RequestHandler;
|
|
381
|
+
|
|
382
|
+
export namespace compression {
|
|
383
|
+
export function supportsBrotli(): boolean;
|
|
384
|
+
export function getDefaultSupportedEncodings(includeBrotli?: boolean): string[];
|
|
385
|
+
export function parseAcceptEncoding(header?: string | null): Array<{ encoding: string; q: number; index: number }>;
|
|
386
|
+
export function selectEncoding(acceptEncoding?: string | null, supportedEncodings?: string[]): string | null;
|
|
387
|
+
export function isCompressible(contentType?: string | null): boolean;
|
|
388
|
+
export function createCompressionStream(encoding: string, options?: CompressionOptions): unknown;
|
|
389
|
+
export function createCompressionMiddleware(options?: CompressionOptions): RequestHandler;
|
|
390
|
+
export function appendVary(res: unknown, field: string): void;
|
|
391
|
+
}
|
|
392
|
+
|
|
77
393
|
export function resolveClientRuntime(options?: {
|
|
78
394
|
clientRuntime?: {
|
|
79
395
|
alpine?: boolean | Record<string, unknown>;
|
|
@@ -87,15 +403,31 @@ export const CLIENT_RUNTIME_BASE: string;
|
|
|
87
403
|
|
|
88
404
|
export function attachDbMiddleware(req: Request, res: Response, next: NextFunction): void;
|
|
89
405
|
|
|
90
|
-
export function getAppContext(): {
|
|
406
|
+
export function getAppContext(): {
|
|
407
|
+
db: DatabaseInstance | null;
|
|
408
|
+
shutdownManager: ShutdownManager | null;
|
|
409
|
+
serviceRegistry: ServiceRegistry | null;
|
|
410
|
+
};
|
|
91
411
|
|
|
92
412
|
export function getDb(): DatabaseInstance;
|
|
93
413
|
|
|
94
414
|
export function hasDb(): boolean;
|
|
95
415
|
|
|
416
|
+
export function getShutdownManager(): ShutdownManager | null;
|
|
417
|
+
|
|
418
|
+
export function hasShutdownManager(): boolean;
|
|
419
|
+
|
|
420
|
+
export function getServiceRegistry(): ServiceRegistry | null;
|
|
421
|
+
|
|
422
|
+
export function hasServiceRegistry(): boolean;
|
|
423
|
+
|
|
96
424
|
export function resetAppContext(): void;
|
|
97
425
|
|
|
98
|
-
export function setAppContext(partial: {
|
|
426
|
+
export function setAppContext(partial: {
|
|
427
|
+
db?: DatabaseInstance | null;
|
|
428
|
+
shutdownManager?: ShutdownManager | null;
|
|
429
|
+
serviceRegistry?: ServiceRegistry | null;
|
|
430
|
+
}): void;
|
|
99
431
|
|
|
100
432
|
// --- File router ---
|
|
101
433
|
|
|
@@ -121,10 +453,31 @@ export function scanDirectory(
|
|
|
121
453
|
|
|
122
454
|
export function loadI18n(pagesDir: string, routePath?: string): Record<string, unknown>;
|
|
123
455
|
|
|
456
|
+
export interface Translator {
|
|
457
|
+
(key: string, params?: Record<string, unknown> | string, defaultVal?: string | null): string;
|
|
458
|
+
locale: string;
|
|
459
|
+
translations: Record<string, unknown>;
|
|
460
|
+
number(num: number | string | null | undefined, options?: Intl.NumberFormatOptions): string;
|
|
461
|
+
formatNumber(num: number | string | null | undefined, options?: Intl.NumberFormatOptions): string;
|
|
462
|
+
currency(amount: number | string | null | undefined, currency?: string, options?: Intl.NumberFormatOptions): string;
|
|
463
|
+
formatCurrency(amount: number | string | null | undefined, currency?: string, options?: Intl.NumberFormatOptions): string;
|
|
464
|
+
date(date: Date | string | number | null | undefined, options?: Intl.DateTimeFormatOptions): string;
|
|
465
|
+
formatDate(date: Date | string | number | null | undefined, options?: Intl.DateTimeFormatOptions): string;
|
|
466
|
+
relativeTime(val: number | string | null | undefined, unit?: Intl.RelativeTimeFormatUnit, options?: Intl.RelativeTimeFormatOptions): string;
|
|
467
|
+
formatRelativeTime(val: number | string | null | undefined, unit?: Intl.RelativeTimeFormatUnit, options?: Intl.RelativeTimeFormatOptions): string;
|
|
468
|
+
plural(count: number | string, forms: Record<string, string>, params?: Record<string, unknown>): string;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
export interface CreateTranslatorOptions {
|
|
472
|
+
locale?: string;
|
|
473
|
+
fallbackTranslations?: Record<string, unknown>;
|
|
474
|
+
fallbackLocale?: string;
|
|
475
|
+
}
|
|
476
|
+
|
|
124
477
|
export function createTranslator(
|
|
125
|
-
dictionaries
|
|
126
|
-
|
|
127
|
-
):
|
|
478
|
+
dictionaries?: Record<string, unknown>,
|
|
479
|
+
options?: CreateTranslatorOptions | string
|
|
480
|
+
): Translator;
|
|
128
481
|
|
|
129
482
|
export function detectLocale(
|
|
130
483
|
req: Request,
|
|
@@ -265,10 +618,23 @@ export interface ScopeOptions {
|
|
|
265
618
|
tenant?: string | null;
|
|
266
619
|
}
|
|
267
620
|
|
|
268
|
-
|
|
621
|
+
// --- ORM: Type Inference Helpers ---
|
|
622
|
+
|
|
623
|
+
export type InferModel<T> = T extends ModelDefinition<infer TModel>
|
|
624
|
+
? TModel
|
|
625
|
+
: T extends ZodObject<infer TShape>
|
|
626
|
+
? import('zod').z.infer<T>
|
|
627
|
+
: T extends ZodTypeAny
|
|
628
|
+
? import('zod').z.infer<T>
|
|
629
|
+
: Record<string, any>;
|
|
630
|
+
|
|
631
|
+
export type InferModelCreate<T> = Partial<InferModel<T>> & Record<string, any>;
|
|
632
|
+
export type InferModelUpdate<T> = Partial<InferModel<T>>;
|
|
633
|
+
|
|
634
|
+
export interface ModelOptions<TSchema extends ZodObject<any> = ZodObject<Record<string, ZodTypeAny>>> {
|
|
269
635
|
name: string;
|
|
270
636
|
table: string;
|
|
271
|
-
schema:
|
|
637
|
+
schema: TSchema;
|
|
272
638
|
primaryKey?: string;
|
|
273
639
|
relations?: Record<string, RelationDefinition>;
|
|
274
640
|
scopes?: ScopeOptions;
|
|
@@ -276,10 +642,16 @@ export interface ModelOptions {
|
|
|
276
642
|
rest?: RestMetadata;
|
|
277
643
|
hooks?: Record<string, (...args: unknown[]) => unknown>;
|
|
278
644
|
hidden?: string[];
|
|
645
|
+
queryLimits?: {
|
|
646
|
+
maxLimit?: number;
|
|
647
|
+
defaultLimit?: number;
|
|
648
|
+
maxIncludes?: number;
|
|
649
|
+
maxFilterConditions?: number;
|
|
650
|
+
};
|
|
279
651
|
cache?: boolean | 'auto' | 'smart' | { strategy: 'auto' | 'smart' };
|
|
280
652
|
}
|
|
281
653
|
|
|
282
|
-
export interface ModelDefinition {
|
|
654
|
+
export interface ModelDefinition<TModel = Record<string, any>> {
|
|
283
655
|
name: string;
|
|
284
656
|
table: string;
|
|
285
657
|
schema: ZodObject<Record<string, ZodTypeAny>>;
|
|
@@ -296,7 +668,7 @@ export interface ModelDefinition {
|
|
|
296
668
|
label: string;
|
|
297
669
|
icon: string | null;
|
|
298
670
|
customFields: Record<string, unknown>;
|
|
299
|
-
queries: Record<string, (repo: Repository) => Promise<unknown>>;
|
|
671
|
+
queries: Record<string, (repo: Repository<TModel>) => Promise<unknown>>;
|
|
300
672
|
};
|
|
301
673
|
rest: {
|
|
302
674
|
enabled: boolean;
|
|
@@ -304,15 +676,23 @@ export interface ModelDefinition {
|
|
|
304
676
|
allowInclude: string[] | null;
|
|
305
677
|
};
|
|
306
678
|
hidden: string[];
|
|
679
|
+
queryLimits: {
|
|
680
|
+
maxLimit?: number;
|
|
681
|
+
defaultLimit?: number;
|
|
682
|
+
maxIncludes?: number;
|
|
683
|
+
maxFilterConditions?: number;
|
|
684
|
+
};
|
|
307
685
|
hooks: Record<string, unknown>;
|
|
308
686
|
cache?: boolean | 'auto' | 'smart' | { strategy: 'auto' | 'smart' };
|
|
309
687
|
}
|
|
310
688
|
|
|
311
|
-
export function defineModel
|
|
689
|
+
export function defineModel<TSchema extends ZodObject<any>>(
|
|
690
|
+
options: ModelOptions<TSchema>
|
|
691
|
+
): ModelDefinition<import('zod').z.infer<TSchema>>;
|
|
312
692
|
|
|
313
|
-
export function getModel(name: string): ModelDefinition | undefined;
|
|
693
|
+
export function getModel<T = Record<string, any>>(name: string): ModelDefinition<T> | undefined;
|
|
314
694
|
|
|
315
|
-
export function getAllModels(): Map<string, ModelDefinition
|
|
695
|
+
export function getAllModels(): Map<string, ModelDefinition<any>>;
|
|
316
696
|
|
|
317
697
|
export function hasModel(name: string): boolean;
|
|
318
698
|
|
|
@@ -340,58 +720,58 @@ export interface FindOptions {
|
|
|
340
720
|
select?: string[];
|
|
341
721
|
}
|
|
342
722
|
|
|
343
|
-
export interface PaginatedResult {
|
|
344
|
-
data:
|
|
723
|
+
export interface PaginatedResult<T = Record<string, any>> {
|
|
724
|
+
data: T[];
|
|
345
725
|
total: number;
|
|
346
726
|
page: number;
|
|
347
727
|
perPage: number;
|
|
348
728
|
totalPages: number;
|
|
349
729
|
}
|
|
350
730
|
|
|
351
|
-
export interface QueryBuilder {
|
|
352
|
-
where(column: string, value: unknown): this;
|
|
353
|
-
where(column: string, operator: string, value: unknown): this;
|
|
354
|
-
where(conditions: Record<string, unknown>): this;
|
|
731
|
+
export interface QueryBuilder<T = Record<string, any>> {
|
|
732
|
+
where(column: keyof T | string, value: unknown): this;
|
|
733
|
+
where(column: keyof T | string, operator: string, value: unknown): this;
|
|
734
|
+
where(conditions: Partial<T> | Record<string, unknown>): this;
|
|
355
735
|
orWhere(...args: unknown[]): this;
|
|
356
|
-
whereIn(column: string, values: unknown[]): this;
|
|
357
|
-
whereBetween(column: string, range: [unknown, unknown]): this;
|
|
358
|
-
select(...columns: string[]): this;
|
|
359
|
-
orderBy(column: string, direction?: 'asc' | 'desc'): this;
|
|
736
|
+
whereIn(column: keyof T | string, values: unknown[]): this;
|
|
737
|
+
whereBetween(column: keyof T | string, range: [unknown, unknown]): this;
|
|
738
|
+
select(...columns: (keyof T | string)[]): this;
|
|
739
|
+
orderBy(column: keyof T | string, direction?: 'asc' | 'desc'): this;
|
|
360
740
|
limit(n: number): this;
|
|
361
741
|
offset(n: number): this;
|
|
362
742
|
with(...relations: string[]): this;
|
|
363
743
|
withTrashed(): this;
|
|
364
744
|
onlyTrashed(): this;
|
|
365
|
-
first(): Promise<
|
|
366
|
-
list(): Promise<
|
|
367
|
-
get(): Promise<
|
|
745
|
+
first(): Promise<T | null>;
|
|
746
|
+
list(): Promise<T[]>;
|
|
747
|
+
get(): Promise<T[]>;
|
|
368
748
|
count(): Promise<number>;
|
|
369
|
-
paginate(page?: number, perPage?: number): Promise<PaginatedResult
|
|
749
|
+
paginate(page?: number, perPage?: number): Promise<PaginatedResult<T>>;
|
|
370
750
|
exists(): Promise<boolean>;
|
|
371
|
-
clone(): QueryBuilder
|
|
751
|
+
clone(): QueryBuilder<T>;
|
|
372
752
|
getWiths(): string[];
|
|
373
753
|
delete(): Promise<number>;
|
|
374
|
-
update(data: Record<string, unknown>): Promise<number>;
|
|
754
|
+
update(data: Partial<T> | Record<string, unknown>): Promise<number>;
|
|
375
755
|
[key: string]: unknown;
|
|
376
756
|
}
|
|
377
757
|
|
|
378
|
-
export interface Repository {
|
|
379
|
-
findById(id: string | number, options?: FindOptions): Promise<
|
|
380
|
-
findOne(conditions: Record<string, unknown>, options?: FindOptions): Promise<
|
|
381
|
-
findAll(options?: FindOptions): Promise<
|
|
382
|
-
create(data: Record<string, unknown>): Promise<
|
|
383
|
-
createMany(data: Record<string, unknown>[]): Promise<
|
|
384
|
-
update(id: string | number, data: Record<string, unknown>): Promise<
|
|
385
|
-
updateWhere(conditions: Record<string, unknown>, data: Record<string, unknown>): Promise<number>;
|
|
758
|
+
export interface Repository<T = Record<string, any>> {
|
|
759
|
+
findById(id: string | number, options?: FindOptions): Promise<T | null>;
|
|
760
|
+
findOne(conditions: Partial<T> | Record<string, unknown>, options?: FindOptions): Promise<T | null>;
|
|
761
|
+
findAll(options?: FindOptions): Promise<T[]>;
|
|
762
|
+
create(data: Partial<T> | Record<string, unknown>): Promise<T>;
|
|
763
|
+
createMany(data: (Partial<T> | Record<string, unknown>)[]): Promise<T[]>;
|
|
764
|
+
update(id: string | number, data: Partial<T> | Record<string, unknown>): Promise<T | null>;
|
|
765
|
+
updateWhere(conditions: Partial<T> | Record<string, unknown>, data: Partial<T> | Record<string, unknown>): Promise<number>;
|
|
386
766
|
delete(id: string | number): Promise<boolean>;
|
|
387
767
|
forceDelete(id: string | number): Promise<boolean>;
|
|
388
|
-
restore(id: string | number): Promise<
|
|
389
|
-
query(): QueryBuilder
|
|
768
|
+
restore(id: string | number): Promise<T | null>;
|
|
769
|
+
query(): QueryBuilder<T>;
|
|
390
770
|
raw(sql: string, bindings?: unknown[]): Promise<unknown>;
|
|
391
|
-
count(conditions?: Record<string, unknown>): Promise<number>;
|
|
392
|
-
exists(conditions: Record<string, unknown>): Promise<boolean>;
|
|
393
|
-
with(...relations: string[]): QueryBuilder
|
|
394
|
-
model: ModelDefinition
|
|
771
|
+
count(conditions?: Partial<T> | Record<string, unknown>): Promise<number>;
|
|
772
|
+
exists(conditions: Partial<T> | Record<string, unknown>): Promise<boolean>;
|
|
773
|
+
with(...relations: string[]): QueryBuilder<T>;
|
|
774
|
+
model: ModelDefinition<T>;
|
|
395
775
|
}
|
|
396
776
|
|
|
397
777
|
// --- ORM: database ---
|
|
@@ -471,21 +851,24 @@ export interface MigrationManager {
|
|
|
471
851
|
|
|
472
852
|
export interface TransactionContext {
|
|
473
853
|
trx: Knex.Transaction;
|
|
474
|
-
getRepository(modelName: string, scopeContext?: ScopeContext): Repository
|
|
475
|
-
createRepository(model: ModelDefinition
|
|
854
|
+
getRepository<T = Record<string, any>>(modelName: string, scopeContext?: ScopeContext): Repository<T>;
|
|
855
|
+
createRepository<T = Record<string, any>>(model: ModelDefinition<T>, scopeContext?: ScopeContext): Repository<T>;
|
|
476
856
|
}
|
|
477
857
|
|
|
478
858
|
export interface DatabaseInstance {
|
|
479
859
|
knex: Knex;
|
|
480
860
|
migrate: MigrationManager;
|
|
481
|
-
getModel(name: string): ModelDefinition
|
|
861
|
+
getModel<T = Record<string, any>>(name: string): ModelDefinition<T>;
|
|
482
862
|
hasModel(name: string): boolean;
|
|
483
|
-
getAllModels(): ModelDefinition[];
|
|
484
|
-
registerModel(model: ModelDefinition): void;
|
|
485
|
-
getRepository(modelName: string, scopeContext?: ScopeContext): Repository
|
|
486
|
-
createRepository(model: ModelDefinition
|
|
487
|
-
query(modelName: string, scopeContext?: ScopeContext): QueryBuilder
|
|
488
|
-
transaction<T>(callback: (ctx: TransactionContext) => Promise<T
|
|
863
|
+
getAllModels(): ModelDefinition<any>[];
|
|
864
|
+
registerModel<T = Record<string, any>>(model: ModelDefinition<T>): void;
|
|
865
|
+
getRepository<T = Record<string, any>>(modelName: string, scopeContext?: ScopeContext): Repository<T>;
|
|
866
|
+
createRepository<T = Record<string, any>>(model: ModelDefinition<T>, scopeContext?: ScopeContext): Repository<T>;
|
|
867
|
+
query<T = Record<string, any>>(modelName: string, scopeContext?: ScopeContext): QueryBuilder<T>;
|
|
868
|
+
transaction<T>(callback: (ctx: TransactionContext) => Promise<T>, scopeContext?: ScopeContext): Promise<T>;
|
|
869
|
+
runInTransaction<T>(callback: (ctx: TransactionContext) => Promise<T>, scopeContext?: ScopeContext): Promise<T>;
|
|
870
|
+
getAmbientTransaction(): Knex.Transaction | null;
|
|
871
|
+
hasActiveTransaction(): boolean;
|
|
489
872
|
createSeeder(): unknown;
|
|
490
873
|
cache: OrmCachePublicApi | null;
|
|
491
874
|
destroy(): Promise<void>;
|
|
@@ -493,6 +876,12 @@ export interface DatabaseInstance {
|
|
|
493
876
|
|
|
494
877
|
export function createDatabase(config: DatabaseConfig): DatabaseInstance;
|
|
495
878
|
|
|
879
|
+
export function runWithAmbientTransaction<T>(trx: Knex.Transaction, callback: () => Promise<T> | T): Promise<T>;
|
|
880
|
+
export function getAmbientTransaction(): Knex.Transaction | null;
|
|
881
|
+
export function hasAmbientTransaction(): boolean;
|
|
882
|
+
export function createTransactionContext(trx: Knex.Transaction, scopeContext?: ScopeContext): TransactionContext;
|
|
883
|
+
export function runTransaction<T>(knex: Knex, callback: (ctx: TransactionContext) => Promise<T>, scopeContext?: ScopeContext): Promise<T>;
|
|
884
|
+
|
|
496
885
|
export function createMemoryCacheProvider(options?: OrmMemoryCacheOptions): {
|
|
497
886
|
get(key: string): unknown;
|
|
498
887
|
set(key: string, value: unknown, opts?: { tags?: string[]; ttlMs?: number }): void;
|
|
@@ -549,6 +938,36 @@ export function createEventContext(
|
|
|
549
938
|
cancel(reason?: string): void;
|
|
550
939
|
};
|
|
551
940
|
|
|
941
|
+
// --- ORM: Query Complexity & DoS Protection ---
|
|
942
|
+
|
|
943
|
+
export class QueryComplexityError extends BadRequestError {
|
|
944
|
+
code: string;
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
export const DEFAULT_QUERY_LIMITS: {
|
|
948
|
+
maxLimit: number;
|
|
949
|
+
defaultLimit: number;
|
|
950
|
+
maxIncludes: number;
|
|
951
|
+
maxFilterConditions: number;
|
|
952
|
+
};
|
|
953
|
+
|
|
954
|
+
export function resolveQueryLimits(model?: ModelDefinition): typeof DEFAULT_QUERY_LIMITS;
|
|
955
|
+
|
|
956
|
+
export function validateQueryComplexity(
|
|
957
|
+
model?: ModelDefinition,
|
|
958
|
+
params?: {
|
|
959
|
+
perPage?: number;
|
|
960
|
+
limit?: number;
|
|
961
|
+
includes?: string[];
|
|
962
|
+
filterCount?: number;
|
|
963
|
+
strict?: boolean;
|
|
964
|
+
}
|
|
965
|
+
): {
|
|
966
|
+
limit: number;
|
|
967
|
+
perPage: number;
|
|
968
|
+
includes: string[];
|
|
969
|
+
};
|
|
970
|
+
|
|
552
971
|
// --- Built-in plugins (subset re-exported from main index.js) ---
|
|
553
972
|
|
|
554
973
|
export function schemaExplorerPlugin(options?: Record<string, unknown>): WebspressoPlugin;
|
|
@@ -649,6 +1068,56 @@ export interface CsrfPluginOptions {
|
|
|
649
1068
|
|
|
650
1069
|
export function csrfPlugin(options?: CsrfPluginOptions): WebspressoPlugin;
|
|
651
1070
|
|
|
1071
|
+
export interface CorsPluginOptions {
|
|
1072
|
+
origin?: string | string[] | RegExp | ((origin: string, cb: (err: Error | null, allow?: boolean | string) => void) => void) | boolean;
|
|
1073
|
+
methods?: string | string[];
|
|
1074
|
+
allowedHeaders?: string | string[];
|
|
1075
|
+
exposedHeaders?: string | string[];
|
|
1076
|
+
credentials?: boolean;
|
|
1077
|
+
maxAge?: number;
|
|
1078
|
+
preflightContinue?: boolean;
|
|
1079
|
+
optionsSuccessStatus?: number;
|
|
1080
|
+
routes?: string | string[] | boolean;
|
|
1081
|
+
global?: boolean;
|
|
1082
|
+
}
|
|
1083
|
+
|
|
1084
|
+
export function corsPlugin(options?: CorsPluginOptions): WebspressoPlugin;
|
|
1085
|
+
|
|
1086
|
+
export interface BasicAuthCredentials {
|
|
1087
|
+
username: string;
|
|
1088
|
+
password?: string;
|
|
1089
|
+
[key: string]: unknown;
|
|
1090
|
+
}
|
|
1091
|
+
|
|
1092
|
+
export interface BasicAuthPluginOptions {
|
|
1093
|
+
/** Apply basic auth as a global middleware across the application. Default false. */
|
|
1094
|
+
global?: boolean;
|
|
1095
|
+
/** Static username-password dictionary. */
|
|
1096
|
+
users?: Record<string, string>;
|
|
1097
|
+
/** Custom async/sync credential verification function. */
|
|
1098
|
+
verify?: (
|
|
1099
|
+
username: string,
|
|
1100
|
+
password: string,
|
|
1101
|
+
req: Request
|
|
1102
|
+
) => boolean | BasicAuthCredentials | Promise<boolean | BasicAuthCredentials>;
|
|
1103
|
+
/** Realm string included in WWW-Authenticate header. Default 'Restricted Area'. */
|
|
1104
|
+
realm?: string;
|
|
1105
|
+
/** Whether to send WWW-Authenticate header on 401. Default true. */
|
|
1106
|
+
challenge?: boolean;
|
|
1107
|
+
/** Route prefixes to protect when global: true. Default true (all routes). */
|
|
1108
|
+
routes?: string | string[] | boolean;
|
|
1109
|
+
/** Path prefixes to bypass basic authentication. */
|
|
1110
|
+
skipPaths?: string[];
|
|
1111
|
+
/** Custom predicate function to skip basic authentication. */
|
|
1112
|
+
skip?: (req: Request) => boolean;
|
|
1113
|
+
/** Custom 401 Unauthorized response handler, string, or object. */
|
|
1114
|
+
unauthorizedResponse?: ((req: Request, res: Response) => unknown) | string | Record<string, unknown>;
|
|
1115
|
+
/** Callback hook on successful authentication. */
|
|
1116
|
+
onAuthenticated?: (req: Request, user: BasicAuthCredentials) => void;
|
|
1117
|
+
}
|
|
1118
|
+
|
|
1119
|
+
export function basicAuthPlugin(options?: BasicAuthPluginOptions): WebspressoPlugin;
|
|
1120
|
+
|
|
652
1121
|
export interface ContentPluginOptions {
|
|
653
1122
|
db: import('./index').Database;
|
|
654
1123
|
adminPath?: string;
|
|
@@ -708,6 +1177,169 @@ export function createLocalFileProvider(options?: {
|
|
|
708
1177
|
publicBasePath?: string;
|
|
709
1178
|
}): UploadStorageProvider;
|
|
710
1179
|
|
|
1180
|
+
// --- Realtime Layer Types ---
|
|
1181
|
+
|
|
1182
|
+
export interface RealtimeSubscriptionCallbacks {
|
|
1183
|
+
connected?: () => void;
|
|
1184
|
+
disconnected?: () => void;
|
|
1185
|
+
rejected?: (error: Error) => void;
|
|
1186
|
+
received?: (data: unknown) => void;
|
|
1187
|
+
}
|
|
1188
|
+
|
|
1189
|
+
export interface RealtimeSubscription {
|
|
1190
|
+
id: string;
|
|
1191
|
+
identifier: string;
|
|
1192
|
+
params: Record<string, unknown>;
|
|
1193
|
+
send(data: unknown): void;
|
|
1194
|
+
perform(action: string, data?: unknown): void;
|
|
1195
|
+
unsubscribe(): void;
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1198
|
+
export interface RealtimeAdapter {
|
|
1199
|
+
capabilities?: {
|
|
1200
|
+
send?: boolean;
|
|
1201
|
+
perform?: boolean;
|
|
1202
|
+
multiplexing?: boolean;
|
|
1203
|
+
serverEvents?: boolean;
|
|
1204
|
+
binary?: boolean;
|
|
1205
|
+
[key: string]: boolean | undefined;
|
|
1206
|
+
};
|
|
1207
|
+
connect(context: { auth: Record<string, unknown>; client: RealtimeClient }): Promise<void>;
|
|
1208
|
+
disconnect(): void;
|
|
1209
|
+
isConnected(): boolean;
|
|
1210
|
+
subscribe(
|
|
1211
|
+
identifier: string,
|
|
1212
|
+
params: Record<string, unknown>,
|
|
1213
|
+
callbacks: RealtimeSubscriptionCallbacks
|
|
1214
|
+
): {
|
|
1215
|
+
send?(data: unknown): void;
|
|
1216
|
+
perform?(action: string, data?: unknown): void;
|
|
1217
|
+
unsubscribe(): void;
|
|
1218
|
+
};
|
|
1219
|
+
send?(identifier: string, data: unknown, sub?: RealtimeSubscription): void;
|
|
1220
|
+
perform?(identifier: string, action: string, data?: unknown, sub?: RealtimeSubscription): void;
|
|
1221
|
+
unsubscribe?(identifier: string, params: Record<string, unknown>, sub?: RealtimeSubscription): void;
|
|
1222
|
+
on?(event: string, handler: (...args: any[]) => void): () => void;
|
|
1223
|
+
destroy?(): void;
|
|
1224
|
+
}
|
|
1225
|
+
|
|
1226
|
+
export type RealtimeAuthStrategy =
|
|
1227
|
+
| false
|
|
1228
|
+
| {
|
|
1229
|
+
strategy: 'cookie';
|
|
1230
|
+
}
|
|
1231
|
+
| {
|
|
1232
|
+
strategy: 'token';
|
|
1233
|
+
getToken: () => string | Promise<string>;
|
|
1234
|
+
refreshToken?: () => string | Promise<string>;
|
|
1235
|
+
onUnauthorized?: (error: Error) => void;
|
|
1236
|
+
}
|
|
1237
|
+
| {
|
|
1238
|
+
strategy: 'custom';
|
|
1239
|
+
resolve: () => Record<string, unknown> | Promise<Record<string, unknown>>;
|
|
1240
|
+
};
|
|
1241
|
+
|
|
1242
|
+
export interface RealtimeReconnectOptions {
|
|
1243
|
+
enabled?: boolean;
|
|
1244
|
+
maxAttempts?: number;
|
|
1245
|
+
baseDelay?: number;
|
|
1246
|
+
maxDelay?: number;
|
|
1247
|
+
factor?: number;
|
|
1248
|
+
jitter?: boolean;
|
|
1249
|
+
}
|
|
1250
|
+
|
|
1251
|
+
export interface RealtimeOptions {
|
|
1252
|
+
adapter: RealtimeAdapter;
|
|
1253
|
+
auth?: RealtimeAuthStrategy;
|
|
1254
|
+
autoConnect?: boolean;
|
|
1255
|
+
reconnect?: RealtimeReconnectOptions;
|
|
1256
|
+
isBrowser?: boolean;
|
|
1257
|
+
}
|
|
1258
|
+
|
|
1259
|
+
export interface RealtimeClient {
|
|
1260
|
+
capabilities: Record<string, boolean>;
|
|
1261
|
+
isConnected(): boolean;
|
|
1262
|
+
connect(overrideAuth?: Record<string, unknown> | null): Promise<void>;
|
|
1263
|
+
disconnect(): void;
|
|
1264
|
+
reconnect(): Promise<void>;
|
|
1265
|
+
reauthenticate(): Promise<void>;
|
|
1266
|
+
subscribe(
|
|
1267
|
+
identifier: string,
|
|
1268
|
+
params?: Record<string, unknown>,
|
|
1269
|
+
callbacks?: RealtimeSubscriptionCallbacks
|
|
1270
|
+
): RealtimeSubscription;
|
|
1271
|
+
on(event: 'connected' | 'disconnected' | 'reconnecting' | 'reconnected' | 'unauthorized' | 'error', handler: (...args: any[]) => void): () => void;
|
|
1272
|
+
once(event: string, handler: (...args: any[]) => void): () => void;
|
|
1273
|
+
off(event: string, handler: (...args: any[]) => void): () => void;
|
|
1274
|
+
destroy(): void;
|
|
1275
|
+
}
|
|
1276
|
+
|
|
1277
|
+
export function createRealtime(options: RealtimeOptions): RealtimeClient;
|
|
1278
|
+
export function realtime(options: RealtimeOptions): RealtimeClient & { plugin: WebspressoPlugin };
|
|
1279
|
+
export function realtimePlugin(options: RealtimeOptions): WebspressoPlugin;
|
|
1280
|
+
|
|
1281
|
+
export interface WebSocketAdapterOptions {
|
|
1282
|
+
url: string | ((context: { auth: Record<string, unknown> }) => string | Promise<string>);
|
|
1283
|
+
authTransport?: 'query' | 'header' | 'protocol' | 'message';
|
|
1284
|
+
queryParamName?: string;
|
|
1285
|
+
protocols?: string | string[];
|
|
1286
|
+
WebSocket?: any;
|
|
1287
|
+
messages?: {
|
|
1288
|
+
subscribe?: (args: { identifier: string; params: Record<string, unknown> }) => unknown;
|
|
1289
|
+
unsubscribe?: (args: { identifier: string; params: Record<string, unknown> }) => unknown;
|
|
1290
|
+
perform?: (args: { identifier: string; action: string; data?: unknown }) => unknown;
|
|
1291
|
+
send?: (args: { identifier: string; data: unknown }) => unknown;
|
|
1292
|
+
auth?: (args: { token: string; metadata: Record<string, unknown> }) => unknown;
|
|
1293
|
+
};
|
|
1294
|
+
capabilities?: Record<string, boolean>;
|
|
1295
|
+
}
|
|
1296
|
+
|
|
1297
|
+
export function websocket(options: WebSocketAdapterOptions): RealtimeAdapter;
|
|
1298
|
+
export function createWebSocketAdapter(options: WebSocketAdapterOptions): RealtimeAdapter;
|
|
1299
|
+
|
|
1300
|
+
export interface SseAdapterOptions {
|
|
1301
|
+
url: string | ((context: { auth: Record<string, unknown> }) => string | Promise<string>);
|
|
1302
|
+
queryParamName?: string;
|
|
1303
|
+
EventSource?: any;
|
|
1304
|
+
capabilities?: Record<string, boolean>;
|
|
1305
|
+
}
|
|
1306
|
+
|
|
1307
|
+
export function sse(options: SseAdapterOptions): RealtimeAdapter;
|
|
1308
|
+
export function createSseAdapter(options: SseAdapterOptions): RealtimeAdapter;
|
|
1309
|
+
|
|
1310
|
+
export interface SocketIoAdapterOptions {
|
|
1311
|
+
url?: string | ((context: { auth: Record<string, unknown> }) => string | Promise<string>);
|
|
1312
|
+
path?: string;
|
|
1313
|
+
io?: any;
|
|
1314
|
+
socketOptions?: Record<string, unknown>;
|
|
1315
|
+
capabilities?: Record<string, boolean>;
|
|
1316
|
+
}
|
|
1317
|
+
|
|
1318
|
+
export function socketIo(options: SocketIoAdapterOptions): RealtimeAdapter;
|
|
1319
|
+
export function createSocketIoAdapter(options: SocketIoAdapterOptions): RealtimeAdapter;
|
|
1320
|
+
|
|
1321
|
+
export interface RedisAdapterOptions {
|
|
1322
|
+
pubClient?: any;
|
|
1323
|
+
subClient?: any;
|
|
1324
|
+
redis?: any;
|
|
1325
|
+
channelPrefix?: string;
|
|
1326
|
+
nodeId?: string;
|
|
1327
|
+
serialize?: (envelope: unknown) => string;
|
|
1328
|
+
deserialize?: (raw: string) => unknown;
|
|
1329
|
+
inMemory?: boolean;
|
|
1330
|
+
capabilities?: Record<string, boolean>;
|
|
1331
|
+
}
|
|
1332
|
+
|
|
1333
|
+
export interface RedisRealtimeAdapter extends RealtimeAdapter {
|
|
1334
|
+
publish(identifier: string, data: unknown): Promise<void>;
|
|
1335
|
+
perform(identifier: string, action: string, data?: unknown): Promise<void>;
|
|
1336
|
+
readonly isInMemory: boolean;
|
|
1337
|
+
readonly nodeId: string;
|
|
1338
|
+
}
|
|
1339
|
+
|
|
1340
|
+
export function redis(options?: RedisAdapterOptions): RedisRealtimeAdapter;
|
|
1341
|
+
export function createRedisAdapter(options?: RedisAdapterOptions): RedisRealtimeAdapter;
|
|
1342
|
+
|
|
711
1343
|
// --- Application kernel (use `kernel.createApp`; not the SSR `createApp`) ---
|
|
712
1344
|
|
|
713
1345
|
export type KernelEventSource = 'orm' | 'auth' | 'route' | 'plugin' | 'system';
|
|
@@ -807,3 +1439,242 @@ export interface WebspressoKernel {
|
|
|
807
1439
|
}
|
|
808
1440
|
|
|
809
1441
|
export const kernel: WebspressoKernel;
|
|
1442
|
+
|
|
1443
|
+
// --- Background Job Queue ---
|
|
1444
|
+
|
|
1445
|
+
export interface JobJSON {
|
|
1446
|
+
id: string | number;
|
|
1447
|
+
name: string;
|
|
1448
|
+
data: unknown;
|
|
1449
|
+
status: 'pending' | 'running' | 'completed' | 'failed';
|
|
1450
|
+
attempts: number;
|
|
1451
|
+
maxAttempts: number;
|
|
1452
|
+
backoff: unknown;
|
|
1453
|
+
priority: number;
|
|
1454
|
+
timeout: number;
|
|
1455
|
+
progress: number;
|
|
1456
|
+
result: unknown;
|
|
1457
|
+
error: string | null;
|
|
1458
|
+
createdAt: string;
|
|
1459
|
+
updatedAt: string;
|
|
1460
|
+
runAt: string;
|
|
1461
|
+
}
|
|
1462
|
+
|
|
1463
|
+
export class Job {
|
|
1464
|
+
id: string | number;
|
|
1465
|
+
name: string;
|
|
1466
|
+
data: any;
|
|
1467
|
+
status: 'pending' | 'running' | 'completed' | 'failed';
|
|
1468
|
+
attempts: number;
|
|
1469
|
+
maxAttempts: number;
|
|
1470
|
+
backoff: number | { type?: 'exponential' | 'fixed'; delay?: number };
|
|
1471
|
+
priority: number;
|
|
1472
|
+
timeout: number;
|
|
1473
|
+
progressValue: number;
|
|
1474
|
+
result: any;
|
|
1475
|
+
error: any;
|
|
1476
|
+
createdAt: Date;
|
|
1477
|
+
updatedAt: Date;
|
|
1478
|
+
runAt: Date;
|
|
1479
|
+
constructor(options?: Record<string, any>);
|
|
1480
|
+
progress(percent: number, message?: string): void;
|
|
1481
|
+
getNextRetryDelay(): number;
|
|
1482
|
+
toJSON(): JobJSON;
|
|
1483
|
+
}
|
|
1484
|
+
|
|
1485
|
+
export interface QueueAdapter {
|
|
1486
|
+
enqueue(job: Job): Promise<Job>;
|
|
1487
|
+
dequeue(jobNames?: string[]): Promise<Job | null>;
|
|
1488
|
+
complete(jobId: string | number, result?: unknown): Promise<Job | null>;
|
|
1489
|
+
fail(jobId: string | number, error?: unknown): Promise<Job | null>;
|
|
1490
|
+
retry(jobId: string | number, delayMs: number, error?: unknown): Promise<Job | null>;
|
|
1491
|
+
getJob(jobId: string | number): Promise<Job | null>;
|
|
1492
|
+
getStats(): Promise<{ pending: number; running: number; completed: number; failed: number; total: number }>;
|
|
1493
|
+
clear(): Promise<void>;
|
|
1494
|
+
}
|
|
1495
|
+
|
|
1496
|
+
export class MemoryQueueAdapter implements QueueAdapter {
|
|
1497
|
+
enqueue(job: Job): Promise<Job>;
|
|
1498
|
+
dequeue(jobNames?: string[]): Promise<Job | null>;
|
|
1499
|
+
complete(jobId: string | number, result?: unknown): Promise<Job | null>;
|
|
1500
|
+
fail(jobId: string | number, error?: unknown): Promise<Job | null>;
|
|
1501
|
+
retry(jobId: string | number, delayMs: number, error?: unknown): Promise<Job | null>;
|
|
1502
|
+
getJob(jobId: string | number): Promise<Job | null>;
|
|
1503
|
+
getStats(): Promise<{ pending: number; running: number; completed: number; failed: number; total: number }>;
|
|
1504
|
+
clear(): Promise<void>;
|
|
1505
|
+
}
|
|
1506
|
+
|
|
1507
|
+
export class DatabaseQueueAdapter implements QueueAdapter {
|
|
1508
|
+
constructor(options: { knex: Knex; tableName?: string });
|
|
1509
|
+
ensureTable(): Promise<void>;
|
|
1510
|
+
enqueue(job: Job): Promise<Job>;
|
|
1511
|
+
dequeue(jobNames?: string[]): Promise<Job | null>;
|
|
1512
|
+
complete(jobId: string | number, result?: unknown): Promise<Job | null>;
|
|
1513
|
+
fail(jobId: string | number, error?: unknown): Promise<Job | null>;
|
|
1514
|
+
retry(jobId: string | number, delayMs: number, error?: unknown): Promise<Job | null>;
|
|
1515
|
+
getJob(jobId: string | number): Promise<Job | null>;
|
|
1516
|
+
getStats(): Promise<{ pending: number; running: number; completed: number; failed: number; total: number }>;
|
|
1517
|
+
clear(): Promise<void>;
|
|
1518
|
+
}
|
|
1519
|
+
|
|
1520
|
+
export class RedisQueueAdapter implements QueueAdapter {
|
|
1521
|
+
constructor(options: { client: unknown; prefix?: string });
|
|
1522
|
+
enqueue(job: Job): Promise<Job>;
|
|
1523
|
+
dequeue(jobNames?: string[]): Promise<Job | null>;
|
|
1524
|
+
complete(jobId: string | number, result?: unknown): Promise<Job | null>;
|
|
1525
|
+
fail(jobId: string | number, error?: unknown): Promise<Job | null>;
|
|
1526
|
+
retry(jobId: string | number, delayMs: number, error?: unknown): Promise<Job | null>;
|
|
1527
|
+
getJob(jobId: string | number): Promise<Job | null>;
|
|
1528
|
+
getStats(): Promise<{ pending: number; running: number; completed: number; failed: number; total: number }>;
|
|
1529
|
+
clear(): Promise<void>;
|
|
1530
|
+
}
|
|
1531
|
+
|
|
1532
|
+
export interface DispatchOptions {
|
|
1533
|
+
delay?: number | Date;
|
|
1534
|
+
attempts?: number;
|
|
1535
|
+
priority?: number;
|
|
1536
|
+
timeout?: number;
|
|
1537
|
+
backoff?: number | { type?: 'exponential' | 'fixed'; delay?: number };
|
|
1538
|
+
}
|
|
1539
|
+
|
|
1540
|
+
export class QueueManager extends import('events').EventEmitter {
|
|
1541
|
+
adapter: QueueAdapter;
|
|
1542
|
+
concurrency: number;
|
|
1543
|
+
pollInterval: number;
|
|
1544
|
+
isRunning: boolean;
|
|
1545
|
+
isPaused: boolean;
|
|
1546
|
+
isDraining: boolean;
|
|
1547
|
+
constructor(options?: {
|
|
1548
|
+
adapter?: QueueAdapter;
|
|
1549
|
+
concurrency?: number;
|
|
1550
|
+
pollInterval?: number;
|
|
1551
|
+
jobsDir?: string | null;
|
|
1552
|
+
autoStart?: boolean;
|
|
1553
|
+
});
|
|
1554
|
+
define(name: string, handler: (job: Job, ctx: { queue: QueueManager }) => Promise<any> | any, options?: DispatchOptions): this;
|
|
1555
|
+
has(name: string): boolean;
|
|
1556
|
+
dispatch(name: string, data?: unknown, options?: DispatchOptions): Promise<Job>;
|
|
1557
|
+
start(): this;
|
|
1558
|
+
pause(): this;
|
|
1559
|
+
resume(): this;
|
|
1560
|
+
drain(timeoutMs?: number): Promise<void>;
|
|
1561
|
+
stop(): Promise<void>;
|
|
1562
|
+
getStats(): Promise<Record<string, unknown>>;
|
|
1563
|
+
getJob(jobId: string | number): Promise<Job | null>;
|
|
1564
|
+
loadJobsFromDirectory(dirPath: string): void;
|
|
1565
|
+
}
|
|
1566
|
+
|
|
1567
|
+
export function createQueueManager(options?: {
|
|
1568
|
+
adapter?: QueueAdapter;
|
|
1569
|
+
concurrency?: number;
|
|
1570
|
+
pollInterval?: number;
|
|
1571
|
+
jobsDir?: string | null;
|
|
1572
|
+
autoStart?: boolean;
|
|
1573
|
+
}): QueueManager;
|
|
1574
|
+
|
|
1575
|
+
export function queuePlugin(options?: {
|
|
1576
|
+
adapter?: 'memory' | 'database' | 'db' | 'redis' | QueueAdapter;
|
|
1577
|
+
db?: { knex: Knex };
|
|
1578
|
+
knex?: Knex;
|
|
1579
|
+
redisClient?: unknown;
|
|
1580
|
+
tableName?: string;
|
|
1581
|
+
concurrency?: number;
|
|
1582
|
+
pollInterval?: number;
|
|
1583
|
+
jobsDir?: string;
|
|
1584
|
+
autoStart?: boolean;
|
|
1585
|
+
}): PluginDefinition;
|
|
1586
|
+
|
|
1587
|
+
// --- SSR Streaming & Chunked Transfer ---
|
|
1588
|
+
|
|
1589
|
+
export interface HtmlStreamOptions {
|
|
1590
|
+
env: import('nunjucks').Environment;
|
|
1591
|
+
templatePath: string;
|
|
1592
|
+
context?: Record<string, unknown>;
|
|
1593
|
+
defer?: Record<string, Promise<unknown> | { promise: Promise<unknown>; template?: string }>;
|
|
1594
|
+
}
|
|
1595
|
+
|
|
1596
|
+
export interface RenderStreamOptions {
|
|
1597
|
+
env?: import('nunjucks').Environment;
|
|
1598
|
+
defer?: Record<string, Promise<unknown> | { promise: Promise<unknown>; template?: string }>;
|
|
1599
|
+
status?: number;
|
|
1600
|
+
flushImmediately?: boolean;
|
|
1601
|
+
}
|
|
1602
|
+
|
|
1603
|
+
export function createHtmlStream(options: HtmlStreamOptions): import('stream').Readable;
|
|
1604
|
+
export function renderStream(
|
|
1605
|
+
res: import('express').Response,
|
|
1606
|
+
templatePath: string,
|
|
1607
|
+
context?: Record<string, unknown>,
|
|
1608
|
+
options?: RenderStreamOptions
|
|
1609
|
+
): Promise<void>;
|
|
1610
|
+
|
|
1611
|
+
export const ssr: {
|
|
1612
|
+
createHtmlStream: typeof createHtmlStream;
|
|
1613
|
+
renderStream: typeof renderStream;
|
|
1614
|
+
};
|
|
1615
|
+
|
|
1616
|
+
// --- Model Context Protocol (MCP) Plugin ---
|
|
1617
|
+
|
|
1618
|
+
export interface McpPluginOptions {
|
|
1619
|
+
path?: string;
|
|
1620
|
+
enabled?: boolean;
|
|
1621
|
+
auth?: {
|
|
1622
|
+
token?: string;
|
|
1623
|
+
localhostOnly?: boolean;
|
|
1624
|
+
verify?: (req: import('express').Request) => boolean | Promise<boolean>;
|
|
1625
|
+
};
|
|
1626
|
+
services?: boolean | {
|
|
1627
|
+
include?: string[];
|
|
1628
|
+
exclude?: string[];
|
|
1629
|
+
readOnly?: boolean;
|
|
1630
|
+
role?: string | string[];
|
|
1631
|
+
};
|
|
1632
|
+
orm?: boolean | {
|
|
1633
|
+
readOnly?: boolean;
|
|
1634
|
+
models?: string[];
|
|
1635
|
+
};
|
|
1636
|
+
system?: boolean;
|
|
1637
|
+
tools?: Array<{
|
|
1638
|
+
name: string;
|
|
1639
|
+
description?: string;
|
|
1640
|
+
inputSchema?: Record<string, unknown>;
|
|
1641
|
+
handler: (args: any, ctx: any) => Promise<any> | any;
|
|
1642
|
+
}>;
|
|
1643
|
+
resources?: Array<{
|
|
1644
|
+
uri?: string;
|
|
1645
|
+
uriTemplate?: string;
|
|
1646
|
+
name?: string;
|
|
1647
|
+
description?: string;
|
|
1648
|
+
mimeType?: string;
|
|
1649
|
+
handler: (uri: string, paramsOrCtx: any, ctx?: any) => Promise<any> | any;
|
|
1650
|
+
}>;
|
|
1651
|
+
prompts?: Array<{
|
|
1652
|
+
name: string;
|
|
1653
|
+
description?: string;
|
|
1654
|
+
arguments?: Array<{ name: string; description?: string; required?: boolean }>;
|
|
1655
|
+
handler: (args: any, ctx: any) => Promise<any> | any;
|
|
1656
|
+
}>;
|
|
1657
|
+
discovery?: boolean;
|
|
1658
|
+
name?: string;
|
|
1659
|
+
version?: string;
|
|
1660
|
+
instructions?: string;
|
|
1661
|
+
}
|
|
1662
|
+
|
|
1663
|
+
export class McpServer {
|
|
1664
|
+
name: string;
|
|
1665
|
+
version: string;
|
|
1666
|
+
instructions: string;
|
|
1667
|
+
constructor(options?: { name?: string; version?: string; instructions?: string; context?: Record<string, unknown> });
|
|
1668
|
+
registerTool(toolDef: any): this;
|
|
1669
|
+
registerTools(toolDefs: any[]): this;
|
|
1670
|
+
unregisterTool(name: string): boolean;
|
|
1671
|
+
registerResource(resourceDef: any): this;
|
|
1672
|
+
registerResourceTemplate(templateDef: any): this;
|
|
1673
|
+
registerPrompt(promptDef: any): this;
|
|
1674
|
+
handleMessage(message: any, callContext?: any): Promise<any>;
|
|
1675
|
+
}
|
|
1676
|
+
|
|
1677
|
+
export function mcpPlugin(options?: McpPluginOptions): WebspressoPlugin;
|
|
1678
|
+
export function createMcpServer(options?: McpPluginOptions): McpServer;
|
|
1679
|
+
|
|
1680
|
+
|