@eienjs/adonisjs-api-query 2.0.0 → 3.0.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.
Files changed (89) hide show
  1. package/README.md +138 -0
  2. package/build/configure.d.ts +1 -5
  3. package/build/configure.js +1 -2
  4. package/build/index.d.ts +12 -6
  5. package/build/index.js +26 -20
  6. package/build/providers/api_query_provider.d.ts +19 -12
  7. package/build/providers/api_query_provider.js +7 -3
  8. package/build/src/allowed_filter.d.ts +14 -10
  9. package/build/src/allowed_filter.js +34 -12
  10. package/build/src/allowed_include.d.ts +6 -11
  11. package/build/src/allowed_include.js +14 -15
  12. package/build/src/allowed_sort.d.ts +2 -6
  13. package/build/src/allowed_sort.js +1 -2
  14. package/build/src/api_query_builder_request.d.ts +33 -12
  15. package/build/src/api_query_builder_request.js +119 -41
  16. package/build/src/base_filterable.d.ts +45 -0
  17. package/build/src/base_filterable.js +172 -0
  18. package/build/src/bindings/api_query_request.js +3 -3
  19. package/build/src/bindings/filterable_query.js +51 -0
  20. package/build/src/bindings/filters_query.js +21 -23
  21. package/build/src/bindings/includes_query.js +32 -33
  22. package/build/src/bindings/sorts_query.js +20 -23
  23. package/build/src/bindings/validation_query.js +27 -0
  24. package/build/src/decorators/filterable.d.ts +20 -0
  25. package/build/src/decorators/filterable.js +24 -0
  26. package/build/src/define_config.d.ts +1 -5
  27. package/build/src/define_config.js +3 -3
  28. package/build/src/enums/filter_operator.d.ts +2 -5
  29. package/build/src/enums/filter_operator.js +1 -2
  30. package/build/src/enums/sort_direction.d.ts +2 -5
  31. package/build/src/enums/sort_direction.js +1 -2
  32. package/build/src/exceptions/allowed_fields_must_be_called_before_allowed_includes.d.ts +4 -8
  33. package/build/src/exceptions/allowed_fields_must_be_called_before_allowed_includes.js +3 -4
  34. package/build/src/exceptions/filterable_not_configured.d.ts +5 -0
  35. package/build/src/exceptions/filterable_not_configured.js +12 -0
  36. package/build/src/exceptions/invalid_append_query.d.ts +4 -6
  37. package/build/src/exceptions/invalid_append_query.js +5 -2
  38. package/build/src/exceptions/invalid_direction.d.ts +2 -6
  39. package/build/src/exceptions/invalid_direction.js +1 -2
  40. package/build/src/exceptions/invalid_field_query.d.ts +7 -0
  41. package/build/src/exceptions/invalid_field_query.js +17 -0
  42. package/build/src/exceptions/invalid_filter_query.d.ts +2 -6
  43. package/build/src/exceptions/invalid_filter_query.js +1 -2
  44. package/build/src/exceptions/invalid_filter_value.d.ts +2 -6
  45. package/build/src/exceptions/invalid_filter_value.js +1 -2
  46. package/build/src/exceptions/invalid_include_query.d.ts +2 -6
  47. package/build/src/exceptions/invalid_include_query.js +1 -2
  48. package/build/src/exceptions/invalid_query.d.ts +2 -6
  49. package/build/src/exceptions/invalid_query.js +1 -2
  50. package/build/src/exceptions/invalid_sort_query.d.ts +2 -6
  51. package/build/src/exceptions/invalid_sort_query.js +1 -2
  52. package/build/src/exceptions/unknown_included_fields_query.d.ts +2 -6
  53. package/build/src/exceptions/unknown_included_fields_query.js +1 -2
  54. package/build/src/exceptions/vine_not_installed.d.ts +5 -0
  55. package/build/src/exceptions/vine_not_installed.js +12 -0
  56. package/build/src/filters/filters_begin_with_strict.d.ts +2 -6
  57. package/build/src/filters/filters_begin_with_strict.js +2 -3
  58. package/build/src/filters/filters_callback.d.ts +2 -6
  59. package/build/src/filters/filters_callback.js +1 -2
  60. package/build/src/filters/filters_ends_with_strict.d.ts +2 -6
  61. package/build/src/filters/filters_ends_with_strict.js +2 -3
  62. package/build/src/filters/filters_exact.d.ts +2 -6
  63. package/build/src/filters/filters_exact.js +15 -12
  64. package/build/src/filters/filters_operator.d.ts +3 -7
  65. package/build/src/filters/filters_operator.js +10 -11
  66. package/build/src/filters/filters_partial.d.ts +2 -8
  67. package/build/src/filters/filters_partial.js +7 -9
  68. package/build/src/filters/filters_scope.d.ts +12 -0
  69. package/build/src/filters/filters_scope.js +98 -0
  70. package/build/src/filters/filters_trashed.d.ts +2 -6
  71. package/build/src/filters/filters_trashed.js +1 -2
  72. package/build/src/includes/included_callback.d.ts +2 -6
  73. package/build/src/includes/included_callback.js +1 -2
  74. package/build/src/includes/included_count.d.ts +2 -6
  75. package/build/src/includes/included_count.js +2 -2
  76. package/build/src/includes/included_relationship.d.ts +4 -8
  77. package/build/src/includes/included_relationship.js +19 -22
  78. package/build/src/sorts/sorts_callback.d.ts +2 -6
  79. package/build/src/sorts/sorts_callback.js +1 -2
  80. package/build/src/sorts/sorts_field.d.ts +2 -6
  81. package/build/src/sorts/sorts_field.js +1 -2
  82. package/build/src/utils/helpers.js +2 -14
  83. package/build/src/validation/schema_builder.d.ts +3 -0
  84. package/build/src/validation/schema_builder.js +38 -0
  85. package/build/src/validation/vine_resolver.js +13 -0
  86. package/build/stubs/main.d.ts +1 -4
  87. package/build/stubs/main.js +1 -2
  88. package/build/types.d.ts +44 -19
  89. package/package.json +31 -24
