@codenameryuu/adonis-lucid-auto-preload 2.7.0 → 2.9.0

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/README.md CHANGED
@@ -40,6 +40,8 @@ Relationships will be auto-preloaded for `find` , `all` and `paginate` queries.
40
40
 
41
41
  **Note:** Relationships must be `belongsTo` , if you are using other relationship types, it may cause infinite loop.
42
42
 
43
+ **Note:** Make sure `AutoPreload` extended in the last position, especially when using `SoftDeletes` package.
44
+
43
45
  ### **Using relation name**
44
46
 
45
47
  ```typescript
@@ -50,10 +52,11 @@ import type { BelongsTo } from "@adonisjs/lucid/types/relations";
50
52
  import { compose } from "@adonisjs/core/helpers";
51
53
 
52
54
  import { AutoPreload } from "@codenameryuu/adonis-lucid-auto-preload";
55
+ import { SoftDeletes } from "@codenameryuu/adonis-lucid-soft-deletes";
53
56
 
54
57
  import ProductCategory from '#models/product-category'
55
58
 
56
- class Product extends compose(BaseModel, AutoPreload) {
59
+ class Product extends compose(BaseModel, SoftDeletes, AutoPreload) {
57
60
  public static $with = ['productCategory'] as const
58
61
 
59
62
  @column({ isPrimary: true })
@@ -74,18 +77,6 @@ class Product extends compose(BaseModel, AutoPreload) {
74
77
  }
75
78
  ```
76
79
 
