@kadirgun/lucid-bravo 0.0.9 → 0.1.1

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
@@ -37,15 +37,15 @@ export default class PostBravo extends LucidBravo<ModelType> {
37
37
  protected model = Post
38
38
  protected defaultLimit = 10
39
39
 
40
- public override getSortable(): LucidBravoAttributes<ModelType>[] {
40
+ protected override getSortable(): LucidBravoAttributes<ModelType>[] {
41
41
  return ['id', 'title']
42
42
  }
43
43
 
44
- public override getAllowedIncludes(): LucidBravoRelations<Post>[] {
44
+ protected override getAllowedIncludes(): LucidBravoRelations<Post>[] {
45
45
  return ['labels']
46
46
  }
47
47
 
48
- public async title(value: string) {
48
+ protected async title(value: string) {
49
49
  this.$query.where('title', 'like', `%${value}%`)
50
50
  }
51
51
  }
package/build/index.js CHANGED
@@ -9,29 +9,21 @@ var LucidBravo = class {
9
9
  $params;
10
10
  $http;
11
11
  $countQuery;
12
+ $filteredQuery;
13
+ applied = false;
12
14
  defaultLimit = 20;
13
15
  defaultSort = null;
14
16
  constructor(params, query) {
15
17
  this.$params = params || {};
16
18
  this.$http = HttpContext.getOrFail();
17
- if (query) {
18
- this.model = query.model;
19
- this.$query = query;
20
- this.$countQuery = this.$query.clone();
21
- }
19
+ if (query) this.$query = query;
20
+ else this.$query = this.getModel().query();
21
+ this.model = this.$query.model;
22
+ this.$countQuery = this.$query.clone();
22
23
  }
23
24
  static build(params, query) {
24
25
  return new this(params, query);
25
26
  }
26
- resolveQuery() {
27
- if (this.$query) return this.$query;
28
- if (this.model) {
29
- this.$query = this.model.query();
30
- this.$countQuery = this.$query.clone();
31
- return this.$query;
32
- }
33
- throw new Error("Either a query must be provided or $model must be set in the subclass");
34
- }
35
27
  /**
36
28
  * Return a whitelist of sortable columns
37
29
  */
@@ -44,33 +36,37 @@ var LucidBravo = class {
44
36
  getAllowedIncludes() {
45
37
  return [];
46
38
  }
39
+ getModel() {
40
+ if (this.model) return this.model;
41
+ throw new Error("Model not defined");
42
+ }
47
43
  /**
48
44
  * Main entry point to apply all filters, includes, sorting and pagination
49
45
  */
50
46
  async apply() {
51
- this.resolveQuery();
47
+ if (this.applied) return this.$query;
52
48
  await this.applyFilters();
53
49
  await this.applyIncludes();
54
50
  await this.applySorting();
55
51
  await this.applyPagination();
52
+ this.applied = true;
56
53
  return this.$query;
57
54
  }
58
- async count() {
59
- this.resolveQuery();
60
- const result = await this.$countQuery.count("* as total").firstOrFail();
55
+ async count(query) {
56
+ const result = await query.count("* as total").firstOrFail();
61
57
  return Number(result.$extras.total);
62
58
  }
63
59
  async paginate() {
64
60
  return {
65
61
  items: await this.apply(),
66
- total: await this.count()
62
+ total: await this.count(this.$countQuery),
63
+ filtered: await this.count(this.$filteredQuery)
67
64
  };
68
65
  }
69
66
  /**
70
67
  * Automatically call methods that match camelCase version of snake_case params
71
68
  */
72
69
  async applyFilters() {
73
- this.resolveQuery();
74
70
  for (const [key, value] of Object.entries(this.$params)) {
75
71
  if ([
76
72
  "page",
@@ -84,25 +80,24 @@ var LucidBravo = class {
84
80
  if (typeof method !== "function") throw new Error(`Expected ${methodName} to be a method on ${this.constructor.name}`);
85
81
  await method.call(this, value);
86
82
  }
83
+ this.$filteredQuery = this.$query.clone();
87
84
  }
88
85
  /**
89
86
  * Apply preload include relations based on allowlist
90
87
  */
91
88
  async applyIncludes() {
92
- const query = this.resolveQuery();
93
89
  const includes = this.$params.include;
94
90
  if (!Array.isArray(includes) || includes.length === 0) return;
95
91
  const allowed = this.getAllowedIncludes();
96
92
  for (const relation of includes) {
97
93
  if (!allowed.includes(relation)) continue;
98
- query.preload(relation);
94
+ this.$query.preload(relation);
99
95
  }
100
96
  }
101
97
  /**
102
98
  * Apply sorting based on sort[field] and sort[order] params
103
99
  */
104
100
  async applySorting() {
105
- const query = this.resolveQuery();
106
101
  const sort = this.$params.sort;
107
102
  const sortable = this.getSortable();
108
103
  let field = sort?.field;
@@ -111,16 +106,12 @@ var LucidBravo = class {
111
106
  field = this.defaultSort.field;
112
107
  order = this.defaultSort.order;
113
108
  }
114
- if (field && sortable.includes(field)) query.orderBy(field, order);
109
+ if (field && sortable.includes(field)) this.$query.orderBy(field, order);
115
110
  }
116
- /**
117
- * Apply simple limit and offset pagination
118
- */
119
111
  async applyPagination() {
120
- const query = this.resolveQuery();
121
112
  const limit = Number(this.$params.limit) || this.defaultLimit;
122
113
  const offset = ((Number(this.$params.page) || 1) - 1) * limit;
123
- if (limit > 0) query.limit(limit).offset(offset);
114
+ if (limit > 0) this.$query.limit(limit).offset(offset);
124
115
  }
125
116
  };
126
117
  //#endregion
@@ -1,34 +1,37 @@
1
1
  import type { LucidModel, ModelQueryBuilderContract } from '@adonisjs/lucid/types/model';
2
- import type { BravoParams, BravoSortOption, LucidBravoRelations, LucidBravoAttributes } from './types.ts';
3
2
  import { HttpContext } from '@adonisjs/core/http';
4
3
  import type { Constructor } from '@adonisjs/core/types/common';
4
+ import type { BravoParams, BravoSortOption, LucidBravoAttributes, LucidBravoRelations } from './types.ts';
5
5
  export declare abstract class LucidBravo<T extends LucidModel> {
6
- protected model?: T;
6
+ private model;
7
7
  protected $query: ModelQueryBuilderContract<T>;
8
8
  protected $params: BravoParams;
9
9
  protected $http: HttpContext;
10
10
  protected $countQuery: ModelQueryBuilderContract<T>;
11
+ protected $filteredQuery: ModelQueryBuilderContract<T>;
12
+ private applied;
11
13
  protected defaultLimit: number;
12
14
  protected defaultSort: BravoSortOption | null;
13
15
  constructor(params?: BravoParams, query?: ModelQueryBuilderContract<T>);
14
16
  static build<T extends LucidModel, B extends LucidBravo<T>>(this: Constructor<B>, params?: BravoParams, query?: ModelQueryBuilderContract<T>): B;
15
- protected resolveQuery(): ModelQueryBuilderContract<T, InstanceType<T>>;
16
17
  /**
17
18
  * Return a whitelist of sortable columns
18
19
  */
19
- getSortable(): LucidBravoAttributes<T>[];
20
+ protected getSortable(): LucidBravoAttributes<T>[];
20
21
  /**
21
22
  * Return a whitelist of allowed relations for preload include
22
23
  */
23
- getAllowedIncludes(): LucidBravoRelations<InstanceType<T>>[];
24
+ protected getAllowedIncludes(): LucidBravoRelations<InstanceType<T>>[];
25
+ protected getModel(): T;
24
26
  /**
25
27
  * Main entry point to apply all filters, includes, sorting and pagination
26
28
  */
27
29
  apply(): Promise<InstanceType<T>[]>;
28
- count(): Promise<number>;
30
+ private count;
29
31
  paginate(): Promise<{
30
32
  items: InstanceType<T>[];
31
33
  total: number;
34
+ filtered: number;
32
35
  }>;
33
36
  /**
34
37
  * Automatically call methods that match camelCase version of snake_case params
@@ -42,8 +45,5 @@ export declare abstract class LucidBravo<T extends LucidModel> {
42
45
  * Apply sorting based on sort[field] and sort[order] params
43
46
  */
44
47
  protected applySorting(): Promise<void>;
45
- /**
46
- * Apply simple limit and offset pagination
47
- */
48
48
  protected applyPagination(): Promise<void>;
49
49
  }
@@ -14,14 +14,17 @@ import {{ entity.name }} from '{{ modelImportPath }}'
14
14
  type ModelType = typeof {{ entity.name }}
15
15
 
16
16
  export default class {{ modelName }}Bravo extends LucidBravo<ModelType> {
17
- protected model = {{ entity.name }}
18
17
  protected defaultLimit = 20
19
18
 
20
- public override getSortable(): LucidBravoAttributes<ModelType>[] {
19
+ protected getModel(): ModelType {
20
+ return {{ modelName }}
21
+ }
22
+
23
+ protected override getSortable(): LucidBravoAttributes<ModelType>[] {
21
24
  return []
22
25
  }
23
26
 
24
- public override getAllowedIncludes(): LucidBravoRelations<{{ entity.name }}>[] {
27
+ protected override getAllowedIncludes(): LucidBravoRelations<{{ entity.name }}>[] {
25
28
  return []
26
29
  }
27
30
  }
@@ -0,0 +1 @@
1
+ export { bravoSchema, bravoValidator } from './bravo.ts';