@@ -2,10 +2,6 @@ import { Filter } from "../../types.js";
2
2
  import { FiltersPartial } from "./filters_partial.js";
3
3
  import { LucidModel } from "@adonisjs/lucid/types/model";
4
4
  import { StrictValuesWithoutRaw } from "@adonisjs/lucid/types/querybuilder";
5
-
6
- //#region src/filters/filters_begin_with_strict.d.ts
7
- declare class FiltersBeginWithStrict<Model extends LucidModel> extends FiltersPartial<Model> implements Filter<Model> {
5
+ export declare class FiltersBeginWithStrict<Model extends LucidModel> extends FiltersPartial<Model> implements Filter<Model> {
8
6
  protected getWhereRawParameters(value: StrictValuesWithoutRaw, property: string): [string, string[]];
9
- }
10
- //#endregion
11
- export { FiltersBeginWithStrict };
7
+ }
@@ -1,9 +1,8 @@
1
1
  import { FiltersPartial } from "./filters_partial.js";
2
- //#region src/filters/filters_begin_with_strict.ts
2
+ // src/filters/filters_begin_with_strict.ts
3
3
  var FiltersBeginWithStrict = class FiltersBeginWithStrict extends FiltersPartial {
4
4
  getWhereRawParameters(value, property) {
5
- return [`${property} LIKE ?`, [`${FiltersBeginWithStrict.escapeLike(value.toString())}%`]];
5
+ return ["?? LIKE ?", [property, `${FiltersBeginWithStrict.escapeLike(value.toString())}%`]];
6
6
  }
7
7
  };
8
- //#endregion
9
8
  export { FiltersBeginWithStrict };
@@ -1,11 +1,7 @@
1
1
  import { Filter } from "../../types.js";
2
2
  import { LucidModel, ModelQueryBuilderContract } from "@adonisjs/lucid/types/model";