77
- ### **Preload soft deleted belongsTo**
78
-
79
- If you are using soft deletes (for example with [`@codenameryuu/adonis-lucid-soft-deletes`](https://github.com/codenameryuu/adonis-lucid-soft-deletes)), you may want a `belongsTo` relationship to be preloaded even when the related row is soft deleted.
80
-
81
- You can opt-in per relationship using an object entry:
82
-
83
- ```typescript
84
- class Product extends compose(BaseModel, AutoPreload) {
85
- public static $with = [{ relation: 'productCategory', withTrashed: true }] as const
86
- }
87
- ```
88
-
89
80
  ```typescript
90
81
  // App/Controllers/Http/ProductsController.ts
91
82
 
@@ -111,10 +102,11 @@ import type { ModelQueryBuilderContract } from '@adonisjs/lucid/types/model'
111
102
  import { compose } from '@adonisjs/core/helpers'
112
103
 
113
104
  import { AutoPreload } from '@codenameryuu/adonis-lucid-auto-preload'
105
+ import { SoftDeletes } from "@codenameryuu/adonis-lucid-soft-deletes";
114
106
 
115
107
  import ProductCategory from '#models/product-category'
116
108
 
117
- class Product extends compose(BaseModel, AutoPreload) {
109
+ class Product extends compose(BaseModel, SoftDeletes, AutoPreload) {
118
110
  public static $with = [
119
111
  (query: ModelQueryBuilderContract<typeof this>) => {
120
112
  query.preload('productCategory')
@@ -163,10 +155,11 @@ import type { BelongsTo } from "@adonisjs/lucid/types/relations";
163
155
  import { compose } from "@adonisjs/core/helpers";
164
156
 
165
157
  import { AutoPreload } from "@codenameryuu/adonis-lucid-auto-preload";
158
+ import { SoftDeletes } from "@codenameryuu/adonis-lucid-soft-deletes";
166
159
 
167
160
  import User from '#models/user'
168
161
 
169
- class ProductCategory extends compose(BaseModel, AutoPreload) {
162
+ class ProductCategory extends compose(BaseModel, SoftDeletes, AutoPreload) {
170
163
  public static $with = ['user'] as const
171
164
 
172
165
  @column({ isPrimary: true })
@@ -195,10 +188,11 @@ import type { BelongsTo } from "@adonisjs/lucid/types/relations";
195
188
  import { compose } from '@adonisjs/core/helpers'
196
189
 
197
190
  import { AutoPreload } from '@codenameryuu/adonis-lucid-auto-preload'
191
+ import { SoftDeletes } from "@codenameryuu/adonis-lucid-soft-deletes";
198
192
 
199
193
  import ProductCategory from '#models/product-category'
200
194
 
201
- class Product extends compose(BaseModel, AutoPreload) {
195
+ class Product extends compose(BaseModel, SoftDeletes, AutoPreload) {
202
196
  public static $with = ['productCategory.user'] as const
203
197
 
204
198
  @column({ isPrimary: true })
@@ -3,13 +3,9 @@ import type { LucidModel } from '@adonisjs/lucid/types/model';
3
3
  type GetWith<T> = T extends {
4
4
  $with: Array<infer Item>;
5
5
  } ? Item extends string ? Item : string : string;
6
- type PreloadSpec = {
7
- relation: string;
8
- withTrashed?: boolean;
9
- };
10
6
  export interface AutoPreloadMixin {
11
7
  <T extends NormalizeConstructor<LucidModel>>(superclass: T): T & {
12
- $with: ReadonlyArray<string | PreloadSpec | ((query: any) => void)>;
8
+ $with: ReadonlyArray<string | ((query: any) => void)>;
13
9
  without(this: T, relationships: Array<GetWith<T>>): any;
14
10
  withOnly(this: T, relationships: Array<GetWith<T>>): any;
15
11
  withoutAny(this: T): any;
@@ -1,15 +1,6 @@
1
1
  import type { NormalizeConstructor } from '@adonisjs/core/types/helpers';
2
2
  import type { LucidModel, ModelQueryBuilderContract } from '@adonisjs/lucid/types/model';
3
- type PreloadSpec = {
4
- relation: string;
5
- /**
6
- * When true, attempts to call `.withTrashed()` on the preload builder.
7
- * Useful with `@codenameryuu/adonis-lucid-soft-deletes` when the related model
8
- * may be soft deleted but should still be returned.
9
- */
10
- withTrashed?: boolean;
11
- };
12
- type PreloadEntry = string | PreloadSpec | ((query: ModelQueryBuilderContract<any, any>) => void);
3
+ type PreloadEntry = string | ((query: ModelQueryBuilderContract<any, any>) => void);
13
4
  export declare function AutoPreload<T extends NormalizeConstructor<LucidModel>>(superclass: T): {
14
5
  new (...args: any[]): {
15
6
  $attributes: import("@adonisjs/lucid/types/model").ModelObject;
@@ -70,12 +61,6 @@ export declare function AutoPreload<T extends NormalizeConstructor<LucidModel>>(
70
61
  toAttributes(): Record<string, any>;
71
62
  related<Name extends undefined>(relation: Name): NonNullable</*elided*/ any[Name]> extends import("@adonisjs/lucid/types/relations").ModelRelations<LucidModel, LucidModel> ? (import("@adonisjs/lucid/types/relations").ModelRelations<LucidModel, LucidModel> & /*elided*/ any[Name] & {})["client"] : never;
72
63
  };
73
- /**
74
- * Propagate query flags used by other mixins (e.g. SoftDeletes) to preload builders.
75
- * SoftDeletes uses `query.ignoreDeleted = false` for `.withTrashed()` / `.onlyTrashed()`.
76
- */
77
- applyPreloadOptions(parent: any, child: any, options?: PreloadSpec): void;
78
- inheritQueryFlags(parent: any, child: any): void;
79
64
  /**
80
65
  * List of relationships to auto-preload.
81
66
  */
@@ -85,7 +70,7 @@ export declare function AutoPreload<T extends NormalizeConstructor<LucidModel>>(
85
70
  beforeFetchHook(query: ModelQueryBuilderContract<any, any>): void;
86
71
  beforePaginateHook(queries: any): void;
87
72
  applyAutoPreload(query: ModelQueryBuilderContract<any, any>): void;
88
- handleNestedPreload(query: any, parts: string[], options?: PreloadSpec, isRoot?: boolean): void;
73
+ handleNestedPreload(query: any, parts: string[]): void;
89
74
  /**
90
75
  * Correct Implementation: Returns the Query Builder to avoid global state pollution
91
76
  */
@@ -1,37 +1,5 @@
1
1
  export function AutoPreload(superclass) {
2
2
  class AutoPreloadModel extends superclass {
3
- /**
4
- * Propagate query flags used by other mixins (e.g. SoftDeletes) to preload builders.
5
- * SoftDeletes uses `query.ignoreDeleted = false` for `.withTrashed()` / `.onlyTrashed()`.
6
- */
7
- static applyPreloadOptions(parent, child, options) {
8
- if (options?.withTrashed) {
9
- if (typeof child?.withTrashed === 'function') {
10
- child.withTrashed();
11
- }
12
- else {
13
- /**
14
- * Fallback for builders that don't have the `withTrashed` macro attached.
15
- * `@codenameryuu/adonis-lucid-soft-deletes` checks `ignoreDeleted === false`.
16
- */
17
- child.ignoreDeleted = false;
18
- }
19
- }
20
- this.inheritQueryFlags(parent, child);
21
- }
22
- static inheritQueryFlags(parent, child) {
23
- if (!parent || !child)
24
- return;
25
- if (Object.prototype.hasOwnProperty.call(parent, 'ignoreDeleted') &&
26
- parent.ignoreDeleted === false) {
27
- if (typeof child.withTrashed === 'function') {
28
- child.withTrashed();
29
- }
30
- else {
31
- child.ignoreDeleted = false;
32
- }
33
- }
34
- }
35
3
  /**
36
4
  * List of relationships to auto-preload.
37
5
  */
@@ -70,20 +38,16 @@ export function AutoPreload(superclass) {
70
38
  const skipList = query.$skipPreloads || [];
71
39
  const onlyList = query.$onlyPreloads || [];
72
40
  for (const relation of relations) {
73
- if (typeof relation === 'string' || (relation && typeof relation === 'object')) {
74
- const name = typeof relation === 'string' ? relation : relation.relation;
75
- const options = typeof relation === 'string' ? undefined : relation;
76
- if (onlyList.length > 0 && !onlyList.includes(name))
41
+ if (typeof relation === 'string') {
42
+ if (onlyList.length > 0 && !onlyList.includes(relation))
77
43
  continue;
78
- if (skipList.includes(name))
44
+ if (skipList.includes(relation))
79
45
  continue;
80
- if (name.includes('.')) {
81
- this.handleNestedPreload(query, name.split('.'), options, true);
46
+ if (relation.includes('.')) {
47
+ this.handleNestedPreload(query, relation.split('.'));
82
48
  }
83
49
  else {
84
- query.preload(name, (builder) => {
85
- this.applyPreloadOptions(query, builder, options);
86
- });
50
+ query.preload(relation);
87
51
  }
88
52
  }
89
53
  else if (typeof relation === 'function') {
@@ -91,15 +55,13 @@ export function AutoPreload(superclass) {
91
55
  }
92
56
  }
93
57
  }
94
- static handleNestedPreload(query, parts, options, isRoot = false) {
58
+ static handleNestedPreload(query, parts) {
95
59
  const current = parts.shift();
96
60
  if (!current)
97
61
  return;
98
62
  query.preload(current, (builder) => {
99
- // Apply options only to the first hop ("productCategory" in "productCategory.user")
100
- this.applyPreloadOptions(query, builder, isRoot ? options : undefined);
101
63
  if (parts.length > 0) {
102
- this.handleNestedPreload(builder, [...parts], options, false);
64
+ this.handleNestedPreload(builder, [...parts]);
103
65
  }
104
66
  });
105
67
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codenameryuu/adonis-lucid-auto-preload",
3
- "version": "2.7.0",
3
+ "version": "2.9.0",
4
4
  "description": "Auto-preload (eager loading) multiple relationships when retrieving Lucid models on Adonis JS",
5
5
  "author": "codenameryuu",
6
6
  "license": "MIT",