@akanjs/document 0.9.56 → 0.9.57

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.
@@ -23,9 +23,14 @@ __export(dbDecorators_exports, {
23
23
  });
24
24
  module.exports = __toCommonJS(dbDecorators_exports);
25
25
  var import_constant = require("@akanjs/constant");
26
- const Model = (docRef, filterRef, cnst, ...addMdls) => {
26
+ var import_loaderInfo = require("./loaderInfo");
27
+ const Model = (docRef, filterRef, cnst, loaderBuilder, ...addMdls) => {
27
28
  class DefaultModel {
28
29
  }
30
+ const loaderInfoMap = loaderBuilder((0, import_loaderInfo.makeLoaderBuilder)());
31
+ Object.entries(loaderInfoMap).forEach(([key, loaderInfo]) => {
32
+ loaderInfo.applyLoaderInfo(DefaultModel, key);
33
+ });
29
34
  return DefaultModel;
30
35
  };
31
36
  const into = Model;
@@ -35,7 +35,6 @@ __export(filterMeta_exports, {
35
35
  module.exports = __toCommonJS(filterMeta_exports);
36
36
  var import_base = require("@akanjs/base");
37
37
  var import_common = require("@akanjs/common");
38
- var import_constant = require("@akanjs/constant");
39
38
  const isFilterModel = (filterRef) => {
40
39
  return Reflect.getMetadata("filter", filterRef.prototype) !== void 0;
41
40
  };
@@ -90,17 +89,12 @@ const getFilterSortMap = (filterRef) => {
90
89
  const filterMeta = getFilterMeta(filterRef);
91
90
  return filterMeta.sort;
92
91
  };
93
- const from = (modelRef, filterSort, ...libFilterRefs) => {
94
- const fieldMetaMap = (0, import_constant.getFieldMetaMap)(modelRef);
95
- const statusFieldMeta = fieldMetaMap.get("status");
96
- if (!statusFieldMeta)
97
- throw new Error(`No status field meta fount in ${modelRef.name}`);
92
+ const from = (modelRef, buildFilter, ...libFilterRefs) => {
98
93
  class Base {
99
94
  }
100
- const querySort = filterSort(filter);
95
+ const querySort = buildFilter(filter);
101
96
  Object.assign(Base.prototype, { latest: { createdAt: -1 }, oldest: { createdAt: 1 }, ...querySort.sort });
102
97
  Object.entries({
103
- byStatuses: filter().opt("statuses", [statusFieldMeta.enum]).query((statuses) => statuses?.length ? { status: { $in: statuses } } : {}),
104
98
  any: filter().query(() => ({ removedAt: { $exists: false } })),
105
99
  ...querySort.query
106
100
  }).forEach(([key, filterInfo]) => {
@@ -123,6 +117,7 @@ const from = (modelRef, filterSort, ...libFilterRefs) => {
123
117
  return Base;
124
118
  };
125
119
  class FilterInfo {
120
+ argNames = [];
126
121
  args;
127
122
  queryFn = null;
128
123
  constructor() {
@@ -133,12 +128,14 @@ class FilterInfo {
133
128
  throw new Error("Query function is already set");
134
129
  else if (this.args.at(-1)?.option?.nullable)
135
130
  throw new Error("Last argument is nullable");
131
+ this.argNames.push(name);
136
132
  this.args.push({ name, argRef, option });
137
133
  return this;
138
134
  }
139
135
  opt(name, argRef, option) {
140
136
  if (this.queryFn)
141
137
  throw new Error("Query function is already set");
138
+ this.argNames.push(name);
142
139
  this.args.push({ name, argRef, option: { ...option, nullable: true } });
143
140
  return this;
144
141
  }
@@ -0,0 +1,60 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+ var loaderInfo_exports = {};
19
+ __export(loaderInfo_exports, {
20
+ LoaderInfo: () => LoaderInfo,
21
+ makeLoaderBuilder: () => makeLoaderBuilder
22
+ });
23
+ module.exports = __toCommonJS(loaderInfo_exports);
24
+ var import__ = require(".");
25
+ class LoaderInfo {
26
+ type;
27
+ field;
28
+ defaultQuery;
29
+ queryArg;
30
+ constructor(type, field, defaultQuery = {}) {
31
+ this.type = type;
32
+ this.field = field;
33
+ this.defaultQuery = defaultQuery;
34
+ }
35
+ applyLoaderInfo(mdlRef, key) {
36
+ switch (this.type) {
37
+ case "field":
38
+ import__.Loader.ByField(this.field, this.defaultQuery)(mdlRef.prototype, key);
39
+ break;
40
+ case "arrayField":
41
+ import__.Loader.ByArrayField(this.field, this.defaultQuery)(mdlRef.prototype, key);
42
+ break;
43
+ case "query":
44
+ import__.Loader.ByQuery(this.field, this.defaultQuery)(mdlRef.prototype, key);
45
+ break;
46
+ default:
47
+ throw new Error(`Invalid inject type: ${this.type}`);
48
+ }
49
+ }
50
+ }
51
+ const makeLoaderBuilder = () => ({
52
+ byField: (fieldName, defaultQuery = {}) => new LoaderInfo("field", fieldName, defaultQuery),
53
+ byArrayField: (fieldName, defaultQuery = {}) => new LoaderInfo("arrayField", fieldName, defaultQuery),
54
+ byQuery: (queryKeys, defaultQuery = {}) => new LoaderInfo("query", queryKeys, defaultQuery)
55
+ });
56
+ // Annotate the CommonJS export names for ESM import in node:
57
+ 0 && (module.exports = {
58
+ LoaderInfo,
59
+ makeLoaderBuilder
60
+ });
@@ -2,7 +2,11 @@ import { dayjs } from "@akanjs/base";
2
2
  import { capitalize, Logger, lowerlize } from "@akanjs/common";
3
3
  import { DEFAULT_PAGE_SIZE, getFieldMetas } from "@akanjs/constant";
4
4
  import { createArrayLoader, createLoader, createQueryLoader, getLoaderMetas } from "./dataLoader";
5
- import { getFilterKeyMetaMapOnPrototype, getFilterQuery, getFilterSort } from "./filterMeta";
5
+ import {
6
+ getFilterKeyMetaMapOnPrototype,
7
+ getFilterQuery,
8
+ getFilterSort
9
+ } from "./filterMeta";
6
10
  import { convertAggregateMatch } from "./schema";
7
11
  class CacheDatabase {
8
12
  constructor(refName, redis) {
@@ -1,7 +1,12 @@
1
1
  import { getFieldMetaMap, setFieldMetaMap } from "@akanjs/constant";
2
- const Model = (docRef, filterRef, cnst, ...addMdls) => {
2
+ import { makeLoaderBuilder } from "./loaderInfo";
3
+ const Model = (docRef, filterRef, cnst, loaderBuilder, ...addMdls) => {
3
4
  class DefaultModel {
4
5
  }
6
+ const loaderInfoMap = loaderBuilder(makeLoaderBuilder());
7
+ Object.entries(loaderInfoMap).forEach(([key, loaderInfo]) => {
8
+ loaderInfo.applyLoaderInfo(DefaultModel, key);
9
+ });
5
10
  return DefaultModel;
6
11
  };
7
12
  const into = Model;
@@ -1,8 +1,5 @@
1
- import {
2
- getNonArrayModel
3
- } from "@akanjs/base";
1
+ import { getNonArrayModel } from "@akanjs/base";
4
2
  import { applyMixins } from "@akanjs/common";
5
- import { getFieldMetaMap } from "@akanjs/constant";
6
3
  const isFilterModel = (filterRef) => {
7
4
  return Reflect.getMetadata("filter", filterRef.prototype) !== void 0;
8
5
  };
@@ -57,17 +54,12 @@ const getFilterSortMap = (filterRef) => {
57
54
  const filterMeta = getFilterMeta(filterRef);
58
55
  return filterMeta.sort;
59
56
  };
60
- const from = (modelRef, filterSort, ...libFilterRefs) => {
61
- const fieldMetaMap = getFieldMetaMap(modelRef);
62
- const statusFieldMeta = fieldMetaMap.get("status");
63
- if (!statusFieldMeta)
64
- throw new Error(`No status field meta fount in ${modelRef.name}`);
57
+ const from = (modelRef, buildFilter, ...libFilterRefs) => {
65
58
  class Base {
66
59
  }
67
- const querySort = filterSort(filter);
60
+ const querySort = buildFilter(filter);
68
61
  Object.assign(Base.prototype, { latest: { createdAt: -1 }, oldest: { createdAt: 1 }, ...querySort.sort });
69
62
  Object.entries({
70
- byStatuses: filter().opt("statuses", [statusFieldMeta.enum]).query((statuses) => statuses?.length ? { status: { $in: statuses } } : {}),
71
63
  any: filter().query(() => ({ removedAt: { $exists: false } })),
72
64
  ...querySort.query
73
65
  }).forEach(([key, filterInfo]) => {
@@ -90,6 +82,7 @@ const from = (modelRef, filterSort, ...libFilterRefs) => {
90
82
  return Base;
91
83
  };
92
84
  class FilterInfo {
85
+ argNames = [];
93
86
  args;
94
87
  queryFn = null;
95
88
  constructor() {
@@ -100,12 +93,14 @@ class FilterInfo {
100
93
  throw new Error("Query function is already set");
101
94
  else if (this.args.at(-1)?.option?.nullable)
102
95
  throw new Error("Last argument is nullable");
96
+ this.argNames.push(name);
103
97
  this.args.push({ name, argRef, option });
104
98
  return this;
105
99
  }
106
100
  opt(name, argRef, option) {
107
101
  if (this.queryFn)
108
102
  throw new Error("Query function is already set");
103
+ this.argNames.push(name);
109
104
  this.args.push({ name, argRef, option: { ...option, nullable: true } });
110
105
  return this;
111
106
  }
@@ -0,0 +1,36 @@
1
+ import { Loader } from ".";
2
+ class LoaderInfo {
3
+ type;
4
+ field;
5
+ defaultQuery;
6
+ queryArg;
7
+ constructor(type, field, defaultQuery = {}) {
8
+ this.type = type;
9
+ this.field = field;
10
+ this.defaultQuery = defaultQuery;
11
+ }
12
+ applyLoaderInfo(mdlRef, key) {
13
+ switch (this.type) {
14
+ case "field":
15
+ Loader.ByField(this.field, this.defaultQuery)(mdlRef.prototype, key);
16
+ break;
17
+ case "arrayField":
18
+ Loader.ByArrayField(this.field, this.defaultQuery)(mdlRef.prototype, key);
19
+ break;
20
+ case "query":
21
+ Loader.ByQuery(this.field, this.defaultQuery)(mdlRef.prototype, key);
22
+ break;
23
+ default:
24
+ throw new Error(`Invalid inject type: ${this.type}`);
25
+ }
26
+ }
27
+ }
28
+ const makeLoaderBuilder = () => ({
29
+ byField: (fieldName, defaultQuery = {}) => new LoaderInfo("field", fieldName, defaultQuery),
30
+ byArrayField: (fieldName, defaultQuery = {}) => new LoaderInfo("arrayField", fieldName, defaultQuery),
31
+ byQuery: (queryKeys, defaultQuery = {}) => new LoaderInfo("query", queryKeys, defaultQuery)
32
+ });
33
+ export {
34
+ LoaderInfo,
35
+ makeLoaderBuilder
36
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@akanjs/document",
3
- "version": "0.9.56",
3
+ "version": "0.9.57",
4
4
  "sourceType": "module",
5
5
  "publishConfig": {
6
6
  "access": "public"
package/src/database.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { Dayjs, GetActionObject, MergedValues, PromiseOrObject } from "@akanjs/base";
1
+ import type { Dayjs, MergedValues, PromiseOrObject } from "@akanjs/base";
2
2
  import { Logger } from "@akanjs/common";
3
3
  import { type DocumentModel, type QueryOf } from "@akanjs/constant";
4
4
  import type DataLoader from "dataloader";
@@ -7,7 +7,8 @@ import type { HydratedDocument } from "mongoose";
7
7
  import type { RedisClientType } from "redis";
8
8
  import type { BaseMiddleware, CRUDEventType, Mdl, SaveEventType } from "./dbDecorators";
9
9
  import type { Database } from "./documentInfo";
10
- import type { DataInputOf, FilterType, FindQueryOption, ListQueryOption, SortOf } from "./types";
10
+ import { ExtractQuery, ExtractSort, FilterInstance } from "./filterMeta";
11
+ import type { DataInputOf, FindQueryOption, ListQueryOption } from "./types";
11
12
  export interface RedisSetOptions {
12
13
  expireAt?: Dayjs;
13
14
  }
@@ -119,6 +120,6 @@ type DatabaseModelWithQuerySort<T extends string, Input, Doc, Obj, Insight, Quer
119
120
  } & {
120
121
  [K in `searchCount${_CapitalizedT}`]: (searchText: string) => Promise<number>;
121
122
  } & QueryMethodPart<Query, Sort, Obj, Doc, Insight, _FindQueryOption, _ListQueryOption, _QueryOfDoc>;
122
- export type DatabaseModel<T extends string, Input, Doc, Obj, Insight, Filter, _CapitalizedT extends string = Capitalize<T>, _QueryOfDoc = QueryOf<Doc>, _Query = GetActionObject<Filter>, _Sort = SortOf<Filter>, _DataInput = DataInputOf<Input, DocumentModel<Obj>>, _FindQueryOption = FindQueryOption<_Sort, Obj>, _ListQueryOption = ListQueryOption<_Sort, Obj>> = DatabaseModelWithQuerySort<T, Input, Doc, Obj, Insight, _Query, _Sort, _CapitalizedT, _QueryOfDoc, _DataInput, _FindQueryOption, _ListQueryOption>;
123
- export declare const databaseModelOf: <T extends string, Input, Doc extends HydratedDocument<any>, Model extends Mdl<any, any>, Middleware extends BaseMiddleware, Insight, Obj, Filter extends FilterType>(database: Database<T, Input, Doc, Model, Middleware, Insight, Obj, Filter>, model: Mdl<any, any>, redis: RedisClientType, meili: MeiliSearch) => DatabaseModel<T, Input, Doc, Model, Insight, Filter>;
123
+ export type DatabaseModel<T extends string, Input, Doc, Obj, Insight, Filter extends FilterInstance, _CapitalizedT extends string = Capitalize<T>, _QueryOfDoc = QueryOf<Doc>, _Query = ExtractQuery<Filter>, _Sort = ExtractSort<Filter>, _DataInput = DataInputOf<Input, DocumentModel<Obj>>, _FindQueryOption = FindQueryOption<_Sort, Obj>, _ListQueryOption = ListQueryOption<_Sort, Obj>> = DatabaseModelWithQuerySort<T, Input, Doc, Obj, Insight, _Query, _Sort, _CapitalizedT, _QueryOfDoc, _DataInput, _FindQueryOption, _ListQueryOption>;
124
+ export declare const databaseModelOf: <T extends string, Input, Doc extends HydratedDocument<any>, Model extends Mdl<any, any>, Middleware extends BaseMiddleware, Insight, Obj, Filter extends FilterInstance>(database: Database<T, Input, Doc, Model, Middleware, Insight, Obj, Filter>, model: Mdl<any, any>, redis: RedisClientType, meili: MeiliSearch) => DatabaseModel<T, Input, Doc, Model, Insight, Filter>;
124
125
  export {};
@@ -1,7 +1,9 @@
1
- import { BaseObject, GetActionObject, type MergeAllActionTypes, PromiseOrObject, Type } from "@akanjs/base";
1
+ import { BaseObject, type MergeAllActionTypes, PromiseOrObject, Type } from "@akanjs/base";
2
2
  import { type ConstantModel, type DocumentModel } from "@akanjs/constant";
3
3
  import type { FilterQuery, HydratedDocument, Model as MongooseModel, PipelineStage, ProjectionType, Schema } from "mongoose";
4
+ import { ExtractQuery, FilterInstance } from ".";
4
5
  import type { DatabaseModel } from "./database";
6
+ import { ExtractLoaderInfoObject, LoaderBuilder } from "./loaderInfo";
5
7
  export type { FilterQuery as QueryOf };
6
8
  export interface DefaultDocMtds<TDocument> {
7
9
  refresh(): Promise<this>;
@@ -37,7 +39,7 @@ export type SchemaOf<Mdl, Doc> = Schema<null, Mdl, Doc, undefined, null, Mdl>;
37
39
  export interface BaseMiddleware {
38
40
  onSchema: (schema: SchemaOf<any, any>) => void;
39
41
  }
40
- export declare const into: <Doc, Filter, T extends string, Input, Full, Light, Insight, AddDbModels extends Type[], _CapitalizedT extends string, _Default, _DefaultInput, _DefaultState, _DefaultStateInput, _DefaultInsight, _PurifiedInput, _Doc, _DocInput, _QueryOfDoc, _Query = GetActionObject<Filter>, _Sort = keyof import("@akanjs/base").GetStateObject<Filter>, _DatabaseModel = DatabaseModel<T, _DocInput, Doc, Full, Insight, Filter, _CapitalizedT, _QueryOfDoc, _Query, _Sort>>(docRef: Type<Doc>, filterRef: Type<Filter>, cnst: ConstantModel<T, Input, Full, Light, Insight, _CapitalizedT, _Default, _DefaultInput, _DefaultState, _DefaultStateInput, _DefaultInsight, _PurifiedInput, _Doc, _DocInput, _QueryOfDoc>, ...addMdls: AddDbModels) => Type<MergeAllActionTypes<AddDbModels, keyof _DatabaseModel & string> & _DatabaseModel>;
42
+ export declare const into: <Doc, Filter extends FilterInstance, T extends string, Input, Full, Light, Insight, AddDbModels extends Type[], _CapitalizedT extends string, _Default, _DefaultInput, _DefaultState, _DefaultStateInput, _DefaultInsight, _PurifiedInput, _Doc, _DocInput, _QueryOfDoc, _Query = ExtractQuery<Filter>, _Sort = keyof Filter["sort"], _DatabaseModel = DatabaseModel<T, _DocInput, Doc, Full, Insight, Filter, _CapitalizedT, _QueryOfDoc, _Query, _Sort>, _LoaderBuilder extends LoaderBuilder<_Doc> = LoaderBuilder<_Doc>>(docRef: Type<Doc>, filterRef: Type<Filter>, cnst: ConstantModel<T, Input, Full, Light, Insight, _CapitalizedT, _Default, _DefaultInput, _DefaultState, _DefaultStateInput, _DefaultInsight, _PurifiedInput, _Doc, _DocInput, _QueryOfDoc>, loaderBuilder: _LoaderBuilder, ...addMdls: AddDbModels) => Type<MergeAllActionTypes<AddDbModels, keyof _DatabaseModel & string> & _DatabaseModel & ExtractLoaderInfoObject<ReturnType<_LoaderBuilder>>>;
41
43
  export declare const by: <Model, AddDbModels extends Type[], _DocModel = Model extends BaseObject ? Doc<Model> : DocumentModel<Model>>(modelRef: Type<Model>, ...addRefs: AddDbModels) => Type<MergeAllActionTypes<AddDbModels, keyof _DocModel & string> & _DocModel>;
42
44
  export declare const beyond: <DbModel, Doc>(model: Type<DbModel>, doc: Type<Doc>) => {
43
45
  new (): {
@@ -2,7 +2,7 @@ import type { Type } from "@akanjs/base";
2
2
  import type { HydratedDocument } from "mongoose";
3
3
  import type { DatabaseModel } from "./database";
4
4
  import type { BaseMiddleware } from "./dbDecorators";
5
- import { FilterType } from "./types";
5
+ import { FilterInstance } from "./filterMeta";
6
6
  export interface DatabaseDocumentModelInfo {
7
7
  input: Type;
8
8
  doc: Type;
@@ -12,16 +12,16 @@ export interface DatabaseDocumentModelInfo {
12
12
  }
13
13
  export declare const documentInfo: {
14
14
  database: Map<string, DatabaseDocumentModelInfo>;
15
- scalar: Map<string, Type>;
15
+ scalar: Map<string, new (...args: any[]) => any>;
16
16
  modelSets: {
17
- input: Set<Type>;
18
- doc: Set<Type>;
19
- model: Set<Type>;
20
- filter: Set<Type>;
21
- middleware: Set<Type>;
22
- scalar: Set<Type>;
17
+ input: Set<new (...args: any[]) => any>;
18
+ doc: Set<new (...args: any[]) => any>;
19
+ model: Set<new (...args: any[]) => any>;
20
+ filter: Set<new (...args: any[]) => any>;
21
+ middleware: Set<new (...args: any[]) => any>;
22
+ scalar: Set<new (...args: any[]) => any>;
23
23
  };
24
- modelRefNameMap: Map<Type, string>;
24
+ modelRefNameMap: Map<new (...args: any[]) => any, string>;
25
25
  getRefName<AllowEmpty extends boolean = false>(modelRef: Type, { allowEmpty }?: {
26
26
  allowEmpty?: AllowEmpty;
27
27
  }): AllowEmpty extends true ? string | undefined : string;
@@ -43,7 +43,7 @@ export declare const documentInfo: {
43
43
  sortKeys: string[];
44
44
  } | undefined;
45
45
  };
46
- export interface Database<T extends string, Input, Doc extends HydratedDocument<any>, Model, Middleware extends BaseMiddleware, Obj, Insight, Filter extends FilterType> {
46
+ export interface Database<T extends string, Input, Doc extends HydratedDocument<any>, Model, Middleware extends BaseMiddleware, Obj, Insight, Filter extends FilterInstance> {
47
47
  refName: T;
48
48
  Input: Type<Input>;
49
49
  Doc: Type<Doc>;
@@ -53,7 +53,7 @@ export interface Database<T extends string, Input, Doc extends HydratedDocument<
53
53
  Insight: Type<Insight>;
54
54
  Filter: Type<Filter>;
55
55
  }
56
- export declare const dbOf: <T extends string, Input, Doc extends HydratedDocument<any>, Model extends DatabaseModel<T, Input, any, Obj, Insight, Filter>, Middleware extends BaseMiddleware, Obj, Insight, Filter extends FilterType>(refName: T, Input: Type<Input>, Doc: Type<Doc>, Model: Type<Model>, Middleware: Type<Middleware>, Obj: Type<Obj>, Insight: Type<Insight>, Filter: Type<Filter>) => Database<T, Input, Doc, Model, Middleware, Obj, Insight, Filter>;
56
+ export declare const dbOf: <T extends string, Input, Doc extends HydratedDocument<any>, Model extends DatabaseModel<T, Input, any, Obj, Insight, Filter>, Middleware extends BaseMiddleware, Obj, Insight, Filter extends FilterInstance>(refName: T, Input: Type<Input>, Doc: Type<Doc>, Model: Type<Model>, Middleware: Type<Middleware>, Obj: Type<Obj>, Insight: Type<Insight>, Filter: Type<Filter>) => Database<T, Input, Doc, Model, Middleware, Obj, Insight, Filter>;
57
57
  export declare const scalarDbOf: <T extends string, Model>(refName: T, Model: Type<Model>) => {
58
58
  refName: T;
59
59
  Model: Type<Model>;
@@ -1,6 +1,6 @@
1
- import { type BaseObject, type MergeAllTypes, type Prettify, type Type } from "@akanjs/base";
1
+ import { type BaseObject, MergeAllKeyOfTypes, type Type } from "@akanjs/base";
2
2
  import { ConstantFieldTypeInput, FieldToValue, PlainTypeToFieldType, QueryOf } from "@akanjs/constant";
3
- import type { ConstantFilterMeta, FilterArgMeta, FilterKeyMeta, SortType } from "./types";
3
+ import type { ConstantFilterMeta, FilterArgMeta, FilterKeyMeta } from "./types";
4
4
  export declare const isFilterModel: (filterRef: Type) => boolean;
5
5
  export declare const getFilterMeta: (filterRef: Type) => ConstantFilterMeta;
6
6
  export declare const setFilterMeta: (filterRef: Type, filterMeta: ConstantFilterMeta) => void;
@@ -10,51 +10,43 @@ export declare const setFilterArgMetasOnPrototype: (prototype: object, key: stri
10
10
  export declare const getFilterArgMetas: (filterRef: Type, key: string) => FilterArgMeta[];
11
11
  export declare const getFilterQuery: (filterRef: Type, key: string) => (...args: any[]) => QueryOf<any>;
12
12
  export declare const getFilterQueryMap: (filterRef: Type) => Map<string, FilterKeyMeta>;
13
- export declare const getFilterSort: (filterRef: Type, key: string) => Partial<{
14
- [x: string]: number;
15
- }>;
16
- export declare const getFilterSortMap: (filterRef: Type) => SortType<{
13
+ export declare const getFilterSort: (filterRef: Type, key: string) => {
17
14
  [key: string]: any;
18
- }>;
19
- export type BaseFilterKey = "latest" | "oldest" | "any" | "byStatuses";
20
- interface BaseFilter<Status extends string = string> {
15
+ };
16
+ export declare const getFilterSortMap: (filterRef: Type) => {
17
+ [key: string]: any;
18
+ };
19
+ export type BaseFilterSortKey = "latest" | "oldest";
20
+ export type BaseFilterQueryKey = "any";
21
+ export type BaseFilterKey = BaseFilterSortKey | BaseFilterQueryKey;
22
+ export interface FilterInstance<Query = unknown, Sort = unknown> {
23
+ query: Query;
24
+ sort: Sort;
25
+ }
26
+ interface BaseQuery<Model> {
27
+ any: FilterInfo<[], [], Model>;
28
+ }
29
+ interface BaseSort {
21
30
  latest: {
22
31
  createdAt: -1;
23
32
  };
24
33
  oldest: {
25
34
  createdAt: 1;
26
35
  };
27
- any: () => {
28
- removedAt: {
29
- $exists: false;
30
- };
31
- };
32
- byStatuses: (statuses?: Status[] | null) => {
33
- status: {
34
- $in: Status[];
35
- };
36
- };
37
36
  }
38
- type ExtractQuery<Query extends {
39
- [key: string]: FilterInfo<any[]>;
40
- }> = {
41
- [K in keyof Query]: Query[K] extends FilterInfo<infer Args> ? (...args: Args) => QueryOf<any> : never;
37
+ export type ExtractQuery<Filter extends FilterInstance> = {
38
+ [K in keyof Filter["query"]]: Filter["query"][K] extends FilterInfo<any, infer Args> ? (...args: Args) => QueryOf<any> : never;
42
39
  };
43
- export declare const from: <Full extends BaseObject, FilterSort extends {
44
- query: {
45
- [key: string]: FilterInfo<any[]>;
46
- };
47
- sort: SortType<Full>;
48
- }, LibFilters extends Type[]>(modelRef: Type<Full>, filterSort: (filter: () => FilterInfo<[], Full>) => FilterSort, ...libFilterRefs: LibFilters) => Type<Prettify<MergeAllTypes<LibFilters> & BaseFilter<Full extends {
49
- status: infer Status;
50
- } ? Status : string> & ExtractQuery<FilterSort["query"]> & FilterSort["sort"]>>;
40
+ export type ExtractSort<Filter extends FilterInstance> = keyof Filter["sort"];
41
+ export declare const from: <Full extends BaseObject, BuildFilter extends (filter: () => FilterInfo<[], [], Full>) => FilterInstance, LibFilters extends Type[], _Filter extends ReturnType<BuildFilter>>(modelRef: Type<Full>, buildFilter: BuildFilter, ...libFilterRefs: LibFilters) => Type<FilterInstance<BaseQuery<Full> & MergeAllKeyOfTypes<LibFilters, "query"> & _Filter["query"], BaseSort & MergeAllKeyOfTypes<LibFilters, "sort"> & _Filter["sort"]>>;
51
42
  interface ArgProps<Value = any> {
52
43
  nullable?: boolean;
53
44
  ref?: string;
54
45
  default?: Value;
55
46
  renderOption?: (arg: any) => string;
56
47
  }
57
- export declare class FilterInfo<Args extends any[] = [], Model = any> {
48
+ export declare class FilterInfo<ArgNames extends string[] = [], Args extends any[] = [], Model = any> {
49
+ readonly argNames: ArgNames;
58
50
  readonly args: {
59
51
  name: string;
60
52
  argRef: any;
@@ -62,10 +54,10 @@ export declare class FilterInfo<Args extends any[] = [], Model = any> {
62
54
  }[];
63
55
  queryFn: ((...args: Args) => QueryOf<any>) | null;
64
56
  constructor();
65
- arg<ExplicitType, Arg extends ConstantFieldTypeInput = PlainTypeToFieldType<ExplicitType>, _FieldToValue = FieldToValue<Arg>>(name: string, argRef: Arg, option?: Omit<ArgProps<_FieldToValue>, "nullable">): FilterInfo<[...Args, arg: _FieldToValue], Model>;
66
- opt<ExplicitType, Arg extends ConstantFieldTypeInput = PlainTypeToFieldType<ExplicitType>, _FieldToValue = FieldToValue<Arg>>(name: string, argRef: Arg, option?: Omit<ArgProps<_FieldToValue>, "nullable">): FilterInfo<[...Args, opt?: _FieldToValue | null], Model>;
57
+ arg<ExplicitType, Arg extends ConstantFieldTypeInput = PlainTypeToFieldType<ExplicitType>, ArgName extends string = "unknown", _FieldToValue = FieldToValue<Arg>>(name: ArgName, argRef: Arg, option?: Omit<ArgProps<_FieldToValue>, "nullable">): FilterInfo<[...ArgNames, ArgName], [...Args, arg: _FieldToValue], Model>;
58
+ opt<ExplicitType, Arg extends ConstantFieldTypeInput = PlainTypeToFieldType<ExplicitType>, ArgName extends string = "unknown", _FieldToValue = FieldToValue<Arg>>(name: ArgName, argRef: Arg, option?: Omit<ArgProps<_FieldToValue>, "nullable">): FilterInfo<[...ArgNames, ArgName], [...Args, opt?: _FieldToValue | null], Model>;
67
59
  query(query: (...args: Args) => QueryOf<Model>): this;
68
60
  applyFilterMeta(filterRef: Type, key: string): void;
69
61
  }
70
- export declare const filter: () => FilterInfo<[], any>;
62
+ export declare const filter: () => FilterInfo<[], [], any>;
71
63
  export {};
@@ -0,0 +1,26 @@
1
+ import { Type } from "@akanjs/base";
2
+ import { FilterQuery } from "mongoose";
3
+ import { Loader } from ".";
4
+ type LoaderType = "field" | "arrayField" | "query";
5
+ export declare class LoaderInfo<Doc, Key extends keyof Doc, QueryArg = Doc[Key]> {
6
+ type: LoaderType;
7
+ field: Key | Key[];
8
+ defaultQuery: FilterQuery<unknown>;
9
+ queryArg: QueryArg;
10
+ constructor(type: LoaderType, field: Key | Key[], defaultQuery?: FilterQuery<unknown>);
11
+ applyLoaderInfo(mdlRef: Type, key: string): void;
12
+ }
13
+ export declare const makeLoaderBuilder: <Doc>() => {
14
+ byField: <Key extends keyof Doc & string>(fieldName: Key, defaultQuery?: FilterQuery<unknown>) => LoaderInfo<Doc, Key, Doc[Key]>;
15
+ byArrayField: <Key extends keyof Doc & string>(fieldName: Key, defaultQuery?: FilterQuery<unknown>) => LoaderInfo<Doc, Key, Doc[Key]>;
16
+ byQuery: <Key extends keyof Doc & string>(queryKeys: readonly Key[], defaultQuery?: FilterQuery<unknown>) => LoaderInfo<Doc, Key, Pick<Doc, Key>>;
17
+ };
18
+ export type LoaderBuilder<Doc = any> = (builder: ReturnType<typeof makeLoaderBuilder<Doc>>) => {
19
+ [key: string]: LoaderInfo<Doc, any, any>;
20
+ };
21
+ export type ExtractLoaderInfoObject<LoaderInfoMap extends {
22
+ [key: string]: LoaderInfo<any, any, any>;
23
+ }> = {
24
+ [K in keyof LoaderInfoMap]: LoaderInfoMap[K] extends LoaderInfo<infer Doc, any, infer QueryArg> ? Loader<QueryArg, Doc> : never;
25
+ };
26
+ export {};
package/src/types.d.ts CHANGED
@@ -1,25 +1,14 @@
1
- import type { Enum, GetStateObject, Type } from "@akanjs/base";
1
+ import type { EnumInstance, GetStateObject, Type } from "@akanjs/base";
2
2
  import type { Document, ProjectionType } from "mongoose";
3
3
  export type DataInputOf<Input, Obj> = {
4
4
  [K in keyof Input as K extends K ? K : never]: Input[K] extends any[] ? Input[K] | undefined : Input[K];
5
5
  } & Partial<Obj>;
6
6
  export type GetDocObject<D> = GetStateObject<Omit<D, Exclude<keyof Document, "id"> | "__v">>;
7
- export interface FilterType {
8
- [key: string]: any;
9
- }
10
- export interface SortType<Model extends {
11
- [key: string]: any;
12
- } = {
13
- [key: string]: any;
14
- }> {
15
- [key: string]: Partial<{
16
- [K in keyof GetStateObject<Model>]: number;
17
- }>;
18
- }
19
- export type SortOf<Filter> = keyof GetStateObject<Filter>;
20
7
  export interface ConstantFilterMeta {
21
8
  refName: string;
22
- sort: SortType;
9
+ sort: {
10
+ [key: string]: any;
11
+ };
23
12
  }
24
13
  export interface FilterKeyProps {
25
14
  type?: "mongo" | "meili";
@@ -33,7 +22,7 @@ export interface FilterArgProps {
33
22
  ref?: string;
34
23
  default?: string | number | boolean | object | null | (() => string | number | boolean | object | null);
35
24
  renderOption?: (value: any) => string;
36
- enum?: Enum;
25
+ enum?: EnumInstance;
37
26
  }
38
27
  export interface FilterArgMeta extends FilterArgProps {
39
28
  name: string;