@stacksjs/types 0.70.88 → 0.70.91
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/ai.d.ts +37 -0
- package/dist/analytics.d.ts +36 -0
- package/dist/api.d.ts +26 -0
- package/dist/app.d.ts +28 -0
- package/dist/attributes.d.ts +1 -0
- package/dist/auth.d.ts +62 -0
- package/dist/auto-imports.d.ts +8 -0
- package/dist/binary.d.ts +11 -0
- package/dist/cache.d.ts +88 -0
- package/dist/cdn.d.ts +4 -0
- package/dist/chat.d.ts +69 -0
- package/dist/cli.d.ts +316 -0
- package/dist/cloud.d.ts +366 -0
- package/dist/cms.d.ts +12 -0
- package/dist/commerce.d.ts +14 -0
- package/dist/components.d.ts +9 -0
- package/dist/configure.d.ts +12 -0
- package/dist/cors.d.ts +47 -0
- package/dist/cron-jobs.d.ts +61 -0
- package/dist/dashboard.d.ts +108 -0
- package/dist/database.d.ts +76 -0
- package/dist/dependencies.d.ts +17 -0
- package/dist/deploy.d.ts +16 -0
- package/dist/dns.d.ts +362 -0
- package/dist/docs.d.ts +23 -0
- package/dist/email.d.ts +207 -0
- package/dist/env.d.ts +1 -0
- package/dist/errors.d.ts +84 -0
- package/dist/events.d.ts +31 -0
- package/dist/exit-code.d.ts +10 -0
- package/dist/feature-flags.d.ts +17 -0
- package/dist/file-systems.d.ts +60 -0
- package/dist/git.d.ts +60 -0
- package/dist/hashing.d.ts +57 -0
- package/dist/helpers.d.ts +1 -0
- package/dist/i18n.d.ts +65 -0
- package/dist/index.d.ts +80 -0
- package/dist/index.js +2 -0
- package/dist/library.d.ts +799 -0
- package/dist/logging.d.ts +15 -0
- package/dist/manifest.d.ts +9 -0
- package/dist/marketing.d.ts +12 -0
- package/dist/model-dashboard-augmentation.d.ts +8 -0
- package/dist/model-names.d.ts +1 -0
- package/dist/model.d.ts +256 -0
- package/dist/monitoring.d.ts +12 -0
- package/dist/notifications.d.ts +126 -0
- package/dist/oauth.d.ts +290 -0
- package/dist/pages.d.ts +10 -0
- package/dist/payments.d.ts +322 -0
- package/dist/phone.d.ts +65 -0
- package/dist/ports.d.ts +20 -0
- package/dist/promise.d.ts +1 -0
- package/dist/push.d.ts +108 -0
- package/dist/queue.d.ts +312 -0
- package/dist/reactivity.d.ts +1 -0
- package/dist/realtime.d.ts +443 -0
- package/dist/request.d.ts +265 -0
- package/dist/response.d.ts +15 -0
- package/dist/router.d.ts +105 -0
- package/dist/saas.d.ts +32 -0
- package/dist/scheduler.d.ts +1 -0
- package/dist/search-engine.d.ts +129 -0
- package/dist/security.d.ts +18 -0
- package/dist/server.d.ts +16 -0
- package/dist/services.d.ts +149 -0
- package/dist/settings-config.d.ts +9 -0
- package/dist/sms.d.ts +144 -0
- package/dist/stack-extensions.d.ts +137 -0
- package/dist/stacks.d.ts +46 -0
- package/dist/storage.d.ts +104 -0
- package/dist/table-names.d.ts +1 -0
- package/dist/tables.d.ts +34 -0
- package/dist/team.d.ts +7 -0
- package/dist/ui.d.ts +55 -0
- package/dist/utils.d.ts +39 -0
- package/package.json +3 -3
|
@@ -0,0 +1,443 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Realtime configuration presets for common use cases
|
|
3
|
+
*/
|
|
4
|
+
export declare const RealtimePresets: {
|
|
5
|
+
/**
|
|
6
|
+
* Server mode presets (ts-broadcasting)
|
|
7
|
+
*/
|
|
8
|
+
server: {
|
|
9
|
+
/**
|
|
10
|
+
* Development preset - minimal config, debug enabled
|
|
11
|
+
*/
|
|
12
|
+
development: {
|
|
13
|
+
enabled: true;
|
|
14
|
+
mode: 'server';
|
|
15
|
+
debug: true;
|
|
16
|
+
server: {
|
|
17
|
+
host: 'localhost';
|
|
18
|
+
port: 6001;
|
|
19
|
+
scheme: 'ws';
|
|
20
|
+
driver: 'bun';
|
|
21
|
+
rateLimit: {
|
|
22
|
+
enabled: false
|
|
23
|
+
};
|
|
24
|
+
healthCheck: {
|
|
25
|
+
enabled: true;
|
|
26
|
+
path: '/health'
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
channels: {
|
|
30
|
+
public: true;
|
|
31
|
+
private: true;
|
|
32
|
+
presence: true
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Production preset - optimized for production workloads
|
|
37
|
+
*/
|
|
38
|
+
production: {
|
|
39
|
+
enabled: true;
|
|
40
|
+
mode: 'server';
|
|
41
|
+
debug: false;
|
|
42
|
+
server: {
|
|
43
|
+
host: '0.0.0.0';
|
|
44
|
+
port: 6001;
|
|
45
|
+
scheme: 'wss';
|
|
46
|
+
driver: 'bun';
|
|
47
|
+
redis: {
|
|
48
|
+
enabled: true;
|
|
49
|
+
prefix: 'stacks:realtime:'
|
|
50
|
+
};
|
|
51
|
+
rateLimit: {
|
|
52
|
+
enabled: true;
|
|
53
|
+
maxConnectionsPerIp: 100;
|
|
54
|
+
maxMessagesPerSecond: 50;
|
|
55
|
+
maxPayloadSize: 65536
|
|
56
|
+
};
|
|
57
|
+
loadManagement: {
|
|
58
|
+
maxConnections: 10000;
|
|
59
|
+
backpressureThreshold: 1000;
|
|
60
|
+
messageQueueSize: 10000;
|
|
61
|
+
gracefulShutdownTimeout: 30000
|
|
62
|
+
};
|
|
63
|
+
autoScaling: {
|
|
64
|
+
min: 2;
|
|
65
|
+
max: 10;
|
|
66
|
+
targetCPU: 70
|
|
67
|
+
};
|
|
68
|
+
healthCheck: {
|
|
69
|
+
enabled: true;
|
|
70
|
+
path: '/health';
|
|
71
|
+
interval: 30
|
|
72
|
+
};
|
|
73
|
+
metrics: {
|
|
74
|
+
enabled: true;
|
|
75
|
+
port: 9090;
|
|
76
|
+
path: '/metrics'
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
channels: {
|
|
80
|
+
public: true;
|
|
81
|
+
private: true;
|
|
82
|
+
presence: true
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
/**
|
|
86
|
+
* High performance preset - optimized for high throughput
|
|
87
|
+
*/
|
|
88
|
+
highPerformance: {
|
|
89
|
+
enabled: true;
|
|
90
|
+
mode: 'server';
|
|
91
|
+
server: {
|
|
92
|
+
driver: 'bun';
|
|
93
|
+
redis: {
|
|
94
|
+
enabled: true;
|
|
95
|
+
cluster: true
|
|
96
|
+
};
|
|
97
|
+
rateLimit: {
|
|
98
|
+
enabled: true;
|
|
99
|
+
maxConnectionsPerIp: 500;
|
|
100
|
+
maxMessagesPerSecond: 200;
|
|
101
|
+
maxPayloadSize: 131072
|
|
102
|
+
};
|
|
103
|
+
loadManagement: {
|
|
104
|
+
maxConnections: 100000;
|
|
105
|
+
backpressureThreshold: 5000;
|
|
106
|
+
messageQueueSize: 50000;
|
|
107
|
+
gracefulShutdownTimeout: 60000
|
|
108
|
+
};
|
|
109
|
+
autoScaling: {
|
|
110
|
+
min: 4;
|
|
111
|
+
max: 50;
|
|
112
|
+
targetCPU: 60
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
/**
|
|
117
|
+
* Chat application preset
|
|
118
|
+
*/
|
|
119
|
+
chat: {
|
|
120
|
+
enabled: true;
|
|
121
|
+
mode: 'server';
|
|
122
|
+
server: {
|
|
123
|
+
driver: 'bun';
|
|
124
|
+
redis: {
|
|
125
|
+
enabled: true
|
|
126
|
+
};
|
|
127
|
+
rateLimit: {
|
|
128
|
+
enabled: true;
|
|
129
|
+
maxConnectionsPerIp: 10;
|
|
130
|
+
maxMessagesPerSecond: 20
|
|
131
|
+
};
|
|
132
|
+
loadManagement: {
|
|
133
|
+
maxConnections: 50000
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
channels: {
|
|
137
|
+
public: true;
|
|
138
|
+
private: true;
|
|
139
|
+
presence: {
|
|
140
|
+
enabled: true;
|
|
141
|
+
maxMembersPerChannel: 500;
|
|
142
|
+
memberInfoTtl: 60
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
/**
|
|
147
|
+
* Gaming preset - low latency, high throughput
|
|
148
|
+
*/
|
|
149
|
+
gaming: {
|
|
150
|
+
enabled: true;
|
|
151
|
+
mode: 'server';
|
|
152
|
+
server: {
|
|
153
|
+
driver: 'bun';
|
|
154
|
+
redis: {
|
|
155
|
+
enabled: true;
|
|
156
|
+
cluster: true
|
|
157
|
+
};
|
|
158
|
+
rateLimit: {
|
|
159
|
+
enabled: true;
|
|
160
|
+
maxConnectionsPerIp: 50;
|
|
161
|
+
maxMessagesPerSecond: 100
|
|
162
|
+
};
|
|
163
|
+
loadManagement: {
|
|
164
|
+
maxConnections: 50000;
|
|
165
|
+
backpressureThreshold: 2000;
|
|
166
|
+
messageQueueSize: 20000
|
|
167
|
+
};
|
|
168
|
+
autoScaling: {
|
|
169
|
+
min: 2;
|
|
170
|
+
max: 20;
|
|
171
|
+
targetCPU: 50
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
channels: {
|
|
175
|
+
public: true;
|
|
176
|
+
private: true;
|
|
177
|
+
presence: true
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
/**
|
|
182
|
+
* Serverless mode presets (API Gateway WebSocket)
|
|
183
|
+
*/
|
|
184
|
+
serverless: {
|
|
185
|
+
/**
|
|
186
|
+
* Development preset
|
|
187
|
+
*/
|
|
188
|
+
development: {
|
|
189
|
+
enabled: true;
|
|
190
|
+
mode: 'serverless';
|
|
191
|
+
debug: true;
|
|
192
|
+
serverless: {
|
|
193
|
+
connectionTimeout: 3600;
|
|
194
|
+
idleTimeout: 600;
|
|
195
|
+
stageName: 'dev';
|
|
196
|
+
memorySize: 256;
|
|
197
|
+
timeout: 30
|
|
198
|
+
};
|
|
199
|
+
channels: {
|
|
200
|
+
public: true;
|
|
201
|
+
private: true;
|
|
202
|
+
presence: true
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
/**
|
|
206
|
+
* Production preset
|
|
207
|
+
*/
|
|
208
|
+
production: {
|
|
209
|
+
enabled: true;
|
|
210
|
+
mode: 'serverless';
|
|
211
|
+
debug: false;
|
|
212
|
+
serverless: {
|
|
213
|
+
connectionTimeout: 3600;
|
|
214
|
+
idleTimeout: 600;
|
|
215
|
+
stageName: 'production';
|
|
216
|
+
memorySize: 512;
|
|
217
|
+
timeout: 30;
|
|
218
|
+
provisionedConcurrency: 2
|
|
219
|
+
};
|
|
220
|
+
channels: {
|
|
221
|
+
public: true;
|
|
222
|
+
private: true;
|
|
223
|
+
presence: true
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
/**
|
|
227
|
+
* Notifications preset - simple push notifications
|
|
228
|
+
*/
|
|
229
|
+
notifications: {
|
|
230
|
+
enabled: true;
|
|
231
|
+
mode: 'serverless';
|
|
232
|
+
serverless: {
|
|
233
|
+
connectionTimeout: 7200;
|
|
234
|
+
idleTimeout: 1800;
|
|
235
|
+
memorySize: 256;
|
|
236
|
+
timeout: 15
|
|
237
|
+
};
|
|
238
|
+
channels: {
|
|
239
|
+
public: true;
|
|
240
|
+
private: true;
|
|
241
|
+
presence: false
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
/**
|
|
247
|
+
* Redis adapter configuration for horizontal scaling
|
|
248
|
+
*/
|
|
249
|
+
export declare interface RealtimeRedisConfig {
|
|
250
|
+
enabled?: boolean
|
|
251
|
+
host?: string
|
|
252
|
+
port?: number
|
|
253
|
+
password?: string
|
|
254
|
+
prefix?: string
|
|
255
|
+
cluster?: boolean
|
|
256
|
+
sentinels?: Array<{ host: string, port: number }>
|
|
257
|
+
sentinelName?: string
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Rate limiting configuration
|
|
261
|
+
*/
|
|
262
|
+
export declare interface RealtimeRateLimitConfig {
|
|
263
|
+
enabled?: boolean
|
|
264
|
+
maxConnectionsPerIp?: number
|
|
265
|
+
maxMessagesPerSecond?: number
|
|
266
|
+
maxPayloadSize?: number
|
|
267
|
+
banDuration?: number
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Encryption configuration
|
|
271
|
+
*/
|
|
272
|
+
export declare interface RealtimeEncryptionConfig {
|
|
273
|
+
enabled?: boolean
|
|
274
|
+
algorithm?: 'aes-256-gcm' | 'chacha20-poly1305'
|
|
275
|
+
keyRotationInterval?: number
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Webhook configuration
|
|
279
|
+
*/
|
|
280
|
+
export declare interface RealtimeWebhooksConfig {
|
|
281
|
+
enabled?: boolean
|
|
282
|
+
url?: string
|
|
283
|
+
events?: Array<'connection' | 'disconnection' | 'subscription' | 'message' | 'error'>
|
|
284
|
+
headers?: Record<string, string>
|
|
285
|
+
timeout?: number
|
|
286
|
+
retries?: number
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Queue integration configuration
|
|
290
|
+
*/
|
|
291
|
+
export declare interface RealtimeQueueConfig {
|
|
292
|
+
enabled?: boolean
|
|
293
|
+
driver?: 'redis' | 'sqs' | 'memory'
|
|
294
|
+
batchSize?: number
|
|
295
|
+
flushInterval?: number
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Load management configuration
|
|
299
|
+
*/
|
|
300
|
+
export declare interface RealtimeLoadConfig {
|
|
301
|
+
maxConnections?: number
|
|
302
|
+
backpressureThreshold?: number
|
|
303
|
+
messageQueueSize?: number
|
|
304
|
+
gracefulShutdownTimeout?: number
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Presence channel configuration
|
|
308
|
+
*/
|
|
309
|
+
export declare interface RealtimePresenceConfig {
|
|
310
|
+
enabled?: boolean
|
|
311
|
+
maxMembersPerChannel?: number
|
|
312
|
+
memberInfoTtl?: number
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Server mode configuration (ts-broadcasting)
|
|
316
|
+
*/
|
|
317
|
+
export declare interface RealtimeServerConfig {
|
|
318
|
+
host?: string
|
|
319
|
+
port?: number
|
|
320
|
+
scheme?: 'ws' | 'wss'
|
|
321
|
+
driver?: 'bun' | 'reverb' | 'pusher' | 'ably'
|
|
322
|
+
redis?: RealtimeRedisConfig
|
|
323
|
+
rateLimit?: RealtimeRateLimitConfig
|
|
324
|
+
encryption?: RealtimeEncryptionConfig
|
|
325
|
+
webhooks?: RealtimeWebhooksConfig
|
|
326
|
+
queue?: RealtimeQueueConfig
|
|
327
|
+
loadManagement?: RealtimeLoadConfig
|
|
328
|
+
instances?: number
|
|
329
|
+
autoScaling?: {
|
|
330
|
+
min?: number
|
|
331
|
+
max?: number
|
|
332
|
+
targetCPU?: number
|
|
333
|
+
targetMemory?: number
|
|
334
|
+
}
|
|
335
|
+
healthCheck?: {
|
|
336
|
+
enabled?: boolean
|
|
337
|
+
path?: string
|
|
338
|
+
interval?: number
|
|
339
|
+
}
|
|
340
|
+
metrics?: {
|
|
341
|
+
enabled?: boolean
|
|
342
|
+
port?: number
|
|
343
|
+
path?: string
|
|
344
|
+
}
|
|
345
|
+
tls?: {
|
|
346
|
+
enabled?: boolean
|
|
347
|
+
cert?: string
|
|
348
|
+
key?: string
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Serverless mode configuration
|
|
353
|
+
*/
|
|
354
|
+
export declare interface RealtimeServerlessConfig {
|
|
355
|
+
connectionTimeout?: number
|
|
356
|
+
idleTimeout?: number
|
|
357
|
+
stageName?: string
|
|
358
|
+
memorySize?: number
|
|
359
|
+
timeout?: number
|
|
360
|
+
provisionedConcurrency?: number
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Channel configuration
|
|
364
|
+
*/
|
|
365
|
+
export declare interface RealtimeChannelsConfig {
|
|
366
|
+
public?: boolean
|
|
367
|
+
private?: boolean
|
|
368
|
+
presence?: boolean | RealtimePresenceConfig
|
|
369
|
+
}
|
|
370
|
+
export declare interface RealtimeOptions {
|
|
371
|
+
enabled?: boolean
|
|
372
|
+
mode?: RealtimeMode
|
|
373
|
+
driver?: 'socket' | 'pusher' | 'bun' | 'reverb' | 'ably'
|
|
374
|
+
server?: RealtimeServerConfig
|
|
375
|
+
serverless?: RealtimeServerlessConfig
|
|
376
|
+
channels?: RealtimeChannelsConfig
|
|
377
|
+
socket?: {
|
|
378
|
+
port?: number
|
|
379
|
+
host?: string
|
|
380
|
+
cors?: {
|
|
381
|
+
origin: string | string[]
|
|
382
|
+
methods: string[]
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
pusher?: {
|
|
386
|
+
appId: string
|
|
387
|
+
key: string
|
|
388
|
+
secret: string
|
|
389
|
+
cluster?: string
|
|
390
|
+
useTLS?: boolean
|
|
391
|
+
}
|
|
392
|
+
app?: {
|
|
393
|
+
id?: string
|
|
394
|
+
key?: string
|
|
395
|
+
secret?: string
|
|
396
|
+
}
|
|
397
|
+
domain?: string
|
|
398
|
+
debug?: boolean
|
|
399
|
+
}
|
|
400
|
+
export declare interface RealtimeInstance {
|
|
401
|
+
event: string
|
|
402
|
+
handle?: (data?: any) => Promise<{ channel: string, type: 'public' | 'private' | 'presence' } | void>
|
|
403
|
+
}
|
|
404
|
+
export declare interface RealtimeDriver {
|
|
405
|
+
connect: () => Promise<void>
|
|
406
|
+
disconnect: () => Promise<void>
|
|
407
|
+
subscribe: (channel: string, callback: (data: any) => void) => void
|
|
408
|
+
unsubscribe: (channel: string) => void
|
|
409
|
+
publish: (channel: string, data: any) => void
|
|
410
|
+
broadcast: (channel: string, event: string, data?: any, type?: ChannelType) => void
|
|
411
|
+
isConnected: () => boolean
|
|
412
|
+
}
|
|
413
|
+
export declare interface Broadcastable {
|
|
414
|
+
broadcastEvent: () => Promise<void>
|
|
415
|
+
broadcastEventNow: () => Promise<void>
|
|
416
|
+
setChannel: (channel: string) => this
|
|
417
|
+
excludeCurrentUser: () => this
|
|
418
|
+
setPresenceChannel: () => this
|
|
419
|
+
setPrivateChannel: () => this
|
|
420
|
+
}
|
|
421
|
+
export declare interface BroadcastInstance {
|
|
422
|
+
channel?: string
|
|
423
|
+
event?: string
|
|
424
|
+
handle?: (data: any) => Promise<void>
|
|
425
|
+
}
|
|
426
|
+
/**
|
|
427
|
+
* Options for the emit function
|
|
428
|
+
*/
|
|
429
|
+
export declare interface EmitOptions {
|
|
430
|
+
private?: boolean
|
|
431
|
+
presence?: boolean
|
|
432
|
+
exclude?: string | string[]
|
|
433
|
+
driver?: DriverType
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* Realtime deployment mode
|
|
437
|
+
* - 'serverless': Uses API Gateway WebSocket + Lambda + DynamoDB
|
|
438
|
+
* - 'server': Uses ts-broadcasting Bun WebSocket server (ECS/Fargate)
|
|
439
|
+
*/
|
|
440
|
+
export type RealtimeMode = 'serverless' | 'server';
|
|
441
|
+
export type RealtimeConfig = Partial<RealtimeOptions>;
|
|
442
|
+
export type DriverType = 'socket' | 'pusher' | 'bun' | 'reverb' | 'ably';
|
|
443
|
+
export type ChannelType = 'public' | 'private' | 'presence';
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
import { User } from '@stacksjs/orm';
|
|
2
|
+
import type { AuthToken } from '@stacksjs/types';
|
|
3
|
+
import type { Infer } from '@stacksjs/ts-validation';
|
|
4
|
+
import type { UploadedFile } from '@stacksjs/storage';
|
|
5
|
+
declare interface RequestData {
|
|
6
|
+
[key: string]: any
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Cookie-access helper exposed via `request.cookies` on
|
|
10
|
+
* {@link RequestInstance}. The methods mirror bun-router's
|
|
11
|
+
* `CookieAccessor` — duplicated locally so this package doesn't
|
|
12
|
+
* have to depend on bun-router for a single type. Keep the surface
|
|
13
|
+
* in sync if bun-router extends its accessor.
|
|
14
|
+
*/
|
|
15
|
+
export declare interface RequestCookies {
|
|
16
|
+
get: (name: string) => string | undefined
|
|
17
|
+
set: (name: string, value: string, options?: {
|
|
18
|
+
path?: string
|
|
19
|
+
domain?: string
|
|
20
|
+
secure?: boolean
|
|
21
|
+
httpOnly?: boolean
|
|
22
|
+
sameSite?: 'strict' | 'lax' | 'none'
|
|
23
|
+
maxAge?: number
|
|
24
|
+
expires?: Date
|
|
25
|
+
}) => void
|
|
26
|
+
delete: (name: string, options?: { path?: string, domain?: string }) => void
|
|
27
|
+
getAll: () => Record<string, string>
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Collection interface for array data (Laravel-style)
|
|
31
|
+
*/
|
|
32
|
+
export declare interface Collection<T> {
|
|
33
|
+
items: T[]
|
|
34
|
+
count: () => number
|
|
35
|
+
first: () => T | undefined
|
|
36
|
+
last: () => T | undefined
|
|
37
|
+
map: <U>(fn: (item: T, index: number) => U) => Collection<U>
|
|
38
|
+
filter: (fn: (item: T, index: number) => boolean) => Collection<T>
|
|
39
|
+
find: (fn: (item: T, index: number) => boolean) => T | undefined
|
|
40
|
+
reduce: <U>(fn: (acc: U, item: T, index: number) => U, initial: U) => U
|
|
41
|
+
forEach: (fn: (item: T, index: number) => void) => void
|
|
42
|
+
toArray: () => T[]
|
|
43
|
+
isEmpty: () => boolean
|
|
44
|
+
isNotEmpty: () => boolean
|
|
45
|
+
pluck: <K extends keyof T>(key: K) => Collection<T[K]>
|
|
46
|
+
unique: () => Collection<T>
|
|
47
|
+
sortBy: <K extends keyof T>(key: K, direction?: 'asc' | 'desc') => Collection<T>
|
|
48
|
+
groupBy: <K extends keyof T>(key: K) => Map<T[K], Collection<T>>
|
|
49
|
+
chunk: (size: number) => Collection<Collection<T>>
|
|
50
|
+
take: (count: number) => Collection<T>
|
|
51
|
+
skip: (count: number) => Collection<T>
|
|
52
|
+
reverse: () => Collection<T>
|
|
53
|
+
sum: (key?: keyof T) => number
|
|
54
|
+
avg: (key?: keyof T) => number
|
|
55
|
+
min: (key?: keyof T) => T | undefined
|
|
56
|
+
max: (key?: keyof T) => T | undefined
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Safe validated data wrapper (Laravel-style)
|
|
60
|
+
*/
|
|
61
|
+
export declare interface SafeData<T extends Record<string, any> = Record<string, any>> {
|
|
62
|
+
only: <K extends keyof T>(keys: K[]) => Pick<T, K>
|
|
63
|
+
except: <K extends keyof T>(keys: K[]) => Omit<T, K>
|
|
64
|
+
merge: <U extends Record<string, unknown>>(data: U) => T & U
|
|
65
|
+
all: () => T
|
|
66
|
+
has: (key: keyof T) => boolean
|
|
67
|
+
get: <K extends keyof T>(key: K) => T[K]
|
|
68
|
+
}
|
|
69
|
+
export declare interface RequestInstance<TFields extends Record<string, any> = Record<string, any>, TParams extends Record<string, string> = Record<string, string>,> {
|
|
70
|
+
url: string
|
|
71
|
+
method: string
|
|
72
|
+
headers: Headers
|
|
73
|
+
query: RequestData
|
|
74
|
+
params: TParams
|
|
75
|
+
jsonBody?: any
|
|
76
|
+
formBody?: any
|
|
77
|
+
files: Record<string, File | File[]>
|
|
78
|
+
cookies?: RequestCookies
|
|
79
|
+
get<K extends keyof TFields & string>(key: K, defaultValue?: TFields[K]): TFields[K]
|
|
80
|
+
get<T = any>(key: string, defaultValue?: T): T
|
|
81
|
+
input<K extends keyof TFields & string>(key: K, defaultValue?: TFields[K]): TFields[K]
|
|
82
|
+
input<T = any>(key: string, defaultValue?: T): T
|
|
83
|
+
all: () => TFields
|
|
84
|
+
only: <K extends keyof TFields & string>(keys: K[]) => Pick<TFields, K>
|
|
85
|
+
except: <K extends keyof TFields & string>(keys: K[]) => Omit<TFields, K>
|
|
86
|
+
has: (key: string | string[]) => boolean
|
|
87
|
+
hasAny: (keys: string[]) => boolean
|
|
88
|
+
filled: (key: string | string[]) => boolean
|
|
89
|
+
missing: (key: string | string[]) => boolean
|
|
90
|
+
merge: (data: Partial<TFields>) => void
|
|
91
|
+
keys: () => (keyof TFields & string)[]
|
|
92
|
+
string: (key: keyof TFields & string, defaultValue?: string) => string
|
|
93
|
+
integer: (key: keyof TFields & string, defaultValue?: number) => number
|
|
94
|
+
float: (key: keyof TFields & string, defaultValue?: number) => number
|
|
95
|
+
boolean: (key: keyof TFields & string, defaultValue?: boolean) => boolean
|
|
96
|
+
array: <T = unknown>(key: keyof TFields & string) => T[]
|
|
97
|
+
date: (key: keyof TFields & string, format?: string) => Date | null
|
|
98
|
+
enum: <T extends Record<string, string | number>>(key: keyof TFields & string, enumType: T) => T[keyof T] | null
|
|
99
|
+
collect: <T = unknown>(key: keyof TFields & string) => Collection<T>
|
|
100
|
+
validate: (rules?: RequestValidationRules, messages?: Record<string, string>) => Promise<TFields>
|
|
101
|
+
getValidated: () => TFields
|
|
102
|
+
safe: () => SafeData<TFields>
|
|
103
|
+
whenHas: <T>(key: keyof TFields & string, callback: (value: T) => void, defaultCallback?: () => void) => void
|
|
104
|
+
whenFilled: <T>(key: keyof TFields & string, callback: (value: T) => void, defaultCallback?: () => void) => void
|
|
105
|
+
isValue: (key: keyof TFields & string, value: unknown) => boolean
|
|
106
|
+
file: (key: string) => UploadedFile | null
|
|
107
|
+
getFiles: (key: string) => UploadedFile[]
|
|
108
|
+
hasFile: (key: string) => boolean
|
|
109
|
+
allFiles: () => Record<string, UploadedFile | UploadedFile[]>
|
|
110
|
+
header: (key: string) => string | null
|
|
111
|
+
bearerToken: () => string | null | AuthToken
|
|
112
|
+
param: <K extends keyof TParams | string, D = string>(
|
|
113
|
+
key: K,
|
|
114
|
+
defaultValue?: D,
|
|
115
|
+
) => K extends keyof TParams ? TParams[K] : (string | D)
|
|
116
|
+
getParam: <K extends string>(key: K) => K extends NumericField ? number : string
|
|
117
|
+
route: (key: string) => number | string | null
|
|
118
|
+
getParams: () => TParams
|
|
119
|
+
getParamAsInt: (key: string) => number | null
|
|
120
|
+
old: <T = unknown>(key: keyof TFields & string, defaultValue?: T) => T
|
|
121
|
+
flashInput: (keys?: (keyof TFields & string)[]) => void
|
|
122
|
+
flashInputOnly: (keys: (keyof TFields & string)[]) => void
|
|
123
|
+
flashInputExcept: (keys: (keyof TFields & string)[]) => void
|
|
124
|
+
json: <T = any>() => Promise<T>
|
|
125
|
+
isEmpty: () => boolean
|
|
126
|
+
browser: () => string | null
|
|
127
|
+
ip: () => string | null
|
|
128
|
+
ipForRateLimit: () => string | null
|
|
129
|
+
getMethod: () => HttpMethod
|
|
130
|
+
user: () => Promise<UserJsonResponse | undefined>
|
|
131
|
+
}
|
|
132
|
+
// Trait methods are attached dynamically by the Stacks model proxy. The
|
|
133
|
+
// open member bag reflects application-level traits that the framework's
|
|
134
|
+
// default User definition cannot know about ahead of time.
|
|
135
|
+
declare type UserJsonResponse = NonNullable<Awaited<ReturnType<typeof User.find>>> & Record<string, any>;
|
|
136
|
+
/**
|
|
137
|
+
* Loose route-param shape kept around for back-compat with code that
|
|
138
|
+
* predates {@link RequestInstance}'s `TParams` generic. New code should
|
|
139
|
+
* rely on the path-extracted `TParams` instead — see {@link ExtractParams}.
|
|
140
|
+
*
|
|
141
|
+
* @deprecated Use {@link ExtractParams}-driven typing on the action /
|
|
142
|
+
* route signature instead. URL route params are always strings at
|
|
143
|
+
* runtime; the `string | number` here misled callers into thinking
|
|
144
|
+
* the framework coerced numbers automatically (it doesn't —
|
|
145
|
+
* `Number(request.params.id)` is the correct pattern).
|
|
146
|
+
*/
|
|
147
|
+
declare type RouteParams = { [key: string]: string | number } | null;
|
|
148
|
+
/**
|
|
149
|
+
* Legacy hard-coded list of param names treated as `number` by
|
|
150
|
+
* {@link RequestInstance.getParam}. The name-match heuristic is
|
|
151
|
+
* brittle (`'judgeId'`, `'user_id'`, etc. all silently fall through
|
|
152
|
+
* to `string`) and will be retired in a future release.
|
|
153
|
+
*
|
|
154
|
+
* @deprecated The name-match returns `number` for these specific keys
|
|
155
|
+
* only — pass the value through {@link Number} or
|
|
156
|
+
* {@link RequestInstance.getParamAsInt} for explicit, predictable
|
|
157
|
+
* coercion. See stacksjs/stacks#1851 Phase 3.
|
|
158
|
+
*/
|
|
159
|
+
declare type NumericField = 'id' | 'age' | 'count' | 'quantity' | 'amount' | 'price' | 'total' | 'score' | 'rating' | 'duration' | 'size' | 'weight' | 'height' | 'width' | 'length' | 'distance' | 'speed' | 'temperature' | 'volume' | 'capacity' | 'density' | 'pressure' | 'force' | 'energy' | 'power' | 'frequency' | 'voltage' | 'current' | 'resistance' | 'time' | 'date' | 'year' | 'month' | 'day' | 'hour' | 'minute' | 'second' | 'millisecond' | 'microsecond' | 'nanosecond';
|
|
160
|
+
/**
|
|
161
|
+
* Template-literal helper that extracts named route params from a
|
|
162
|
+
* path string (stacksjs/stacks#1851 Phase 2a). Supports both Stacks's
|
|
163
|
+
* brace-style (`/users/{id}`) and Express-style (`/users/:id`) so a
|
|
164
|
+
* project using either gets typed `params` out of the box.
|
|
165
|
+
*
|
|
166
|
+
* @example
|
|
167
|
+
* ExtractParams<'/api/judges/{id}/follow'> // { id: string }
|
|
168
|
+
* ExtractParams<'/api/orders/:orderId/items/:itemId'> // { orderId: string, itemId: string }
|
|
169
|
+
* ExtractParams<'/api/health'> // Record<string, never>
|
|
170
|
+
*/
|
|
171
|
+
// Step 1: pull the next param name out of either `{name}` or `:name`,
|
|
172
|
+
// recurse on the rest, and union the keys.
|
|
173
|
+
declare type ExtractParamKeys<S extends string> = S extends `${string}{${infer Key}}${infer Rest}`
|
|
174
|
+
? Key | ExtractParamKeys<Rest>
|
|
175
|
+
// colon form: `…/:name/…` (colon must be at a segment boundary
|
|
176
|
+
// so we don't match `:` inside e.g. a port number; the `/` before
|
|
177
|
+
// it enforces that)
|
|
178
|
+
: S extends `${string}/:${infer Key}/${infer Rest}`
|
|
179
|
+
? KeyHead<Key> | ExtractParamKeys<`/${Rest}`>
|
|
180
|
+
// tail colon-form: `…/:name` (no trailing slash)
|
|
181
|
+
: S extends `${string}/:${infer Key}`
|
|
182
|
+
? KeyHead<Key>
|
|
183
|
+
: never;
|
|
184
|
+
// `KeyHead<'name>'>` → `'name>'` because TS template literal infers
|
|
185
|
+
// the longest possible match. We need to handle params that are at
|
|
186
|
+
// the end of the path AND followed by a query string. This util
|
|
187
|
+
// truncates a captured key at the first non-name character.
|
|
188
|
+
declare type KeyHead<S extends string> = S extends `${infer H}/${string}` ? H :
|
|
189
|
+
S extends `${infer H}?${string}` ? H :
|
|
190
|
+
S extends `${infer H}.${string}` ? H :
|
|
191
|
+
S;
|
|
192
|
+
export type ExtractParams<S extends string> = [ExtractParamKeys<S>] extends [never]
|
|
193
|
+
? Record<string, never>
|
|
194
|
+
: { [K in ExtractParamKeys<S>]: string }
|
|
195
|
+
export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS' | 'CONNECT' | 'TRACE';
|
|
196
|
+
/**
|
|
197
|
+
* RequestInstance - Generic, model-aware request interface with Laravel-style methods.
|
|
198
|
+
*
|
|
199
|
+
* When used bare (`RequestInstance`), all methods accept any string keys (backward compatible).
|
|
200
|
+
* When parameterized with model fields (`RequestInstance<{ title: string, views: number }>`),
|
|
201
|
+
* all input methods narrow to those fields with full autocomplete and type inference.
|
|
202
|
+
*
|
|
203
|
+
* The global type alias connects this to models:
|
|
204
|
+
* `RequestInstance<typeof Post>` → narrows to Post's fields automatically.
|
|
205
|
+
*
|
|
206
|
+
* @example
|
|
207
|
+
* // Untyped (accepts any key)
|
|
208
|
+
* function handle(request: RequestInstance) {
|
|
209
|
+
* request.get('anything') // returns any
|
|
210
|
+
* }
|
|
211
|
+
*
|
|
212
|
+
* @example
|
|
213
|
+
* // Model-aware (narrows to Post's fields)
|
|
214
|
+
* function handle(request: RequestInstance<typeof Post>) {
|
|
215
|
+
* request.get('title') // autocompletes, returns string
|
|
216
|
+
* request.get('views') // autocompletes, returns number
|
|
217
|
+
* request.get('invalid') // TS error!
|
|
218
|
+
* const data = await request.validate() // returns typed Post fields
|
|
219
|
+
* }
|
|
220
|
+
*/
|
|
221
|
+
/**
|
|
222
|
+
* Public alias for `RequestInstance<TFields>`. Use this in actions when
|
|
223
|
+
* you want to type the `request` argument explicitly (e.g. without
|
|
224
|
+
* pulling in a model object).
|
|
225
|
+
*
|
|
226
|
+
* @example
|
|
227
|
+
* ```ts
|
|
228
|
+
* import { Action } from '@stacksjs/actions'
|
|
229
|
+
* import type { ActionRequest } from '@stacksjs/types'
|
|
230
|
+
*
|
|
231
|
+
* type CreatePostInput = { title: string; body: string }
|
|
232
|
+
*
|
|
233
|
+
* export default new Action({
|
|
234
|
+
* name: 'CreatePost',
|
|
235
|
+
* handle(request: ActionRequest<CreatePostInput>) {
|
|
236
|
+
* const { title, body } = request.only(['title', 'body'])
|
|
237
|
+
* // ^ inferred as { title: string; body: string }
|
|
238
|
+
* },
|
|
239
|
+
* })
|
|
240
|
+
* ```
|
|
241
|
+
*/
|
|
242
|
+
export type ActionRequest<TFields extends Record<string, any> = Record<string, any>, TParams extends Record<string, string> = Record<string, string>,> = RequestInstance<TFields, TParams>;
|
|
243
|
+
/**
|
|
244
|
+
* Read the body shape declared by an action's `validations:` field as
|
|
245
|
+
* a TypeScript object type (stacksjs/stacks#1851 Phase 2b). Threaded
|
|
246
|
+
* into {@link RequestInstance}'s `TFields` so `request.all()` returns
|
|
247
|
+
* the body shape with the field types {@link Infer}'d from each
|
|
248
|
+
* `schema.X()` rule.
|
|
249
|
+
*
|
|
250
|
+
* @example
|
|
251
|
+
* const validations = {
|
|
252
|
+
* email: { rule: schema.string().email() },
|
|
253
|
+
* password: { rule: schema.string().min(8) },
|
|
254
|
+
* remember: { rule: schema.boolean() },
|
|
255
|
+
* } as const
|
|
256
|
+
* type Body = InferValidations<typeof validations>
|
|
257
|
+
* // → { email: string, password: string, remember: boolean }
|
|
258
|
+
*/
|
|
259
|
+
export type InferValidations<V extends Record<string, { rule: any }>> = {
|
|
260
|
+
[K in keyof V]: Infer<V[K]['rule']>
|
|
261
|
+
}
|
|
262
|
+
export type RequestValidationRules = Record<string, string | {
|
|
263
|
+
rule: { validate: (value: any) => any }
|
|
264
|
+
message?: string | Record<string, string>
|
|
265
|
+
}>;
|