@cequrebackends/cequre-ts 0.11.4
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/dist/adapters/bun/bun-cron.d.ts +20 -0
- package/dist/adapters/bun/bun-media.d.ts +9 -0
- package/dist/adapters/bun/bun-redis-cache.d.ts +33 -0
- package/dist/adapters/bun/bun-response.d.ts +13 -0
- package/dist/adapters/bun/bun-server.d.ts +6 -0
- package/dist/adapters/bun/bun-storage.d.ts +10 -0
- package/dist/adapters/bun/bun-websocket.d.ts +104 -0
- package/dist/adapters/bun/index.d.ts +9 -0
- package/dist/adapters/bun/index.js +547 -0
- package/dist/adapters/node/index.d.ts +9 -0
- package/dist/adapters/node/index.js +902 -0
- package/dist/adapters/node/node-cron.d.ts +20 -0
- package/dist/adapters/node/node-media.d.ts +9 -0
- package/dist/adapters/node/node-redis-cache.d.ts +32 -0
- package/dist/adapters/node/node-response.d.ts +13 -0
- package/dist/adapters/node/node-server.d.ts +6 -0
- package/dist/adapters/node/node-storage.d.ts +10 -0
- package/dist/adapters/node/node-websocket.d.ts +102 -0
- package/dist/index-17yswtmg.js +175 -0
- package/dist/index-kyvy0s1x.js +2662 -0
- package/dist/index-mfqj7cwr.js +165 -0
- package/dist/index-rf1kdn5b.js +732 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +3152 -0
- package/dist/interface-map.d.ts +175 -0
- package/dist/shared/core/adapter.d.ts +84 -0
- package/dist/shared/core/base-sql-adapter.d.ts +34 -0
- package/dist/shared/core/cache.d.ts +8 -0
- package/dist/shared/core/email.d.ts +53 -0
- package/dist/shared/core/index.d.ts +12 -0
- package/dist/shared/core/index.js +47 -0
- package/dist/shared/core/openapi.d.ts +24 -0
- package/dist/shared/core/plugins.d.ts +2 -0
- package/dist/shared/core/request.d.ts +32 -0
- package/dist/shared/core/sdk.d.ts +3 -0
- package/dist/shared/core/stream.d.ts +24 -0
- package/dist/shared/core/types-generator.d.ts +0 -0
- package/dist/shared/core/types.d.ts +304 -0
- package/dist/shared/core/ulid.d.ts +5 -0
- package/dist/shared/core/validator.d.ts +32 -0
- package/dist/shared/main/access-evaluator.d.ts +13 -0
- package/dist/shared/main/access.d.ts +34 -0
- package/dist/shared/main/aot.d.ts +3 -0
- package/dist/shared/main/hooks.d.ts +76 -0
- package/dist/shared/main/population.d.ts +13 -0
- package/dist/shared/main/router.d.ts +112 -0
- package/dist/shared/main/runtime.d.ts +195 -0
- package/dist/shared/main/sse.d.ts +87 -0
- package/dist/shared/utils/crypto.d.ts +23 -0
- package/dist/shared/utils/durable-queue.d.ts +20 -0
- package/dist/shared/utils/duration.d.ts +15 -0
- package/dist/shared/utils/error.d.ts +52 -0
- package/dist/shared/utils/kv/adapters/memory.d.ts +20 -0
- package/dist/shared/utils/kv/adapters/sqlite.d.ts +32 -0
- package/dist/shared/utils/kv/index.d.ts +37 -0
- package/dist/shared/utils/kv/types.d.ts +38 -0
- package/dist/shared/utils/logger.d.ts +42 -0
- package/dist/shared/utils/queue-manager.d.ts +64 -0
- package/dist/shared/utils/url.d.ts +13 -0
- package/package.json +63 -0
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
import type { CequreRequestContext } from "../main/access";
|
|
2
|
+
export interface CequreAST {
|
|
3
|
+
collections: CollectionConfig[];
|
|
4
|
+
globals?: CollectionConfig[];
|
|
5
|
+
core?: {
|
|
6
|
+
api?: {
|
|
7
|
+
prefix?: string;
|
|
8
|
+
version?: string;
|
|
9
|
+
deprecatedVersions?: string[];
|
|
10
|
+
sunsetDate?: string;
|
|
11
|
+
maxBodyBytes?: number;
|
|
12
|
+
requestTimeoutMs?: number;
|
|
13
|
+
trustedProxies?: string[];
|
|
14
|
+
docs?: {
|
|
15
|
+
enabled?: boolean;
|
|
16
|
+
authRequired?: boolean;
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
adminUI?: {
|
|
21
|
+
enabled?: boolean;
|
|
22
|
+
user?: string;
|
|
23
|
+
};
|
|
24
|
+
migrate?: {
|
|
25
|
+
dropOrphan?: boolean;
|
|
26
|
+
};
|
|
27
|
+
security?: {
|
|
28
|
+
auth?: {
|
|
29
|
+
strategies?: string[];
|
|
30
|
+
jwt?: {
|
|
31
|
+
accessTokenExpiry?: string;
|
|
32
|
+
refreshTokenExpiry?: string;
|
|
33
|
+
cookies?: {
|
|
34
|
+
name?: string;
|
|
35
|
+
timeout?: string;
|
|
36
|
+
domain?: string;
|
|
37
|
+
secure?: boolean;
|
|
38
|
+
httpOnly?: boolean;
|
|
39
|
+
sameSite?: "lax" | "strict" | "none";
|
|
40
|
+
refreshToken?: boolean;
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
apiKey?: {
|
|
44
|
+
header?: string;
|
|
45
|
+
enabled?: boolean;
|
|
46
|
+
};
|
|
47
|
+
passwordPolicy?: {
|
|
48
|
+
minLength?: number;
|
|
49
|
+
requireUppercase?: boolean;
|
|
50
|
+
requireNumber?: boolean;
|
|
51
|
+
};
|
|
52
|
+
lockout?: {
|
|
53
|
+
maxAttempts?: number;
|
|
54
|
+
durationMinutes?: number;
|
|
55
|
+
};
|
|
56
|
+
mfa?: {
|
|
57
|
+
enabled?: boolean;
|
|
58
|
+
issuer?: string;
|
|
59
|
+
enforceForRoles?: string[];
|
|
60
|
+
backupCodeCount?: number;
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
tls?: {
|
|
64
|
+
cert?: string;
|
|
65
|
+
key?: string;
|
|
66
|
+
passphrase?: string;
|
|
67
|
+
serverName?: string;
|
|
68
|
+
};
|
|
69
|
+
cors?: {
|
|
70
|
+
origin?: string[];
|
|
71
|
+
credentials?: boolean;
|
|
72
|
+
};
|
|
73
|
+
rateLimit?: {
|
|
74
|
+
read?: {
|
|
75
|
+
max?: number;
|
|
76
|
+
window?: string;
|
|
77
|
+
};
|
|
78
|
+
write?: {
|
|
79
|
+
max?: number;
|
|
80
|
+
window?: string;
|
|
81
|
+
};
|
|
82
|
+
login?: {
|
|
83
|
+
max?: number;
|
|
84
|
+
window?: string;
|
|
85
|
+
};
|
|
86
|
+
};
|
|
87
|
+
headers?: {
|
|
88
|
+
enabled?: boolean;
|
|
89
|
+
contentSecurityPolicy?: string | false;
|
|
90
|
+
};
|
|
91
|
+
audit?: {
|
|
92
|
+
enabled?: boolean;
|
|
93
|
+
secret?: string;
|
|
94
|
+
retentionDays?: number;
|
|
95
|
+
};
|
|
96
|
+
secrets?: {
|
|
97
|
+
enabled?: boolean;
|
|
98
|
+
encryptionKey?: string;
|
|
99
|
+
};
|
|
100
|
+
csrfTrustedOrigins?: string[];
|
|
101
|
+
};
|
|
102
|
+
monitoring?: {
|
|
103
|
+
enabled?: boolean;
|
|
104
|
+
apiKey?: string;
|
|
105
|
+
healthCheck?: {
|
|
106
|
+
enabled?: boolean;
|
|
107
|
+
path?: string;
|
|
108
|
+
requiresAuth?: boolean;
|
|
109
|
+
};
|
|
110
|
+
requestId?: {
|
|
111
|
+
enabled?: boolean;
|
|
112
|
+
};
|
|
113
|
+
};
|
|
114
|
+
email?: {
|
|
115
|
+
from?: string;
|
|
116
|
+
appName?: string;
|
|
117
|
+
resetTokenExpiryMinutes?: number;
|
|
118
|
+
resetPasswordUrl?: string;
|
|
119
|
+
verifyEmailUrl?: string;
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
export interface CollectionConfig {
|
|
123
|
+
slug: string;
|
|
124
|
+
hidden?: boolean;
|
|
125
|
+
auth?: boolean;
|
|
126
|
+
realtime?: {
|
|
127
|
+
secure?: boolean;
|
|
128
|
+
ws?: boolean | string[];
|
|
129
|
+
sse?: boolean | string[];
|
|
130
|
+
durableStream?: boolean | string[];
|
|
131
|
+
};
|
|
132
|
+
cache?: {
|
|
133
|
+
ttl?: string | number;
|
|
134
|
+
strategy?: "stale-while-revalidate" | string;
|
|
135
|
+
};
|
|
136
|
+
fields: FieldConfig[];
|
|
137
|
+
}
|
|
138
|
+
export interface FieldConfig {
|
|
139
|
+
name: string;
|
|
140
|
+
type: string;
|
|
141
|
+
unique?: boolean;
|
|
142
|
+
optional?: boolean;
|
|
143
|
+
hidden?: boolean;
|
|
144
|
+
omit?: boolean;
|
|
145
|
+
default?: any;
|
|
146
|
+
target?: string;
|
|
147
|
+
on?: string;
|
|
148
|
+
values?: string[];
|
|
149
|
+
options?: string[];
|
|
150
|
+
encrypt?: boolean;
|
|
151
|
+
readRoles?: string[];
|
|
152
|
+
writeRoles?: string[];
|
|
153
|
+
saveToJWT?: boolean;
|
|
154
|
+
searchable?: boolean;
|
|
155
|
+
fields?: FieldConfig[];
|
|
156
|
+
isArray?: boolean;
|
|
157
|
+
}
|
|
158
|
+
export interface UploadedFile {
|
|
159
|
+
filename: string;
|
|
160
|
+
originalName: string;
|
|
161
|
+
mimetype: string;
|
|
162
|
+
size: number;
|
|
163
|
+
url: string;
|
|
164
|
+
}
|
|
165
|
+
export interface StorageProvider {
|
|
166
|
+
saveFile(file: File, options?: {
|
|
167
|
+
filename?: string;
|
|
168
|
+
}): Promise<UploadedFile>;
|
|
169
|
+
deleteFile(filename: string): Promise<void>;
|
|
170
|
+
initMultipartUpload?(options: {
|
|
171
|
+
filename: string;
|
|
172
|
+
mimetype: string;
|
|
173
|
+
size: number;
|
|
174
|
+
}): Promise<{
|
|
175
|
+
uploadId: string;
|
|
176
|
+
filename: string;
|
|
177
|
+
parts?: {
|
|
178
|
+
partNumber: number;
|
|
179
|
+
url: string;
|
|
180
|
+
}[];
|
|
181
|
+
}>;
|
|
182
|
+
completeMultipartUpload?(uploadId: string, filename: string, parts: {
|
|
183
|
+
partNumber: number;
|
|
184
|
+
etag?: string;
|
|
185
|
+
}[]): Promise<UploadedFile>;
|
|
186
|
+
getFileUrl?(filename: string): Promise<string | undefined>;
|
|
187
|
+
}
|
|
188
|
+
export interface CacheStore {
|
|
189
|
+
get(key: string): Promise<any | null>;
|
|
190
|
+
set(key: string, value: any, ttlSeconds?: number): Promise<void>;
|
|
191
|
+
del(...keys: string[]): Promise<number>;
|
|
192
|
+
close(): void;
|
|
193
|
+
}
|
|
194
|
+
export type PluginCompilePhase = "request.start" | "beforeHandler" | "afterHandler" | "request.completed" | "request.error";
|
|
195
|
+
export interface CompileVars {
|
|
196
|
+
[key: string]: string;
|
|
197
|
+
}
|
|
198
|
+
export interface AOTCompileContext {
|
|
199
|
+
phase: PluginCompilePhase;
|
|
200
|
+
vars: CompileVars;
|
|
201
|
+
state: Record<string, any>;
|
|
202
|
+
}
|
|
203
|
+
export interface CequrePlugin {
|
|
204
|
+
name: string;
|
|
205
|
+
runsBefore?: string[];
|
|
206
|
+
runsAfter?: string[];
|
|
207
|
+
onInit?: (app: any) => void | Promise<void>;
|
|
208
|
+
onCompile?: (ctx: AOTCompileContext) => string | undefined;
|
|
209
|
+
preRequest?: (request: Request) => void | Response | Promise<void | Response>;
|
|
210
|
+
beforeRequest?: (ctx: CequreRequestContext) => void | Promise<void>;
|
|
211
|
+
afterRequest?: (ctx: CequreRequestContext, response: Response) => void | Promise<void>;
|
|
212
|
+
onError?: (ctx: CequreRequestContext, error: any) => Response | void | Promise<Response | void>;
|
|
213
|
+
onDestroy?: () => void | Promise<void>;
|
|
214
|
+
}
|
|
215
|
+
export interface CequreEmailSendOptions {
|
|
216
|
+
from?: string;
|
|
217
|
+
to?: string;
|
|
218
|
+
cc?: string;
|
|
219
|
+
bcc?: string;
|
|
220
|
+
replyTo?: string;
|
|
221
|
+
subject?: string;
|
|
222
|
+
text?: string;
|
|
223
|
+
html?: string;
|
|
224
|
+
}
|
|
225
|
+
export interface CequreEmailTransport {
|
|
226
|
+
send(options: CequreEmailSendOptions): Promise<{
|
|
227
|
+
messageId: string;
|
|
228
|
+
}>;
|
|
229
|
+
verify(): Promise<boolean>;
|
|
230
|
+
}
|
|
231
|
+
export interface EmailTemplates {
|
|
232
|
+
welcome?: (data: {
|
|
233
|
+
to: string;
|
|
234
|
+
appName: string;
|
|
235
|
+
}) => {
|
|
236
|
+
subject?: string;
|
|
237
|
+
html: string;
|
|
238
|
+
text?: string;
|
|
239
|
+
};
|
|
240
|
+
forgotPassword?: (data: {
|
|
241
|
+
to: string;
|
|
242
|
+
resetUrl: string;
|
|
243
|
+
appName: string;
|
|
244
|
+
expiresInMinutes: number;
|
|
245
|
+
}) => {
|
|
246
|
+
subject?: string;
|
|
247
|
+
html: string;
|
|
248
|
+
text?: string;
|
|
249
|
+
};
|
|
250
|
+
passwordResetSuccess?: (data: {
|
|
251
|
+
to: string;
|
|
252
|
+
appName: string;
|
|
253
|
+
}) => {
|
|
254
|
+
subject?: string;
|
|
255
|
+
html: string;
|
|
256
|
+
text?: string;
|
|
257
|
+
};
|
|
258
|
+
verifyEmail?: (data: {
|
|
259
|
+
to: string;
|
|
260
|
+
verifyUrl: string;
|
|
261
|
+
appName: string;
|
|
262
|
+
}) => {
|
|
263
|
+
subject?: string;
|
|
264
|
+
html: string;
|
|
265
|
+
text?: string;
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
export interface EmailConfig {
|
|
269
|
+
from?: string;
|
|
270
|
+
appName?: string;
|
|
271
|
+
resetTokenExpiryMinutes?: number;
|
|
272
|
+
resetPasswordUrl?: string;
|
|
273
|
+
verifyEmailUrl?: string;
|
|
274
|
+
transport?: CequreEmailTransport;
|
|
275
|
+
templates?: EmailTemplates;
|
|
276
|
+
}
|
|
277
|
+
export interface CequreServerConfig {
|
|
278
|
+
port?: number;
|
|
279
|
+
hostname?: string;
|
|
280
|
+
fetch: (req: Request, server?: any) => Promise<Response> | Response;
|
|
281
|
+
tls?: any;
|
|
282
|
+
maxRequestBodySize?: number;
|
|
283
|
+
routes?: Record<string, any>;
|
|
284
|
+
websocket?: any;
|
|
285
|
+
}
|
|
286
|
+
export interface ServerProvider {
|
|
287
|
+
start(config: CequreServerConfig): void | any;
|
|
288
|
+
stop?(): Promise<void>;
|
|
289
|
+
}
|
|
290
|
+
export interface CronProvider {
|
|
291
|
+
registerJob(name: string, cronExpression: string, handler: () => void | Promise<void>): void;
|
|
292
|
+
startAll(): void;
|
|
293
|
+
stopAll(): void;
|
|
294
|
+
list?(): Promise<string[]> | string[];
|
|
295
|
+
stop?(name: string): Promise<boolean> | boolean;
|
|
296
|
+
}
|
|
297
|
+
export interface RealtimeProvider {
|
|
298
|
+
websocket?: {
|
|
299
|
+
route(options: any): (req: Request, server: any) => Promise<Response>;
|
|
300
|
+
broadcastAll(payload: any, options?: any): void;
|
|
301
|
+
broadcastToRoom(room: string, payload: any, options?: any): void;
|
|
302
|
+
handlers?(): any;
|
|
303
|
+
};
|
|
304
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type TSchema } from "@sinclair/typebox";
|
|
2
|
+
import type { CollectionConfig } from "./types";
|
|
3
|
+
/**
|
|
4
|
+
* Build a TypeBox object schema for creating a document in the given collection.
|
|
5
|
+
* - Required fields (non-optional) are marked required
|
|
6
|
+
* - Password fields are excluded — password only lives in auth endpoints (register/login/etc)
|
|
7
|
+
* - @omit fields are excluded — server-managed only, never accepted via API
|
|
8
|
+
* - System fields (id, createdAt, updatedAt) are omitted from input
|
|
9
|
+
* - Undeclared fields are not allowed (TypeCompiler strict mode)
|
|
10
|
+
*/
|
|
11
|
+
export declare function buildCollectionCreateSchema(collection: CollectionConfig): TSchema;
|
|
12
|
+
/**
|
|
13
|
+
* Build a TypeBox object schema for updating a document in the given collection.
|
|
14
|
+
* - All fields are optional (partial update)
|
|
15
|
+
* - Password fields are excluded — password only lives in auth endpoints
|
|
16
|
+
* - @omit fields are excluded — server-managed only, never accepted via API
|
|
17
|
+
* - System fields (id, createdAt, updatedAt) are omitted from input
|
|
18
|
+
* - Undeclared fields are not allowed
|
|
19
|
+
*/
|
|
20
|
+
export declare function buildCollectionUpdateSchema(collection: CollectionConfig): TSchema;
|
|
21
|
+
/**
|
|
22
|
+
* Validate data against the collection's create schema.
|
|
23
|
+
* Throws CequreError.BadRequest on validation failure.
|
|
24
|
+
* If the collection has no fields defined, validation is skipped (cannot validate against nothing).
|
|
25
|
+
*/
|
|
26
|
+
export declare function validateCreate(collection: CollectionConfig, data: unknown): Record<string, unknown>;
|
|
27
|
+
/**
|
|
28
|
+
* Validate data against the collection's update schema.
|
|
29
|
+
* Throws CequreError.BadRequest on validation failure.
|
|
30
|
+
* If the collection has no fields defined, validation is skipped.
|
|
31
|
+
*/
|
|
32
|
+
export declare function validateUpdate(collection: CollectionConfig, data: unknown): Record<string, unknown>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { WhereClause } from "../core/adapter";
|
|
2
|
+
import type { CequreRequestContext } from "./access";
|
|
3
|
+
export type EvalResult = boolean | WhereClause<any> | null;
|
|
4
|
+
/**
|
|
5
|
+
* Evaluates a DSL access expression AST node against a runtime context.
|
|
6
|
+
*
|
|
7
|
+
* Returns:
|
|
8
|
+
* - `true` → operation allowed
|
|
9
|
+
* - `false` → operation denied
|
|
10
|
+
* - `WhereClause` → operation allowed, query scoped (read only)
|
|
11
|
+
* - `null` → intermediate value (null literal), treated as falsy by callers
|
|
12
|
+
*/
|
|
13
|
+
export declare function evaluateAccessExpression(expr: any, ctx: CequreRequestContext, action?: string): EvalResult;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { CequreRuntime } from "../../shared/main/runtime";
|
|
2
|
+
import type { WhereClause } from "../core/adapter";
|
|
3
|
+
import type { ExtractAuthUser } from "../core/request";
|
|
4
|
+
export interface AuthUser {
|
|
5
|
+
id: string;
|
|
6
|
+
role: string;
|
|
7
|
+
[key: string]: any;
|
|
8
|
+
}
|
|
9
|
+
export interface CequreRequestContext<TCollections extends Record<string, any> = any, TState = unknown, TAuthUser extends AuthUser = ExtractAuthUser<TCollections>> {
|
|
10
|
+
request: Request;
|
|
11
|
+
user: TAuthUser | null;
|
|
12
|
+
cequre: CequreRuntime<TCollections>;
|
|
13
|
+
state?: TState;
|
|
14
|
+
route?: any;
|
|
15
|
+
id?: string;
|
|
16
|
+
data?: unknown;
|
|
17
|
+
}
|
|
18
|
+
export type AccessControlFunction<TDoc = any, TCollections extends Record<string, any> = any, TAuthUser extends AuthUser = AuthUser> = (ctx: CequreRequestContext<TCollections, unknown, TAuthUser>) => boolean | WhereClause<TDoc> | Promise<boolean | WhereClause<TDoc>>;
|
|
19
|
+
export interface AccessRules<TDoc = any, TCollections extends Record<string, any> = any, TAuthUser extends AuthUser = AuthUser> {
|
|
20
|
+
read?: AccessControlFunction<TDoc, TCollections, TAuthUser>;
|
|
21
|
+
create?: AccessControlFunction<TDoc, TCollections, TAuthUser>;
|
|
22
|
+
update?: AccessControlFunction<TDoc, TCollections, TAuthUser>;
|
|
23
|
+
delete?: AccessControlFunction<TDoc, TCollections, TAuthUser>;
|
|
24
|
+
register?: AccessControlFunction<TDoc, TCollections, TAuthUser>;
|
|
25
|
+
login?: AccessControlFunction<TDoc, TCollections, TAuthUser>;
|
|
26
|
+
refresh?: AccessControlFunction<TDoc, TCollections, TAuthUser>;
|
|
27
|
+
logout?: AccessControlFunction<TDoc, TCollections, TAuthUser>;
|
|
28
|
+
forgotPassword?: AccessControlFunction<TDoc, TCollections, TAuthUser>;
|
|
29
|
+
resetPassword?: AccessControlFunction<TDoc, TCollections, TAuthUser>;
|
|
30
|
+
mfaLogin?: AccessControlFunction<TDoc, TCollections, TAuthUser>;
|
|
31
|
+
mfaEnroll?: AccessControlFunction<TDoc, TCollections, TAuthUser>;
|
|
32
|
+
mfaVerify?: AccessControlFunction<TDoc, TCollections, TAuthUser>;
|
|
33
|
+
mfaDisable?: AccessControlFunction<TDoc, TCollections, TAuthUser>;
|
|
34
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { CequreNativeRouteOptions } from "../../shared/main/router";
|
|
2
|
+
export declare function compileRouteHandler(route: any, // CompiledRoute
|
|
3
|
+
options: CequreNativeRouteOptions<any>, ctx: Record<string, any>): (request: Request, server: any) => Response | undefined | Promise<Response | undefined>;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { AuthUser, CequreRequestContext } from "./access";
|
|
2
|
+
export interface HookContext<TCollections extends Record<string, any> = any, TAuthUser extends AuthUser = AuthUser> extends CequreRequestContext<TCollections, unknown, TAuthUser> {
|
|
3
|
+
collection: string;
|
|
4
|
+
}
|
|
5
|
+
export type HookFunction<T = Record<string, unknown>, TCollections extends Record<string, any> = any, TAuthUser extends AuthUser = AuthUser> = (ctx: HookContext<TCollections, TAuthUser> & {
|
|
6
|
+
data: T;
|
|
7
|
+
}) => T | Promise<T> | void | Promise<void>;
|
|
8
|
+
export interface Hooks<T = Record<string, unknown>, TCollections extends Record<string, any> = any, TAuthUser extends AuthUser = AuthUser> {
|
|
9
|
+
beforeCreate?: HookFunction<T, TCollections, TAuthUser>;
|
|
10
|
+
afterCreate?: HookFunction<T, TCollections, TAuthUser>;
|
|
11
|
+
beforeRead?: HookFunction<any, TCollections, TAuthUser>;
|
|
12
|
+
afterRead?: HookFunction<any, TCollections, TAuthUser>;
|
|
13
|
+
beforeUpdate?: HookFunction<T, TCollections, TAuthUser>;
|
|
14
|
+
afterUpdate?: HookFunction<T, TCollections, TAuthUser>;
|
|
15
|
+
beforeDelete?: HookFunction<T, TCollections, TAuthUser>;
|
|
16
|
+
afterDelete?: HookFunction<T, TCollections, TAuthUser>;
|
|
17
|
+
beforeLogin?: HookFunction<{
|
|
18
|
+
email?: string;
|
|
19
|
+
password?: string;
|
|
20
|
+
} & Record<string, unknown>, TCollections, TAuthUser>;
|
|
21
|
+
afterLogin?: HookFunction<{
|
|
22
|
+
user?: T;
|
|
23
|
+
tokens?: {
|
|
24
|
+
accessToken: string;
|
|
25
|
+
refreshToken?: string;
|
|
26
|
+
};
|
|
27
|
+
challenge?: string;
|
|
28
|
+
message?: string;
|
|
29
|
+
}, TCollections, TAuthUser>;
|
|
30
|
+
beforeRegister?: HookFunction<Partial<T> & Record<string, unknown>, TCollections, TAuthUser>;
|
|
31
|
+
afterRegister?: HookFunction<{
|
|
32
|
+
user: T;
|
|
33
|
+
tokens?: {
|
|
34
|
+
accessToken: string;
|
|
35
|
+
refreshToken?: string;
|
|
36
|
+
};
|
|
37
|
+
}, TCollections, TAuthUser>;
|
|
38
|
+
beforeForgotPassword?: HookFunction<{
|
|
39
|
+
email?: string;
|
|
40
|
+
} & Record<string, unknown>, TCollections, TAuthUser>;
|
|
41
|
+
afterForgotPassword?: HookFunction<{
|
|
42
|
+
user: T;
|
|
43
|
+
resetUrl: string;
|
|
44
|
+
token: string;
|
|
45
|
+
}, TCollections, TAuthUser>;
|
|
46
|
+
beforeResetPassword?: HookFunction<{
|
|
47
|
+
token?: string;
|
|
48
|
+
password?: string;
|
|
49
|
+
} & Record<string, unknown>, TCollections, TAuthUser>;
|
|
50
|
+
afterResetPassword?: HookFunction<{
|
|
51
|
+
user: T;
|
|
52
|
+
}, TCollections, TAuthUser>;
|
|
53
|
+
beforeMfaVerify?: HookFunction<{
|
|
54
|
+
token?: string;
|
|
55
|
+
code?: string;
|
|
56
|
+
} & Record<string, unknown>, TCollections, TAuthUser>;
|
|
57
|
+
afterMfaVerify?: HookFunction<{
|
|
58
|
+
user: T;
|
|
59
|
+
}, TCollections, TAuthUser>;
|
|
60
|
+
beforeMfaEnroll?: HookFunction<any, TCollections, TAuthUser>;
|
|
61
|
+
afterMfaEnroll?: HookFunction<{
|
|
62
|
+
user: T;
|
|
63
|
+
}, TCollections, TAuthUser>;
|
|
64
|
+
beforeMfaLogin?: HookFunction<{
|
|
65
|
+
email?: string;
|
|
66
|
+
password?: string;
|
|
67
|
+
code?: string;
|
|
68
|
+
} & Record<string, unknown>, TCollections, TAuthUser>;
|
|
69
|
+
afterMfaLogin?: HookFunction<{
|
|
70
|
+
user: T;
|
|
71
|
+
tokens?: {
|
|
72
|
+
accessToken: string;
|
|
73
|
+
refreshToken?: string;
|
|
74
|
+
};
|
|
75
|
+
}, TCollections, TAuthUser>;
|
|
76
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { CequreAST } from "../core/types";
|
|
2
|
+
import type { CequreAdapter } from "../core/adapter";
|
|
3
|
+
/**
|
|
4
|
+
* Recursively populates relationship fields within a set of documents up to a maximum depth of 2.
|
|
5
|
+
* Uses batched queries via the 'in' operator to avoid N+1 issues.
|
|
6
|
+
*
|
|
7
|
+
* @param schema - The full Cequre AST schema to lookup relations
|
|
8
|
+
* @param collectionSlug - The slug of the collection the docs belong to
|
|
9
|
+
* @param docs - The array of documents to hydrate
|
|
10
|
+
* @param adapter - The underlying storage adapter to fetch related records
|
|
11
|
+
* @param depth - The remaining depth to populate (clamps to max 2 initially)
|
|
12
|
+
*/
|
|
13
|
+
export declare function populateDocuments(schema: CequreAST, collectionSlug: string, docs: any[], adapter: CequreAdapter, depth: number): Promise<any[]>;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import type { TSchema, Static } from "@sinclair/typebox";
|
|
2
|
+
import type { CequreRuntime } from "./runtime";
|
|
3
|
+
import type { CequreRouteContext, CequreParams, CequreQuery } from "../core/request";
|
|
4
|
+
import { type BunRouteResult } from "../../adapters/bun/bun-response";
|
|
5
|
+
import type { CequreMonitoringAPI } from "@cequrebackends/cequre-plugin-monitoring";
|
|
6
|
+
export type CequreRouteHandler<TCollections extends Record<string, any> = any, TState = unknown, TParams extends TSchema | undefined = undefined, TQuery extends TSchema | undefined = undefined, TBody extends TSchema | undefined = undefined, TResponse extends TSchema | undefined = undefined> = (context: CequreRouteContext<TCollections, TState, TParams extends TSchema ? Static<TParams> : CequreParams, TQuery extends TSchema ? Static<TQuery> : CequreQuery, TBody extends TSchema ? Static<TBody> : unknown>) => TResponse extends TSchema ? BunRouteResult<Static<TResponse>> | Promise<BunRouteResult<Static<TResponse>>> : BunRouteResult | Promise<BunRouteResult>;
|
|
7
|
+
export interface CequreRouteOptions<TParams extends TSchema | undefined = undefined, TQuery extends TSchema | undefined = undefined, TBody extends TSchema | undefined = undefined, TResponse extends TSchema | undefined = undefined> {
|
|
8
|
+
body?: TBody;
|
|
9
|
+
query?: TQuery;
|
|
10
|
+
params?: TParams;
|
|
11
|
+
response?: TResponse;
|
|
12
|
+
detail?: {
|
|
13
|
+
summary?: string;
|
|
14
|
+
description?: string;
|
|
15
|
+
tags?: string[];
|
|
16
|
+
[key: string]: any;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* If true, SDKs will generate this endpoint as a streaming client (.streamRequest)
|
|
20
|
+
*/
|
|
21
|
+
stream?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* When true the route requires an authentication credential on every
|
|
24
|
+
* request. Used by plugin guards and admin-only routes that should never
|
|
25
|
+
* accept anonymous callers, regardless of the route handler body.
|
|
26
|
+
*/
|
|
27
|
+
authRequired?: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Ignore the global API prefix when registering this route.
|
|
30
|
+
*/
|
|
31
|
+
ignorePrefix?: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Run one or more guard functions before the main handler.
|
|
34
|
+
* If a Response is returned, execution halts and returns that response.
|
|
35
|
+
*/
|
|
36
|
+
beforeHandle?: ((context: CequreRouteContext<any, any, any, any, any>) => any) | Array<(context: CequreRouteContext<any, any, any, any, any>) => any>;
|
|
37
|
+
}
|
|
38
|
+
export interface CequreRoute<TCollections extends Record<string, any> = any, TState = unknown, TParams extends TSchema | undefined = undefined, TQuery extends TSchema | undefined = undefined, TBody extends TSchema | undefined = undefined, TResponse extends TSchema | undefined = undefined> {
|
|
39
|
+
method: string;
|
|
40
|
+
path: string;
|
|
41
|
+
handler: CequreRouteHandler<TCollections, TState, TParams, TQuery, TBody, TResponse>;
|
|
42
|
+
options?: CequreRouteOptions<TParams, TQuery, TBody, TResponse>;
|
|
43
|
+
}
|
|
44
|
+
interface CompiledRoute<TCollections extends Record<string, any> = any, TState = unknown, TParams extends TSchema | undefined = undefined, TQuery extends TSchema | undefined = undefined, TBody extends TSchema | undefined = undefined, TResponse extends TSchema | undefined = undefined> extends CequreRoute<TCollections, TState, TParams, TQuery, TBody, TResponse> {
|
|
45
|
+
segments: string[];
|
|
46
|
+
bodyCoercer?: SchemaCoercer;
|
|
47
|
+
queryCoercer?: SchemaCoercer;
|
|
48
|
+
paramsCoercer?: SchemaCoercer;
|
|
49
|
+
shouldReadBody: boolean;
|
|
50
|
+
}
|
|
51
|
+
type NativeBunRequest = Request & {
|
|
52
|
+
params?: CequreParams;
|
|
53
|
+
};
|
|
54
|
+
type NativeBunRouteHandler = (request: NativeBunRequest, server: Bun.Server<unknown> | undefined) => Response | undefined | Promise<Response | undefined>;
|
|
55
|
+
type SchemaCoercer = (value: unknown) => unknown;
|
|
56
|
+
export type CequreNativeRoutes = Record<string, NativeBunRouteHandler | Partial<Record<string, NativeBunRouteHandler | Response>> | Response | false>;
|
|
57
|
+
export interface CequreNativeRouteOptions<TState = unknown> {
|
|
58
|
+
state?: TState | ((server?: Bun.Server<unknown>) => TState);
|
|
59
|
+
resolveUser?: (request: Request) => CequreRouteContext["user"] | Promise<CequreRouteContext["user"]>;
|
|
60
|
+
onError?: (error: unknown, request: Request) => Response;
|
|
61
|
+
headers?: Record<string, string>;
|
|
62
|
+
cors?: any["cors"];
|
|
63
|
+
/**
|
|
64
|
+
* Server-known set of origins allowed to issue state-changing cookie-
|
|
65
|
+
* authenticated requests. When set, the CSRF guard accepts these origins
|
|
66
|
+
* regardless of Host parsing.
|
|
67
|
+
*/
|
|
68
|
+
csrfTrustedOrigins?: string[];
|
|
69
|
+
cequre?: CequreRuntime;
|
|
70
|
+
plugins?: any[];
|
|
71
|
+
monitoring?: CequreMonitoringAPI;
|
|
72
|
+
requestId?: {
|
|
73
|
+
enabled?: boolean;
|
|
74
|
+
};
|
|
75
|
+
/** Optional rate limiter checked before the route handler runs. */
|
|
76
|
+
rateLimiter?: {
|
|
77
|
+
check: (request: Request) => Promise<Response | null> | Response | null;
|
|
78
|
+
};
|
|
79
|
+
/** Maximum request body size in bytes. Requests exceeding this are rejected before body read. */
|
|
80
|
+
maxBodyBytes?: number;
|
|
81
|
+
/** Optional KV store for idempotency key caching on POST/PUT/PATCH. */
|
|
82
|
+
idempotencyKV?: {
|
|
83
|
+
get: (key: string) => Promise<any | null>;
|
|
84
|
+
set: (key: string, value: any, ttl?: number) => Promise<void>;
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
export declare class CequreRouter<TCollections extends Record<string, any> = any, TState = unknown> {
|
|
88
|
+
private routes;
|
|
89
|
+
private prefix;
|
|
90
|
+
constructor(prefix?: string);
|
|
91
|
+
/**
|
|
92
|
+
* Prepends the configured prefix to a path if the path doesn't already start with it.
|
|
93
|
+
* Routes registered with an explicit prefix (e.g. internal routes using `${prefix}`)
|
|
94
|
+
* won't be double-prefixed. Routes registered without the prefix (e.g. user custom
|
|
95
|
+
* routes like "/greeting") get the prefix auto-prepended.
|
|
96
|
+
*/
|
|
97
|
+
private applyPrefix;
|
|
98
|
+
matchRoute(method: string, pathname: string): CompiledRoute<TCollections, TState, any, any, any, any> | undefined;
|
|
99
|
+
add<TParams extends TSchema | undefined = undefined, TQuery extends TSchema | undefined = undefined, TBody extends TSchema | undefined = undefined, TResponse extends TSchema | undefined = undefined>(method: string, path: string, handler: CequreRouteHandler<TCollections, TState, TParams, TQuery, TBody, TResponse>, options?: CequreRouteOptions<TParams, TQuery, TBody, TResponse>): this;
|
|
100
|
+
get<TParams extends TSchema | undefined = undefined, TQuery extends TSchema | undefined = undefined, TBody extends TSchema | undefined = undefined, TResponse extends TSchema | undefined = undefined>(path: string, handler: CequreRouteHandler<TCollections, TState, TParams, TQuery, TBody, TResponse>, options?: CequreRouteOptions<TParams, TQuery, TBody, TResponse>): this;
|
|
101
|
+
post<TParams extends TSchema | undefined = undefined, TQuery extends TSchema | undefined = undefined, TBody extends TSchema | undefined = undefined, TResponse extends TSchema | undefined = undefined>(path: string, handler: CequreRouteHandler<TCollections, TState, TParams, TQuery, TBody, TResponse>, options?: CequreRouteOptions<TParams, TQuery, TBody, TResponse>): this;
|
|
102
|
+
put<TParams extends TSchema | undefined = undefined, TQuery extends TSchema | undefined = undefined, TBody extends TSchema | undefined = undefined, TResponse extends TSchema | undefined = undefined>(path: string, handler: CequreRouteHandler<TCollections, TState, TParams, TQuery, TBody, TResponse>, options?: CequreRouteOptions<TParams, TQuery, TBody, TResponse>): this;
|
|
103
|
+
patch<TParams extends TSchema | undefined = undefined, TQuery extends TSchema | undefined = undefined, TBody extends TSchema | undefined = undefined, TResponse extends TSchema | undefined = undefined>(path: string, handler: CequreRouteHandler<TCollections, TState, TParams, TQuery, TBody, TResponse>, options?: CequreRouteOptions<TParams, TQuery, TBody, TResponse>): this;
|
|
104
|
+
delete<TParams extends TSchema | undefined = undefined, TQuery extends TSchema | undefined = undefined, TBody extends TSchema | undefined = undefined, TResponse extends TSchema | undefined = undefined>(path: string, handler: CequreRouteHandler<TCollections, TState, TParams, TQuery, TBody, TResponse>, options?: CequreRouteOptions<TParams, TQuery, TBody, TResponse>): this;
|
|
105
|
+
all<TParams extends TSchema | undefined = undefined, TQuery extends TSchema | undefined = undefined, TBody extends TSchema | undefined = undefined, TResponse extends TSchema | undefined = undefined>(path: string, handler: CequreRouteHandler<TCollections, TState, TParams, TQuery, TBody, TResponse>, options?: CequreRouteOptions<TParams, TQuery, TBody, TResponse>): this;
|
|
106
|
+
list(): CequreRoute<TCollections, TState, any, any, any, any>[];
|
|
107
|
+
use(routes: CequreRouter<TCollections, TState> | CequreRoute<TCollections, TState, any, any, any, any>[] | undefined | null): this;
|
|
108
|
+
toNativeRoutes(options?: CequreNativeRouteOptions<TState>): CequreNativeRoutes;
|
|
109
|
+
handle(request: Request, state?: TState, user?: CequreRouteContext<any>["user"], cequre?: import("./runtime").CequreRuntime<any>): Promise<Response | undefined>;
|
|
110
|
+
}
|
|
111
|
+
export declare function createRouter<TCollections extends Record<string, any> = any, TState = unknown>(): CequreRouter<TCollections, TState>;
|
|
112
|
+
export {};
|