@stacksjs/orm 0.75.185 → 0.75.186

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.
Files changed (2) hide show
  1. package/dist/define-model.d.ts +30 -58
  2. package/package.json +23 -23
@@ -7,7 +7,7 @@ import { createSoftDeleteMethods } from './traits/soft-deletes';
7
7
  import { createTaggableMethods } from './traits/taggable';
8
8
  import { createTwoFactorMethods } from './traits/two-factor';
9
9
  import { type OrmModelDefinition as BQBModelDefinition, type OrmModelStatic } from '@stacksjs/query-builder';
10
- import type { ApiMiddleware, DashboardModelOptions } from '@stacksjs/types';
10
+ import type { ApiMiddleware, DashboardModelOptions, SearchEngineSearchParams } from '@stacksjs/types';
11
11
  import type { BelongsToForeignKeys } from './model-types';
12
12
  import type { Faker } from '@stacksjs/faker';
13
13
  import type { GdprTraitOptions, PersonalAttribute } from './gdpr/types';
@@ -53,6 +53,20 @@ export declare function withoutValidation<T>(fn: () => T | Promise<T>): Promise<
53
53
  * projecting each row, which is what a column-rearranging `shape` wants anyway.
54
54
  */
55
55
  export declare function projectDocumentsFromTrait(models: Record<string, unknown>[], config: SearchableTraitConfig): Promise<Record<string, unknown>[]>;
56
+ /**
57
+ * Lightweight search-query builder returned by `Model.search()`
58
+ * (#1891). Thin wrapper around the search-engine driver — defers
59
+ * `.get()` / `.paginate()` / `.raw()` to the driver and lets
60
+ * callers attach filter / facet params via the standard search
61
+ * payload shape.
62
+ */
63
+ declare function createSearchQueryBuilder(_baseModel: Record<string, unknown>, indexName: string, query: string, initialParams?: SearchEngineSearchParams, searchableFields?: readonly string[]): {
64
+ get: () => Promise<unknown[]>
65
+ paginate: (perPage: number, page?: number) => Promise<{ hits: unknown[], total: number, page: number, perPage: number }>
66
+ raw: () => Promise<unknown>
67
+ with: (params: SearchEngineSearchParams) => ReturnType<typeof createSearchQueryBuilder>
68
+ where: (filter: SearchFilter) => ReturnType<typeof createSearchQueryBuilder>
69
+ };
56
70
  export declare function defineModel<const TDef extends ModelDefinition>(definition: TDef): StacksModelStatic<TDef>;
57
71
  /**
58
72
  * Normalize a ModelInstance (or array of them, or already-plain row) into
@@ -133,7 +147,8 @@ export declare interface StacksModelDefinition extends Omit<BQBModelDefinition,
133
147
  primaryKey?: string
134
148
  autoIncrement?: boolean
135
149
  dashboard?: DashboardModelOptions
136
- traits?: Omit<NonNullable<BQBModelDefinition['traits']>, 'useApi'> & {
150
+ traits?: Omit<NonNullable<BQBModelDefinition['traits']>, 'useApi' | 'useSearch'> & {
151
+ useSearch?: boolean | SearchableTraitConfig
137
152
  useApi?: boolean | {
138
153
  readonly uri?: string
139
154
  readonly prefix?: string
@@ -163,10 +178,10 @@ export declare interface StacksModelDefinition extends Omit<BQBModelDefinition,
163
178
  */
