@stacksjs/types 0.72.57 → 0.72.61

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/index.js CHANGED
@@ -1,2 +1,2 @@
1
1
  // @bun
2
- function x(p){return typeof p==="object"&&p!==null&&"id"in p&&"userId"in p&&"clientId"in p&&"scopes"in p}function H(p){return x(p)&&"abilities"in p}function N(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 G}from"@stacksjs/strings";function K(p){if(p===null)return"null";let P=G(p).slice(8,-1).toLowerCase();return typeof p==="object"||typeof p==="function"?P:typeof p}function Q(p){return p}function R(p){return p}var W={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 Z={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 A={calendar:{github:"stacksjs/calendar",package:"@stacksjs/calendar",description:"Calendar links, ICS generation, and an STX calendar component"},table:{github:"stacksjs/table",package:"@stacksjs/table",description:"Typed table drivers and an STX data table component"}};export{A as stackExtensionRegistry,H as isPersonalAccessToken,N as isOAuthClient,x as isAccessToken,K as getTypeName,R as defineModels,Q as defineModel,U as SocialLinkIcon,Z as RealtimePresets,W as QueuePresets,_ as ExitCode,F as Every};
2
+ function a(e){return typeof e==="object"&&e!==null&&"id"in e&&"userId"in e&&"clientId"in e&&"scopes"in e}function c(e){return a(e)&&"abilities"in e}function d(e){return typeof e==="object"&&e!==null&&"id"in e&&"name"in e&&"secret"in e&&"redirect"in e}var i;((t)=>{t.Second="* * * * * *";t.FiveSeconds="*/5 * * * * *";t.TenSeconds="*/10 * * * * *";t.ThirtySeconds="*/30 * * * * *";t.Minute="* * * * *";t.TwoMinutes="*/2 * * * *";t.FiveMinutes="*/5 * * * *";t.TenMinutes="*/10 * * * *";t.FifteenMinutes="*/15 * * * *";t.ThirtyMinutes="*/30 * * * *";t.Hour="0 * * * *";t.HalfHour="0,30 * * * *";t.Day="0 0 * * *";t.Week="0 0 * * 0";t.Weekday="0 0 * * 1-5";t.Weekend="0 0 * * 0,6";t.Month="0 0 1 * *";t.Year="0 0 1 1 *"})(i||={});var s;((r)=>{r.Bluesky="bluesky";r.Discord="discord";r.Facebook="facebook";r.GitHub="github";r.Instagram="instagram";r.LinkedIn="linkedin";r.Mastodon="mastodon";r.Slack="slack";r.Twitter="twitter";r.YouTube="youtube"})(s||={});var l;((n)=>{n[n.Success=0]="Success";n[n.FatalError=1]="FatalError";n[n.InvalidArgument=9]="InvalidArgument"})(l||={});import{toString as p}from"@stacksjs/strings";function y(e){if(e===null)return"null";let o=p(e).slice(8,-1).toLowerCase();return typeof e==="object"||typeof e==="function"?o:typeof e}function h(e){return e}function T(e){return e}var C={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 M={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 S={calendar:{github:"stacksjs/calendar",package:"@stacksjs/calendar",description:"Calendar links, ICS generation, and an STX calendar component"},table:{github:"stacksjs/table",package:"@stacksjs/table",description:"Typed table drivers and an STX data table component"}};export{i as Every,l as ExitCode,C as QueuePresets,M as RealtimePresets,s as SocialLinkIcon,h as defineModel,T as defineModels,y as getTypeName,a as isAccessToken,d as isOAuthClient,c as isPersonalAccessToken,S as stackExtensionRegistry};
package/dist/request.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { User } from '@stacksjs/orm';
2
2
  import type { AuthToken } from '@stacksjs/types';
3
- import type { Infer } from '@stacksjs/ts-validation';
3
+ import type { Infer, IsRequired } from '@stacksjs/ts-validation';
4
4
  import type { UploadedFile } from '@stacksjs/storage';
5
5
  declare interface RequestData {
6
6
  [key: string]: any
@@ -89,9 +89,9 @@ export declare interface RequestInstance<TFields extends Record<string, any> = R
89
89
  body?: ReadableStream<Uint8Array> | null
90
90
  getUrl?: () => string
91
91
  cookies?: RequestCookies
92
- get<K extends keyof TFields & string>(key: K, defaultValue?: TFields[K]): TFields[K]
92
+ get<K extends keyof TInput<TFields, TParams> & string>(key: K, defaultValue?: TInput<TFields, TParams>[K]): TInput<TFields, TParams>[K]
93
93
  get<T = any>(key: string, defaultValue?: T): T
94
- input<K extends keyof TFields & string>(key: K, defaultValue?: TFields[K]): TFields[K]
94
+ input<K extends keyof TInput<TFields, TParams> & string>(key: K, defaultValue?: TInput<TFields, TParams>[K]): TInput<TFields, TParams>[K]
95
95
  input<T = any>(key: string, defaultValue?: T): T
96
96
  all: () => TFields
97
97
  only<K extends keyof TFields & string>(keys: K[]): Pick<TFields, K>
@@ -245,9 +245,64 @@ export type ActionRequest<TFields extends Record<string, any> = Record<string, a
245
245
  * type Body = InferValidations<typeof validations>
246
246
  * // → { email: string, password: string, remember: boolean }
247
247
  */
248
- export type InferValidations<V extends Record<string, { rule: any }>> = {
249
- [K in keyof V]: Infer<V[K]['rule']>
250
- }
248
+ /**
249
+ * Resolve a computed type to its final shape, for display.
250
+ *
251
+ * A named alias over a generic is shown by TypeScript as the alias: hovering
252
+ * `handle`'s parameter reported
253
+ *
254
+ * InferValidations<{ id: { rule: WithConditionals<NumberValidatorType> }; … }>
255
+ *
256
+ * which is the machinery, not the answer. It says nothing about what `id`
257
+ * actually is - the reader has to go and resolve it themselves, which is
258
+ * exactly the work the inference was supposed to save. Mapping the type through
259
+ * a fresh object literal forces it to be displayed evaluated, so the same hover
260
+ * reports `{ id: number, name: string }`.
261
+ *
262
+ * Display only: `Resolved<T>` and `T` are the same type.
263
+ */
264
+ export type Resolved<T> = T extends infer U ? { [K in keyof U]: U[K] } : never;
265
+ /**
266
+ * The shape a set of validation rules describes.
267
+ *
268
+ * Optionality comes from the rules themselves: a field whose rule went through
269
+ * `.required()` is a required key, and everything else is optional. Before
270
+ * ts-validation 0.5.6 there was nothing to read - `required()` returned `this`
271
+ * and `isRequired` was a runtime boolean - so every field typed as present,
272
+ * including the ones a handler has to guard. `user.name` was `string` on a
273
+ * payload where it could be absent, which is the type saying something the
274
+ * runtime does not.
275
+ *
276
+ * Written as two mapped types rather than one with an optional modifier,
277
+ * because `?` cannot be applied conditionally per key.
278
+ */
279
+ export type InferValidations<V extends Record<string, { rule: any }>> = Resolved<
280
+ & { [K in keyof V as IsRequired<V[K]['rule']> extends true ? K : never]: Infer<V[K]['rule']> }
281
+ & { [K in keyof V as IsRequired<V[K]['rule']> extends true ? never : K]?: Infer<V[K]['rule']> }
282
+ >;
283
+ /**
284
+ * What `get()` and `input()` can actually be asked for.
285
+ *
286
+ * They read one merged bag — `getAllInputFor` folds query, then body, then
287
+ * route params, in that order — so a path param is as reachable through
288
+ * `request.get('id')` as a validated body field is. The declarations were keyed
289
+ * on `TFields` alone, which meant `request.params.id` was `string` while
290
+ * `request.get('id')` right beside it was `any`: the same value, typed on one
291
+ * route and not the other.
292
+ *
293
+ * Params override fields where the names collide, because that is the order the
294
+ * runtime merges in.
295
+ */
296
+ export type TInput<TFields extends Record<string, any>, TParams extends Record<string, string>,> = string extends keyof TParams
297
+ /*
298
+ * No path was declared, so `TParams` is the wide `Record<string, string>`
299
+ * default and its `keyof` is `string`. Merging that would `Omit` every key
300
+ * from `TFields` and leave the fields typed as strings - so an action with
301
+ * validations but no `path:` would have had its inferred body erased. When
302
+ * nothing is known about the params, the fields are the whole answer.
303
+ */
304
+ ? TFields
305
+ : Omit<TFields, keyof TParams> & TParams;
251
306
  export type RequestValidationRules = Record<string, string | {
252
307
  rule: { validate: (value: any) => any }
253
308
  message?: string | Record<string, string>
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@stacksjs/types",
3
3
  "type": "module",
4
- "version": "0.72.57",
4
+ "version": "0.72.61",
5
5
  "description": "The Stacks framework types.",
6
6
  "author": "Chris Breuer",
7
7
  "contributors": [
@@ -58,8 +58,8 @@
58
58
  "dependencies": {
59
59
  "@stacksjs/bunpress": "^0.2.8",
60
60
  "@stacksjs/clapp": "^0.2.12",
61
- "@stacksjs/stx": "^0.2.219",
62
- "@stacksjs/ts-validation": "^0.5.5",
61
+ "@stacksjs/stx": "^0.2.227",
62
+ "@stacksjs/ts-validation": "^0.5.6",
63
63
  "bun-query-builder": "^0.2.53"
64
64
  },
65
65
  "peerDependencies": {
@@ -71,7 +71,7 @@
71
71
  }
72
72
  },
73
73
  "devDependencies": {
74
- "@stacksjs/validation": "0.72.57",
74
+ "@stacksjs/validation": "0.72.61",
75
75
  "better-dx": "^0.2.24",
76
76
  "meilisearch": "^0.59.0"
77
77
  },