@akanjs/document 0.9.42 → 0.9.44

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.
@@ -88,7 +88,6 @@ class DatabaseModelStorage {
88
88
  __ModelType__ = "DatabaseModelStorage";
89
89
  }
90
90
  const databaseModelOf = (database, model, redis, meili) => {
91
- //! 잘되는지 확인 필요
92
91
  const [modelName, className] = [database.refName, (0, import_common.capitalize)(database.refName)];
93
92
  const insightFieldMetas = (0, import_constant.getFieldMetas)(database.Insight);
94
93
  const accumulator = Object.fromEntries(insightFieldMetas.map((fieldMeta) => [fieldMeta.key, fieldMeta.accumulate]));
@@ -182,18 +181,11 @@ const databaseModelOf = (database, model, redis, meili) => {
182
181
  const data = res[0];
183
182
  return data ?? defaultInsight;
184
183
  }
185
- async getDefaultSummary(addQuery = {}) {
186
- if (!database.Summary)
187
- return {};
188
- const fieldMetas = (0, import_constant.getFieldMetas)(database.Summary);
189
- const summary = {};
190
- await Promise.all(
191
- fieldMetas.filter((fieldMeta) => !!fieldMeta.query).map(async (fieldMeta) => {
192
- const query = typeof fieldMeta.query === "function" ? fieldMeta.query() : fieldMeta.query;
193
- summary[fieldMeta.key] = query ? await model.countDocuments({ ...query, ...addQuery }) : fieldMeta.default;
194
- })
195
- );
196
- return summary;
184
+ listenPre(type, listener) {
185
+ return this.__model.listenPre(type, listener);
186
+ }
187
+ listenPost(type, listener) {
188
+ return this.__model.listenPost(type, listener);
197
189
  }
198
190
  async [`get${className}`](id) {
199
191
  const doc = await this.__loader.load(id);
@@ -26,13 +26,12 @@ __export(dbDecorators_exports, {
26
26
  by: () => by,
27
27
  dbOf: () => dbOf,
28
28
  getAllDatabaseModelNames: () => getAllDatabaseModelNames,
29
- inside: () => inside,
30
29
  into: () => into
31
30
  });
32
31
  module.exports = __toCommonJS(dbDecorators_exports);
33
32
  var import_constant = require("@akanjs/constant");
34
- const dbOf = (refName, Input, Doc, Model2, Middleware, Obj, Insight, Filter, Summary) => {
35
- return { refName, Input, Doc, Model: Model2, Middleware, Obj, Insight, Filter, Summary };
33
+ const dbOf = (refName, Input, Doc, Model2, Middleware, Obj, Insight, Filter) => {
34
+ return { refName, Input, Doc, Model: Model2, Middleware, Obj, Insight, Filter };
36
35
  };
37
36
  class InputDatabaseStorage {
38
37
  }
@@ -76,24 +75,18 @@ const Database = {
76
75
  };
77
76
  }
78
77
  };
79
- const Model = (docRef, cnst) => {
78
+ const Model = (docRef, cnst, ...addMdls) => {
80
79
  class DefaultModel {
81
80
  }
82
81
  return DefaultModel;
83
82
  };
84
83
  const into = Model;
85
- const AddModel = (modelRef, cnst) => {
84
+ const by = (modelRef, ...addRefs) => {
85
+ addRefs.forEach((addRef) => {
86
+ AddInputOrDocument(modelRef, addRef);
87
+ });
86
88
  return modelRef;
87
89
  };
88
- const inside = AddModel;
89
- const by = (modelRef, addRef) => {
90
- if (!addRef)
91
- return InputOrDocument(modelRef);
92
- return AddInputOrDocument(modelRef, addRef);
93
- };
94
- const InputOrDocument = (inputRef) => {
95
- return inputRef;
96
- };
97
90
  const AddInputOrDocument = (modelRef, addRef) => {
98
91
  const fieldMetaMap = (0, import_constant.getFieldMetaMap)(modelRef);
99
92
  const addFieldMetas = (0, import_constant.getFieldMetaMap)(addRef);
@@ -117,6 +110,5 @@ const beyond = (model, doc) => {
117
110
  by,
118
111
  dbOf,
119
112
  getAllDatabaseModelNames,
120
- inside,
121
113
  into
122
114
  });
package/cjs/src/schema.js CHANGED
@@ -67,32 +67,59 @@ const getDefaultSchemaOptions = () => ({
67
67
  ]);
68
68
  return obj.length ? new this(obj[0]) : null;
69
69
  },
70
- addSummary: async function(prefix = "total", num = 1) {
71
- const update = Array.isArray(prefix) ? {
72
- $inc: {
73
- ...prefix.reduce((acc, cur) => ({ ...acc, [`${cur}${this.modelName}`]: num }), {})
74
- }
75
- } : { $inc: { [`${prefix}${this.modelName}`]: num } };
76
- await this.db.collection("summaries").updateOne({ status: "active" }, update);
70
+ preSaveListenerSet: /* @__PURE__ */ new Set(),
71
+ postSaveListenerSet: /* @__PURE__ */ new Set(),
72
+ preCreateListenerSet: /* @__PURE__ */ new Set(),
73
+ postCreateListenerSet: /* @__PURE__ */ new Set(),
74
+ preUpdateListenerSet: /* @__PURE__ */ new Set(),
75
+ postUpdateListenerSet: /* @__PURE__ */ new Set(),
76
+ preRemoveListenerSet: /* @__PURE__ */ new Set(),
77
+ postRemoveListenerSet: /* @__PURE__ */ new Set(),
78
+ listenPre: function(type, listener) {
79
+ if (type === "save") {
80
+ this.preSaveListenerSet.add(listener);
81
+ return () => {
82
+ this.preSaveListenerSet.delete(listener);
83
+ };
84
+ } else if (type === "create") {
85
+ this.preCreateListenerSet.add(listener);
86
+ return () => {
87
+ this.preCreateListenerSet.delete(listener);
88
+ };
89
+ } else if (type === "update") {
90
+ this.preUpdateListenerSet.add(listener);
91
+ return () => {
92
+ this.preUpdateListenerSet.delete(listener);
93
+ };
94
+ } else {
95
+ this.preRemoveListenerSet.add(listener);
96
+ return () => {
97
+ this.preRemoveListenerSet.delete(listener);
98
+ };
99
+ }
77
100
  },
78
- moveSummary: async function(prev, next, num = 1) {
79
- await this.db.collection("summaries").updateOne(
80
- { status: "active" },
81
- {
82
- $inc: {
83
- [`${prev}${this.modelName}`]: -num,
84
- [`${next}${this.modelName}`]: num
85
- }
86
- }
87
- );
88
- },
89
- subSummary: async function(prefix = "total", num = 1) {
90
- const update = Array.isArray(prefix) ? {
91
- $inc: {
92
- ...prefix.reduce((acc, cur) => ({ ...acc, [`${cur}${this.modelName}`]: -num }), {})
93
- }
94
- } : { $inc: { [`${prefix}${this.modelName}`]: -num } };
95
- await this.db.collection("summaries").updateOne({ status: "active" }, update);
101
+ listenPost: function(type, listener) {
102
+ if (type === "save") {
103
+ this.postSaveListenerSet.add(listener);
104
+ return () => {
105
+ this.postSaveListenerSet.delete(listener);
106
+ };
107
+ } else if (type === "create") {
108
+ this.postCreateListenerSet.add(listener);
109
+ return () => {
110
+ this.postCreateListenerSet.delete(listener);
111
+ };
112
+ } else if (type === "update") {
113
+ this.postUpdateListenerSet.add(listener);
114
+ return () => {
115
+ this.postUpdateListenerSet.delete(listener);
116
+ };
117
+ } else {
118
+ this.postRemoveListenerSet.add(listener);
119
+ return () => {
120
+ this.postSaveListenerSet.delete(listener);
121
+ };
122
+ }
96
123
  }
97
124
  }
98
125
  });
@@ -72,7 +72,6 @@ class DatabaseModelStorage {
72
72
  __ModelType__ = "DatabaseModelStorage";
73
73
  }
74
74
  const databaseModelOf = (database, model, redis, meili) => {
75
- //! 잘되는지 확인 필요
76
75
  const [modelName, className] = [database.refName, capitalize(database.refName)];
77
76
  const insightFieldMetas = getFieldMetas(database.Insight);
78
77
  const accumulator = Object.fromEntries(insightFieldMetas.map((fieldMeta) => [fieldMeta.key, fieldMeta.accumulate]));
@@ -166,18 +165,11 @@ const databaseModelOf = (database, model, redis, meili) => {
166
165
  const data = res[0];
167
166
  return data ?? defaultInsight;
168
167
  }
169
- async getDefaultSummary(addQuery = {}) {
170
- if (!database.Summary)
171
- return {};
172
- const fieldMetas = getFieldMetas(database.Summary);
173
- const summary = {};
174
- await Promise.all(
175
- fieldMetas.filter((fieldMeta) => !!fieldMeta.query).map(async (fieldMeta) => {
176
- const query = typeof fieldMeta.query === "function" ? fieldMeta.query() : fieldMeta.query;
177
- summary[fieldMeta.key] = query ? await model.countDocuments({ ...query, ...addQuery }) : fieldMeta.default;
178
- })
179
- );
180
- return summary;
168
+ listenPre(type, listener) {
169
+ return this.__model.listenPre(type, listener);
170
+ }
171
+ listenPost(type, listener) {
172
+ return this.__model.listenPost(type, listener);
181
173
  }
182
174
  async [`get${className}`](id) {
183
175
  const doc = await this.__loader.load(id);
@@ -3,8 +3,8 @@ import {
3
3
  getFieldMetaMap,
4
4
  setFieldMetaMap
5
5
  } from "@akanjs/constant";
6
- const dbOf = (refName, Input, Doc, Model2, Middleware, Obj, Insight, Filter, Summary) => {
7
- return { refName, Input, Doc, Model: Model2, Middleware, Obj, Insight, Filter, Summary };
6
+ const dbOf = (refName, Input, Doc, Model2, Middleware, Obj, Insight, Filter) => {
7
+ return { refName, Input, Doc, Model: Model2, Middleware, Obj, Insight, Filter };
8
8
  };
9
9
  class InputDatabaseStorage {
10
10
  }
@@ -48,24 +48,18 @@ const Database = {
48
48
  };
49
49
  }
50
50
  };
51
- const Model = (docRef, cnst) => {
51
+ const Model = (docRef, cnst, ...addMdls) => {
52
52
  class DefaultModel {
53
53
  }
54
54
  return DefaultModel;
55
55
  };
56
56
  const into = Model;
57
- const AddModel = (modelRef, cnst) => {
57
+ const by = (modelRef, ...addRefs) => {
58
+ addRefs.forEach((addRef) => {
59
+ AddInputOrDocument(modelRef, addRef);
60
+ });
58
61
  return modelRef;
59
62
  };
60
- const inside = AddModel;
61
- const by = (modelRef, addRef) => {
62
- if (!addRef)
63
- return InputOrDocument(modelRef);
64
- return AddInputOrDocument(modelRef, addRef);
65
- };
66
- const InputOrDocument = (inputRef) => {
67
- return inputRef;
68
- };
69
63
  const AddInputOrDocument = (modelRef, addRef) => {
70
64
  const fieldMetaMap = getFieldMetaMap(modelRef);
71
65
  const addFieldMetas = getFieldMetaMap(addRef);
@@ -88,6 +82,5 @@ export {
88
82
  by,
89
83
  dbOf,
90
84
  getAllDatabaseModelNames,
91
- inside,
92
85
  into
93
86
  };
package/esm/src/schema.js CHANGED
@@ -44,32 +44,59 @@ const getDefaultSchemaOptions = () => ({
44
44
  ]);
45
45
  return obj.length ? new this(obj[0]) : null;
46
46
  },
47
- addSummary: async function(prefix = "total", num = 1) {
48
- const update = Array.isArray(prefix) ? {
49
- $inc: {
50
- ...prefix.reduce((acc, cur) => ({ ...acc, [`${cur}${this.modelName}`]: num }), {})
51
- }
52
- } : { $inc: { [`${prefix}${this.modelName}`]: num } };
53
- await this.db.collection("summaries").updateOne({ status: "active" }, update);
47
+ preSaveListenerSet: /* @__PURE__ */ new Set(),
48
+ postSaveListenerSet: /* @__PURE__ */ new Set(),
49
+ preCreateListenerSet: /* @__PURE__ */ new Set(),
50
+ postCreateListenerSet: /* @__PURE__ */ new Set(),
51
+ preUpdateListenerSet: /* @__PURE__ */ new Set(),
52
+ postUpdateListenerSet: /* @__PURE__ */ new Set(),
53
+ preRemoveListenerSet: /* @__PURE__ */ new Set(),
54
+ postRemoveListenerSet: /* @__PURE__ */ new Set(),
55
+ listenPre: function(type, listener) {
56
+ if (type === "save") {
57
+ this.preSaveListenerSet.add(listener);
58
+ return () => {
59
+ this.preSaveListenerSet.delete(listener);
60
+ };
61
+ } else if (type === "create") {
62
+ this.preCreateListenerSet.add(listener);
63
+ return () => {
64
+ this.preCreateListenerSet.delete(listener);
65
+ };
66
+ } else if (type === "update") {
67
+ this.preUpdateListenerSet.add(listener);
68
+ return () => {
69
+ this.preUpdateListenerSet.delete(listener);
70
+ };
71
+ } else {
72
+ this.preRemoveListenerSet.add(listener);
73
+ return () => {
74
+ this.preRemoveListenerSet.delete(listener);
75
+ };
76
+ }
54
77
  },
55
- moveSummary: async function(prev, next, num = 1) {
56
- await this.db.collection("summaries").updateOne(
57
- { status: "active" },
58
- {
59
- $inc: {
60
- [`${prev}${this.modelName}`]: -num,
61
- [`${next}${this.modelName}`]: num
62
- }
63
- }
64
- );
65
- },
66
- subSummary: async function(prefix = "total", num = 1) {
67
- const update = Array.isArray(prefix) ? {
68
- $inc: {
69
- ...prefix.reduce((acc, cur) => ({ ...acc, [`${cur}${this.modelName}`]: -num }), {})
70
- }
71
- } : { $inc: { [`${prefix}${this.modelName}`]: -num } };
72
- await this.db.collection("summaries").updateOne({ status: "active" }, update);
78
+ listenPost: function(type, listener) {
79
+ if (type === "save") {
80
+ this.postSaveListenerSet.add(listener);
81
+ return () => {
82
+ this.postSaveListenerSet.delete(listener);
83
+ };
84
+ } else if (type === "create") {
85
+ this.postCreateListenerSet.add(listener);
86
+ return () => {
87
+ this.postCreateListenerSet.delete(listener);
88
+ };
89
+ } else if (type === "update") {
90
+ this.postUpdateListenerSet.add(listener);
91
+ return () => {
92
+ this.postUpdateListenerSet.delete(listener);
93
+ };
94
+ } else {
95
+ this.postRemoveListenerSet.add(listener);
96
+ return () => {
97
+ this.postSaveListenerSet.delete(listener);
98
+ };
99
+ }
73
100
  }
74
101
  }
75
102
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@akanjs/document",
3
- "version": "0.9.42",
3
+ "version": "0.9.44",
4
4
  "sourceType": "module",
5
5
  "publishConfig": {
6
6
  "access": "public"
package/src/database.d.ts CHANGED
@@ -1,11 +1,11 @@
1
- import { type Dayjs } from "@akanjs/base";
1
+ import type { Dayjs, GetActionObject, MergedValues, PromiseOrObject } from "@akanjs/base";
2
2
  import { Logger } from "@akanjs/common";
3
- import { type DocumentModel, type FilterType, type FindQueryOption, type GetActionObject, type ListQueryOption, type QueryOf, type SortOf } from "@akanjs/constant";
3
+ import { type DocumentModel, type FilterType, type FindQueryOption, type ListQueryOption, type QueryOf, type SortOf } from "@akanjs/constant";
4
4
  import type DataLoader from "dataloader";
5
5
  import type { Filter, MeiliSearch } from "meilisearch";
6
6
  import type { HydratedDocument } from "mongoose";
7
7
  import type { RedisClientType } from "redis";
8
- import type { BaseMiddleware, Database, Mdl } from "./dbDecorators";
8
+ import type { BaseMiddleware, CRUDEventType, Database, Mdl, SaveEventType } from "./dbDecorators";
9
9
  import type { DataInputOf } from "./types";
10
10
  interface RedisSetOptions {
11
11
  expireAt?: Dayjs;
@@ -41,25 +41,53 @@ declare class SearchDatabase<T = any> {
41
41
  sort?: string | null;
42
42
  }): Promise<number>;
43
43
  }
44
- export type DatabaseModel<T extends string, Input, Doc, Obj, Insight, Filter, Summary = any> = DatabaseModelWithQuerySort<T, Input, Doc, Obj, Insight, GetActionObject<Filter>, SortOf<Filter>, Summary>;
45
- type DatabaseModelWithQuerySort<T extends string, Input, Doc, Obj, Insight, Query, Sort, Summary = any> = {
44
+ type QueryMethodOfKey<CapitalizedK extends string, Doc, Insight, _Args extends any[], _ListArgs extends any[], _FindArgs extends any[]> = {
45
+ [K in `list${CapitalizedK}`]: (...args: _ListArgs) => Promise<Doc[]>;
46
+ } & {
47
+ [K in `listIds${CapitalizedK}`]: (...args: _ListArgs) => Promise<string[]>;
48
+ } & {
49
+ [K in `find${CapitalizedK}`]: (...args: _FindArgs) => Promise<Doc | null>;
50
+ } & {
51
+ [K in `findId${CapitalizedK}`]: (...args: _FindArgs) => Promise<string | null>;
52
+ } & {
53
+ [K in `pick${CapitalizedK}`]: (...args: _FindArgs) => Promise<Doc>;
54
+ } & {
55
+ [K in `pickId${CapitalizedK}`]: (...args: _FindArgs) => Promise<string>;
56
+ } & {
57
+ [K in `exists${CapitalizedK}`]: (...args: _Args) => Promise<string | null>;
58
+ } & {
59
+ [K in `count${CapitalizedK}`]: (...args: _Args) => Promise<number>;
60
+ } & {
61
+ [K in `insight${CapitalizedK}`]: (...args: _Args) => Promise<Insight>;
62
+ };
63
+ export type QueryMethodPart<Query, Sort, Obj, Doc, Insight, _FindQueryOption = FindQueryOption<Sort, Obj>, _ListQueryOption = ListQueryOption<Sort, Obj>> = MergedValues<{
64
+ [K in keyof Query]: K extends string ? Query[K] extends (...args: infer Args) => any ? QueryMethodOfKey<Capitalize<K>, Doc, Insight, Args, [
65
+ ...Args,
66
+ queryOption?: _ListQueryOption
67
+ ], [
68
+ ...Args,
69
+ queryOption?: _FindQueryOption
70
+ ]> : never : never;
71
+ }>;
72
+ type DatabaseModelWithQuerySort<T extends string, Input, Doc, Obj, Insight, Query, Sort, _CapitalizedT extends string = Capitalize<T>, _QueryOfDoc = QueryOf<Doc>, _DataInput = DataInputOf<Input, DocumentModel<Obj>>, _FindQueryOption = FindQueryOption<Sort, Obj>, _ListQueryOption = ListQueryOption<Sort, Obj>> = {
46
73
  logger: Logger;
47
74
  __model: Mdl<Doc, Obj>;
48
75
  __cache: CacheDatabase<T>;
49
76
  __search: SearchDatabase<T>;
50
77
  __loader: DataLoader<string, Doc, string>;
51
- __list(query?: QueryOf<Doc>, queryOption?: ListQueryOption<Sort, Obj>): Promise<Doc[]>;
52
- __listIds(query?: QueryOf<Doc>, queryOption?: ListQueryOption<Sort, Obj>): Promise<string[]>;
53
- __find(query?: QueryOf<Doc>, queryOption?: FindQueryOption<Sort, Obj>): Promise<Doc | null>;
54
- __findId(query?: QueryOf<Doc>, queryOption?: FindQueryOption<Sort, Obj>): Promise<string | null>;
55
- __pick(query?: QueryOf<Doc>, queryOption?: FindQueryOption<Sort, Obj>): Promise<Doc>;
56
- __pickId(query?: QueryOf<Doc>, queryOption?: FindQueryOption<Sort, Obj>): Promise<string>;
57
- __exists(query?: QueryOf<Doc>): Promise<string | null>;
58
- __count(query?: QueryOf<Doc>): Promise<number>;
59
- __insight(query?: QueryOf<Doc>): Promise<Insight>;
60
- getDefaultSummary(addQuery?: QueryOf<Doc>): Promise<Summary>;
61
- } & {
62
- [key in Capitalize<T>]: Mdl<Doc, Obj>;
78
+ __list(query: _QueryOfDoc, queryOption?: _ListQueryOption): Promise<Doc[]>;
79
+ __listIds(query: _QueryOfDoc, queryOption?: _ListQueryOption): Promise<string[]>;
80
+ __find(query: _QueryOfDoc, queryOption?: _FindQueryOption): Promise<Doc | null>;
81
+ __findId(query: _QueryOfDoc, queryOption?: _FindQueryOption): Promise<string | null>;
82
+ __pick(query: _QueryOfDoc, queryOption?: _FindQueryOption): Promise<Doc>;
83
+ __pickId(query: _QueryOfDoc, queryOption?: _FindQueryOption): Promise<string>;
84
+ __exists(query: _QueryOfDoc): Promise<string | null>;
85
+ __count(query: _QueryOfDoc): Promise<number>;
86
+ __insight(query: _QueryOfDoc): Promise<Insight>;
87
+ listenPre: (type: SaveEventType, listener: (doc: Doc, type: CRUDEventType) => PromiseOrObject<void>) => () => void;
88
+ listenPost: (type: SaveEventType, listener: (doc: Doc, type: CRUDEventType) => PromiseOrObject<void>) => () => void;
89
+ } & {
90
+ [key in _CapitalizedT]: Mdl<Doc, Obj>;
63
91
  } & {
64
92
  [key in `${T}Loader`]: DataLoader<string, Doc, string>;
65
93
  } & {
@@ -67,44 +95,27 @@ type DatabaseModelWithQuerySort<T extends string, Input, Doc, Obj, Insight, Quer
67
95
  } & {
68
96
  [key in `${T}Search`]: SearchDatabase<T>;
69
97
  } & {
70
- [K in `get${Capitalize<T>}`]: (id: string) => Promise<Doc>;
98
+ [K in `get${_CapitalizedT}`]: (id: string) => Promise<Doc>;
71
99
  } & {
72
- [K in `load${Capitalize<T>}`]: (id?: string) => Promise<Doc | null>;
100
+ [K in `load${_CapitalizedT}`]: (id?: string) => Promise<Doc | null>;
73
101
  } & {
74
- [K in `load${Capitalize<T>}Many`]: (ids: string) => Promise<Doc[]>;
102
+ [K in `load${_CapitalizedT}Many`]: (ids: string[]) => Promise<Doc[]>;
75
103
  } & {
76
- [K in `create${Capitalize<T>}`]: (data: DataInputOf<Input, DocumentModel<Obj>>) => Promise<Doc>;
104
+ [K in `create${_CapitalizedT}`]: (data: _DataInput) => Promise<Doc>;
77
105
  } & {
78
- [K in `update${Capitalize<T>}`]: (id: string, data: DataInputOf<Input, DocumentModel<Obj>>) => Promise<Doc>;
106
+ [K in `update${_CapitalizedT}`]: (id: string, data: _DataInput) => Promise<Doc>;
79
107
  } & {
80
- [K in `remove${Capitalize<T>}`]: (id: string) => Promise<Doc>;
108
+ [K in `remove${_CapitalizedT}`]: (id: string) => Promise<Doc>;
81
109
  } & {
82
- [K in `search${Capitalize<T>}`]: (searchText: string, queryOption?: ListQueryOption<Sort, Obj>) => Promise<{
110
+ [K in `search${_CapitalizedT}`]: (searchText: string, queryOption?: _ListQueryOption) => Promise<{
83
111
  docs: Doc[];
84
112
  count: number;
85
113
  }>;
86
114
  } & {
87
- [K in `searchDocs${Capitalize<T>}`]: (searchText: string, queryOption?: ListQueryOption<Sort, Obj>) => Promise<Doc[]>;
88
- } & {
89
- [K in `searchCount${Capitalize<T>}`]: (searchText: string) => Promise<number>;
115
+ [K in `searchDocs${_CapitalizedT}`]: (searchText: string, queryOption?: _ListQueryOption) => Promise<Doc[]>;
90
116
  } & {
91
- [K in keyof Query as K extends string ? `list${Capitalize<K>}` : never]: Query[K] extends (...args: infer Args) => any ? (...args: [...Args, queryOption?: ListQueryOption<Sort, Obj>]) => Promise<Doc[]> : never;
92
- } & {
93
- [K in keyof Query as K extends string ? `listIds${Capitalize<K>}` : never]: Query[K] extends (...args: infer Args) => any ? (...args: [...Args, queryOption?: ListQueryOption<Sort, Obj>]) => Promise<string[]> : never;
94
- } & {
95
- [K in keyof Query as K extends string ? `find${Capitalize<K>}` : never]: Query[K] extends (...args: infer Args) => any ? (...args: [...Args, queryOption?: FindQueryOption<Sort, Obj>]) => Promise<Doc | null> : never;
96
- } & {
97
- [K in keyof Query as K extends string ? `findId${Capitalize<K>}` : never]: Query[K] extends (...args: infer Args) => any ? (...args: [...Args, queryOption?: FindQueryOption<Sort, Obj>]) => Promise<string | null> : never;
98
- } & {
99
- [K in keyof Query as K extends string ? `pick${Capitalize<K>}` : never]: Query[K] extends (...args: infer Args) => any ? (...args: [...Args, queryOption?: FindQueryOption<Sort, Obj>]) => Promise<Doc> : never;
100
- } & {
101
- [K in keyof Query as K extends string ? `pickId${Capitalize<K>}` : never]: Query[K] extends (...args: infer Args) => any ? (...args: [...Args, queryOption?: FindQueryOption<Sort, Obj>]) => Promise<string> : never;
102
- } & {
103
- [K in keyof Query as K extends string ? `exists${Capitalize<K>}` : never]: Query[K] extends (...args: infer Args) => any ? (...args: [...Args]) => Promise<string | null> : never;
104
- } & {
105
- [K in keyof Query as K extends string ? `count${Capitalize<K>}` : never]: Query[K] extends (...args: infer Args) => any ? (...args: [...Args]) => Promise<number> : never;
106
- } & {
107
- [K in keyof Query as K extends string ? `insight${Capitalize<K>}` : never]: Query[K] extends (...args: infer Args) => any ? (...args: [...Args]) => Promise<Insight> : never;
108
- };
109
- 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, Summary>(database: Database<T, Input, Doc, Model, Middleware, Insight, Obj, Filter, Summary>, model: Mdl<any, any>, redis: RedisClientType, meili: MeiliSearch) => DatabaseModel<T, Input, Doc, Model, Insight, Filter, Summary>;
117
+ [K in `searchCount${_CapitalizedT}`]: (searchText: string) => Promise<number>;
118
+ } & QueryMethodPart<Query, Sort, Obj, Doc, Insight, _FindQueryOption, _ListQueryOption>;
119
+ 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>;
120
+ 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>;
110
121
  export {};
@@ -1,4 +1,4 @@
1
- import { BaseObject, Type } from "@akanjs/base";
1
+ import { BaseObject, type MergeAllActionTypes, PromiseOrObject, Type } from "@akanjs/base";
2
2
  import { type ConstantModel, type DocumentModel, type FilterType } from "@akanjs/constant";
3
3
  import type { FilterQuery, HydratedDocument, Model as MongooseModel, PipelineStage, ProjectionType, Schema } from "mongoose";
4
4
  import type { DatabaseModel } from "./database";
@@ -12,23 +12,32 @@ type HydratedDocumentWithId<TDocument> = Omit<HydratedDocument<TDocument, Defaul
12
12
  id: string;
13
13
  } & DefaultDocMtds<TDocument>;
14
14
  export type Doc<M> = HydratedDocumentWithId<DocumentModel<M>>;
15
- interface DefaultMdlStats<TDocument, TSchema> {
16
- pickOneAndWrite: (query: FilterQuery<TSchema>, rawData: Partial<TSchema>) => Promise<TDocument>;
17
- pickAndWrite: (docId: string, rawData: Partial<TSchema>) => Promise<TDocument>;
18
- pickOne: (query: FilterQuery<TSchema>, projection?: ProjectionType<TSchema>) => Promise<TDocument>;
19
- pickById: (docId: string | undefined, projection?: ProjectionType<TSchema>) => Promise<TDocument>;
20
- addSummary: (prefix?: string | string[], num?: number) => Promise<void>;
21
- moveSummary: (prev: string, next: string, num?: number) => Promise<void>;
22
- subSummary: (prefix?: string | string[], num?: number) => Promise<void>;
23
- sample: (query: FilterQuery<TSchema>, size?: number, aggregations?: PipelineStage[]) => Promise<TDocument[]>;
24
- sampleOne: (query: FilterQuery<TSchema>, aggregations?: PipelineStage[]) => Promise<TDocument | null>;
15
+ export type CRUDEventType = "create" | "update" | "remove";
16
+ export type SaveEventType = "save" | CRUDEventType;
17
+ interface DefaultMdlStats<TDocument, TSchema, _Partial extends Partial<TSchema> = Partial<TSchema>, _FilterQuery extends FilterQuery<TSchema> = FilterQuery<TSchema>, _Projection extends ProjectionType<TSchema> = ProjectionType<TSchema>> {
18
+ pickOneAndWrite: (query: _FilterQuery, rawData: _Partial) => Promise<TDocument>;
19
+ pickAndWrite: (docId: string, rawData: _Partial) => Promise<TDocument>;
20
+ pickOne: (query: _FilterQuery, projection?: _Projection) => Promise<TDocument>;
21
+ pickById: (docId: string | undefined, projection?: _Projection) => Promise<TDocument>;
22
+ sample: (query: _FilterQuery, size?: number, aggregations?: PipelineStage[]) => Promise<TDocument[]>;
23
+ sampleOne: (query: _FilterQuery, aggregations?: PipelineStage[]) => Promise<TDocument | null>;
24
+ preSaveListenerSet: Set<(doc: TDocument, type: CRUDEventType) => PromiseOrObject<void>>;
25
+ postSaveListenerSet: Set<(doc: TDocument, type: CRUDEventType) => PromiseOrObject<void>>;
26
+ preCreateListenerSet: Set<(doc: TDocument, type: CRUDEventType) => PromiseOrObject<void>>;
27
+ postCreateListenerSet: Set<(doc: TDocument, type: CRUDEventType) => PromiseOrObject<void>>;
28
+ preUpdateListenerSet: Set<(doc: TDocument, type: CRUDEventType) => PromiseOrObject<void>>;
29
+ postUpdateListenerSet: Set<(doc: TDocument, type: CRUDEventType) => PromiseOrObject<void>>;
30
+ preRemoveListenerSet: Set<(doc: TDocument, type: CRUDEventType) => PromiseOrObject<void>>;
31
+ postRemoveListenerSet: Set<(doc: TDocument, type: CRUDEventType) => PromiseOrObject<void>>;
32
+ listenPre: (eventType: SaveEventType, listener: (doc: TDocument, type: CRUDEventType) => PromiseOrObject<void>) => () => void;
33
+ listenPost: (eventType: SaveEventType, listener: (doc: TDocument, type: CRUDEventType) => PromiseOrObject<void>) => () => void;
25
34
  }
26
35
  export type Mdl<Doc extends HydratedDocument<any>, Raw> = MongooseModel<Raw, unknown, unknown, unknown, Doc> & DefaultMdlStats<Doc, DocumentModel<Raw>>;
27
36
  export type SchemaOf<Mdl, Doc> = Schema<null, Mdl, Doc, undefined, null, Mdl>;
28
37
  export interface BaseMiddleware {
29
38
  onSchema: (schema: SchemaOf<any, any>) => void;
30
39
  }
31
- export interface Database<T extends string, Input, Doc extends HydratedDocument<any>, Model, Middleware extends BaseMiddleware, Obj, Insight, Filter extends FilterType, Summary> {
40
+ export interface Database<T extends string, Input, Doc extends HydratedDocument<any>, Model, Middleware extends BaseMiddleware, Obj, Insight, Filter extends FilterType> {
32
41
  refName: T;
33
42
  Input: Type<Input>;
34
43
  Doc: Type<Doc>;
@@ -37,9 +46,8 @@ export interface Database<T extends string, Input, Doc extends HydratedDocument<
37
46
  Obj: Type<Obj>;
38
47
  Insight: Type<Insight>;
39
48
  Filter: Type<Filter>;
40
- Summary?: Type<Summary>;
41
49
  }
42
- 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, Summary>(refName: T, Input: Type<Input>, Doc: Type<Doc>, Model: Type<Model>, Middleware: Type<Middleware>, Obj: Type<Obj>, Insight: Type<Insight>, Filter: Type<Filter>, Summary?: Type<Summary>) => Database<T, Input, Doc, Model, Middleware, Obj, Insight, Filter, Summary>;
50
+ 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>;
43
51
  export declare class InputDatabaseStorage {
44
52
  }
45
53
  export declare class DocumentDatabaseStorage {
@@ -55,11 +63,8 @@ export declare const Database: {
55
63
  Model: (returns: () => Type) => (target: any) => void;
56
64
  Middleware: (returns: () => Type) => (target: any) => void;
57
65
  };
58
- export declare const into: <Doc, T extends string, Input, Full, Light, Insight, Summary, Filter extends FilterType>(docRef: Type<Doc>, cnst: ConstantModel<T, Input, Full, Light, Insight, Filter, Summary>) => Type<DatabaseModel<T, DocumentModel<Input>, Doc, Full, Insight, Filter, Summary>>;
59
- export declare const inside: <Doc, T extends string, Input, Full, Light, Insight, Filter extends FilterType, Summary>(modelRef: Type, cnst: ConstantModel<T, Input, Full, Light, Insight, Filter, Summary>) => Type<DatabaseModel<T, DocumentModel<Input>, Doc, Full, Insight, Filter, Summary>>;
60
- export declare const by: <Model, AddModel>(modelRef: Type<Model>, addRef?: Type<AddModel>) => AddModel extends {
61
- [key: string]: any;
62
- } ? Type<Model & (AddModel extends BaseObject ? Doc<AddModel> : DocumentModel<AddModel>)> : Type<Model extends BaseObject ? Doc<Model> : DocumentModel<Model>>;
66
+ export declare const into: <Doc, T extends string, Input, Full, Light, Insight, Filter extends FilterType, _CapitalizedT extends string, _Default, _DefaultInput, _DefaultState, _DefaultStateInput, _Doc, _DocInput, _QueryOfDoc, _Query, _Sort, AddDbModels extends Type[], _DatabaseModel = DatabaseModel<T, _DocInput, Doc, Full, Insight, Filter, _CapitalizedT, _QueryOfDoc, _Query, _Sort>>(docRef: Type<Doc>, cnst: ConstantModel<T, Input, Full, Light, Insight, Filter, _CapitalizedT, _Default, _DefaultInput, _DefaultState, _DefaultStateInput, _Doc, _DocInput, _QueryOfDoc, _Query, _Sort>, ...addMdls: AddDbModels) => Type<MergeAllActionTypes<AddDbModels, keyof _DatabaseModel & string> & _DatabaseModel>;
67
+ 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>;
63
68
  export declare const beyond: <DbModel, Doc>(model: Type<DbModel>, doc: Type<Doc>) => {
64
69
  new (): {
65
70
  onSchema(schema: SchemaOf<DbModel, Doc>): void;
package/src/schema.d.ts CHANGED
@@ -1,4 +1,6 @@
1
+ import { PromiseOrObject } from "@akanjs/base";
1
2
  import { FilterQuery, PipelineStage, type ProjectionType } from "mongoose";
3
+ import { CRUDEventType, SaveEventType } from "./dbDecorators";
2
4
  export declare const getDefaultSchemaOptions: <TSchema, TDocument>() => {
3
5
  toJSON: {
4
6
  getters: boolean;
@@ -19,9 +21,16 @@ export declare const getDefaultSchemaOptions: <TSchema, TDocument>() => {
19
21
  pickById: (docId: string | undefined, projection?: ProjectionType<TSchema>) => Promise<TDocument>;
20
22
  sample: (query: FilterQuery<TSchema>, size?: number, aggregations?: PipelineStage[]) => Promise<TDocument[]>;
21
23
  sampleOne: (query: FilterQuery<TSchema>, aggregations?: PipelineStage[]) => Promise<TDocument | null>;
22
- addSummary: (prefix?: string, num?: number) => Promise<void>;
23
- moveSummary: (prev: string, next: string, num?: number) => Promise<void>;
24
- subSummary: (prefix?: string, num?: number) => Promise<void>;
24
+ preSaveListenerSet: Set<(doc: TDocument, type: CRUDEventType) => PromiseOrObject<void>>;
25
+ postSaveListenerSet: Set<(doc: TDocument, type: CRUDEventType) => PromiseOrObject<void>>;
26
+ preCreateListenerSet: Set<(doc: TDocument, type: CRUDEventType) => PromiseOrObject<void>>;
27
+ postCreateListenerSet: Set<(doc: TDocument, type: CRUDEventType) => PromiseOrObject<void>>;
28
+ preUpdateListenerSet: Set<(doc: TDocument, type: CRUDEventType) => PromiseOrObject<void>>;
29
+ postUpdateListenerSet: Set<(doc: TDocument, type: CRUDEventType) => PromiseOrObject<void>>;
30
+ preRemoveListenerSet: Set<(doc: TDocument, type: CRUDEventType) => PromiseOrObject<void>>;
31
+ postRemoveListenerSet: Set<(doc: TDocument, type: CRUDEventType) => PromiseOrObject<void>>;
32
+ listenPre: (type: SaveEventType, listener: (doc: TDocument, type: CRUDEventType) => PromiseOrObject<void>) => () => void;
33
+ listenPost: (type: SaveEventType, listener: (doc: TDocument, type: CRUDEventType) => PromiseOrObject<void>) => () => void;
25
34
  };
26
35
  };
27
36
  export declare const convertAggregateMatch: (query: any) => {
package/src/types.d.ts CHANGED
@@ -1,5 +1,6 @@
1
+ import type { GetStateObject } from "@akanjs/base";
2
+ import type { Document } from "mongoose";
1
3
  export type DataInputOf<Input, Obj> = {
2
- [K in keyof Input as Input[K] extends any[] ? never : K]: Input[K];
3
- } & {
4
- [K in keyof Input as Input[K] extends any[] ? K : never]?: Input[K];
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
+ export type GetDocObject<D> = GetStateObject<Omit<D, Exclude<keyof Document, "id"> | "__v">>;