3
-
4
- //#region src/filters/filters_callback.d.ts
5
- declare class FiltersCallback<Model extends LucidModel> implements Filter<Model> {
3
+ export declare class FiltersCallback<Model extends LucidModel> implements Filter<Model> {
6
4
  private callback;
7
5
  constructor(callback: (query: ModelQueryBuilderContract<Model>, value: unknown, property: string) => void);
8
6
  handle(query: ModelQueryBuilderContract<Model, InstanceType<Model>>, value: unknown, property: string): void;
9
- }
10
- //#endregion
11
- export { FiltersCallback };
7
+ }
@@ -1,4 +1,4 @@
1
- //#region src/filters/filters_callback.ts
1
+ // src/filters/filters_callback.ts
2
2
  var FiltersCallback = class {
3
3
  callback;
4
4
  constructor(callback) {
@@ -8,5 +8,4 @@ var FiltersCallback = class {
8
8
  this.callback(query, value, property);
9
9
  }
10
10
  };
11
- //#endregion
12
11
  export { FiltersCallback };
@@ -2,10 +2,6 @@ import { Filter } from "../../types.js";
2
2
  import { FiltersPartial } from "./filters_partial.js";
3
3
  import { LucidModel } from "@adonisjs/lucid/types/model";
4
4
  import { StrictValuesWithoutRaw } from "@adonisjs/lucid/types/querybuilder";
5
-
6
- //#region src/filters/filters_ends_with_strict.d.ts
7
- declare class FiltersEndsWithStrict<Model extends LucidModel> extends FiltersPartial<Model> implements Filter<Model> {
5
+ export declare class FiltersEndsWithStrict<Model extends LucidModel> extends FiltersPartial<Model> implements Filter<Model> {
8
6
  protected getWhereRawParameters(value: StrictValuesWithoutRaw, property: string): [string, string[]];
9
- }
10
- //#endregion
11
- export { FiltersEndsWithStrict };
7
+ }
@@ -1,9 +1,8 @@
1
1
  import { FiltersPartial } from "./filters_partial.js";
2
- //#region src/filters/filters_ends_with_strict.ts
2
+ // src/filters/filters_ends_with_strict.ts
3
3
  var FiltersEndsWithStrict = class FiltersEndsWithStrict extends FiltersPartial {
4
4
  getWhereRawParameters(value, property) {
5
- return [`${property} LIKE ?`, [`%${FiltersEndsWithStrict.escapeLike(value.toString())}`]];
5
+ return ["?? LIKE ?", [property, `%${FiltersEndsWithStrict.escapeLike(value.toString())}`]];
6
6
  }
7
7
  };
8
- //#endregion
9
8
  export { FiltersEndsWithStrict };
@@ -1,9 +1,7 @@
1
1
  import { Filter } from "../../types.js";
2
2
  import { LucidModel, ModelQueryBuilderContract } from "@adonisjs/lucid/types/model";
3
3
  import { StrictValuesWithoutRaw } from "@adonisjs/lucid/types/querybuilder";
4
-
5
- //#region src/filters/filters_exact.d.ts
6
- declare class FiltersExact<Model extends LucidModel> implements Filter<Model> {
4
+ export declare class FiltersExact<Model extends LucidModel> implements Filter<Model> {
7
5
  protected shouldAddRelationConstraint: boolean;
8
6
  protected relationConstraints: string[];
9
7
  constructor(shouldAddRelationConstraint?: boolean);
@@ -11,6 +9,4 @@ declare class FiltersExact<Model extends LucidModel> implements Filter<Model> {
11
9
  protected qualifyColumn(query: ModelQueryBuilderContract<Model, InstanceType<Model>>, column: string): string;
12
10
  protected isRelationProperty(query: ModelQueryBuilderContract<Model, InstanceType<Model>>, property: string): boolean;
13
11
  protected withRelationConstraint(query: ModelQueryBuilderContract<Model, InstanceType<Model>>, value: StrictValuesWithoutRaw | null, property: string): void;
14
- }
15
- //#endregion
16
- export { FiltersExact };
12
+ }
@@ -1,5 +1,4 @@
1
- import collect$1 from "collect.js";
2
- //#region src/filters/filters_exact.ts
1
+ // src/filters/filters_exact.ts
3
2
  var FiltersExact = class {
4
3
  shouldAddRelationConstraint;
5
4
  relationConstraints = [];
@@ -12,36 +11,40 @@ var FiltersExact = class {
12
11
  return;
13
12
  }
14
13
  if (Array.isArray(value)) {
15
- query.whereIn(this.qualifyColumn(query, property), value);
14
+ const flatValues = value.flat(Infinity).filter((item) => typeof item !== "object" || item === null);
15
+ if (flatValues.length === 0) return;
16
+ query.whereIn(this.qualifyColumn(query, property), flatValues);
16
17
  return;
17
18
  }
18
19
  if (value === null) {
19
20
  query.whereNull(this.qualifyColumn(query, property));
20
21
  return;
21
22
  }
23
+ if (typeof value === "object") return;
22
24
  query.where(this.qualifyColumn(query, property), "=", value);
23
25
  }
24
26
  qualifyColumn(query, column) {
25
27
  if (column.includes(".")) return column;
26
- return `${query.model.table}.${query.model.$getColumn(column)?.columnName}`;
28
+ return `${query.model.table}.${query.model.$getColumn(column)?.columnName ?? column}`;
27
29
  }
28
30
  isRelationProperty(query, property) {
29
- if (!property.includes(".")) return false;
30
- if (this.relationConstraints.includes(property)) return false;
31
+ if (!property.includes(".") || this.relationConstraints.includes(property)) return false;
31
32
  const firstRelationShip = property.split(".", 1)[0];
32
33
  return query.model.$relationsDefinitions.has(firstRelationShip);
33
34
  }
34
35
  withRelationConstraint(query, value, property) {
35
- const [relation, relationProperty] = collect$1(property.split(".")).pipe((parts) => {
36
- const rProperty = parts.pop();
37
- return [parts.implode("."), rProperty];
38
- });
36
+ const parts = property.split(".");
37
+ const relationProperty = parts.pop();
38
+ const relation = parts.join(".");
39
39
  query.whereHas(relation, (subQuery) => {
40
40
  const columnName = this.qualifyColumn(subQuery, relationProperty);
41
41
  this.relationConstraints.push(columnName);
42
- this.handle(subQuery, value, columnName);
42
+ try {
43
+ this.handle(subQuery, value, columnName);
44
+ } finally {
45
+ this.relationConstraints.pop();
46
+ }
43
47
  });
44
48
  }
45
49
  };
46
- //#endregion
47
50
  export { FiltersExact };
@@ -1,11 +1,9 @@
1
- import { FilterOperator } from "../enums/filter_operator.js";
2
1
  import { EnumType, Filter } from "../../types.js";
2
+ import { FilterOperator } from "../enums/filter_operator.js";
3
3
  import { FiltersExact } from "./filters_exact.js";
4
4
  import { LucidModel, ModelQueryBuilderContract } from "@adonisjs/lucid/types/model";
5
5
  import { StrictValuesWithoutRaw } from "@adonisjs/lucid/types/querybuilder";
6
-
7
- //#region src/filters/filters_operator.d.ts
8
- declare class FiltersOperator<Model extends LucidModel> extends FiltersExact<Model> implements Filter<Model> {
6
+ export declare class FiltersOperator<Model extends LucidModel> extends FiltersExact<Model> implements Filter<Model> {
9
7
  protected shouldAddRelationConstraint: boolean;
10
8
  protected filterOperator: EnumType<typeof FilterOperator>;
11
9
  protected boolean: 'and' | 'or';
@@ -13,6 +11,4 @@ declare class FiltersOperator<Model extends LucidModel> extends FiltersExact<Mod
13
11
  handle(query: ModelQueryBuilderContract<Model, InstanceType<Model>>, value: StrictValuesWithoutRaw | null, property: string): void;
14
12
  protected getDynamicFilterOperator(value: string): EnumType<typeof FilterOperator>;
15
13
  protected removeDynamicFilterOperatorFromValue(value: string, filterOperator: EnumType<typeof FilterOperator>): string;
16
- }
17
- //#endregion
18
- export { FiltersOperator };
14
+ }
@@ -1,7 +1,7 @@
1
- import { substrReplace } from "../utils/helpers.js";
2
- import { FiltersExact } from "./filters_exact.js";
3
1
  import { FilterOperator } from "../enums/filter_operator.js";
4
- //#region src/filters/filters_operator.ts
2
+ import { FiltersExact } from "./filters_exact.js";
3
+ // src/filters/filters_operator.ts
4
+ const SORTED_OPERATORS = Object.values(FilterOperator).filter((op) => op !== FilterOperator.Dynamic).toSorted((a, b) => b.length - a.length);
5
5
  var FiltersOperator = class extends FiltersExact {
6
6
  shouldAddRelationConstraint;
7
7
  filterOperator;
@@ -29,9 +29,11 @@ var FiltersOperator = class extends FiltersExact {
29
29
  query.whereNull(this.qualifyColumn(query, property));
30
30
  return;
31
31
  }
32
+ if (typeof value === "object") return;
32
33
  if (filterOperator === FilterOperator.Dynamic) {
33
- filterOperator = this.getDynamicFilterOperator(value.toString());
34
- value = this.removeDynamicFilterOperatorFromValue(value.toString(), filterOperator);
34
+ const strValue = value.toString();
35
+ filterOperator = this.getDynamicFilterOperator(strValue);
36
+ value = this.removeDynamicFilterOperatorFromValue(strValue, filterOperator);
35
37
  }
36
38
  if (this.boolean === "and") {
37
39
  query.where(this.qualifyColumn(query, property), filterOperator, value);
@@ -40,14 +42,11 @@ var FiltersOperator = class extends FiltersExact {
40
42
  query.orWhere(this.qualifyColumn(query, property), filterOperator, value);
41
43
  }
42
44
  getDynamicFilterOperator(value) {
43
- let filterOperator = FilterOperator.Equal;
44
- for (const filterOperatorCase of Object.values(FilterOperator)) if (value.startsWith(filterOperatorCase) && filterOperatorCase !== FilterOperator.Dynamic) filterOperator = filterOperatorCase;
45
- return filterOperator;
45
+ for (const filterOperatorCase of SORTED_OPERATORS) if (value.startsWith(filterOperatorCase)) return filterOperatorCase;
46
+ return FilterOperator.Equal;
46
47
  }
47
48
  removeDynamicFilterOperatorFromValue(value, filterOperator) {
48
- if (value.includes(filterOperator)) value = substrReplace(value, "", 0, filterOperator.length);
49
- return value;
49
+ return value.startsWith(filterOperator) ? value.slice(filterOperator.length) : value;
50
50
  }
51
51
  };
52
- //#endregion
53
52
  export { FiltersOperator };
@@ -2,15 +2,9 @@ import { Filter } from "../../types.js";
2
2
  import { FiltersExact } from "./filters_exact.js";
3
3
  import { LucidModel, ModelQueryBuilderContract } from "@adonisjs/lucid/types/model";
4
4
  import { StrictValuesWithoutRaw } from "@adonisjs/lucid/types/querybuilder";
5
- import { DialectContract } from "@adonisjs/lucid/types/database";
6
-
7
- //#region src/filters/filters_partial.d.ts
8
- declare class FiltersPartial<Model extends LucidModel> extends FiltersExact<Model> implements Filter<Model> {
5
+ export declare class FiltersPartial<Model extends LucidModel> extends FiltersExact<Model> implements Filter<Model> {
9
6
  handle(query: ModelQueryBuilderContract<Model, InstanceType<Model>>, value: StrictValuesWithoutRaw | null, property: string): void;
10
7
  protected parsePropertyToColumn(query: ModelQueryBuilderContract<Model, InstanceType<Model>>, property: string): string;
11
- protected getDatabaseDialect(query: ModelQueryBuilderContract<Model, InstanceType<Model>>): DialectContract['name'];
12
8
  protected getWhereRawParameters(value: StrictValuesWithoutRaw | null, property: string): [string, string[]];
13
9
  protected static escapeLike(value: string): string;
14
- }
15
- //#endregion
16
- export { FiltersPartial };
10
+ }
@@ -1,5 +1,5 @@
1
1
  import { FiltersExact } from "./filters_exact.js";
2
- //#region src/filters/filters_partial.ts
2
+ // src/filters/filters_partial.ts
3
3
  var FiltersPartial = class FiltersPartial extends FiltersExact {
4
4
  handle(query, value, property) {
5
5
  if (this.shouldAddRelationConstraint && this.isRelationProperty(query, property)) {
@@ -7,16 +7,18 @@ var FiltersPartial = class FiltersPartial extends FiltersExact {
7
7
  return;
8
8
  }
9
9
  if (Array.isArray(value)) {
10
- if (value.every((item) => item.toString().length === 0)) return;
10
+ const subValues = value.flat(Infinity).filter((item) => item !== null && typeof item !== "object" && String(item).length > 0);
11
+ if (subValues.length === 0) return;
11
12
  query.where((subQuery) => {
12
- const subValues = value.filter((item) => item.toString().length > 0);
13
+ const column = this.parsePropertyToColumn(subQuery, property);
13
14
  for (const partialValue of subValues) {
14
- const [innerSql, innerBindings] = this.getWhereRawParameters(partialValue, this.parsePropertyToColumn(subQuery, property));
15
+ const [innerSql, innerBindings] = this.getWhereRawParameters(partialValue, column);
15
16
  subQuery.orWhereRaw(innerSql, innerBindings);
16
17
  }
17
18
  });
18
19
  return;
19
20
  }
21
+ if (value === null || typeof value === "object") return;
20
22
  const [sql, bindings] = this.getWhereRawParameters(value, this.parsePropertyToColumn(query, property));
21
23
  query.whereRaw(sql, bindings);
22
24
  }
@@ -24,16 +26,12 @@ var FiltersPartial = class FiltersPartial extends FiltersExact {
24
26
  if (property.includes(".")) return property;
25
27
  return query.model.$getColumn(property)?.columnName ?? property;
26
28
  }
27
- getDatabaseDialect(query) {
28
- return query.client.dialect.name;
29
- }
30
29
  getWhereRawParameters(value, property) {
31
30
  const resolvedValue = String(value).toLowerCase();
32
31
  return ["LOWER(??) LIKE ?", [property, `%${FiltersPartial.escapeLike(resolvedValue)}%`]];
33
32
  }
34
33
  static escapeLike(value) {
35
- return value.replaceAll("\\", "\\\\").replaceAll("_", String.raw`\\_`).replaceAll("%", String.raw`\\%`);
34
+ return value.replaceAll("\\", String.raw`\\`).replaceAll("_", String.raw`\_`).replaceAll("%", String.raw`\%`);
36
35
  }
37
36
  };
38
- //#endregion
39
37
  export { FiltersPartial };
@@ -0,0 +1,12 @@
1
+ import { Filter } from "../../types.js";
2
+ import { LucidModel, ModelQueryBuilderContract } from "@adonisjs/lucid/types/model";
3
+ export declare class FiltersScope<Model extends LucidModel> implements Filter<Model> {
4
+ handle(query: ModelQueryBuilderContract<Model, InstanceType<Model>>, value: unknown, property: string): void;
5
+ protected applyScope(query: ModelQueryBuilderContract<Model, InstanceType<Model>>, value: unknown, property: string): void;
6
+ protected getModelScopeFunction(model: LucidModel, candidate: string): ((...args: unknown[]) => void) | undefined;
7
+ protected resolveScopeMethod(model: Model, property: string): string;
8
+ protected extractParametersString(fn: (...args: unknown[]) => void): string | null;
9
+ protected hasParameters(fn: (...args: unknown[]) => void): boolean;
10
+ protected countParameters(fn: (...args: unknown[]) => void): number;
11
+ protected resolveArguments(scopeFn: ((...args: unknown[]) => void) | undefined, value: unknown, resolvedParamCount?: number): unknown[];
12
+ }
@@ -0,0 +1,98 @@
1
+ import string from "@adonisjs/core/helpers/string";
2
+ import { BaseModel } from "@adonisjs/lucid/orm";
3
+ // src/filters/filters_scope.ts
4
+ const FN_PARAMS_REGEX = /^(?:async\s*)?(?:function[^(]*\(([^)]*)\)|\(([^)]*)\)\s*=>|([^\s(=>]+)\s*=>)/;
5
+ const RESERVED_MODEL_METHODS = /* @__PURE__ */ new Set([
6
+ "boot",
7
+ "before",
8
+ "after",
9
+ "saving",
10
+ "creating",
11
+ "updating",
12
+ "deleting",
13
+ "finding",
14
+ "fetching",
15
+ "paginating",
16
+ "constructor",
17
+ "prototype"
18
+ ]);
19
+ var FiltersScope = class {
20
+ handle(query, value, property) {
21
+ const dotIndex = property.indexOf(".");
22
+ if (dotIndex !== -1) {
23
+ const firstRelation = property.slice(0, dotIndex);
24
+ if (query.model.$relationsDefinitions.has(firstRelation)) {
25
+ const remainingProperty = property.slice(dotIndex + 1);
26
+ query.whereHas(firstRelation, (subQuery) => {
27
+ this.handle(subQuery, value, remainingProperty);
28
+ });
29
+ return;
30
+ }
31
+ }
32
+ this.applyScope(query, value, property);
33
+ }
34
+ applyScope(query, value, property) {
35
+ const scopeMethod = this.resolveScopeMethod(query.model, property);
36
+ const scopeFn = this.getModelScopeFunction(query.model, scopeMethod);
37
+ if (!scopeFn) throw new Error(`"${scopeMethod}" is not defined as a query scope on "${query.model.name}" model`);
38
+ const paramCount = this.countParameters(scopeFn);
39
+ if (paramCount <= 1) {
40
+ if (value === false) return;
41
+ query.withScopes((scopes) => {
42
+ scopes[scopeMethod]();
43
+ });
44
+ return;
45
+ }
46
+ const args = this.resolveArguments(scopeFn, value, paramCount);
47
+ query.withScopes((scopes) => {
48
+ scopes[scopeMethod](...args);
49
+ });
50
+ }
51
+ getModelScopeFunction(model, candidate) {
52
+ if (!candidate || candidate.startsWith("$") || candidate.startsWith("_") || RESERVED_MODEL_METHODS.has(candidate)) return;
53
+ let current = model;
54
+ while (typeof current === "function" && current !== BaseModel && current !== Function.prototype && current !== Object.prototype) {
55
+ if (Object.hasOwn(current, candidate)) {
56
+ const fn = current[candidate];
57
+ return typeof fn === "function" ? fn : void 0;
58
+ }
59
+ current = Object.getPrototypeOf(current);
60
+ }
61
+ }
62
+ resolveScopeMethod(model, property) {
63
+ const camelCased = string.camelCase(property);
64
+ const propertyWithScope = `${property}Scope`;
65
+ const camelCasedWithScope = `${camelCased}Scope`;
66
+ const candidates = property === camelCased ? [property, propertyWithScope] : [
67
+ property,
68
+ camelCased,
69
+ propertyWithScope,
70
+ camelCasedWithScope
71
+ ];
72
+ for (const candidate of candidates) if (this.getModelScopeFunction(model, candidate)) return candidate;
73
+ return camelCased;
74
+ }
75
+ extractParametersString(fn) {
76
+ const match = FN_PARAMS_REGEX.exec(fn.toString());
77
+ if (!match) return null;
78
+ return (match.at(1) ?? match.at(2) ?? match.at(3) ?? "").trim();
79
+ }
80
+ hasParameters(fn) {
81
+ return this.countParameters(fn) > 1;
82
+ }
83
+ countParameters(fn) {
84
+ if (fn.length > 1) return fn.length;
85
+ const params = this.extractParametersString(fn);
86
+ if (!params) return fn.length;
87
+ return params.split(",").length;
88
+ }
89
+ resolveArguments(scopeFn, value, resolvedParamCount) {
90
+ if (Array.isArray(value)) return value;
91
+ if (typeof value === "object" && value !== null) {
92
+ if ((resolvedParamCount ?? (scopeFn ? this.countParameters(scopeFn) : 0)) > 2) return Object.values(value);
93
+ return [value];
94
+ }
95
+ return [value];
96
+ }
97
+ };
98
+ export { FiltersScope };
@@ -1,10 +1,6 @@
1
1
  import { Filter } from "../../types.js";
2
2
  import { LucidModel, ModelQueryBuilderContract } from "@adonisjs/lucid/types/model";
3
3
  import { StrictValuesWithoutRaw } from "@adonisjs/lucid/types/querybuilder";
4
-
5
- //#region src/filters/filters_trashed.d.ts
6
- declare class FiltersTrashed<Model extends LucidModel> implements Filter<Model> {
4
+ export declare class FiltersTrashed<Model extends LucidModel> implements Filter<Model> {
7
5
  handle(query: ModelQueryBuilderContract<Model, InstanceType<Model>>, value: StrictValuesWithoutRaw | null, _property: string): void;
8
- }
9
- //#endregion
10
- export { FiltersTrashed };
6
+ }
@@ -1,4 +1,4 @@
1
- //#region src/filters/filters_trashed.ts
1
+ // src/filters/filters_trashed.ts
2
2
  var FiltersTrashed = class {
3
3
  handle(query, value, _property) {
4
4
  if (!("withTrashed" in query && "onlyTrashed" in query)) return;
@@ -10,5 +10,4 @@ var FiltersTrashed = class {
10
10
  if (value === "only") queryWithSoftDeletes.onlyTrashed();
11
11
  }
12
12
  };
13
- //#endregion
14
13
  export { FiltersTrashed };
@@ -1,12 +1,8 @@
1
1
  import { Include } from "../../types.js";
2
2
  import { LucidModel, ModelQueryBuilderContract } from "@adonisjs/lucid/types/model";
3
3
  import { ModelRelations } from "@adonisjs/lucid/types/relations";
4
-
5
- //#region src/includes/included_callback.d.ts
6
- declare class IncludedCallback<ParentModel extends LucidModel, RelatedModel extends LucidModel> implements Include<ParentModel> {
4
+ export declare class IncludedCallback<ParentModel extends LucidModel, RelatedModel extends LucidModel> implements Include<ParentModel> {
7
5
  readonly callback: (query: ModelRelations<RelatedModel, ParentModel>['builder'] | ModelRelations<RelatedModel, ParentModel>['subQuery']) => void;
8
6
  constructor(callback: (query: ModelRelations<RelatedModel, ParentModel>['builder'] | ModelRelations<RelatedModel, ParentModel>['subQuery']) => void);
9
7
  handle(query: ModelQueryBuilderContract<ParentModel, InstanceType<ParentModel>>, include: string): void;
10
- }
11
- //#endregion
12
- export { IncludedCallback };
8
+ }
@@ -1,4 +1,4 @@
1
- //#region src/includes/included_callback.ts
1
+ // src/includes/included_callback.ts
2
2
  var IncludedCallback = class {
3
3
  callback;
4
4
  constructor(callback) {
@@ -8,5 +8,4 @@ var IncludedCallback = class {
8
8
  query.preload(include, this.callback);
9
9
  }
10
10
  };
11
- //#endregion
12
11
  export { IncludedCallback };
@@ -1,9 +1,5 @@
1
1
  import { Include } from "../../types.js";
2
2
  import { LucidModel, ModelQueryBuilderContract } from "@adonisjs/lucid/types/model";
3
-
4
- //#region src/includes/included_count.d.ts
5
- declare class IncludedCount<ParentModel extends LucidModel> implements Include<ParentModel> {
3
+ export declare class IncludedCount<ParentModel extends LucidModel> implements Include<ParentModel> {
6
4
  handle(query: ModelQueryBuilderContract<ParentModel, InstanceType<ParentModel>>, count: string): void;
7
- }
8
- //#endregion
9
- export { IncludedCount };
5
+ }
@@ -1,11 +1,11 @@
1
1
  import app from "@adonisjs/core/services/app";
2
- //#region src/includes/included_count.ts
2
+ // src/includes/included_count.ts
3
3
  var IncludedCount = class {
4
4
  handle(query, count) {
5
5
  const suffix = app.config.get("apiquery.countSuffix", "Count");
6
6
  const relation = count.endsWith(suffix) ? count.slice(0, -suffix.length) : count;
7
+ if (!query.model.$hasRelation(relation)) return;
7
8
  query.withCount(relation);
8
9
  }
9
10
  };
10
- //#endregion
11
11
  export { IncludedCount };
@@ -1,13 +1,9 @@
1
1
  import { Include } from "../../types.js";
2
- import { Collection } from "collect.js";
3
2
  import { LucidModel, ModelQueryBuilderContract } from "@adonisjs/lucid/types/model";
4
-
5
- //#region src/includes/included_relationship.d.ts
6
- declare class IncludedRelationship<ParentModel extends LucidModel> implements Include<ParentModel> {
3
+ export declare class IncludedRelationship<ParentModel extends LucidModel> implements Include<ParentModel> {
7
4
  getRequestedFieldsForRelatedTable?: (relationship: string) => string[];
8
5
  handle(query: ModelQueryBuilderContract<ParentModel, InstanceType<ParentModel>>, relationship: string): void;
9
- static getIndividualRelationshipPathsFromInclude(include: string): Collection<string>;
6
+ static getIndividualRelationshipPathsFromInclude(include: string): string[];
7
+ private applyRequestedFields;
10
8
  private buildNestedQuery;
11
- }
12
- //#endregion
13
- export { IncludedRelationship };
9
+ }
@@ -1,40 +1,37 @@
1
- import { Collection } from "collect.js";
2
- //#region src/includes/included_relationship.ts
1
+ // src/includes/included_relationship.ts
3
2
  var IncludedRelationship = class {
4
3
  getRequestedFieldsForRelatedTable;
5
4
  handle(query, relationship) {
6
- const relatedTables = relationship.split(".");
7
- if (relatedTables.length === 0) return;
8
- const [relation, ...rest] = relatedTables;
9
- if (!query.model.$hasRelation(relation)) return;
5
+ const [relation, ...rest] = relationship.split(".");
6
+ if (!relation || !query.model.$hasRelation(relation)) return;
10
7
  query.preload(relation, (subQuery) => {
11
- if (this.getRequestedFieldsForRelatedTable !== void 0) {
12
- const fields = this.getRequestedFieldsForRelatedTable(relation);
13
- if (fields.length > 0) subQuery.select(fields);
14
- }
8
+ this.applyRequestedFields(subQuery, relation);
15
9
  this.buildNestedQuery(rest, subQuery, relation);
16
10
  });
17
11
  }
18
12
  static getIndividualRelationshipPathsFromInclude(include) {
19
- return new Collection(include.split(".")).reduce((includes, relationship) => {
20
- const includesArray = includes ?? new Collection();
21
- if (includesArray.isEmpty()) return includesArray.push(relationship);
22
- return includesArray.push(`${includes.last()}.${relationship}`);
23
- }, new Collection());
13
+ const parts = include.split(".");
14
+ const includes = [];
15
+ let current = "";
16
+ for (const part of parts) {
17
+ current = current ? `${current}.${part}` : part;
18
+ includes.push(current);
19
+ }
20
+ return includes;
21
+ }
22
+ applyRequestedFields(query, relationshipName) {
23
+ if (this.getRequestedFieldsForRelatedTable === void 0) return;
24
+ const fields = this.getRequestedFieldsForRelatedTable(relationshipName);
25
+ if (fields.length > 0) query.select(fields);
24
26
  }
25
27
  buildNestedQuery(relatedTables, subQuery, parent = "") {
26
- if (relatedTables.length === 0) return;
27
28
  const [relation, ...rest] = relatedTables;
28
- if (!subQuery.model.$hasRelation(relation)) return;
29
+ if (!relation || !subQuery.model.$hasRelation(relation)) return;
29
30
  subQuery.preload(relation, (nestedQuery) => {
30
31
  const fullRelationName = parent === "" ? relation : `${parent}.${relation}`;
31
- if (this.getRequestedFieldsForRelatedTable !== void 0) {
32
- const fields = this.getRequestedFieldsForRelatedTable(fullRelationName);
33
- if (fields.length > 0) nestedQuery.select(fields);
34
- }
32
+ this.applyRequestedFields(nestedQuery, fullRelationName);
35
33
  this.buildNestedQuery(rest, nestedQuery, fullRelationName);
36
34
  });
37
35
  }
38
36
  };
39
- //#endregion
40
37
  export { IncludedRelationship };
@@ -1,11 +1,7 @@
1
1
  import { Sort } from "../../types.js";
2
2
  import { LucidModel, ModelQueryBuilderContract } from "@adonisjs/lucid/types/model";
3
-
4
- //#region src/sorts/sorts_callback.d.ts
5
- declare class SortsCallback<Model extends LucidModel> implements Sort<Model> {
3
+ export declare class SortsCallback<Model extends LucidModel> implements Sort<Model> {
6
4
  private readonly _callback;
7
5
  constructor(_callback: (query: ModelQueryBuilderContract<Model>, isDescending: boolean, property: string) => void);
8
6
  handle(query: ModelQueryBuilderContract<Model>, isDescending: boolean, property: string): void;
9
- }
10
- //#endregion
11
- export { SortsCallback };
7
+ }
@@ -1,4 +1,4 @@
1
- //#region src/sorts/sorts_callback.ts
1
+ // src/sorts/sorts_callback.ts
2
2
  var SortsCallback = class {
3
3
  _callback;
4
4
  constructor(_callback) {
@@ -8,5 +8,4 @@ var SortsCallback = class {
8
8
  this._callback(query, isDescending, property);
9
9
  }
10
10
  };
11
- //#endregion
12
11
  export { SortsCallback };
@@ -1,9 +1,5 @@
1
1
  import { Sort } from "../../types.js";
2
2
  import { LucidModel, ModelQueryBuilderContract } from "@adonisjs/lucid/types/model";
3
-
4
- //#region src/sorts/sorts_field.d.ts
5
- declare class SortsField<Model extends LucidModel> implements Sort<Model> {
3
+ export declare class SortsField<Model extends LucidModel> implements Sort<Model> {
6
4
  handle(query: ModelQueryBuilderContract<Model>, isDescending: boolean, property: string): void;
7
- }
8
- //#endregion
9
- export { SortsField };
5
+ }
@@ -1,8 +1,7 @@
1
- //#region src/sorts/sorts_field.ts
1
+ // src/sorts/sorts_field.ts
2
2
  var SortsField = class {
3
3
  handle(query, isDescending, property) {
4
4
  query.orderBy(property, isDescending ? "desc" : "asc");
5
5
  }
6
6
  };
7
- //#endregion
8
7
  export { SortsField };
@@ -1,15 +1,4 @@
1
- //#region src/utils/helpers.ts
2
- const substrReplace = (str, replace, start, length) => {
3
- if (start < 0) start += str.length;
4
- length ??= str.length;
5
- if (length < 0) length = length + str.length - start;
6
- return [
7
- str.slice(0, start),
8
- replace.slice(0, Math.max(0, length)),
9
- replace.slice(length),
10
- str.slice(start + length)
11
- ].join("");
12
- };
1
+ // src/utils/helpers.ts
13
2
  const strBeforeLast = (subject, search) => {
14
3
  if (search === "") return subject;
15
4
  const pos = subject.lastIndexOf(search);
@@ -22,5 +11,4 @@ const strAfterLast = (subject, search) => {
22
11
  if (pos === -1) return subject;
23
12
  return subject.slice(pos + search.length);
24
13
  };
25
- //#endregion
26
- export { strAfterLast, strBeforeLast, substrReplace };
14
+ export { strAfterLast, strBeforeLast };