@stacksjs/types 0.70.45 → 0.70.53
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +21 -0
- package/dist/auth.d.ts +7 -0
- package/dist/cache.d.ts +10 -1
- package/dist/cli.d.ts +2 -1
- package/dist/cms.d.ts +12 -0
- package/dist/commerce.d.ts +14 -0
- package/dist/cors.d.ts +47 -0
- package/dist/dashboard.d.ts +75 -0
- package/dist/database.d.ts +10 -0
- package/dist/email.d.ts +6 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +1 -1
- package/dist/logging.d.ts +3 -0
- package/dist/marketing.d.ts +12 -0
- package/dist/model-dashboard-augmentation.d.ts +8 -0
- package/dist/model.d.ts +4 -1
- package/dist/monitoring.d.ts +12 -0
- package/dist/queue.d.ts +2 -0
- package/dist/realtime.d.ts +8 -8
- package/dist/request.d.ts +107 -4
- package/dist/search-engine.d.ts +8 -1
- package/dist/services.d.ts +9 -0
- package/dist/stacks.d.ts +6 -1
- package/package.json +5 -5
- package/src/auth.ts +39 -0
- package/src/cache.ts +49 -2
- package/src/cli.ts +1 -0
- package/src/cms.ts +14 -0
- package/src/commerce.ts +18 -0
- package/src/cors.ts +86 -0
- package/src/dashboard.ts +178 -0
- package/src/database.ts +14 -0
- package/src/email.ts +94 -0
- package/src/index.ts +9 -0
- package/src/logging.ts +32 -0
- package/src/marketing.ts +14 -0
- package/src/model-dashboard-augmentation.ts +51 -0
- package/src/model.ts +33 -1
- package/src/monitoring.ts +14 -0
- package/src/queue.ts +8 -0
- package/src/request.ts +166 -5
- package/src/search-engine.ts +32 -1
- package/src/services.ts +26 -0
- package/src/stacks.ts +46 -3
package/LICENSE.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Open Web Foundation
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/auth.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export declare interface AuthOptions {
|
|
2
|
+
enabled?: boolean
|
|
3
|
+
env?: string[]
|
|
2
4
|
default: string
|
|
3
5
|
guards: {
|
|
4
6
|
[key: string]: {
|
|
@@ -22,6 +24,11 @@ export declare interface AuthOptions {
|
|
|
22
24
|
passwordReset: {
|
|
23
25
|
expire: number
|
|
24
26
|
throttle: number
|
|
27
|
+
url?: string
|
|
28
|
+
}
|
|
29
|
+
emailVerification?: {
|
|
30
|
+
expire?: number
|
|
31
|
+
url?: string
|
|
25
32
|
}
|
|
26
33
|
}
|
|
27
34
|
export declare interface AuthInstance {
|
package/dist/cache.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Cache Options - Configuration for the caching system
|
|
3
3
|
*/
|
|
4
4
|
export declare interface CacheOptions {
|
|
5
|
-
driver: 'memory' | 'redis'
|
|
5
|
+
driver: 'memory' | 'redis' | 'singlestore'
|
|
6
6
|
prefix: string
|
|
7
7
|
ttl: number
|
|
8
8
|
maxKeys?: number
|
|
@@ -22,6 +22,15 @@ export declare interface CacheOptions {
|
|
|
22
22
|
checkPeriod?: number
|
|
23
23
|
deleteOnExpire?: boolean
|
|
24
24
|
}
|
|
25
|
+
singlestore?: {
|
|
26
|
+
host?: string
|
|
27
|
+
port?: number
|
|
28
|
+
username?: string
|
|
29
|
+
password?: string
|
|
30
|
+
database?: string
|
|
31
|
+
table?: string
|
|
32
|
+
ssl?: boolean
|
|
33
|
+
}
|
|
25
34
|
}
|
|
26
35
|
}
|
|
27
36
|
/**
|
package/dist/cli.d.ts
CHANGED
package/dist/cms.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* **CMS Options**
|
|
3
|
+
*
|
|
4
|
+
* Top-level feature gate plus any future CMS-wide settings. The CMS bundle
|
|
5
|
+
* (Post / Page / Author / Comment / Tag / Category models + edit dashboards)
|
|
6
|
+
* stays inert at boot when `enabled` is `false`.
|
|
7
|
+
*/
|
|
8
|
+
export declare interface CmsOptions {
|
|
9
|
+
enabled?: boolean
|
|
10
|
+
env?: string[]
|
|
11
|
+
}
|
|
12
|
+
export type CmsConfig = Partial<CmsOptions>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* **Commerce Options**
|
|
3
|
+
*
|
|
4
|
+
* Top-level feature gate plus storefront defaults. The commerce bundle
|
|
5
|
+
* (Order / Cart / Product / Customer / Coupon / GiftCard / Shipping models +
|
|
6
|
+
* storefront API) stays inert at boot when `enabled` is `false`.
|
|
7
|
+
*/
|
|
8
|
+
export declare interface CommerceOptions {
|
|
9
|
+
enabled?: boolean
|
|
10
|
+
env?: string[]
|
|
11
|
+
currency?: string
|
|
12
|
+
defaultTaxRate?: number
|
|
13
|
+
}
|
|
14
|
+
export type CommerceConfig = Partial<CommerceOptions>;
|
package/dist/cors.d.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CORS configuration types (stacksjs/stacks#1859 H-2).
|
|
3
|
+
*
|
|
4
|
+
* Lives in `@stacksjs/types` so userland `config/cors.ts` files can
|
|
5
|
+
* `import type { CorsConfig } from '@stacksjs/types'` and get full
|
|
6
|
+
* IntelliSense, and so the Cors middleware can read
|
|
7
|
+
* `config.cors` with proper typing instead of an `as any` cast.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Raw CORS configuration — every field optional. Defaults fill in
|
|
11
|
+
* any field that's missing when the middleware resolves config.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* // config/cors.ts
|
|
16
|
+
* import type { CorsConfig } from '@stacksjs/types'
|
|
17
|
+
*
|
|
18
|
+
* export default {
|
|
19
|
+
* origin: ['https://app.example.com', 'https://admin.example.com'],
|
|
20
|
+
* credentials: true,
|
|
21
|
+
* methods: ['GET', 'POST', 'PUT', 'DELETE'],
|
|
22
|
+
* allowedHeaders: ['Content-Type', 'Authorization', 'X-CSRF-Token'],
|
|
23
|
+
* maxAge: 600,
|
|
24
|
+
* } satisfies CorsConfig
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export declare interface CorsConfig {
|
|
28
|
+
origin?: '*' | string[] | ((origin: string) => boolean)
|
|
29
|
+
methods?: string[]
|
|
30
|
+
allowedHeaders?: string[]
|
|
31
|
+
exposedHeaders?: string[]
|
|
32
|
+
credentials?: boolean
|
|
33
|
+
maxAge?: number
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Resolved CORS configuration with all defaults applied. This is the
|
|
37
|
+
* shape the middleware passes through `applyCorsHeaders` /
|
|
38
|
+
* `buildPreflightResponse`.
|
|
39
|
+
*/
|
|
40
|
+
export declare interface ResolvedCorsConfig {
|
|
41
|
+
origin: '*' | string[] | ((origin: string) => boolean)
|
|
42
|
+
methods: string[]
|
|
43
|
+
allowedHeaders: string[]
|
|
44
|
+
exposedHeaders: string[]
|
|
45
|
+
credentials: boolean
|
|
46
|
+
maxAge: number
|
|
47
|
+
}
|
package/dist/dashboard.d.ts
CHANGED
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
* row when there's no newsletter without losing the model viewer.
|
|
13
13
|
*/
|
|
14
14
|
export declare interface DashboardOptions {
|
|
15
|
+
enabled?: boolean
|
|
16
|
+
env?: string[]
|
|
15
17
|
sections?: {
|
|
16
18
|
library?: { enabled?: boolean }
|
|
17
19
|
content?: { enabled?: boolean }
|
|
@@ -29,5 +31,78 @@ export declare interface DashboardOptions {
|
|
|
29
31
|
allModels?: { enabled?: boolean }
|
|
30
32
|
}
|
|
31
33
|
}
|
|
34
|
+
ci?: {
|
|
35
|
+
enabled?: boolean
|
|
36
|
+
orgs?: string[]
|
|
37
|
+
runnerCaps?: Record<string, number>
|
|
38
|
+
runnerCapDefault?: number
|
|
39
|
+
ignoreRepos?: string[]
|
|
40
|
+
notifications?: {
|
|
41
|
+
enabled?: boolean
|
|
42
|
+
channels?: Array<'email' | 'sms' | 'chat' | 'database'>
|
|
43
|
+
recipients?: Array<{ email?: string, phone?: string, userId?: number }>
|
|
44
|
+
cooldownMinutes?: number
|
|
45
|
+
}
|
|
46
|
+
alerts?: {
|
|
47
|
+
enabled?: boolean
|
|
48
|
+
queuedThreshold?: number
|
|
49
|
+
windowMinutes?: number
|
|
50
|
+
channels?: Array<'email' | 'sms' | 'chat' | 'database'>
|
|
51
|
+
recipients?: Array<{ email?: string, phone?: string, userId?: number }>
|
|
52
|
+
retentionHours?: number
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Per-model dashboard configuration (stacksjs/stacks#1843).
|
|
58
|
+
*
|
|
59
|
+
* Attach to a model definition to influence how the model surfaces in the
|
|
60
|
+
* dashboard sidebar without touching the framework's dashboard internals:
|
|
61
|
+
*
|
|
62
|
+
* ```ts
|
|
63
|
+
* defineModel({
|
|
64
|
+
* name: 'AuditLog',
|
|
65
|
+
* table: 'audit_logs',
|
|
66
|
+
* dashboard: {
|
|
67
|
+
* section: 'management',
|
|
68
|
+
* icon: 'shield',
|
|
69
|
+
* roles: ['admin'],
|
|
70
|
+
* description: 'Append-only audit trail (admin-only)',
|
|
71
|
+
* },
|
|
72
|
+
* attributes: { … },
|
|
73
|
+
* })
|
|
74
|
+
* ```
|
|
75
|
+
*
|
|
76
|
+
* Resolution chain (most specific → fallback):
|
|
77
|
+
*
|
|
78
|
+
* 1. `dashboard.enabled === false` → model is hidden from the sidebar
|
|
79
|
+
* entirely. The dynamic ORM viewer (`/models/<id>`) still works for
|
|
80
|
+
* direct navigation, but the row is suppressed.
|
|
81
|
+
* 2. `dashboard.section` → pins the model to that section, overriding
|
|
82
|
+
* the path-based auto-categorisation (commerce/, Content/, etc.).
|
|
83
|
+
* 3. `dashboard.label` / `dashboard.icon` → display overrides; fall back
|
|
84
|
+
* to the model name and `iconMap` lookup.
|
|
85
|
+
* 4. `dashboard.roles` → role-gates the sidebar row. The server-side
|
|
86
|
+
* sidebar builder emits the row with role metadata; the client filters
|
|
87
|
+
* it out for users who lack a matching role. Permissive default
|
|
88
|
+
* (unauthenticated viewers see everything — see `useRole.ts`).
|
|
89
|
+
*/
|
|
90
|
+
export declare interface DashboardModelOptions {
|
|
91
|
+
enabled?: boolean
|
|
92
|
+
label?: string
|
|
93
|
+
icon?: string
|
|
94
|
+
section?:
|
|
95
|
+
| 'home'
|
|
96
|
+
| 'library'
|
|
97
|
+
| 'content'
|
|
98
|
+
| 'commerce'
|
|
99
|
+
| 'marketing'
|
|
100
|
+
| 'analytics'
|
|
101
|
+
| 'management'
|
|
102
|
+
| 'utilities'
|
|
103
|
+
| 'data'
|
|
104
|
+
| 'app'
|
|
105
|
+
roles?: string[]
|
|
106
|
+
description?: string
|
|
32
107
|
}
|
|
33
108
|
export type DashboardConfig = Partial<DashboardOptions>;
|
package/dist/database.d.ts
CHANGED
|
@@ -12,6 +12,16 @@ export declare interface DatabaseOptions {
|
|
|
12
12
|
password?: string
|
|
13
13
|
prefix?: string
|
|
14
14
|
}
|
|
15
|
+
singlestore?: {
|
|
16
|
+
url?: string
|
|
17
|
+
host?: string
|
|
18
|
+
port?: number
|
|
19
|
+
name?: string
|
|
20
|
+
username?: string
|
|
21
|
+
password?: string
|
|
22
|
+
prefix?: string
|
|
23
|
+
ssl?: boolean
|
|
24
|
+
}
|
|
15
25
|
sqlite: {
|
|
16
26
|
url?: string
|
|
17
27
|
database?: string
|
package/dist/email.d.ts
CHANGED
|
@@ -102,12 +102,15 @@ export declare interface EmailOptions {
|
|
|
102
102
|
address: string
|
|
103
103
|
}
|
|
104
104
|
mailboxes: string[] | MailboxConfig[]
|
|
105
|
+
forwards?: Record<string, string[]>
|
|
105
106
|
domain?: string
|
|
106
107
|
url: string
|
|
107
108
|
charset: string
|
|
108
109
|
server: EmailServerConfig
|
|
109
110
|
notifications?: EmailNotificationsConfig
|
|
110
111
|
default: 'log' | 'ses' | 'sendgrid' | 'mailgun' | 'mailtrap' | 'smtp'
|
|
112
|
+
suppressionPolicy?: 'strict' | 'transactional-allowed' | 'off'
|
|
113
|
+
unsubscribeRoute?: string
|
|
111
114
|
}
|
|
112
115
|
export declare interface MailtrapConfig extends EmailDriverConfig {
|
|
113
116
|
token: string
|
|
@@ -142,6 +145,7 @@ export declare interface EmailMessage {
|
|
|
142
145
|
to: string | string[] | EmailAddress[]
|
|
143
146
|
cc?: string | string[] | EmailAddress[]
|
|
144
147
|
bcc?: string | string[] | EmailAddress[]
|
|
148
|
+
replyTo?: EmailAddress | EmailAddress[] | string | string[]
|
|
145
149
|
subject: string
|
|
146
150
|
template?: string
|
|
147
151
|
html?: string
|
|
@@ -151,6 +155,8 @@ export declare interface EmailMessage {
|
|
|
151
155
|
onSuccess?: () => Promise<{ message: string }> | { message: string }
|
|
152
156
|
onError?: (error: Error) => Promise<{ message: string }> | { message: string }
|
|
153
157
|
handle?: () => Promise<{ message: string }> | { message: string }
|
|
158
|
+
idempotencyKey?: string
|
|
159
|
+
tag?: 'transactional' | 'broadcast'
|
|
154
160
|
}
|
|
155
161
|
// Email interfaces
|
|
156
162
|
export declare interface EmailAddress {
|
package/dist/index.d.ts
CHANGED
|
@@ -15,10 +15,17 @@ export * from './cdn';
|
|
|
15
15
|
export * from './chat';
|
|
16
16
|
export * from './cli';
|
|
17
17
|
export * from './cloud';
|
|
18
|
+
export * from './cms';
|
|
19
|
+
export * from './commerce';
|
|
18
20
|
export * from './components';
|
|
19
21
|
export * from './configure';
|
|
22
|
+
export * from './cors';
|
|
20
23
|
export * from './cron-jobs';
|
|
21
24
|
export * from './dashboard';
|
|
25
|
+
// Module-augments bun-query-builder's BrowserModelDefinition with the
|
|
26
|
+
// stacks `dashboard` slot. Importing this file (transitively via the
|
|
27
|
+
// barrel) is what makes `defineModel({ dashboard: {...} })` typecheck.
|
|
28
|
+
export * from './model-dashboard-augmentation';
|
|
22
29
|
export * from './database';
|
|
23
30
|
export * from './dependencies';
|
|
24
31
|
export * from './deploy';
|
|
@@ -37,8 +44,10 @@ export * from './i18n';
|
|
|
37
44
|
export * from './library';
|
|
38
45
|
export * from './logging';
|
|
39
46
|
export * from './manifest';
|
|
47
|
+
export * from './marketing';
|
|
40
48
|
export * from './model';
|
|
41
49
|
export * from './model-names';
|
|
50
|
+
export * from './monitoring';
|
|
42
51
|
export * from './notifications';
|
|
43
52
|
export * from './pages';
|
|
44
53
|
export * from './payments';
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
function
|
|
2
|
+
function x(p){return typeof p==="object"&&p!==null&&"id"in p&&"userId"in p&&"clientId"in p&&"scopes"in p}function G(p){return x(p)&&"abilities"in p}function H(p){return typeof p==="object"&&p!==null&&"id"in p&&"name"in p&&"secret"in p&&"redirect"in p}var F;((D)=>{D.Second="* * * * * *";D.FiveSeconds="*/5 * * * * *";D.TenSeconds="*/10 * * * * *";D.ThirtySeconds="*/30 * * * * *";D.Minute="* * * * *";D.TwoMinutes="*/2 * * * *";D.FiveMinutes="*/5 * * * *";D.TenMinutes="*/10 * * * *";D.FifteenMinutes="*/15 * * * *";D.ThirtyMinutes="*/30 * * * *";D.Hour="0 * * * *";D.HalfHour="0,30 * * * *";D.Day="0 0 * * *";D.Week="0 0 * * 0";D.Weekday="0 0 * * 1-5";D.Weekend="0 0 * * 0,6";D.Month="0 0 1 * *";D.Year="0 0 1 1 *"})(F||={});var U;((B)=>{B.Bluesky="bluesky";B.Discord="discord";B.Facebook="facebook";B.GitHub="github";B.Instagram="instagram";B.LinkedIn="linkedin";B.Mastodon="mastodon";B.Slack="slack";B.Twitter="twitter";B.YouTube="youtube"})(U||={});var _;((O)=>{O[O.Success=0]="Success";O[O.FatalError=1]="FatalError";O[O.InvalidArgument=9]="InvalidArgument"})(_||={});import{toString as f}from"@stacksjs/strings";function J(p){if(p===null)return"null";let P=f(p).slice(8,-1).toLowerCase();return typeof p==="object"||typeof p==="function"?P:typeof p}function M(p){return p}function Q(p){return p}var V={development:{default:"sync",connections:{sync:{driver:"sync"}},failed:{driver:"database",table:"failed_jobs"}},production:{default:"redis",connections:{redis:{driver:"redis",prefix:"stacks:queue",concurrency:5,distributedLock:!0,metrics:{enabled:!0},defaultDeadLetterOptions:{enabled:!0,maxRetries:3}}},failed:{driver:"redis",prefix:"stacks:failed"},worker:{concurrency:5,shutdownTimeout:30000}},highPerformance:{default:"redis",connections:{redis:{driver:"redis",prefix:"stacks:queue",concurrency:20,distributedLock:!0,metrics:{enabled:!0,collectInterval:5000},horizontalScaling:{enabled:!0,maxWorkersPerInstance:20,jobsPerWorker:50},defaultDeadLetterOptions:{enabled:!0,maxRetries:5}}},failed:{driver:"redis",prefix:"stacks:failed"},worker:{concurrency:20,shutdownTimeout:60000}},database:{default:"database",connections:{database:{driver:"database",table:"jobs",queue:"default",retryAfter:90}},failed:{driver:"database",table:"failed_jobs"}}};var X={server:{development:{enabled:!0,mode:"server",debug:!0,server:{host:"localhost",port:6001,scheme:"ws",driver:"bun",rateLimit:{enabled:!1},healthCheck:{enabled:!0,path:"/health"}},channels:{public:!0,private:!0,presence:!0}},production:{enabled:!0,mode:"server",debug:!1,server:{host:"0.0.0.0",port:6001,scheme:"wss",driver:"bun",redis:{enabled:!0,prefix:"stacks:realtime:"},rateLimit:{enabled:!0,maxConnectionsPerIp:100,maxMessagesPerSecond:50,maxPayloadSize:65536},loadManagement:{maxConnections:1e4,backpressureThreshold:1000,messageQueueSize:1e4,gracefulShutdownTimeout:30000},autoScaling:{min:2,max:10,targetCPU:70},healthCheck:{enabled:!0,path:"/health",interval:30},metrics:{enabled:!0,port:9090,path:"/metrics"}},channels:{public:!0,private:!0,presence:!0}},highPerformance:{enabled:!0,mode:"server",server:{driver:"bun",redis:{enabled:!0,cluster:!0},rateLimit:{enabled:!0,maxConnectionsPerIp:500,maxMessagesPerSecond:200,maxPayloadSize:131072},loadManagement:{maxConnections:1e5,backpressureThreshold:5000,messageQueueSize:50000,gracefulShutdownTimeout:60000},autoScaling:{min:4,max:50,targetCPU:60}}},chat:{enabled:!0,mode:"server",server:{driver:"bun",redis:{enabled:!0},rateLimit:{enabled:!0,maxConnectionsPerIp:10,maxMessagesPerSecond:20},loadManagement:{maxConnections:50000}},channels:{public:!0,private:!0,presence:{enabled:!0,maxMembersPerChannel:500,memberInfoTtl:60}}},gaming:{enabled:!0,mode:"server",server:{driver:"bun",redis:{enabled:!0,cluster:!0},rateLimit:{enabled:!0,maxConnectionsPerIp:50,maxMessagesPerSecond:100},loadManagement:{maxConnections:50000,backpressureThreshold:2000,messageQueueSize:20000},autoScaling:{min:2,max:20,targetCPU:50}},channels:{public:!0,private:!0,presence:!0}}},serverless:{development:{enabled:!0,mode:"serverless",debug:!0,serverless:{connectionTimeout:3600,idleTimeout:600,stageName:"dev",memorySize:256,timeout:30},channels:{public:!0,private:!0,presence:!0}},production:{enabled:!0,mode:"serverless",debug:!1,serverless:{connectionTimeout:3600,idleTimeout:600,stageName:"production",memorySize:512,timeout:30,provisionedConcurrency:2},channels:{public:!0,private:!0,presence:!0}},notifications:{enabled:!0,mode:"serverless",serverless:{connectionTimeout:7200,idleTimeout:1800,memorySize:256,timeout:15},channels:{public:!0,private:!0,presence:!1}}}};var $={};export{$ as stackExtensionRegistry,G as isPersonalAccessToken,H as isOAuthClient,x as isAccessToken,J as getTypeName,Q as defineModels,M as defineModel,U as SocialLinkIcon,X as RealtimePresets,V as QueuePresets,_ as ExitCode,F as Every};
|
package/dist/logging.d.ts
CHANGED
|
@@ -8,5 +8,8 @@
|
|
|
8
8
|
export declare interface LoggingOptions {
|
|
9
9
|
logsPath: string
|
|
10
10
|
deploymentsPath: string
|
|
11
|
+
level?: 'debug' | 'info' | 'success' | 'warning' | 'error'
|
|
12
|
+
format?: 'json' | 'text'
|
|
13
|
+
writeToFile?: boolean
|
|
11
14
|
}
|
|
12
15
|
export type LoggingConfig = Partial<LoggingOptions>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* **Marketing Options**
|
|
3
|
+
*
|
|
4
|
+
* Top-level feature gate for the marketing bundle (`/api/email/subscribe`,
|
|
5
|
+
* `/api/contact`, Campaign / EmailList / SocialPost). Stays inert at boot
|
|
6
|
+
* when `enabled` is `false`.
|
|
7
|
+
*/
|
|
8
|
+
export declare interface MarketingOptions {
|
|
9
|
+
enabled?: boolean
|
|
10
|
+
env?: string[]
|
|
11
|
+
}
|
|
12
|
+
export type MarketingConfig = Partial<MarketingOptions>;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { DashboardModelOptions } from './dashboard';
|
|
2
|
+
// Re-export for `import type { DashboardModelOptions } from '@stacksjs/types'`.
|
|
3
|
+
export type { DashboardModelOptions };
|
|
4
|
+
declare module 'bun-query-builder' {
|
|
5
|
+
interface BrowserModelDefinition {
|
|
6
|
+
readonly dashboard?: DashboardModelOptions
|
|
7
|
+
}
|
|
8
|
+
}
|
package/dist/model.d.ts
CHANGED
|
@@ -103,6 +103,7 @@ export declare interface LikeableOptions {
|
|
|
103
103
|
}
|
|
104
104
|
export declare interface SeedOptions {
|
|
105
105
|
count: number
|
|
106
|
+
fixtures?: Array<Record<string, unknown>>
|
|
106
107
|
}
|
|
107
108
|
declare interface ActivityLogOption {
|
|
108
109
|
exclude: LogAttribute[]
|
|
@@ -210,6 +211,8 @@ export declare interface Attribute {
|
|
|
210
211
|
export declare interface CompositeIndex {
|
|
211
212
|
name: string
|
|
212
213
|
columns: string[]
|
|
214
|
+
unique?: boolean
|
|
215
|
+
where?: string
|
|
213
216
|
}
|
|
214
217
|
export declare interface AttributesElements {
|
|
215
218
|
[key: string]: Attribute
|
|
@@ -241,7 +244,7 @@ declare type ActionPath = string;
|
|
|
241
244
|
declare type ActionName = string;
|
|
242
245
|
declare type Action = ActionPath | ActionName | undefined;
|
|
243
246
|
export type ApiRoutes = 'index' | 'show' | 'store' | 'update' | 'destroy';
|
|
244
|
-
export type SocialProviders = 'google' | 'github' | 'twitter' | 'facebook';
|
|
247
|
+
export type SocialProviders = 'google' | 'github' | 'apple' | 'twitter' | 'facebook';
|
|
245
248
|
declare type LogAttribute = string;
|
|
246
249
|
export type SocialOptions = SocialProviders[];
|
|
247
250
|
declare type ApiOptions = DeepPartial<ApiSettings>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* **Monitoring Options**
|
|
3
|
+
*
|
|
4
|
+
* Top-level feature gate for the monitoring bundle (Error model +
|
|
5
|
+
* error-tracking views and actions). Stays inert at boot when `enabled`
|
|
6
|
+
* is `false`.
|
|
7
|
+
*/
|
|
8
|
+
export declare interface MonitoringOptions {
|
|
9
|
+
enabled?: boolean
|
|
10
|
+
env?: string[]
|
|
11
|
+
}
|
|
12
|
+
export type MonitoringConfig = Partial<MonitoringOptions>;
|
package/dist/queue.d.ts
CHANGED
package/dist/realtime.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ export declare const RealtimePresets: {
|
|
|
9
9
|
/**
|
|
10
10
|
* Development preset - minimal config, debug enabled
|
|
11
11
|
*/
|
|
12
|
-
|
|
12
|
+
development: {
|
|
13
13
|
enabled: true;
|
|
14
14
|
mode: 'server';
|
|
15
15
|
debug: true;
|
|
@@ -35,7 +35,7 @@ export declare const RealtimePresets: {
|
|
|
35
35
|
/**
|
|
36
36
|
* Production preset - optimized for production workloads
|
|
37
37
|
*/
|
|
38
|
-
|
|
38
|
+
production: {
|
|
39
39
|
enabled: true;
|
|
40
40
|
mode: 'server';
|
|
41
41
|
debug: false;
|
|
@@ -85,7 +85,7 @@ export declare const RealtimePresets: {
|
|
|
85
85
|
/**
|
|
86
86
|
* High performance preset - optimized for high throughput
|
|
87
87
|
*/
|
|
88
|
-
|
|
88
|
+
highPerformance: {
|
|
89
89
|
enabled: true;
|
|
90
90
|
mode: 'server';
|
|
91
91
|
server: {
|
|
@@ -116,7 +116,7 @@ export declare const RealtimePresets: {
|
|
|
116
116
|
/**
|
|
117
117
|
* Chat application preset
|
|
118
118
|
*/
|
|
119
|
-
|
|
119
|
+
chat: {
|
|
120
120
|
enabled: true;
|
|
121
121
|
mode: 'server';
|
|
122
122
|
server: {
|
|
@@ -146,7 +146,7 @@ export declare const RealtimePresets: {
|
|
|
146
146
|
/**
|
|
147
147
|
* Gaming preset - low latency, high throughput
|
|
148
148
|
*/
|
|
149
|
-
|
|
149
|
+
gaming: {
|
|
150
150
|
enabled: true;
|
|
151
151
|
mode: 'server';
|
|
152
152
|
server: {
|
|
@@ -185,7 +185,7 @@ export declare const RealtimePresets: {
|
|
|
185
185
|
/**
|
|
186
186
|
* Development preset
|
|
187
187
|
*/
|
|
188
|
-
|
|
188
|
+
development: {
|
|
189
189
|
enabled: true;
|
|
190
190
|
mode: 'serverless';
|
|
191
191
|
debug: true;
|
|
@@ -205,7 +205,7 @@ export declare const RealtimePresets: {
|
|
|
205
205
|
/**
|
|
206
206
|
* Production preset
|
|
207
207
|
*/
|
|
208
|
-
|
|
208
|
+
production: {
|
|
209
209
|
enabled: true;
|
|
210
210
|
mode: 'serverless';
|
|
211
211
|
debug: false;
|
|
@@ -226,7 +226,7 @@ export declare const RealtimePresets: {
|
|
|
226
226
|
/**
|
|
227
227
|
* Notifications preset - simple push notifications
|
|
228
228
|
*/
|
|
229
|
-
|
|
229
|
+
notifications: {
|
|
230
230
|
enabled: true;
|
|
231
231
|
mode: 'serverless';
|
|
232
232
|
serverless: {
|
package/dist/request.d.ts
CHANGED
|
@@ -1,10 +1,32 @@
|
|
|
1
1
|
import { User } from '@stacksjs/orm';
|
|
2
2
|
import type { AuthToken } from '@stacksjs/types';
|
|
3
|
+
import type { Infer } from '@stacksjs/ts-validation';
|
|
3
4
|
import type { ModelRow } from '@stacksjs/orm';
|
|
4
5
|
import type { UploadedFile } from '@stacksjs/storage';
|
|
5
6
|
declare interface RequestData {
|
|
6
7
|
[key: string]: any
|
|
7
8
|
}
|
|
9
|
+
/**
|
|
10
|
+
* Cookie-access helper exposed via `request.cookies` on
|
|
11
|
+
* {@link RequestInstance}. The methods mirror bun-router's
|
|
12
|
+
* `CookieAccessor` — duplicated locally so this package doesn't
|
|
13
|
+
* have to depend on bun-router for a single type. Keep the surface
|
|
14
|
+
* in sync if bun-router extends its accessor.
|
|
15
|
+
*/
|
|
16
|
+
export declare interface RequestCookies {
|
|
17
|
+
get: (name: string) => string | undefined
|
|
18
|
+
set: (name: string, value: string, options?: {
|
|
19
|
+
path?: string
|
|
20
|
+
domain?: string
|
|
21
|
+
secure?: boolean
|
|
22
|
+
httpOnly?: boolean
|
|
23
|
+
sameSite?: 'strict' | 'lax' | 'none'
|
|
24
|
+
maxAge?: number
|
|
25
|
+
expires?: Date
|
|
26
|
+
}) => void
|
|
27
|
+
delete: (name: string, options?: { path?: string, domain?: string }) => void
|
|
28
|
+
getAll: () => Record<string, string>
|
|
29
|
+
}
|
|
8
30
|
/**
|
|
9
31
|
* Collection interface for array data (Laravel-style)
|
|
10
32
|
*/
|
|
@@ -45,15 +67,16 @@ export declare interface SafeData<T extends Record<string, any> = Record<string,
|
|
|
45
67
|
has: (key: keyof T) => boolean
|
|
46
68
|
get: <K extends keyof T>(key: K) => T[K]
|
|
47
69
|
}
|
|
48
|
-
export declare interface RequestInstance<TFields extends Record<string, any> = Record<string, any
|
|
70
|
+
export declare interface RequestInstance<TFields extends Record<string, any> = Record<string, any>, TParams extends Record<string, string> = Record<string, string>,> {
|
|
49
71
|
url: string
|
|
50
72
|
method: string
|
|
51
73
|
headers: Headers
|
|
52
74
|
query: RequestData
|
|
53
|
-
params:
|
|
75
|
+
params: TParams
|
|
54
76
|
jsonBody?: any
|
|
55
77
|
formBody?: any
|
|
56
78
|
files: Record<string, File | File[]>
|
|
79
|
+
cookies?: RequestCookies
|
|
57
80
|
get: <K extends keyof TFields & string>(key: K, defaultValue?: TFields[K]) => TFields[K]
|
|
58
81
|
input: <K extends keyof TFields & string>(key: K, defaultValue?: TFields[K]) => TFields[K]
|
|
59
82
|
all: () => TFields
|
|
@@ -85,9 +108,13 @@ export declare interface RequestInstance<TFields extends Record<string, any> = R
|
|
|
85
108
|
allFiles: () => Record<string, UploadedFile | UploadedFile[]>
|
|
86
109
|
header: (key: string) => string | null
|
|
87
110
|
bearerToken: () => string | null | AuthToken
|
|
111
|
+
param: <K extends keyof TParams | string, D = string>(
|
|
112
|
+
key: K,
|
|
113
|
+
defaultValue?: D,
|
|
114
|
+
) => K extends keyof TParams ? TParams[K] : (string | D)
|
|
88
115
|
getParam: <K extends string>(key: K) => K extends NumericField ? number : string
|
|
89
116
|
route: (key: string) => number | string | null
|
|
90
|
-
getParams: () =>
|
|
117
|
+
getParams: () => TParams
|
|
91
118
|
getParamAsInt: (key: string) => number | null
|
|
92
119
|
old: <T = unknown>(key: keyof TFields & string, defaultValue?: T) => T
|
|
93
120
|
flashInput: (keys?: (keyof TFields & string)[]) => void
|
|
@@ -102,8 +129,65 @@ export declare interface RequestInstance<TFields extends Record<string, any> = R
|
|
|
102
129
|
user: () => Promise<UserJsonResponse | undefined>
|
|
103
130
|
}
|
|
104
131
|
declare type UserJsonResponse = ModelRow<typeof User>;
|
|
132
|
+
/**
|
|
133
|
+
* Loose route-param shape kept around for back-compat with code that
|
|
134
|
+
* predates {@link RequestInstance}'s `TParams` generic. New code should
|
|
135
|
+
* rely on the path-extracted `TParams` instead — see {@link ExtractParams}.
|
|
136
|
+
*
|
|
137
|
+
* @deprecated Use {@link ExtractParams}-driven typing on the action /
|
|
138
|
+
* route signature instead. URL route params are always strings at
|
|
139
|
+
* runtime; the `string | number` here misled callers into thinking
|
|
140
|
+
* the framework coerced numbers automatically (it doesn't —
|
|
141
|
+
* `Number(request.params.id)` is the correct pattern).
|
|
142
|
+
*/
|
|
105
143
|
declare type RouteParams = { [key: string]: string | number } | null;
|
|
144
|
+
/**
|
|
145
|
+
* Legacy hard-coded list of param names treated as `number` by
|
|
146
|
+
* {@link RequestInstance.getParam}. The name-match heuristic is
|
|
147
|
+
* brittle (`'judgeId'`, `'user_id'`, etc. all silently fall through
|
|
148
|
+
* to `string`) and will be retired in a future release.
|
|
149
|
+
*
|
|
150
|
+
* @deprecated The name-match returns `number` for these specific keys
|
|
151
|
+
* only — pass the value through {@link Number} or
|
|
152
|
+
* {@link RequestInstance.getParamAsInt} for explicit, predictable
|
|
153
|
+
* coercion. See stacksjs/stacks#1851 Phase 3.
|
|
154
|
+
*/
|
|
106
155
|
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';
|
|
156
|
+
/**
|
|
157
|
+
* Template-literal helper that extracts named route params from a
|
|
158
|
+
* path string (stacksjs/stacks#1851 Phase 2a). Supports both Stacks's
|
|
159
|
+
* brace-style (`/users/{id}`) and Express-style (`/users/:id`) so a
|
|
160
|
+
* project using either gets typed `params` out of the box.
|
|
161
|
+
*
|
|
162
|
+
* @example
|
|
163
|
+
* ExtractParams<'/api/judges/{id}/follow'> // { id: string }
|
|
164
|
+
* ExtractParams<'/api/orders/:orderId/items/:itemId'> // { orderId: string, itemId: string }
|
|
165
|
+
* ExtractParams<'/api/health'> // Record<string, never>
|
|
166
|
+
*/
|
|
167
|
+
// Step 1: pull the next param name out of either `{name}` or `:name`,
|
|
168
|
+
// recurse on the rest, and union the keys.
|
|
169
|
+
declare type ExtractParamKeys<S extends string> = S extends `${string}{${infer Key}}${infer Rest}`
|
|
170
|
+
? Key | ExtractParamKeys<Rest>
|
|
171
|
+
// colon form: `…/:name/…` (colon must be at a segment boundary
|
|
172
|
+
// so we don't match `:` inside e.g. a port number; the `/` before
|
|
173
|
+
// it enforces that)
|
|
174
|
+
: S extends `${string}/:${infer Key}/${infer Rest}`
|
|
175
|
+
? KeyHead<Key> | ExtractParamKeys<`/${Rest}`>
|
|
176
|
+
// tail colon-form: `…/:name` (no trailing slash)
|
|
177
|
+
: S extends `${string}/:${infer Key}`
|
|
178
|
+
? KeyHead<Key>
|
|
179
|
+
: never;
|
|
180
|
+
// `KeyHead<'name>'>` → `'name>'` because TS template literal infers
|
|
181
|
+
// the longest possible match. We need to handle params that are at
|
|
182
|
+
// the end of the path AND followed by a query string. This util
|
|
183
|
+
// truncates a captured key at the first non-name character.
|
|
184
|
+
declare type KeyHead<S extends string> = S extends `${infer H}/${string}` ? H :
|
|
185
|
+
S extends `${infer H}?${string}` ? H :
|
|
186
|
+
S extends `${infer H}.${string}` ? H :
|
|
187
|
+
S;
|
|
188
|
+
export type ExtractParams<S extends string> = [ExtractParamKeys<S>] extends [never]
|
|
189
|
+
? Record<string, never>
|
|
190
|
+
: { [K in ExtractParamKeys<S>]: string }
|
|
107
191
|
export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS' | 'CONNECT' | 'TRACE';
|
|
108
192
|
/**
|
|
109
193
|
* RequestInstance - Generic, model-aware request interface with Laravel-style methods.
|
|
@@ -151,4 +235,23 @@ export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' |
|
|
|
151
235
|
* })
|
|
152
236
|
* ```
|
|
153
237
|
*/
|
|
154
|
-
export type ActionRequest<TFields extends Record<string, any> = Record<string, any
|
|
238
|
+
export type ActionRequest<TFields extends Record<string, any> = Record<string, any>, TParams extends Record<string, string> = Record<string, string>,> = RequestInstance<TFields, TParams>;
|
|
239
|
+
/**
|
|
240
|
+
* Read the body shape declared by an action's `validations:` field as
|
|
241
|
+
* a TypeScript object type (stacksjs/stacks#1851 Phase 2b). Threaded
|
|
242
|
+
* into {@link RequestInstance}'s `TFields` so `request.all()` returns
|
|
243
|
+
* the body shape with the field types {@link Infer}'d from each
|
|
244
|
+
* `schema.X()` rule.
|
|
245
|
+
*
|
|
246
|
+
* @example
|
|
247
|
+
* const validations = {
|
|
248
|
+
* email: { rule: schema.string().email() },
|
|
249
|
+
* password: { rule: schema.string().min(8) },
|
|
250
|
+
* remember: { rule: schema.boolean() },
|
|
251
|
+
* } as const
|
|
252
|
+
* type Body = InferValidations<typeof validations>
|
|
253
|
+
* // → { email: string, password: string, remember: boolean }
|
|
254
|
+
*/
|
|
255
|
+
export type InferValidations<V extends Record<string, { rule: any }>> = {
|
|
256
|
+
[K in keyof V]: Infer<V[K]['rule']>
|
|
257
|
+
}
|