@akanjs/document 0.0.28 → 0.0.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@akanjs/document",
3
- "version": "0.0.28",
3
+ "version": "0.0.29",
4
4
  "type": "commonjs",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -10,5 +10,54 @@
10
10
  "url": "https://github.com/akan-team/akanjs.git",
11
11
  "directory": "pkgs/@akanjs/document"
12
12
  },
13
+ "dependencies": {
14
+ "@apollo/server": "^4.11.2",
15
+ "@inquirer/prompts": "^7.2.1",
16
+ "@nestjs/apollo": "^12.2.2",
17
+ "@nestjs/common": "^10.4.15",
18
+ "@nestjs/core": "^10.4.15",
19
+ "@nestjs/graphql": "^12.2.2",
20
+ "@nestjs/mongoose": "^10.1.0",
21
+ "@nestjs/passport": "^10.0.3",
22
+ "@nestjs/platform-express": "^10.4.15",
23
+ "@nestjs/platform-socket.io": "^10.4.15",
24
+ "@nestjs/schedule": "^4.1.2",
25
+ "@nestjs/websockets": "^10.4.15",
26
+ "@socket.io/redis-adapter": "^8.3.0",
27
+ "@urql/core": "^5.1.0",
28
+ "apple-signin": "^1.0.9",
29
+ "bull": "^4.16.5",
30
+ "class-transformer": "^0.5.1",
31
+ "class-validator": "^0.14.1",
32
+ "dataloader": "^2.2.3",
33
+ "dayjs": "^1.11.13",
34
+ "express": "^4.21.2",
35
+ "graphql": "^16.10.0",
36
+ "iap": "^1.1.1",
37
+ "immer": "^10.1.1",
38
+ "jsonwebtoken": "^9.0.2",
39
+ "lodash": "^4.17.21",
40
+ "meilisearch": "^0.47.0",
41
+ "mongoose": "^8.9.3",
42
+ "next": "^15.3.0",
43
+ "passport": "^0.7.0",
44
+ "passport-apple": "^2.0.2",
45
+ "passport-facebook": "^3.0.0",
46
+ "passport-github": "^1.1.0",
47
+ "passport-google-oauth20": "^2.0.0",
48
+ "passport-kakao": "^1.0.1",
49
+ "passport-naver": "^1.0.6",
50
+ "picocolors": "^1.1.1",
51
+ "pluralize": "^8.0.0",
52
+ "react": "^18.3.1",
53
+ "react-dom": "^18.3.1",
54
+ "redis": "^4.7.0",
55
+ "reflect-metadata": "^0.2.2",
56
+ "rxjs": "^7.8.1",
57
+ "socket.io": "^4.8.1",
58
+ "socket.io-client": "^4.8.1",
59
+ "tunnel-ssh": "^5.2.0",
60
+ "ua-parser-js": "^1.0.40"
61
+ },
13
62
  "main": "./index.js"
14
63
  }