164
179
  declare interface SearchableTraitConfig {
165
180
  index?: string
166
- displayable?: string[]
167
- searchable?: string[]
168
- sortable?: string[]
169
- filterable?: string[]
181
+ displayable?: readonly string[]
182
+ searchable?: readonly string[]
183
+ sortable?: readonly string[]
184
+ filterable?: readonly string[]
170
185
  shape?: (model: any) => Record<string, unknown> | null | undefined | Promise<Record<string, unknown> | null | undefined>
171
186
  shapeMany?: (models: any[]) => Record<string, unknown>[] | Promise<Record<string, unknown>[]>
172
187
  hidden?: Set<string>
@@ -330,58 +345,15 @@ declare type QueryModel<TDef extends ModelDefinition> = OrmModelStatic<QueryDefi
330
345
  declare type ModelWriteData<TDef extends ModelDefinition> = Parameters<QueryModel<TDef>['create']>[0];
331
346
  declare type ModelForceWriteData<TDef extends ModelDefinition> = Parameters<ReturnType<QueryModel<TDef>['make']>['forceFill']>[0]
332
347
  & Partial<BelongsToForeignKeys<QueryDefinition<TDef>>>;
333
- /**
334
- * Stacks-enhanced model definition.
335
- *
336
- * Wraps bun-query-builder's `createModel()` with:
337
- * - Event dispatching via `traits.observe`
338
- * - Trait methods (billable, taggable, categorizable, commentable, likeable, 2FA)
339
- * - Full backward compatibility with generators (migration, routes, dashboard)
340
- *
341
- * ### Relationships
342
- * Each entry in `belongsTo`, `hasMany`, `hasOne`, `belongsToMany`,
343
- * `hasOneThrough`, and `hasManyThrough` declares a typed relation
344
- * usable via `.with('relationName')`:
345
- *
346
- * ```ts
347
- * defineModel({
348
- * belongsTo: ['Author'], // ↪ post.author
349
- * hasMany: ['Comment'], // ↪ post.comments (lowercase + pluralized)
350
- * hasOne: ['Cover'], // ↪ post.cover
351
- * })
352
- * ```
353
- *
354
- * After eager loading the related row(s) are reachable as a property
355
- * on the instance — `(await Post.with('author').first()).author`.
356
- *
357
- * @example
358
- * ```ts
359
- * import { defineModel } from '@stacksjs/orm'
360
- * import { schema } from '@stacksjs/validation'
361
- *
362
- * export default defineModel({
363
- * name: 'Post',
364
- * table: 'posts',
365
- * attributes: {
366
- * title: { fillable: true, validation: { rule: schema.string() } },
367
- * views: { fillable: true, validation: { rule: schema.number() } },
368
- * },
369
- * belongsTo: ['Author'],
370
- * hasMany: ['Tag', 'Category', 'Comment'],
371
- * traits: { useTimestamps: true, useUuid: true },
372
- * })
373
- *
374
- * // Result: Post.where('title', 'test') — 'title' narrowed to valid columns
375
- * // Result: Post.with('author') — 'author' narrowed to valid relations
376
- * ```
377
- */
378
- // `update` and `delete` are omitted from the builder's surface because Stacks
379
- // installs its own (see addStaticHelpers). bun-query-builder 0.2.70 declares a
380
- // native static `update` returning a non-optional record; left in the
381
- // intersection its signature came first, so `await Model.update(id, data)` was
382
- // typed as never undefined while the method that actually runs returns
383
- // undefined for a row that is gone.
384
- export type StacksModelStatic<TDef extends ModelDefinition> = Omit<QueryModel<TDef>, 'update' | 'delete'> & TDef & TraitMethods & {
348
+ /** Search statics exist precisely when the model enables the search trait. */
349
+ export type ModelSearchStatics<TDef> = TDef extends { traits: { useSearch: infer TSearch } }
350
+ ? TSearch extends false | undefined ? {} : {
351
+ search: (query: string, params?: SearchEngineSearchParams) => ReturnType<typeof createSearchQueryBuilder>
352
+ makeAllSearchable: (chunkSize?: number) => Promise<number>
353
+ removeAllFromSearch: () => Promise<void>
354
+ }
355
+ : {}
356
+ export type StacksModelStatic<TDef extends ModelDefinition> = Omit<QueryModel<TDef>, 'update' | 'delete'> & TDef & TraitMethods & ModelSearchStatics<TDef> & {
385
357
  readonly [MODEL_DEFINITION]: TDef
386
358
  update: (id: number | string, data: ModelWriteData<TDef>) => ReturnType<QueryModel<TDef>['find']>
387
359
  forceUpdate: (id: number | string, data: ModelForceWriteData<TDef>) => ReturnType<QueryModel<TDef>['find']>
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@stacksjs/orm",
3
3
  "type": "module",
4
4
  "sideEffects": false,
5
- "version": "0.75.185",
5
+ "version": "0.75.186",
6
6
  "description": "The Stacks ORM integration",
7
7
  "author": "Chris Breuer",
8
8
  "contributors": [
@@ -63,31 +63,31 @@
63
63
  "prepublishOnly": "bun run build"
64
64
  },
65
65
  "dependencies": {
66
- "@stacksjs/cache": "0.75.185",
67
- "@stacksjs/cli": "0.75.185",
68
- "@stacksjs/config": "0.75.185",
69
- "@stacksjs/database": "0.75.185",
70
- "@stacksjs/env": "0.75.185",
71
- "@stacksjs/error-handling": "0.75.185",
72
- "@stacksjs/events": "0.75.185",
73
- "@stacksjs/logging": "0.75.185",
74
- "@stacksjs/model-meta": "0.75.185",
75
- "@stacksjs/pagination": "0.75.185",
76
- "@stacksjs/path": "0.75.185",
77
- "@stacksjs/query-builder": "0.75.185",
78
- "@stacksjs/realtime": "0.75.185",
79
- "@stacksjs/router": "0.75.185",
80
- "@stacksjs/storage": "0.75.185",
81
- "@stacksjs/strings": "0.75.185",
66
+ "@stacksjs/cache": "0.75.186",
67
+ "@stacksjs/cli": "0.75.186",
68
+ "@stacksjs/config": "0.75.186",
69
+ "@stacksjs/database": "0.75.186",
70
+ "@stacksjs/env": "0.75.186",
71
+ "@stacksjs/error-handling": "0.75.186",
72
+ "@stacksjs/events": "0.75.186",
73
+ "@stacksjs/logging": "0.75.186",
74
+ "@stacksjs/model-meta": "0.75.186",
75
+ "@stacksjs/pagination": "0.75.186",
76
+ "@stacksjs/path": "0.75.186",
77
+ "@stacksjs/query-builder": "0.75.186",
78
+ "@stacksjs/realtime": "0.75.186",
79
+ "@stacksjs/router": "0.75.186",
80
+ "@stacksjs/storage": "0.75.186",
81
+ "@stacksjs/strings": "0.75.186",
82
82
  "@stacksjs/ts-validation": "^0.5.6",
83
- "@stacksjs/validation": "0.75.185",
83
+ "@stacksjs/validation": "0.75.186",
84
84
  "bun-query-builder": "^0.3.8"
85
85
  },
86
86
  "peerDependencies": {
87
- "@stacksjs/auth": "0.75.185",
88
- "@stacksjs/payments": "0.75.185",
89
- "@stacksjs/queue": "0.75.185",
90
- "@stacksjs/search-engine": "0.75.185",
87
+ "@stacksjs/auth": "0.75.186",
88
+ "@stacksjs/payments": "0.75.186",
89
+ "@stacksjs/queue": "0.75.186",
90
+ "@stacksjs/search-engine": "0.75.186",
91
91
  "stripe": "23.0.0"
92
92
  },
93
93
  "peerDependenciesMeta": {
@@ -108,7 +108,7 @@
108
108
  }
109
109
  },
110
110
  "devDependencies": {
111
- "@stacksjs/types": "0.75.185",
111
+ "@stacksjs/types": "0.75.186",
112
112
  "better-dx": "^0.2.24",
113
113
  "stripe": "23.0.0"
114
114
  }