@stacksjs/orm 0.70.72 → 0.70.74

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.
@@ -101,6 +101,8 @@ export declare function buildReadColumnMap(attributes: Record<string, unknown> |
101
101
  * ?sort=discountType,name → ORDER BY discount_type ASC, name ASC
102
102
  */
103
103
  export declare function applySorting(query: any, sortParam: string | null, columns: ReadonlyMap<string, string>): any;
104
+ declare function safeJSON(s: string): unknown;
105
+ declare function safeJSONOrEmpty(_s: string): unknown;
104
106
  /**
105
107
  * Apply a model's `casts` to a record, in either direction:
106
108
  * - `'get'` — DB shape → JS-typed values (read responses)
@@ -161,18 +163,25 @@ export declare const SYSTEM_COLUMNS: string[];
161
163
  * Built-in cast resolvers — kept in sync with @stacksjs/orm/define-model.
162
164
  * A duplicate here is the simplest way to keep auto-CRUD parity with the
163
165
  * model-driven path without introducing a circular import.
164
- */
165
- export declare const AUTO_CRUD_CASTERS: {
166
- string: { get: (v) => unknown; set: (v) => unknown };
167
- number: { get: (v) => unknown; set: (v) => unknown };
168
- integer: { get: (v) => unknown; set: (v) => unknown };
169
- float: { get: (v) => unknown; set: (v) => unknown };
170
- boolean: { get: (v) => unknown; set: (v) => unknown };
171
- json: { get: (v) => unknown; set: (v) => unknown };
172
- datetime: { get: (v) => unknown; set: (v) => unknown };
173
- date: { get: (v) => unknown; set: (v) => unknown };
174
- array: { get: (v) => unknown; set: (v) => unknown }
175
- };
166
+ * @defaultValue
167
+ * ```ts
168
+ * {
169
+ * string: { get: (v) => unknown | null, set: (v) => unknown | null },
170
+ * number: { get: (v) => unknown | null, set: (v) => unknown | null },
171
+ * integer: { get: (v) => unknown | null, set: (v) => unknown | null },
172
+ * float: { get: (v) => unknown | null, set: (v) => unknown | null },
173
+ * boolean: { get: (v) => boolean, set: (v) => number },
174
+ * json: { get: (v) => null | unknown, set: (v) => null | unknown },
175
+ * datetime: { get: (v) => Date | null, set: (v) => unknown },
176
+ * date: { get: (v) => Date | null, set: (v) => unknown },
177
+ * array: {
178
+ * get: (v) => never[] | unknown | unknown | never[],
179
+ * set: (v) => null | unknown
180
+ * }
181
+ * }
182
+ * ```
183
+ */
184
+ export declare const AUTO_CRUD_CASTERS: Record<string, { get: (v: unknown) => unknown, set: (v: unknown) => unknown }>;
176
185
  // Default page size for the auto-CRUD index route. Matches the
177
186
  // request-aware Model.paginate() / resolvePageArgs default (15) so the
178
187
  // REST list endpoint and the in-process paginator agree out of the box.
@@ -5,6 +5,7 @@ import { createLikeableMethods } from './traits/likeable';
5
5
  import { createSoftDeleteMethods } from './traits/soft-deletes';
6
6
  import { createTaggableMethods } from './traits/taggable';
7
7
  import { createTwoFactorMethods } from './traits/two-factor';
8
+ import { type OrmModelDefinition as BQBModelDefinition, type OrmModelStatic } from '@stacksjs/query-builder';
8
9
  import type { InferRelationNames } from '@stacksjs/query-builder';
9
10
  // Re-export types from bun-query-builder for convenience
10
11
  export type { ModelDefinition, InferRelationNames, ModelAttributes, InferModelAttributes, SystemFields, ColumnName, AttributeKeys, FillableKeys, HiddenKeys, ModelInstance, ModelQueryBuilder } from '@stacksjs/query-builder';
@@ -21,52 +22,7 @@ export type { ModelDefinition, InferRelationNames, ModelAttributes, InferModelAt
21
22
  * ```
22
23
  */
23
24
  export declare function withoutEvents<T>(fn: () => T | Promise<T>): Promise<T>;
24
- /**
25
- * Stacks-enhanced model definition.
26
- *
27
- * Wraps bun-query-builder's `createModel()` with:
28
- * - Event dispatching via `traits.observe`
29
- * - Trait methods (billable, taggable, categorizable, commentable, likeable, 2FA)
30
- * - Full backward compatibility with generators (migration, routes, dashboard)
31
- *
32
- * ### Relationships
33
- * Each entry in `belongsTo`, `hasMany`, `hasOne`, `belongsToMany`,
34
- * `hasOneThrough`, and `hasManyThrough` declares a typed relation
35
- * usable via `.with('relationName')`:
36
- *
37
- * ```ts
38
- * defineModel({
39
- * belongsTo: ['Author'], // ↪ post.author
40
- * hasMany: ['Comment'], // ↪ post.comments (lowercase + pluralized)
41
- * hasOne: ['Cover'], // ↪ post.cover
42
- * })
43
- * ```
44
- *
45
- * After eager loading the related row(s) are reachable as a property
46
- * on the instance — `(await Post.with('author').first()).author`.
47
- *
48
- * @example
49
- * ```ts
50
- * import { defineModel } from '@stacksjs/orm'
51
- * import { schema } from '@stacksjs/validation'
52
- *
53
- * export default defineModel({
54
- * name: 'Post',
55
- * table: 'posts',
56
- * attributes: {
57
- * title: { type: 'string', fillable: true, validation: { rule: schema.string() } },
58
- * views: { type: 'number', fillable: true, validation: { rule: schema.number() } },
59
- * },
60
- * belongsTo: ['Author'],
61
- * hasMany: ['Tag', 'Category', 'Comment'],
62
- * traits: { useTimestamps: true, useUuid: true },
63
- * } as const)
64
- *
65
- * // Result: Post.where('title', 'test') — 'title' narrowed to valid columns
66
- * // Result: Post.with('author') — 'author' narrowed to valid relations
67
- * ```
68
- */
69
- export declare function defineModel<const TDef extends ModelDefinition>(definition: TDef): void;
25
+ export declare function defineModel<const TDef extends ModelDefinition>(definition: TDef): StacksModelStatic<TDef>;
70
26
  /**
71
27
  * Normalize a ModelInstance (or array of them, or already-plain row) into
72
28
  * a serialization-ready plain object.
@@ -88,12 +44,12 @@ export declare interface CasterInterface {
88
44
  get(value: unknown): unknown
89
45
  set(value: unknown): unknown
90
46
  }
91
- declare interface StacksModelDefinition {
47
+ declare interface StacksModelDefinition extends Omit<BQBModelDefinition, 'attributes' | 'indexes' | 'traits'> {
92
48
  name: string
93
49
  table: string
94
50
  primaryKey?: string
95
51
  autoIncrement?: boolean
96
- traits?: Record<string, unknown>
52
+ traits?: NonNullable<BQBModelDefinition['traits']> & Record<string, unknown>
97
53
  indexes?: Array<{ name: string, columns: string[], unique?: boolean, where?: string }>
98
54
  casts?: Record<string, CastType | CasterInterface>
99
55
  attributes: {
@@ -139,6 +95,58 @@ export declare interface TraitMethods {
139
95
  */
140
96
  export type CastType = 'string' | 'number' | 'boolean' | 'json' | 'datetime' | 'date' | 'array' | 'integer' | 'float';
141
97
  declare type ModelDefinition = StacksModelDefinition;
98
+ /**
99
+ * Stacks-enhanced model definition.
100
+ *
101
+ * Wraps bun-query-builder's `createModel()` with:
102
+ * - Event dispatching via `traits.observe`
103
+ * - Trait methods (billable, taggable, categorizable, commentable, likeable, 2FA)
104
+ * - Full backward compatibility with generators (migration, routes, dashboard)
105
+ *
106
+ * ### Relationships
107
+ * Each entry in `belongsTo`, `hasMany`, `hasOne`, `belongsToMany`,
108
+ * `hasOneThrough`, and `hasManyThrough` declares a typed relation
109
+ * usable via `.with('relationName')`:
110
+ *
111
+ * ```ts
112
+ * defineModel({
113
+ * belongsTo: ['Author'], // ↪ post.author
114
+ * hasMany: ['Comment'], // ↪ post.comments (lowercase + pluralized)
115
+ * hasOne: ['Cover'], // ↪ post.cover
116
+ * })
117
+ * ```
118
+ *
119
+ * After eager loading the related row(s) are reachable as a property
120
+ * on the instance — `(await Post.with('author').first()).author`.
121
+ *
122
+ * @example
123
+ * ```ts
124
+ * import { defineModel } from '@stacksjs/orm'
125
+ * import { schema } from '@stacksjs/validation'
126
+ *
127
+ * export default defineModel({
128
+ * name: 'Post',
129
+ * table: 'posts',
130
+ * attributes: {
131
+ * title: { type: 'string', fillable: true, validation: { rule: schema.string() } },
132
+ * views: { type: 'number', fillable: true, validation: { rule: schema.number() } },
133
+ * },
134
+ * belongsTo: ['Author'],
135
+ * hasMany: ['Tag', 'Category', 'Comment'],
136
+ * traits: { useTimestamps: true, useUuid: true },
137
+ * } as const)
138
+ *
139
+ * // Result: Post.where('title', 'test') — 'title' narrowed to valid columns
140
+ * // Result: Post.with('author') — 'author' narrowed to valid relations
141
+ * ```
142
+ */
143
+ export type StacksModelStatic<TDef extends ModelDefinition> = OrmModelStatic<TDef> & TDef & TraitMethods & {
144
+ update: (id: number | string, data: Record<string, unknown>) => ReturnType<OrmModelStatic<TDef>['find']>
145
+ forceUpdate: (id: number | string, data: Record<string, unknown>) => ReturnType<OrmModelStatic<TDef>['find']>
146
+ forceCreate: (data: Record<string, unknown>) => ReturnType<OrmModelStatic<TDef>['create']>
147
+ delete: (id: number | string) => Promise<boolean>
148
+ withoutEvents: <T>(fn: () => T | Promise<T>) => Promise<T>
149
+ }
142
150
  /**
143
151
  * Thrown by `Model.findOrFail(id)` (and other strict lookups) when no row matches.
144
152
  * Callers can `instanceof` against this to distinguish "missing" from other errors.
package/dist/index.d.ts CHANGED
@@ -15,6 +15,13 @@ export type {
15
15
  InferTableName,
16
16
  ModelDefinition,
17
17
  } from '@stacksjs/query-builder';
18
+ /**
19
+ * Returns a Proxy that lazily forwards every property access to the
20
+ * loaded model in `_loaded[name]`. Returns `undefined` before the
21
+ * deferred load completes — callers that need the load to finish
22
+ * first should `await ormReady`.
23
+ */
24
+ declare function lazyModel<T>(name: string): T;
18
25
  /**
19
26
  * Resolves once all framework-default models have been loaded into the
20
27
  * lazy-export proxies. Server bootstrap code that wants to ensure model
@@ -23,7 +30,7 @@ export type {
23
30
  * time any HTTP handler runs, the microtask queue has long drained.
24
31
  */
25
32
  export declare const ormReady: Promise<void>;
26
- export declare const User: any;
33
+ export declare const User: boolean;
27
34
  // Queue framework models. The CLI commands `buddy queue:status`,
28
35
  // `queue:failed`, `queue:flush`, `queue:inspect`, `queue:monitor`,
29
36
  // `queue:clear` import them as `import { Job, FailedJob } from
@@ -37,62 +44,62 @@ export declare const User: any;
37
44
  // returns `undefined` for unloaded models, and the CLI queue commands
38
45
  // can check `await ormReady; if (!Job) throw …` to surface a clear
39
46
  // "run ./buddy queue:install" error.
40
- export declare const Job: any;
41
- export declare const FailedJob: any;
42
- export declare const Activity: any;
43
- export declare const Author: any;
44
- export declare const Campaign: any;
45
- export declare const Cart: any;
46
- export declare const CartItem: any;
47
- export declare const Category: any;
48
- export declare const Comment: any;
49
- export declare const Coupon: any;
50
- export declare const Customer: any;
51
- export declare const DeliveryRoute: any;
52
- export declare const Deployment: any;
53
- export declare const DigitalDelivery: any;
54
- export declare const Driver: any;
55
- export declare const CampaignSend: any;
56
- export declare const EmailList: any;
57
- export declare const EmailListSubscriber: any;
58
- export declare const ErrorModel: any;
59
- export declare const GiftCard: any;
60
- export declare const LicenseKey: any;
61
- export declare const Log: any;
62
- export declare const LoyaltyPoint: any;
63
- export declare const LoyaltyReward: any;
64
- export declare const Manufacturer: any;
65
- export declare const Notification: any;
66
- export declare const Order: any;
67
- export declare const OrderItem: any;
68
- export declare const Page: any;
69
- export declare const Payment: any;
70
- export declare const PaymentMethod: any;
71
- export declare const PaymentProduct: any;
72
- export declare const PaymentTransaction: any;
73
- export declare const Post: any;
74
- export declare const PrintDevice: any;
75
- export declare const Product: any;
76
- export declare const ProductUnit: any;
77
- export declare const ProductVariant: any;
78
- export declare const Receipt: any;
79
- export declare const Release: any;
80
- export declare const Request: any;
81
- export declare const Review: any;
82
- export declare const ShippingMethod: any;
83
- export declare const ShippingRate: any;
84
- export declare const ShippingZone: any;
85
- export declare const SocialPost: any;
86
- export declare const Subscriber: any;
87
- export declare const SubscriberEmail: any;
88
- export declare const Subscription: any;
89
- export declare const Tag: any;
90
- export declare const TaxRate: any;
91
- export declare const Team: any;
92
- export declare const Transaction: any;
93
- export declare const WaitlistProduct: any;
94
- export declare const WaitlistRestaurant: any;
95
- export declare const Websocket: any;
47
+ export declare const Job: boolean;
48
+ export declare const FailedJob: boolean;
49
+ export declare const Activity: boolean;
50
+ export declare const Author: boolean;
51
+ export declare const Campaign: boolean;
52
+ export declare const Cart: boolean;
53
+ export declare const CartItem: boolean;
54
+ export declare const Category: boolean;
55
+ export declare const Comment: boolean;
56
+ export declare const Coupon: boolean;
57
+ export declare const Customer: boolean;
58
+ export declare const DeliveryRoute: boolean;
59
+ export declare const Deployment: boolean;
60
+ export declare const DigitalDelivery: boolean;
61
+ export declare const Driver: boolean;
62
+ export declare const CampaignSend: boolean;
63
+ export declare const EmailList: boolean;
64
+ export declare const EmailListSubscriber: boolean;
65
+ export declare const ErrorModel: boolean;
66
+ export declare const GiftCard: boolean;
67
+ export declare const LicenseKey: boolean;
68
+ export declare const Log: boolean;
69
+ export declare const LoyaltyPoint: boolean;
70
+ export declare const LoyaltyReward: boolean;
71
+ export declare const Manufacturer: boolean;
72
+ export declare const Notification: boolean;
73
+ export declare const Order: boolean;
74
+ export declare const OrderItem: boolean;
75
+ export declare const Page: boolean;
76
+ export declare const Payment: boolean;
77
+ export declare const PaymentMethod: boolean;
78
+ export declare const PaymentProduct: boolean;
79
+ export declare const PaymentTransaction: boolean;
80
+ export declare const Post: boolean;
81
+ export declare const PrintDevice: boolean;
82
+ export declare const Product: boolean;
83
+ export declare const ProductUnit: boolean;
84
+ export declare const ProductVariant: boolean;
85
+ export declare const Receipt: boolean;
86
+ export declare const Release: boolean;
87
+ export declare const Request: boolean;
88
+ export declare const Review: boolean;
89
+ export declare const ShippingMethod: boolean;
90
+ export declare const ShippingRate: boolean;
91
+ export declare const ShippingZone: boolean;
92
+ export declare const SocialPost: boolean;
93
+ export declare const Subscriber: boolean;
94
+ export declare const SubscriberEmail: boolean;
95
+ export declare const Subscription: boolean;
96
+ export declare const Tag: boolean;
97
+ export declare const TaxRate: boolean;
98
+ export declare const Team: boolean;
99
+ export declare const Transaction: boolean;
100
+ export declare const WaitlistProduct: boolean;
101
+ export declare const WaitlistRestaurant: boolean;
102
+ export declare const Websocket: boolean;
96
103
  /**
97
104
  * Framework-default User row shape. Matches the attributes declared on
98
105
  * `storage/framework/defaults/app/Models/User.ts` plus the system
@@ -113,6 +120,12 @@ export declare interface UserModel {
113
120
  public_key?: string | null
114
121
  created_at: string
115
122
  updated_at: string | null
123
+ stripe_id?: string | null
124
+ two_factor_enabled?: boolean
125
+ hasStripeId: () => boolean
126
+ hasRole: (role: string) => boolean | Promise<boolean>
127
+ assignRole: (role: string) => unknown | Promise<unknown>
128
+ update: (data: Record<string, unknown>) => Promise<UserModel>
116
129
  [key: string]: unknown
117
130
  }
118
131
  /**