@@ -0,0 +1,26 @@
1
+ import type { Type } from "@akanjs/base";
2
+ import DataLoader from "dataloader";
3
+ import type { FilterQuery, Model } from "mongoose";
4
+ import { Schema, Types } from "mongoose";
5
+ export declare const Id: typeof Types.ObjectId;
6
+ export declare const ObjectId: typeof Schema.Types.ObjectId;
7
+ export declare const Mixed: typeof Schema.Types.Mixed;
8
+ export { DataLoader };
9
+ export declare const createLoader: <Key, Value>(model: Model<any>, fieldName?: string, defaultQuery?: FilterQuery<unknown>) => DataLoader<Key, Value, Key>;
10
+ export declare const createArrayLoader: <K, V>(model: Model<unknown, unknown, unknown, unknown>, fieldName?: string, defaultQuery?: FilterQuery<unknown>) => DataLoader<K, V, K>;
11
+ export declare const createArrayElementLoader: <K, V>(model: Model<unknown>, fieldName?: string, defaultQuery?: FilterQuery<unknown>) => DataLoader<K, V, K>;
12
+ export declare const createQueryLoader: <Key, Value>(model: Model<any>, queryKeys: string[], defaultQuery?: FilterQuery<unknown>) => DataLoader<Key, Value, Key>;
13
+ export interface LoaderMeta {
14
+ key: string;
15
+ type: "Field" | "ArrayField" | "Query";
16
+ fieldName?: string;
17
+ queryKeys?: string[];
18
+ defaultQuery: FilterQuery<unknown>;
19
+ }
20
+ export declare const getLoaderMetas: (target: Type) => LoaderMeta[];
21
+ export type Loader<Field, Value> = DataLoader<Field, Value | null>;
22
+ export declare const Loader: {
23
+ ByField: (fieldName: string, defaultQuery?: FilterQuery<unknown>) => (target: object, key: string) => void;
24
+ ByArrayField: (fieldName: string, defaultQuery?: FilterQuery<unknown>) => (target: object, key: string) => void;
25
+ ByQuery: (queryKeys: string[], defaultQuery?: FilterQuery<unknown>) => (target: object, key: string) => void;
26
+ };
@@ -0,0 +1,152 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
+ // If the importer is in node compatibility mode or this is not an ESM
21
+ // file that has been converted to a CommonJS file using a Babel-
22
+ // compatible transform (i.e. "__esModule" has not been set), then set
23
+ // "default" to the CommonJS "module.exports" for node compatibility.
24
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
+ mod
26
+ ));
27
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
+ var dataLoader_exports = {};
29
+ __export(dataLoader_exports, {
30
+ DataLoader: () => import_dataloader.default,
31
+ Id: () => Id,
32
+ Loader: () => Loader,
33
+ Mixed: () => Mixed,
34
+ ObjectId: () => ObjectId,
35
+ createArrayElementLoader: () => createArrayElementLoader,
36
+ createArrayLoader: () => createArrayLoader,
37
+ createLoader: () => createLoader,
38
+ createQueryLoader: () => createQueryLoader,
39
+ getLoaderMetas: () => getLoaderMetas
40
+ });
41
+ module.exports = __toCommonJS(dataLoader_exports);
42
+ var import_dataloader = __toESM(require("dataloader"));
43
+ var import_lodash = require("lodash");
44
+ var import_mongoose = require("mongoose");
45
+ const Id = import_mongoose.Types.ObjectId;
46
+ const ObjectId = import_mongoose.Schema.Types.ObjectId;
47
+ const Mixed = import_mongoose.Schema.Types.Mixed;
48
+ const createLoader = (model, fieldName = "_id", defaultQuery = {}) => {
49
+ return new import_dataloader.default(
50
+ (fields) => {
51
+ const query = { ...defaultQuery };
52
+ query[fieldName] = { $in: fields };
53
+ const data = model.find(query).then((list) => {
54
+ const listByKey = (0, import_lodash.keyBy)(list, fieldName);
55
+ return fields.map((id) => (0, import_lodash.get)(listByKey, id, null));
56
+ });
57
+ return data;
58
+ },
59
+ { name: "dataloader", cache: false }
60
+ );
61
+ };
62
+ const createArrayLoader = (model, fieldName = "_id", defaultQuery = {}) => {
63
+ return new import_dataloader.default((fields) => {
64
+ const query = { ...defaultQuery };
65
+ query[fieldName] = { $in: fields };
66
+ const data = model.find(query).then((list) => {
67
+ return fields.map((field) => list.filter((item) => field === item[fieldName]));
68
+ });
69
+ return data;
70
+ });
71
+ };
72
+ const createArrayElementLoader = (model, fieldName = "_id", defaultQuery = {}) => {
73
+ return new import_dataloader.default(
74
+ (fields) => {
75
+ const query = { ...defaultQuery };
76
+ query[fieldName] = { $in: fields };
77
+ const data = model.find(query).then((list) => {
78
+ const flat = (0, import_lodash.flatMap)(
79
+ list,
80
+ (dat) => dat[fieldName].map((datField) => ({
81
+ ...dat.toObject(),
82
+ key: datField
83
+ }))
84
+ );
85
+ const listByKey = (0, import_lodash.groupBy)(flat, (dat) => dat.key);
86
+ return fields.map((id) => (0, import_lodash.get)(listByKey, id, null));
87
+ });
88
+ return data;
89
+ },
90
+ { name: "dataloader", cache: false }
91
+ );
92
+ };
93
+ const createQueryLoader = (model, queryKeys, defaultQuery = {}) => {
94
+ return new import_dataloader.default(
95
+ (queries) => {
96
+ const query = {
97
+ $and: [{ $or: queries }, defaultQuery]
98
+ };
99
+ const getQueryKey = (query2) => queryKeys.map((key) => query2[key].toString()).join("");
100
+ const data = model.find(query).then((list) => {
101
+ const listByKey = (0, import_lodash.keyBy)(list, getQueryKey);
102
+ return queries.map((query2) => (0, import_lodash.get)(listByKey, getQueryKey(query2), null));
103
+ });
104
+ return data;
105
+ },
106
+ { name: "dataloader", cache: false }
107
+ );
108
+ };
109
+ const getLoaderMetaMapByPrototype = (prototype) => {
110
+ const loaderMetaMap = Reflect.getOwnMetadata("loaders", prototype) ?? /* @__PURE__ */ new Map();
111
+ return loaderMetaMap;
112
+ };
113
+ const getLoaderMetas = (target) => {
114
+ const metas = [...getLoaderMetaMapByPrototype(target.prototype).values()];
115
+ return metas;
116
+ };
117
+ const Loader = {
118
+ ByField: (fieldName, defaultQuery = {}) => {
119
+ return function(target, key) {
120
+ const loaderMetaMap = getLoaderMetaMapByPrototype(target);
121
+ loaderMetaMap.set(key, { key, type: "Field", fieldName, defaultQuery });
122
+ Reflect.defineMetadata("loaders", loaderMetaMap, target);
123
+ };
124
+ },
125
+ ByArrayField: (fieldName, defaultQuery = {}) => {
126
+ return function(target, key) {
127
+ const loaderMetaMap = getLoaderMetaMapByPrototype(target);
128
+ loaderMetaMap.set(key, { key, type: "ArrayField", fieldName, defaultQuery });
129
+ Reflect.defineMetadata("loaders", loaderMetaMap, target);
130
+ };
131
+ },
132
+ ByQuery: (queryKeys, defaultQuery = {}) => {
133
+ return function(target, key) {
134
+ const loaderMetaMap = getLoaderMetaMapByPrototype(target);
135
+ loaderMetaMap.set(key, { key, type: "Query", queryKeys, defaultQuery });
136
+ Reflect.defineMetadata("loaders", loaderMetaMap, target);
137
+ };
138
+ }
139
+ };
140
+ // Annotate the CommonJS export names for ESM import in node:
141
+ 0 && (module.exports = {
142
+ DataLoader,
143
+ Id,
144
+ Loader,
145
+ Mixed,
146
+ ObjectId,
147
+ createArrayElementLoader,
148
+ createArrayLoader,
149
+ createLoader,
150
+ createQueryLoader,
151
+ getLoaderMetas
152
+ });
@@ -0,0 +1,110 @@
1
+ import { type Dayjs } from "@akanjs/base";
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";
4
+ import type DataLoader from "dataloader";
5
+ import type { Filter, MeiliSearch } from "meilisearch";
6
+ import type { HydratedDocument } from "mongoose";
7
+ import type { RedisClientType } from "redis";
8
+ import type { BaseMiddleware, Database, Mdl } from "./dbDecorators";
9
+ import type { DataInputOf } from "./types";
10
+ interface RedisSetOptions {
11
+ expireAt?: Dayjs;
12
+ }
13
+ declare class CacheDatabase<T = any> {
14
+ private readonly refName;
15
+ private readonly redis;
16
+ private logger;
17
+ constructor(refName: string, redis: RedisClientType);
18
+ set(topic: string, key: string, value: string | number | Buffer, option?: RedisSetOptions): Promise<void>;
19
+ get<T extends string | number | Buffer>(topic: string, key: string): Promise<T | undefined>;
20
+ delete(topic: string, key: string): Promise<void>;
21
+ }
22
+ declare class SearchDatabase<T = any> {
23
+ readonly refName: string;
24
+ readonly meili: MeiliSearch;
25
+ private logger;
26
+ private index;
27
+ constructor(refName: string, meili: MeiliSearch);
28
+ searchIds(searchText: string | undefined | null, option?: {
29
+ filter?: Filter;
30
+ skip?: number | null;
31
+ limit?: number | null;
32
+ sort?: string[] | null;
33
+ }): Promise<{
34
+ ids: string[];
35
+ total: number;
36
+ }>;
37
+ count(searchText: string | undefined | null, option?: {
38
+ filter?: Filter;
39
+ skip?: number | null;
40
+ limit?: number | null;
41
+ sort?: string | null;
42
+ }): Promise<number>;
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> = {
46
+ logger: Logger;
47
+ __model: Mdl<Doc, Obj>;
48
+ __cache: CacheDatabase<T>;
49
+ __search: SearchDatabase<T>;
50
+ __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>;
63
+ } & {
64
+ [key in `${T}Loader`]: DataLoader<string, Doc, string>;
65
+ } & {
66
+ [key in `${T}Cache`]: CacheDatabase<T>;
67
+ } & {
68
+ [key in `${T}Search`]: SearchDatabase<T>;
69
+ } & {
70
+ [K in `get${Capitalize<T>}`]: (id: string) => Promise<Doc>;
71
+ } & {
72
+ [K in `load${Capitalize<T>}`]: (id?: string) => Promise<Doc | null>;
73
+ } & {
74
+ [K in `load${Capitalize<T>}Many`]: (ids: string) => Promise<Doc[]>;
75
+ } & {
76
+ [K in `create${Capitalize<T>}`]: (data: DataInputOf<Input, DocumentModel<Obj>>) => Promise<Doc>;
77
+ } & {
78
+ [K in `update${Capitalize<T>}`]: (id: string, data: DataInputOf<Input, DocumentModel<Obj>>) => Promise<Doc>;
79
+ } & {
80
+ [K in `remove${Capitalize<T>}`]: (id: string) => Promise<Doc>;
81
+ } & {
82
+ [K in `search${Capitalize<T>}`]: (searchText: string, queryOption?: ListQueryOption<Sort, Obj>) => Promise<{
83
+ docs: Doc[];
84
+ count: number;
85
+ }>;
86
+ } & {
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>;
90
+ } & {
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>;
110
+ export {};
@@ -0,0 +1,312 @@
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 database_exports = {};
19
+ __export(database_exports, {
20
+ databaseModelOf: () => databaseModelOf
21
+ });
22
+ module.exports = __toCommonJS(database_exports);
23
+ var import_base = require("@akanjs/base");
24
+ var import_common = require("@akanjs/common");
25
+ var import_constant = require("@akanjs/constant");
26
+ var import_nest = require("@akanjs/nest");
27
+ var import_dataLoader = require("./dataLoader");
28
+ var import_schema = require("./schema");
29
+ class CacheDatabase {
30
+ constructor(refName, redis) {
31
+ this.refName = refName;
32
+ this.redis = redis;
33
+ this.logger = new import_common.Logger(`${refName}Cache`);
34
+ }
35
+ logger;
36
+ async set(topic, key, value, option = {}) {
37
+ const setOption = { PXAT: option.expireAt?.toDate().getTime() };
38
+ await this.redis.set(`${this.refName}:${topic}:${key}`, value, setOption);
39
+ }
40
+ async get(topic, key) {
41
+ const value = await this.redis.get(`${this.refName}:${topic}:${key}`);
42
+ return value;
43
+ }
44
+ async delete(topic, key) {
45
+ await this.redis.del(`${this.refName}:${topic}:${key}`);
46
+ }
47
+ }
48
+ class SearchDatabase {
49
+ constructor(refName, meili) {
50
+ this.refName = refName;
51
+ this.meili = meili;
52
+ this.logger = new import_common.Logger(`${refName}Search`);
53
+ this.index = meili.index((0, import_common.lowerlize)(refName));
54
+ }
55
+ logger;
56
+ index;
57
+ async searchIds(searchText, option = {}) {
58
+ const { skip = 0, limit = import_constant.DEFAULT_PAGE_SIZE, sort } = option;
59
+ if (!searchText) {
60
+ const { results, total } = await this.index.getDocuments({ offset: skip ?? 0, limit: limit ?? 0 });
61
+ return { ids: results.map((result) => result.id), total };
62
+ }
63
+ const { hits, estimatedTotalHits } = await this.index.search(searchText, {
64
+ offset: skip ?? 0,
65
+ limit: limit ?? 0,
66
+ sort: sort ?? [],
67
+ filter: option.filter,
68
+ attributesToRetrieve: ["id"]
69
+ });
70
+ return { ids: hits.map((hit) => hit.id), total: estimatedTotalHits };
71
+ }
72
+ async count(searchText, option = {}) {
73
+ const { skip = 0, limit = import_constant.DEFAULT_PAGE_SIZE, sort = "" } = option;
74
+ if (!searchText) {
75
+ const { results, total } = await this.index.getDocuments({ offset: skip ?? 0, limit: limit ?? 0 });
76
+ return total;
77
+ }
78
+ const { hits, estimatedTotalHits } = await this.index.search(searchText, {
79
+ offset: skip ?? 0,
80
+ limit: limit ?? 0,
81
+ filter: option.filter,
82
+ attributesToRetrieve: ["id"]
83
+ });
84
+ return estimatedTotalHits;
85
+ }
86
+ }
87
+ class DatabaseModelStorage {
88
+ __ModelType__ = "DatabaseModelStorage";
89
+ }
90
+ const databaseModelOf = (database, model, redis, meili) => {
91
+ //! 잘되는지 확인 필요
92
+ const [modelName, className] = [database.refName, (0, import_common.capitalize)(database.refName)];
93
+ const insightFieldMetas = (0, import_constant.getFieldMetas)(database.Insight);
94
+ const accumulator = Object.fromEntries(insightFieldMetas.map((fieldMeta) => [fieldMeta.key, fieldMeta.accumulate]));
95
+ const defaultInsight = Object.fromEntries(insightFieldMetas.map((fieldMeta) => [fieldMeta.key, fieldMeta.default]));
96
+ const makeSafeQuery = (query) => ({ removedAt: { $exists: false }, ...query ?? {} });
97
+ const makeSafeMatchStage = (query) => ({
98
+ $match: { removedAt: { $exists: false }, ...(0, import_schema.convertAggregateMatch)(query) }
99
+ });
100
+ const getListQuery = (query, queryOption) => {
101
+ const find = makeSafeQuery(query);
102
+ const sort = (0, import_constant.getFilterSort)(database.Filter, queryOption?.sort ?? "latest");
103
+ const skip = queryOption?.skip ?? 0;
104
+ const limit = queryOption?.limit === null ? import_constant.DEFAULT_PAGE_SIZE : queryOption?.limit ?? 0;
105
+ const select = queryOption?.select;
106
+ const sample = queryOption?.sample;
107
+ return { find, sort, skip, limit, select, sample };
108
+ };
109
+ const getFindQuery = (query, queryOption) => {
110
+ const find = makeSafeQuery(query);
111
+ const sort = (0, import_constant.getFilterSort)(database.Filter, queryOption?.sort ?? "latest");
112
+ const skip = queryOption?.skip ?? 0;
113
+ const select = queryOption?.select;
114
+ const sample = queryOption?.sample ?? false;
115
+ return { find, sort, skip, select, sample };
116
+ };
117
+ const getSearchSort = (sortKey) => {
118
+ const sort = (0, import_constant.getFilterSort)(database.Filter, sortKey ?? "latest");
119
+ return Object.entries(sort).map(([key, value]) => `${key}:${value === 1 ? "asc" : "desc"}`);
120
+ };
121
+ const loader = (0, import_dataLoader.createLoader)(model);
122
+ const cacheDatabase = new CacheDatabase(database.refName, redis);
123
+ const searchDatabase = new SearchDatabase(database.refName, meili);
124
+ const DatabaseModel = Reflect.getMetadata(database.refName, DatabaseModelStorage.prototype) ?? class DatabaseModel {
125
+ logger = new import_common.Logger(`${modelName}Model`);
126
+ __model = model;
127
+ __cache = cacheDatabase;
128
+ __search = searchDatabase;
129
+ __loader = loader;
130
+ async __list(query, queryOption) {
131
+ const { find, sort, skip, limit, select, sample } = getListQuery(query, queryOption);
132
+ return sample ? await this.__model.sample(find, limit) : await this.__model.find(find, select).sort(sort).skip(skip).limit(limit);
133
+ }
134
+ async __listIds(query, queryOption) {
135
+ const { find, sort, skip, limit, sample } = getListQuery(query, queryOption);
136
+ return (sample ? await this.__model.sample(find, limit, [{ $project: { _id: 1 } }]) : await this.__model.find(find).sort(sort).skip(skip).limit(limit).select("_id")).map(({ _id }) => _id.toString());
137
+ }
138
+ async __find(query, queryOption) {
139
+ const { find, sort, skip, select, sample } = getFindQuery(query, queryOption);
140
+ const doc = sample ? await this.__model.sampleOne(find) : await this.__model.findOne(find, select).sort(sort).skip(skip);
141
+ if (!doc)
142
+ return null;
143
+ return doc;
144
+ }
145
+ async __findId(query, queryOption) {
146
+ const { find, sort, skip, sample } = getFindQuery(query, queryOption);
147
+ const doc = sample ? await this.__model.sampleOne(find, [{ $project: { _id: 1 } }]) : await this.__model.findOne(find).sort(sort).skip(skip).select("_id");
148
+ if (!doc)
149
+ return null;
150
+ return doc._id.toString();
151
+ }
152
+ async __pick(query, queryOption) {
153
+ const { find, sort, skip, select, sample } = getFindQuery(query, queryOption);
154
+ const doc = sample ? await this.__model.sampleOne(find) : await this.__model.findOne(find, select).sort(sort).skip(skip);
155
+ if (!doc)
156
+ throw new Error(`No Document (${database.refName}): ${JSON.stringify(query)}`);
157
+ return doc;
158
+ }
159
+ async __pickId(query, queryOption) {
160
+ const { find, sort, skip, sample } = getFindQuery(query, queryOption);
161
+ const doc = sample ? await this.__model.sampleOne(find, [{ $project: { _id: 1 } }]) : await this.__model.findOne(find).sort(sort).skip(skip).select("_id");
162
+ if (!doc)
163
+ throw new Error(`No Document (${database.refName}): ${JSON.stringify(query)}`);
164
+ return doc._id.toString();
165
+ }
166
+ async __exists(query) {
167
+ const find = makeSafeQuery(query);
168
+ const existingId = await this.__model.exists(find);
169
+ return existingId?.toString() ?? null;
170
+ }
171
+ async __count(query) {
172
+ const find = makeSafeQuery(query);
173
+ return await this.__model.countDocuments(find);
174
+ }
175
+ async __insight(query) {
176
+ if (!accumulator)
177
+ throw new Error(`No Insight (${database.refName})`);
178
+ const res = await this.__model.aggregate([
179
+ makeSafeMatchStage(query),
180
+ { $group: { _id: null, ...accumulator } }
181
+ ]);
182
+ const data = res[0];
183
+ return data ?? defaultInsight;
184
+ }
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;
197
+ }
198
+ async [`get${className}`](id) {
199
+ const doc = await this.__loader.load(id);
200
+ if (!doc)
201
+ throw new Error(`No Document (${database.refName}): ${id}`);
202
+ return doc;
203
+ }
204
+ async [`load${className}`](id) {
205
+ return id ? await this.__loader.load(id) : null;
206
+ }
207
+ async [`load${className}Many`](ids) {
208
+ return await this.__loader.loadMany(ids);
209
+ }
210
+ async [`create${className}`](data) {
211
+ return await new this.__model(data).save();
212
+ }
213
+ async [`update${className}`](id, data) {
214
+ const doc = await this.__model.pickById(id);
215
+ return await doc.set(data).save();
216
+ }
217
+ async [`remove${className}`](id) {
218
+ const doc = await this.__model.pickById(id);
219
+ return await doc.set({ removedAt: (0, import_base.dayjs)() }).save();
220
+ }
221
+ async [`search${className}`](searchText, queryOption = {}) {
222
+ const { skip, limit, sort } = queryOption;
223
+ const { ids, total } = await this.__search.searchIds(searchText, { skip, limit, sort: getSearchSort(sort) });
224
+ const docs = await this.__loader.loadMany(ids);
225
+ return { docs, count: total };
226
+ }
227
+ async [`searchDocs${className}`](searchText, queryOption = {}) {
228
+ const { skip, limit, sort } = queryOption;
229
+ const { ids } = await this.__search.searchIds(searchText, { skip, limit, sort: getSearchSort(sort) });
230
+ return await this.__loader.loadMany(ids);
231
+ }
232
+ async [`searchCount${className}`](searchText) {
233
+ return await this.__search.count(searchText);
234
+ }
235
+ };
236
+ DatabaseModel.prototype[className] = model;
237
+ DatabaseModel.prototype[`${modelName}Loader`] = loader;
238
+ DatabaseModel.prototype[`${modelName}Cache`] = cacheDatabase;
239
+ DatabaseModel.prototype[`${modelName}Search`] = searchDatabase;
240
+ const getQueryDataFromKey = (queryKey, args) => {
241
+ const lastArg = args.at(-1);
242
+ const hasQueryOption = lastArg && typeof lastArg === "object" && (typeof lastArg.select === "object" || typeof lastArg.skip === "number" || typeof lastArg.limit === "number" || typeof lastArg.sort === "string");
243
+ const queryFn = (0, import_constant.getFilterQuery)(database.Filter, queryKey);
244
+ const query = queryFn(...hasQueryOption ? args.slice(0, -1) : args);
245
+ const queryOption = hasQueryOption ? lastArg : {};
246
+ return { query, queryOption };
247
+ };
248
+ const filterKeyMetaMap = (0, import_constant.getFilterKeyMetaMapOnPrototype)(database.Filter.prototype);
249
+ const queryKeys = [...filterKeyMetaMap.keys()];
250
+ queryKeys.forEach((queryKey) => {
251
+ const queryFn = (0, import_constant.getFilterQuery)(database.Filter, queryKey);
252
+ DatabaseModel.prototype[`list${(0, import_common.capitalize)(queryKey)}`] = async function(...args) {
253
+ const { query, queryOption } = getQueryDataFromKey(queryKey, args);
254
+ return this.__list(query, queryOption);
255
+ };
256
+ DatabaseModel.prototype[`listIds${(0, import_common.capitalize)(queryKey)}`] = async function(...args) {
257
+ const { query, queryOption } = getQueryDataFromKey(queryKey, args);
258
+ return this.__listIds(query, queryOption);
259
+ };
260
+ DatabaseModel.prototype[`find${(0, import_common.capitalize)(queryKey)}`] = async function(...args) {
261
+ const { query, queryOption } = getQueryDataFromKey(queryKey, args);
262
+ return this.__find(query, queryOption);
263
+ };
264
+ DatabaseModel.prototype[`findId${(0, import_common.capitalize)(queryKey)}`] = async function(...args) {
265
+ const { query, queryOption } = getQueryDataFromKey(queryKey, args);
266
+ return this.__findId(query, queryOption);
267
+ };
268
+ DatabaseModel.prototype[`pick${(0, import_common.capitalize)(queryKey)}`] = async function(...args) {
269
+ const { query, queryOption } = getQueryDataFromKey(queryKey, args);
270
+ return this.__pick(query, queryOption);
271
+ };
272
+ DatabaseModel.prototype[`pickId${(0, import_common.capitalize)(queryKey)}`] = async function(...args) {
273
+ const { query, queryOption } = getQueryDataFromKey(queryKey, args);
274
+ return this.__pickId(query, queryOption);
275
+ };
276
+ DatabaseModel.prototype[`exists${(0, import_common.capitalize)(queryKey)}`] = async function(...args) {
277
+ const query = queryFn(...args);
278
+ return this.__exists(query);
279
+ };
280
+ DatabaseModel.prototype[`count${(0, import_common.capitalize)(queryKey)}`] = async function(...args) {
281
+ const query = queryFn(...args);
282
+ return this.__count(query);
283
+ };
284
+ DatabaseModel.prototype[`insight${(0, import_common.capitalize)(queryKey)}`] = async function(...args) {
285
+ const query = queryFn(...args);
286
+ return this.__insight(query);
287
+ };
288
+ });
289
+ const loaderMetas = (0, import_dataLoader.getLoaderMetas)(database.Model);
290
+ loaderMetas.forEach((loaderMeta) => {
291
+ const loader2 = loaderMeta.type === "Field" ? (0, import_dataLoader.createLoader)(model, loaderMeta.fieldName) : loaderMeta.type === "ArrayField" ? (0, import_dataLoader.createArrayLoader)(model, loaderMeta.fieldName) : loaderMeta.type === "Query" ? (0, import_dataLoader.createQueryLoader)(model, loaderMeta.queryKeys ?? []) : null;
292
+ DatabaseModel.prototype[loaderMeta.key] = loader2;
293
+ });
294
+ Object.getOwnPropertyNames(database.Model.prototype).forEach((key) => {
295
+ DatabaseModel.prototype[key] = database.Model.prototype[key];
296
+ });
297
+ const createDescriptor = Object.getOwnPropertyDescriptor(DatabaseModel.prototype, `create${className}`);
298
+ if (createDescriptor)
299
+ (0, import_nest.Transaction)()(DatabaseModel.prototype, `create${className}`, createDescriptor);
300
+ const updateDescriptor = Object.getOwnPropertyDescriptor(DatabaseModel.prototype, `update${className}`);
301
+ if (updateDescriptor)
302
+ (0, import_nest.Transaction)()(DatabaseModel.prototype, `update${className}`, updateDescriptor);
303
+ const removeDescriptor = Object.getOwnPropertyDescriptor(DatabaseModel.prototype, `remove${className}`);
304
+ if (removeDescriptor)
305
+ (0, import_nest.Transaction)()(DatabaseModel.prototype, `remove${className}`, removeDescriptor);
306
+ Reflect.defineMetadata(database.refName, DatabaseModel, DatabaseModelStorage.prototype);
307
+ return new DatabaseModel();
308
+ };
309
+ // Annotate the CommonJS export names for ESM import in node:
310
+ 0 && (module.exports = {
311
+ databaseModelOf
312
+ });
@@ -0,0 +1,67 @@
1
+ import { BaseObject, Type } from "@akanjs/base";
2
+ import { type ConstantModel, type DocumentModel, type FilterType } from "@akanjs/constant";
3
+ import type { FilterQuery, HydratedDocument, Model as MongooseModel, PipelineStage, ProjectionType, Schema } from "mongoose";
4
+ import type { DatabaseModel } from "./database";
5
+ export type { FilterQuery as QueryOf };
6
+ interface DefaultDocMtds<TDocument> {
7
+ refresh(): Promise<this>;
8
+ set(data: Partial<TDocument>): this;
9
+ save(): Promise<this>;
10
+ }
11
+ type HydratedDocumentWithId<TDocument> = Omit<HydratedDocument<TDocument, DefaultDocMtds<TDocument>>, "id" | "set" | "save"> & {
12
+ id: string;
13
+ } & DefaultDocMtds<TDocument>;
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>;
25
+ }
26
+ export type Mdl<Doc extends HydratedDocument<any>, Raw> = MongooseModel<Raw, unknown, unknown, unknown, Doc> & DefaultMdlStats<Doc, DocumentModel<Raw>>;
27
+ export type SchemaOf<Mdl, Doc> = Schema<null, Mdl, Doc, undefined, null, Mdl>;
28
+ export interface BaseMiddleware {
29
+ onSchema: (schema: SchemaOf<any, any>) => void;
30
+ }
31
+ export interface Database<T extends string, Input, Doc extends HydratedDocument<any>, Model, Middleware extends BaseMiddleware, Obj, Insight, Filter extends FilterType, Summary> {
32
+ refName: T;
33
+ Input: Type<Input>;
34
+ Doc: Type<Doc>;
35
+ Model: Type<Model>;
36
+ Middleware: Type<Middleware>;
37
+ Obj: Type<Obj>;
38
+ Insight: Type<Insight>;
39
+ Filter: Type<Filter>;
40
+ Summary?: Type<Summary>;
41
+ }
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>;
43
+ export declare class InputDatabaseStorage {
44
+ }
45
+ export declare class DocumentDatabaseStorage {
46
+ }
47
+ export declare class ModelDatabaseStorage {
48
+ }
49
+ export declare class MiddlewareDatabaseStorage {
50
+ }
51
+ export declare const getAllDatabaseModelNames: () => string[];
52
+ export declare const Database: {
53
+ Input: (returns: () => Type) => (target: any) => void;
54
+ Document: (returns: () => Type) => (target: any) => void;
55
+ Model: (returns: () => Type) => (target: any) => void;
56
+ Middleware: (returns: () => Type) => (target: any) => void;
57
+ };
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>>;
63
+ export declare const beyond: <DbModel, Doc>(model: Type<DbModel>, doc: Type<Doc>) => {
64
+ new (): {
65
+ onSchema(schema: SchemaOf<DbModel, Doc>): void;
66
+ };
67
+ };
@@ -0,0 +1,122 @@
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 dbDecorators_exports = {};
19
+ __export(dbDecorators_exports, {
20
+ Database: () => Database,
21
+ DocumentDatabaseStorage: () => DocumentDatabaseStorage,
22
+ InputDatabaseStorage: () => InputDatabaseStorage,
23
+ MiddlewareDatabaseStorage: () => MiddlewareDatabaseStorage,
24
+ ModelDatabaseStorage: () => ModelDatabaseStorage,
25
+ beyond: () => beyond,
26
+ by: () => by,
27
+ dbOf: () => dbOf,
28
+ getAllDatabaseModelNames: () => getAllDatabaseModelNames,
29
+ inside: () => inside,
30
+ into: () => into
31
+ });
32
+ module.exports = __toCommonJS(dbDecorators_exports);
33
+ 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 };
36
+ };
37
+ class InputDatabaseStorage {
38
+ }
39
+ class DocumentDatabaseStorage {
40
+ }
41
+ class ModelDatabaseStorage {
42
+ }
43
+ class MiddlewareDatabaseStorage {
44
+ }
45
+ const getAllDatabaseModelNames = () => {
46
+ const modelNames = Reflect.getMetadataKeys(ModelDatabaseStorage.prototype) ?? [];
47
+ return modelNames;
48
+ };
49
+ const Database = {
50
+ Input: (returns) => {
51
+ return function(target) {
52
+ const modelRef = returns();
53
+ const classMeta = (0, import_constant.getClassMeta)(modelRef);
54
+ Reflect.defineMetadata(classMeta.refName, target, InputDatabaseStorage.prototype);
55
+ };
56
+ },
57
+ Document: (returns) => {
58
+ return function(target) {
59
+ const modelRef = returns();
60
+ const classMeta = (0, import_constant.getClassMeta)(modelRef);
61
+ Reflect.defineMetadata(classMeta.refName, target, DocumentDatabaseStorage.prototype);
62
+ };
63
+ },
64
+ Model: (returns) => {
65
+ return function(target) {
66
+ const modelRef = returns();
67
+ const classMeta = (0, import_constant.getClassMeta)(modelRef);
68
+ Reflect.defineMetadata(classMeta.refName, target, ModelDatabaseStorage.prototype);
69
+ };
70
+ },
71
+ Middleware: (returns) => {
72
+ return function(target) {
73
+ const modelRef = returns();
74
+ const classMeta = (0, import_constant.getClassMeta)(modelRef);
75
+ Reflect.defineMetadata(classMeta.refName, target, MiddlewareDatabaseStorage.prototype);
76
+ };
77
+ }
78
+ };
79
+ const Model = (docRef, cnst) => {
80
+ class DefaultModel {
81
+ }
82
+ return DefaultModel;
83
+ };
84
+ const into = Model;
85
+ const AddModel = (modelRef, cnst) => {
86
+ return modelRef;
87
+ };
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
+ const AddInputOrDocument = (modelRef, addRef) => {
98
+ const fieldMetaMap = (0, import_constant.getFieldMetaMap)(modelRef);
99
+ const addFieldMetas = (0, import_constant.getFieldMetaMap)(addRef);
100
+ (0, import_constant.setFieldMetaMap)(modelRef, new Map([...fieldMetaMap, ...addFieldMetas]));
101
+ return modelRef;
102
+ };
103
+ const beyond = (model, doc) => {
104
+ return class Middleware {
105
+ onSchema(schema) {
106
+ }
107
+ };
108
+ };
109
+ // Annotate the CommonJS export names for ESM import in node:
110
+ 0 && (module.exports = {
111
+ Database,
112
+ DocumentDatabaseStorage,
113
+ InputDatabaseStorage,
114
+ MiddlewareDatabaseStorage,
115
+ ModelDatabaseStorage,
116
+ beyond,
117
+ by,
118
+ dbOf,
119
+ getAllDatabaseModelNames,
120
+ inside,
121
+ into
122
+ });
package/src/index.d.ts CHANGED
@@ -1 +1,5 @@
1
- export declare const a = 1;
1
+ export * from "./dbDecorators";
2
+ export * from "./schema";
3
+ export * from "./types";
4
+ export * from "./database";
5
+ export * from "./dataLoader";
package/src/index.js CHANGED
@@ -2,10 +2,6 @@ var __defProp = Object.defineProperty;
2
2
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
3
  var __getOwnPropNames = Object.getOwnPropertyNames;
4
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
5
  var __copyProps = (to, from, except, desc) => {
10
6
  if (from && typeof from === "object" || typeof from === "function") {
11
7
  for (let key of __getOwnPropNames(from))
@@ -14,14 +10,20 @@ var __copyProps = (to, from, except, desc) => {
14
10
  }
15
11
  return to;
16
12
  };
13
+ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
17
14
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
15
  var src_exports = {};
19
- __export(src_exports, {
20
- a: () => a
21
- });
22
16
  module.exports = __toCommonJS(src_exports);
23
- const a = 1;
17
+ __reExport(src_exports, require("./dbDecorators"), module.exports);
18
+ __reExport(src_exports, require("./schema"), module.exports);
19
+ __reExport(src_exports, require("./types"), module.exports);
20
+ __reExport(src_exports, require("./database"), module.exports);
21
+ __reExport(src_exports, require("./dataLoader"), module.exports);
24
22
  // Annotate the CommonJS export names for ESM import in node:
25
23
  0 && (module.exports = {
26
- a
24
+ ...require("./dbDecorators"),
25
+ ...require("./schema"),
26
+ ...require("./types"),
27
+ ...require("./database"),
28
+ ...require("./dataLoader")
27
29
  });
@@ -0,0 +1,29 @@
1
+ import { FilterQuery, PipelineStage, type ProjectionType } from "mongoose";
2
+ export declare const getDefaultSchemaOptions: <TSchema, TDocument>() => {
3
+ toJSON: {
4
+ getters: boolean;
5
+ virtuals: boolean;
6
+ };
7
+ toObject: {
8
+ getters: boolean;
9
+ virtuals: boolean;
10
+ };
11
+ _id: boolean;
12
+ id: boolean;
13
+ timestamps: boolean;
14
+ methods: {
15
+ refresh: () => Promise<any>;
16
+ };
17
+ statics: {
18
+ pickOne: (query: FilterQuery<TSchema>, projection?: ProjectionType<TSchema>) => Promise<TDocument>;
19
+ pickById: (docId: string | undefined, projection?: ProjectionType<TSchema>) => Promise<TDocument>;
20
+ sample: (query: FilterQuery<TSchema>, size?: number, aggregations?: PipelineStage[]) => Promise<TDocument[]>;
21
+ 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>;
25
+ };
26
+ };
27
+ export declare const convertAggregateMatch: (query: any) => {
28
+ [k: string]: any;
29
+ };
package/src/schema.js ADDED
@@ -0,0 +1,128 @@
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 schema_exports = {};
19
+ __export(schema_exports, {
20
+ convertAggregateMatch: () => convertAggregateMatch,
21
+ getDefaultSchemaOptions: () => getDefaultSchemaOptions
22
+ });
23
+ module.exports = __toCommonJS(schema_exports);
24
+ var import_base = require("@akanjs/base");
25
+ var import_common = require("@akanjs/common");
26
+ var import_mongoose = require("mongoose");
27
+ const getDefaultSchemaOptions = () => ({
28
+ toJSON: { getters: false, virtuals: true },
29
+ toObject: { getters: false, virtuals: true },
30
+ _id: true,
31
+ id: true,
32
+ timestamps: true,
33
+ methods: {
34
+ refresh: async function() {
35
+ Object.assign(this, await this.constructor.findById(this._id));
36
+ return this;
37
+ }
38
+ },
39
+ statics: {
40
+ pickOne: async function(query, projection) {
41
+ const doc = await this.findOne(query, projection);
42
+ if (!doc)
43
+ throw new Error("No Document");
44
+ return doc;
45
+ },
46
+ pickById: async function(docId, projection) {
47
+ if (!docId)
48
+ throw new Error("No Document ID");
49
+ const doc = await this.findById(docId, projection);
50
+ if (!doc)
51
+ throw new Error("No Document");
52
+ return doc;
53
+ },
54
+ sample: async function(query, size = 1, aggregations = []) {
55
+ const objs = await this.aggregate([
56
+ { $match: convertAggregateMatch(query) },
57
+ { $sample: { size } },
58
+ ...aggregations
59
+ ]);
60
+ return objs.map((obj) => new this(obj));
61
+ },
62
+ sampleOne: async function(query, aggregations = []) {
63
+ const obj = await this.aggregate([
64
+ { $match: convertAggregateMatch(query) },
65
+ { $sample: { size: 1 } },
66
+ ...aggregations
67
+ ]);
68
+ return obj.length ? new this(obj[0]) : null;
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);
77
+ },
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);
96
+ }
97
+ }
98
+ });
99
+ const convertOperatorValue = (value) => {
100
+ if (Array.isArray(value))
101
+ return value.map((v) => convertOperatorValue(v));
102
+ else if (!value)
103
+ return value;
104
+ else if ((0, import_mongoose.isValidObjectId)(value))
105
+ return new import_mongoose.Types.ObjectId(value);
106
+ else if ((0, import_common.isValidDate)(value))
107
+ return (0, import_base.dayjs)(value).toDate();
108
+ else if (value.constructor !== Object)
109
+ return value;
110
+ else if (typeof value !== "object")
111
+ return value;
112
+ else
113
+ return Object.fromEntries(
114
+ Object.entries(value).map(([key, value2]) => [key, convertOperatorValue(value2)])
115
+ );
116
+ };
117
+ const convertAggregateMatch = (query) => {
118
+ return Object.fromEntries(
119
+ Object.entries(query).map(([key, value]) => {
120
+ return [key, convertOperatorValue(value)];
121
+ })
122
+ );
123
+ };
124
+ // Annotate the CommonJS export names for ESM import in node:
125
+ 0 && (module.exports = {
126
+ convertAggregateMatch,
127
+ getDefaultSchemaOptions
128
+ });
package/src/types.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ 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];
5
+ } & Partial<Obj>;
package/src/types.js ADDED
@@ -0,0 +1,15 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __copyProps = (to, from, except, desc) => {
6
+ if (from && typeof from === "object" || typeof from === "function") {
7
+ for (let key of __getOwnPropNames(from))
8
+ if (!__hasOwnProp.call(to, key) && key !== except)
9
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
10
+ }
11
+ return to;
12
+ };
13
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
14
+ var types_exports = {};
15
+ module.exports = __toCommonJS(types_exports);