@cyberskill/shared 3.2.0 → 3.3.0
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/dist/config/commitlint/index.js +8 -9
- package/dist/config/commitlint/index.js.map +1 -1
- package/dist/config/config.type.js +8 -5
- package/dist/config/config.type.js.map +1 -1
- package/dist/config/config.util.js +33 -42
- package/dist/config/config.util.js.map +1 -1
- package/dist/config/env/env.constant.js +6 -5
- package/dist/config/env/env.constant.js.map +1 -1
- package/dist/config/env/env.util.js +26 -27
- package/dist/config/env/env.util.js.map +1 -1
- package/dist/config/env/index.js +2 -7
- package/dist/config/eslint/index.js +23 -19
- package/dist/config/eslint/index.js.map +1 -1
- package/dist/config/graphql-codegen/graphql-codegen.util.js +30 -38
- package/dist/config/graphql-codegen/graphql-codegen.util.js.map +1 -1
- package/dist/config/graphql-codegen/index.js +2 -5
- package/dist/config/index.js +3 -7
- package/dist/config/lint-staged/index.js +8 -7
- package/dist/config/lint-staged/index.js.map +1 -1
- package/dist/config/storybook/index.js +2 -6
- package/dist/config/storybook/storybook.main.js +19 -18
- package/dist/config/storybook/storybook.main.js.map +1 -1
- package/dist/config/storybook/storybook.preview.js +31 -37
- package/dist/config/storybook/storybook.preview.js.map +1 -1
- package/dist/config/vitest/index.js +3 -7
- package/dist/config/vitest/vitest.e2e.js +14 -17
- package/dist/config/vitest/vitest.e2e.js.map +1 -1
- package/dist/config/vitest/vitest.unit.js +31 -32
- package/dist/config/vitest/vitest.unit.js.map +1 -1
- package/dist/constant/common.js +6 -5
- package/dist/constant/common.js.map +1 -1
- package/dist/constant/index.js +3 -7
- package/dist/constant/response-status.d.ts +186 -186
- package/dist/constant/response-status.js +254 -253
- package/dist/constant/response-status.js.map +1 -1
- package/dist/node/apollo-server/apollo-server.util.js +27 -29
- package/dist/node/apollo-server/apollo-server.util.js.map +1 -1
- package/dist/node/apollo-server/index.js +2 -7
- package/dist/node/cli/index.js +112 -113
- package/dist/node/cli/index.js.map +1 -1
- package/dist/node/command/command.type.js +8 -5
- package/dist/node/command/command.type.js.map +1 -1
- package/dist/node/command/command.util.js +136 -149
- package/dist/node/command/command.util.js.map +1 -1
- package/dist/node/command/index.js +3 -12
- package/dist/node/express/express.type.d.ts +11 -0
- package/dist/node/express/express.type.js +2 -0
- package/dist/node/express/express.util.js +74 -65
- package/dist/node/express/express.util.js.map +1 -1
- package/dist/node/express/index.js +3 -14
- package/dist/node/fs/fs.util.js +27 -51
- package/dist/node/fs/fs.util.js.map +1 -1
- package/dist/node/fs/index.js +2 -19
- package/dist/node/log/index.js +2 -8
- package/dist/node/log/log.type.js +8 -5
- package/dist/node/log/log.type.js.map +1 -1
- package/dist/node/log/log.util.js +51 -68
- package/dist/node/log/log.util.js.map +1 -1
- package/dist/node/mongo/index.js +8 -26
- package/dist/node/mongo/mongo.constant.js +6 -6
- package/dist/node/mongo/mongo.constant.js.map +1 -1
- package/dist/node/mongo/mongo.controller.mongoose.d.ts +6 -1
- package/dist/node/mongo/mongo.controller.mongoose.js +333 -467
- package/dist/node/mongo/mongo.controller.mongoose.js.map +1 -1
- package/dist/node/mongo/mongo.controller.native.js +153 -212
- package/dist/node/mongo/mongo.controller.native.js.map +1 -1
- package/dist/node/mongo/mongo.dynamic-populate.js +164 -192
- package/dist/node/mongo/mongo.dynamic-populate.js.map +1 -1
- package/dist/node/mongo/mongo.populate.js +229 -262
- package/dist/node/mongo/mongo.populate.js.map +1 -1
- package/dist/node/mongo/mongo.type.js +8 -17
- package/dist/node/mongo/mongo.type.js.map +1 -1
- package/dist/node/mongo/mongo.util.js +134 -293
- package/dist/node/mongo/mongo.util.js.map +1 -1
- package/dist/node/package/index.js +3 -11
- package/dist/node/package/package.type.js +8 -5
- package/dist/node/package/package.type.js.map +1 -1
- package/dist/node/package/package.util.js +216 -225
- package/dist/node/package/package.util.js.map +1 -1
- package/dist/node/path/index.js +3 -58
- package/dist/node/path/path.constant.js +211 -298
- package/dist/node/path/path.constant.js.map +1 -1
- package/dist/node/path/path.util.js +13 -16
- package/dist/node/path/path.util.js.map +1 -1
- package/dist/node/storage/index.js +3 -10
- package/dist/node/storage/storage.constant.js +6 -8
- package/dist/node/storage/storage.constant.js.map +1 -1
- package/dist/node/storage/storage.util.js +127 -178
- package/dist/node/storage/storage.util.js.map +1 -1
- package/dist/node/upload/index.js +4 -16
- package/dist/node/upload/upload.constant.js +58 -32
- package/dist/node/upload/upload.constant.js.map +1 -1
- package/dist/node/upload/upload.type.js +8 -5
- package/dist/node/upload/upload.type.js.map +1 -1
- package/dist/node/upload/upload.util.js +125 -137
- package/dist/node/upload/upload.util.js.map +1 -1
- package/dist/node/ws/index.js +2 -6
- package/dist/node/ws/ws.type.d.ts +7 -8
- package/dist/node/ws/ws.util.js +46 -44
- package/dist/node/ws/ws.util.js.map +1 -1
- package/dist/node_modules/.pnpm/vitest@4.1.0_@types_node@25.5.0_jsdom@29.0.0_@noble_hashes@1.8.0__vite@8.0.0_@types_nod_53aa4254f295b3c40bb8f17b6ab226b5/node_modules/vitest/dist/config.js +8 -0
- package/dist/node_modules/.pnpm/vitest@4.1.0_@types_node@25.5.0_jsdom@29.0.0_@noble_hashes@1.8.0__vite@8.0.0_@types_nod_53aa4254f295b3c40bb8f17b6ab226b5/node_modules/vitest/dist/config.js.map +1 -0
- package/dist/react/apollo-client/apollo-client.component.js +16 -18
- package/dist/react/apollo-client/apollo-client.component.js.map +1 -1
- package/dist/react/apollo-client/apollo-client.constant.js +6 -5
- package/dist/react/apollo-client/apollo-client.constant.js.map +1 -1
- package/dist/react/apollo-client/apollo-client.context.js +10 -13
- package/dist/react/apollo-client/apollo-client.context.js.map +1 -1
- package/dist/react/apollo-client/apollo-client.module.scss.js +8 -7
- package/dist/react/apollo-client/apollo-client.module.scss.js.map +1 -1
- package/dist/react/apollo-client/apollo-client.util.js +57 -75
- package/dist/react/apollo-client/apollo-client.util.js.map +1 -1
- package/dist/react/apollo-client/index.js +7 -30
- package/dist/react/apollo-client/links/index.js +2 -5
- package/dist/react/apollo-client/links/upload.js +63 -107
- package/dist/react/apollo-client/links/upload.js.map +1 -1
- package/dist/react/apollo-client-nextjs/apollo-client-nextjs.component.js +14 -16
- package/dist/react/apollo-client-nextjs/apollo-client-nextjs.component.js.map +1 -1
- package/dist/react/apollo-client-nextjs/apollo-client-nextjs.rsc.js +8 -7
- package/dist/react/apollo-client-nextjs/apollo-client-nextjs.rsc.js.map +1 -1
- package/dist/react/apollo-client-nextjs/apollo-client-nextjs.util.js +14 -14
- package/dist/react/apollo-client-nextjs/apollo-client-nextjs.util.js.map +1 -1
- package/dist/react/apollo-client-nextjs/index.js +3 -7
- package/dist/react/apollo-error/apollo-error.component.js +57 -69
- package/dist/react/apollo-error/apollo-error.component.js.map +1 -1
- package/dist/react/apollo-error/apollo-error.context.js +7 -6
- package/dist/react/apollo-error/apollo-error.context.js.map +1 -1
- package/dist/react/apollo-error/apollo-error.hook.js +10 -10
- package/dist/react/apollo-error/apollo-error.hook.js.map +1 -1
- package/dist/react/apollo-error/apollo-error.module.scss.js +15 -11
- package/dist/react/apollo-error/apollo-error.module.scss.js.map +1 -1
- package/dist/react/apollo-error/apollo-error.provider.js +31 -25
- package/dist/react/apollo-error/apollo-error.provider.js.map +1 -1
- package/dist/react/apollo-error/apollo-error.util.js +14 -16
- package/dist/react/apollo-error/apollo-error.util.js.map +1 -1
- package/dist/react/apollo-error/index.js +5 -15
- package/dist/react/i18next/i18next.hook.js +7 -6
- package/dist/react/i18next/i18next.hook.js.map +1 -1
- package/dist/react/i18next/i18next.util.js +9 -8
- package/dist/react/i18next/i18next.util.js.map +1 -1
- package/dist/react/i18next/index.js +3 -7
- package/dist/react/loading/index.js +3 -9
- package/dist/react/loading/loading.component.js +47 -48
- package/dist/react/loading/loading.component.js.map +1 -1
- package/dist/react/loading/loading.context.js +7 -6
- package/dist/react/loading/loading.context.js.map +1 -1
- package/dist/react/loading/loading.hook.js +11 -11
- package/dist/react/loading/loading.hook.js.map +1 -1
- package/dist/react/loading/loading.module.scss.js +18 -15
- package/dist/react/loading/loading.module.scss.js.map +1 -1
- package/dist/react/loading/loading.provider.js +26 -18
- package/dist/react/loading/loading.provider.js.map +1 -1
- package/dist/react/log/index.js +2 -6
- package/dist/react/log/log.util.d.ts +8 -0
- package/dist/react/log/log.util.js +33 -29
- package/dist/react/log/log.util.js.map +1 -1
- package/dist/react/next-intl/index.js +6 -14
- package/dist/react/next-intl/next-intl.constant.js +16 -15
- package/dist/react/next-intl/next-intl.constant.js.map +1 -1
- package/dist/react/next-intl/next-intl.context.js +7 -6
- package/dist/react/next-intl/next-intl.context.js.map +1 -1
- package/dist/react/next-intl/next-intl.hoc.js +20 -23
- package/dist/react/next-intl/next-intl.hoc.js.map +1 -1
- package/dist/react/next-intl/next-intl.hook.js +13 -14
- package/dist/react/next-intl/next-intl.hook.js.map +1 -1
- package/dist/react/next-intl/next-intl.provider.js +28 -23
- package/dist/react/next-intl/next-intl.provider.js.map +1 -1
- package/dist/react/storage/index.js +3 -7
- package/dist/react/storage/storage.hook.js +61 -58
- package/dist/react/storage/storage.hook.js.map +1 -1
- package/dist/react/storage/storage.util.js +36 -68
- package/dist/react/storage/storage.util.js.map +1 -1
- package/dist/react/toast/index.js +2 -6
- package/dist/react/userback/index.js +2 -5
- package/dist/react/userback/userback.component.js +27 -27
- package/dist/react/userback/userback.component.js.map +1 -1
- package/dist/style.css +2 -1
- package/dist/typescript/common.type.js +8 -5
- package/dist/typescript/common.type.js.map +1 -1
- package/dist/typescript/index.js +2 -5
- package/dist/util/common/common.util.js +119 -48
- package/dist/util/common/common.util.js.map +1 -1
- package/dist/util/common/index.js +2 -9
- package/dist/util/index.js +6 -27
- package/dist/util/object/index.d.ts +3 -0
- package/dist/util/object/index.js +2 -10
- package/dist/util/object/object.util.js +94 -128
- package/dist/util/object/object.util.js.map +1 -1
- package/dist/util/serializer/index.js +2 -5
- package/dist/util/serializer/serializer.util.js +73 -78
- package/dist/util/serializer/serializer.util.js.map +1 -1
- package/dist/util/string/index.d.ts +3 -0
- package/dist/util/string/index.js +2 -10
- package/dist/util/string/string.util.js +59 -71
- package/dist/util/string/string.util.js.map +1 -1
- package/dist/util/validate/index.d.ts +3 -0
- package/dist/util/validate/index.js +2 -5
- package/dist/util/validate/validate.util.js +13 -39
- package/dist/util/validate/validate.util.js.map +1 -1
- package/package.json +29 -27
- package/dist/config/env/index.js.map +0 -1
- package/dist/config/graphql-codegen/index.js.map +0 -1
- package/dist/config/index.js.map +0 -1
- package/dist/config/storybook/index.js.map +0 -1
- package/dist/config/vitest/index.js.map +0 -1
- package/dist/constant/index.js.map +0 -1
- package/dist/node/apollo-server/index.js.map +0 -1
- package/dist/node/command/index.js.map +0 -1
- package/dist/node/express/index.js.map +0 -1
- package/dist/node/fs/index.js.map +0 -1
- package/dist/node/log/index.js.map +0 -1
- package/dist/node/mongo/index.js.map +0 -1
- package/dist/node/package/index.js.map +0 -1
- package/dist/node/path/index.js.map +0 -1
- package/dist/node/storage/index.js.map +0 -1
- package/dist/node/upload/index.js.map +0 -1
- package/dist/node/ws/index.js.map +0 -1
- package/dist/node_modules/.pnpm/vitest@4.0.18_@types_node@25.3.5_jiti@2.6.1_jsdom@28.1.0_@noble_hashes@1.8.0__sass@1.97.3_tsx@4.21.0_yaml@2.8.2/node_modules/vitest/dist/config.js +0 -7
- package/dist/node_modules/.pnpm/vitest@4.0.18_@types_node@25.3.5_jiti@2.6.1_jsdom@28.1.0_@noble_hashes@1.8.0__sass@1.97.3_tsx@4.21.0_yaml@2.8.2/node_modules/vitest/dist/config.js.map +0 -1
- package/dist/react/apollo-client/index.js.map +0 -1
- package/dist/react/apollo-client/links/index.js.map +0 -1
- package/dist/react/apollo-client-nextjs/index.js.map +0 -1
- package/dist/react/apollo-error/index.js.map +0 -1
- package/dist/react/i18next/index.js.map +0 -1
- package/dist/react/loading/index.js.map +0 -1
- package/dist/react/log/index.js.map +0 -1
- package/dist/react/next-intl/index.js.map +0 -1
- package/dist/react/storage/index.js.map +0 -1
- package/dist/react/toast/index.js.map +0 -1
- package/dist/react/userback/index.js.map +0 -1
- package/dist/typescript/index.js.map +0 -1
- package/dist/util/common/index.js.map +0 -1
- package/dist/util/index.js.map +0 -1
- package/dist/util/object/index.js.map +0 -1
- package/dist/util/serializer/index.js.map +0 -1
- package/dist/util/string/index.js.map +0 -1
- package/dist/util/validate/index.js.map +0 -1
|
@@ -1,197 +1,169 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
import { deepClone as e } from "../../util/object/object.util.js";
|
|
2
|
+
import { catchError as t } from "../log/log.util.js";
|
|
3
|
+
import { convertEnumToModelName as n } from "./mongo.util.js";
|
|
4
|
+
import { applyNestedPopulate as r } from "./mongo.populate.js";
|
|
5
|
+
//#region src/node/mongo/mongo.dynamic-populate.ts
|
|
6
|
+
function i(e) {
|
|
7
|
+
return typeof e == "object" && !!e;
|
|
7
8
|
}
|
|
8
|
-
function
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
if (typeof e == "string")
|
|
29
|
-
return [...S].some(
|
|
30
|
-
(t) => e === t || e.startsWith(`${t}.`)
|
|
31
|
-
) ? void 0 : e;
|
|
32
|
-
if (typeof e == "object" && e !== null) {
|
|
33
|
-
const t = e, u = t.path || t.populate || "";
|
|
34
|
-
return [...S].some(
|
|
35
|
-
(s) => u === s || u.startsWith(`${s}.`)
|
|
36
|
-
) ? void 0 : e;
|
|
37
|
-
}
|
|
38
|
-
return e;
|
|
9
|
+
function a(e, t) {
|
|
10
|
+
if (!e || !t || t.length === 0) return e;
|
|
11
|
+
let n = new Set(t.map((e) => e.name));
|
|
12
|
+
if (Array.isArray(e)) {
|
|
13
|
+
let t = e.filter((e) => {
|
|
14
|
+
if (typeof e == "string") return ![...n].some((t) => e === t || e.startsWith(`${t}.`));
|
|
15
|
+
if (typeof e == "object" && e) {
|
|
16
|
+
let t = e, r = t.path || t.populate || "";
|
|
17
|
+
return ![...n].some((e) => r === e || r.startsWith(`${e}.`));
|
|
18
|
+
}
|
|
19
|
+
return !0;
|
|
20
|
+
});
|
|
21
|
+
return t.length > 0 ? t : void 0;
|
|
22
|
+
}
|
|
23
|
+
if (typeof e == "string") return [...n].some((t) => e === t || e.startsWith(`${t}.`)) ? void 0 : e;
|
|
24
|
+
if (typeof e == "object" && e) {
|
|
25
|
+
let t = e, r = t.path || t.populate || "";
|
|
26
|
+
return [...n].some((e) => r === e || r.startsWith(`${e}.`)) ? void 0 : e;
|
|
27
|
+
}
|
|
28
|
+
return e;
|
|
39
29
|
}
|
|
40
|
-
function
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
30
|
+
function o(e, r, i) {
|
|
31
|
+
if (!e.length || !r || !i?.ref) return [];
|
|
32
|
+
let a = /* @__PURE__ */ new Map();
|
|
33
|
+
return e.forEach((e) => {
|
|
34
|
+
try {
|
|
35
|
+
let t = i.ref(e);
|
|
36
|
+
if (t == null) return;
|
|
37
|
+
let r = typeof t == "string" ? t : String(t);
|
|
38
|
+
if (r && r.trim() !== "") {
|
|
39
|
+
let t = n(r);
|
|
40
|
+
a.has(t) || a.set(t, []), a.get(t).push(e);
|
|
41
|
+
}
|
|
42
|
+
} catch (e) {
|
|
43
|
+
t(/* @__PURE__ */ Error(`Dynamic ref function failed for virtual "${r}": ${e instanceof Error ? e.message : String(e)}`));
|
|
44
|
+
}
|
|
45
|
+
}), Array.from(a.entries(), ([e, t]) => ({
|
|
46
|
+
model: e,
|
|
47
|
+
docs: t
|
|
48
|
+
}));
|
|
58
49
|
}
|
|
59
|
-
function
|
|
60
|
-
|
|
50
|
+
function s(e) {
|
|
51
|
+
return typeof e == "object" && !!e && "toObject" in e && typeof e.toObject == "function";
|
|
61
52
|
}
|
|
62
|
-
async function
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
r && (l.has(r) || l.set(r, []), E && l.get(r).push(E), i.populate && l.get(r).push(i.populate));
|
|
175
|
-
} else
|
|
176
|
-
y.push(f);
|
|
177
|
-
}
|
|
178
|
-
const w = [...y];
|
|
179
|
-
return l.forEach((f, i) => {
|
|
180
|
-
const o = [];
|
|
181
|
-
for (const r of f)
|
|
182
|
-
(typeof r == "string" || r && typeof r == "object") && o.push(r);
|
|
183
|
-
o.length > 0 ? w.push({ path: i, populate: o }) : w.push(i);
|
|
184
|
-
}), w;
|
|
185
|
-
})(t);
|
|
186
|
-
await A(e, h, n, S, s);
|
|
187
|
-
}
|
|
188
|
-
return h;
|
|
53
|
+
async function c(t, n, i, a, c, l) {
|
|
54
|
+
if (!n.length || !i.length || !a) return n;
|
|
55
|
+
let u = i.filter((e) => {
|
|
56
|
+
if (Array.isArray(a)) return a.length > 0 && a.some((t) => {
|
|
57
|
+
if (typeof t == "string") return t === e.name || t.startsWith(`${e.name}.`);
|
|
58
|
+
if (t && typeof t == "object") {
|
|
59
|
+
let n = t, r = n.path || n.populate || "";
|
|
60
|
+
return r === e.name || r.startsWith(`${e.name}.`);
|
|
61
|
+
}
|
|
62
|
+
return !1;
|
|
63
|
+
});
|
|
64
|
+
if (typeof a == "string") return a === e.name || a.startsWith(`${e.name}.`);
|
|
65
|
+
if (typeof a == "object" && a) {
|
|
66
|
+
let t = a, n = t.path || t.populate || "";
|
|
67
|
+
return n === e.name || n.startsWith(`${e.name}.`);
|
|
68
|
+
}
|
|
69
|
+
return !1;
|
|
70
|
+
});
|
|
71
|
+
if (u.length === 0) return n;
|
|
72
|
+
let d = e(n.map((e) => s(e) ? e.toObject() : e));
|
|
73
|
+
d.forEach((e) => {
|
|
74
|
+
u.forEach(({ name: t, options: n }) => {
|
|
75
|
+
t in e || (e[t] = n.count ? 0 : n.justOne ? null : []);
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
let f = /* @__PURE__ */ new Map();
|
|
79
|
+
for (let e of u) {
|
|
80
|
+
let { name: t, options: n } = e, r = o(d, t, n);
|
|
81
|
+
for (let i of r) {
|
|
82
|
+
f.has(i.model) || f.set(i.model, {
|
|
83
|
+
virtuals: [],
|
|
84
|
+
localValueSets: /* @__PURE__ */ new Map(),
|
|
85
|
+
docsByLocalValue: /* @__PURE__ */ new Map()
|
|
86
|
+
});
|
|
87
|
+
let r = f.get(i.model);
|
|
88
|
+
r.virtuals.some((e) => e.name === t) || (r.virtuals.push(e), r.localValueSets.set(t, /* @__PURE__ */ new Set()));
|
|
89
|
+
let a = r.localValueSets.get(t);
|
|
90
|
+
i.docs.forEach((e) => {
|
|
91
|
+
let t = e[n.localField];
|
|
92
|
+
if (t != null) {
|
|
93
|
+
let n = String(t);
|
|
94
|
+
a.add(n);
|
|
95
|
+
let i = -1, o = e;
|
|
96
|
+
o.id === void 0 ? o._id !== void 0 && (i = d.findIndex((e) => e._id?.toString?.() === o._id?.toString?.())) : i = d.findIndex((e) => e.id === o.id), i !== -1 && (r.docsByLocalValue.has(n) || r.docsByLocalValue.set(n, []), r.docsByLocalValue.get(n).push(i));
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return await Promise.all(Array.from(f.entries(), async ([e, n]) => {
|
|
102
|
+
let r = t.models[e];
|
|
103
|
+
if (!r) return;
|
|
104
|
+
let i = /* @__PURE__ */ new Set();
|
|
105
|
+
if (n.localValueSets.forEach((e) => {
|
|
106
|
+
e.forEach((e) => i.add(e));
|
|
107
|
+
}), i.size === 0) return;
|
|
108
|
+
let a = [...new Set(n.virtuals.map((e) => e.options.foreignField))], o = [...i], s;
|
|
109
|
+
s = a.length === 1 ? { [String(a[0])]: { $in: o } } : { $or: a.map((e) => ({ [e]: { $in: o } })) };
|
|
110
|
+
let l = await r.find(s, c).lean();
|
|
111
|
+
for (let e of n.virtuals) {
|
|
112
|
+
let { name: t, options: r } = e, a = l.filter((e) => {
|
|
113
|
+
let t = e[r.foreignField];
|
|
114
|
+
return t != null && i.has(String(t));
|
|
115
|
+
});
|
|
116
|
+
if (r.count) {
|
|
117
|
+
let e = /* @__PURE__ */ new Map();
|
|
118
|
+
a.forEach((t) => {
|
|
119
|
+
let n = t[r.foreignField]?.toString();
|
|
120
|
+
n && e.set(n, (e.get(n) || 0) + 1);
|
|
121
|
+
}), n.localValueSets.get(t).forEach((r) => {
|
|
122
|
+
let i = n.docsByLocalValue.get(r) || [], a = e.get(r) || 0;
|
|
123
|
+
i.forEach((e) => {
|
|
124
|
+
let n = d[e];
|
|
125
|
+
n[t] === void 0 && (n[t] = a);
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
} else {
|
|
129
|
+
let e = /* @__PURE__ */ new Map();
|
|
130
|
+
a.forEach((t) => {
|
|
131
|
+
let n = t[r.foreignField]?.toString();
|
|
132
|
+
n && (e.has(n) || e.set(n, []), e.get(n).push(t));
|
|
133
|
+
}), n.localValueSets.get(t).forEach((i) => {
|
|
134
|
+
let a = n.docsByLocalValue.get(i) || [], o = e.get(i) || [], s = r.justOne ? o[0] || null : o;
|
|
135
|
+
a.forEach((e) => {
|
|
136
|
+
let n = d[e];
|
|
137
|
+
n[t] = s;
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
})), a && await r(t, d, ((e) => {
|
|
143
|
+
let t = Array.isArray(e) ? e : [e], n = /* @__PURE__ */ new Map(), r = [];
|
|
144
|
+
for (let e of t) if (typeof e == "string") if (e.includes(".")) {
|
|
145
|
+
let t = e.split("."), r = t[0] || "", i = t.slice(1).join(".");
|
|
146
|
+
r && (n.has(r) || n.set(r, []), i && n.get(r).push(i));
|
|
147
|
+
} else r.push(e);
|
|
148
|
+
else if (e && typeof e == "object") {
|
|
149
|
+
let t = e;
|
|
150
|
+
if (t.path && t.path.includes(".")) {
|
|
151
|
+
let e = t.path.split("."), r = e[0] || "", i = e.slice(1).join(".");
|
|
152
|
+
r && (n.has(r) || n.set(r, []), i && n.get(r).push(i), t.populate && n.get(r).push(t.populate));
|
|
153
|
+
} else r.push(e);
|
|
154
|
+
}
|
|
155
|
+
let i = [...r];
|
|
156
|
+
return n.forEach((e, t) => {
|
|
157
|
+
let n = [];
|
|
158
|
+
for (let t of e) (typeof t == "string" || t && typeof t == "object") && n.push(t);
|
|
159
|
+
i.push(n.length > 0 ? {
|
|
160
|
+
path: t,
|
|
161
|
+
populate: n
|
|
162
|
+
} : t);
|
|
163
|
+
}), i;
|
|
164
|
+
})(a), i, l), d;
|
|
189
165
|
}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
k as populateDynamicVirtuals,
|
|
195
|
-
F as remapDynamicPopulate
|
|
196
|
-
};
|
|
197
|
-
//# sourceMappingURL=mongo.dynamic-populate.js.map
|
|
166
|
+
//#endregion
|
|
167
|
+
export { a as filterDynamicVirtualsFromPopulate, s as isMongooseDoc, i as isObject, c as populateDynamicVirtuals, o as remapDynamicPopulate };
|
|
168
|
+
|
|
169
|
+
//# sourceMappingURL=mongo.dynamic-populate.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mongo.dynamic-populate.js","sources":["../../../src/node/mongo/mongo.dynamic-populate.ts"],"sourcesContent":["import type mongooseRaw from 'mongoose';\n\nimport { deepClone } from '#util/index.js';\n\nimport type { I_DynamicVirtualConfig, I_DynamicVirtualOptions, T_Input_Populate } from './mongo.type.js';\n\nimport { catchError } from '../log/index.js';\nimport { applyNestedPopulate } from './mongo.populate.js';\nimport { convertEnumToModelName } from './mongo.util.js';\n\n/**\n * Checks if value is object-like (e.g., objects, arrays, etc.), not null.\n */\nexport function isObject(value: unknown): value is object {\n return value != null && typeof value === 'object';\n}\n\n/**\n * Filters out dynamic virtuals from populate options to prevent Mongoose from trying to populate them.\n * This function creates a new populate configuration that only includes regular virtuals.\n *\n * @template T - The document type\n * @param populate - The original populate options\n * @param dynamicVirtuals - Array of dynamic virtual configurations\n * @returns Filtered populate options excluding dynamic virtuals\n */\nexport function filterDynamicVirtualsFromPopulate<T>(\n populate: T_Input_Populate | undefined,\n dynamicVirtuals: I_DynamicVirtualConfig<T>[] | undefined,\n): T_Input_Populate | undefined {\n if (!populate || !dynamicVirtuals || dynamicVirtuals.length === 0) {\n return populate;\n }\n\n const dynamicVirtualNames = new Set(dynamicVirtuals.map(v => v.name));\n\n if (Array.isArray(populate)) {\n const filtered = populate.filter((p) => {\n if (typeof p === 'string') {\n return ![...dynamicVirtualNames].some(virtualName =>\n p === virtualName || p.startsWith(`${virtualName}.`),\n );\n }\n\n if (typeof p === 'object' && p !== null) {\n const popObj = p as { path?: string; populate?: string };\n const path = popObj.path || popObj.populate || '';\n\n return ![...dynamicVirtualNames].some(virtualName =>\n path === virtualName || path.startsWith(`${virtualName}.`),\n );\n }\n\n return true;\n });\n\n return filtered.length > 0 ? (filtered as T_Input_Populate) : undefined;\n }\n\n if (typeof populate === 'string') {\n return [...dynamicVirtualNames].some(virtualName =>\n populate === virtualName || populate.startsWith(`${virtualName}.`),\n )\n ? undefined\n : populate;\n }\n\n if (typeof populate === 'object' && populate !== null) {\n const popObj = populate as { path?: string; populate?: string };\n const path = popObj.path || popObj.populate || '';\n\n return [...dynamicVirtualNames].some(virtualName =>\n path === virtualName || path.startsWith(`${virtualName}.`),\n )\n ? undefined\n : populate;\n }\n\n return populate;\n}\n\n/**\n * Groups documents by the resolved model name for a dynamic virtual field.\n * Used to batch population queries for dynamic virtuals.\n *\n * @template T - The document type\n * @template R - The model name type (usually string or enum)\n * @param {T[]} documents - The array of documents to process\n * @param {string} virtualName - The name of the dynamic virtual field\n * @param {I_DynamicVirtualOptions<T, R>} virtualOptions - The dynamic virtual options (must include a ref function)\n * @returns {Array<{ model: string; docs: T[] }>} An array of groups, each with a model name and the docs for that model\n */\nexport function remapDynamicPopulate<T, R extends string = string>(\n documents: T[],\n virtualName: string,\n virtualOptions: I_DynamicVirtualOptions<T, R>,\n): Array<{ model: string; docs: T[] }> {\n if (!documents.length || !virtualName || !virtualOptions?.ref) {\n return [];\n }\n\n const modelGroups = new Map<string, T[]>();\n documents.forEach((doc) => {\n try {\n const modelName = virtualOptions.ref(doc);\n\n if (modelName === undefined || modelName === null) {\n return;\n }\n\n const modelNameString = typeof modelName === 'string' ? modelName : String(modelName);\n\n if (modelNameString && modelNameString.trim() !== '') {\n const convertedModelName = convertEnumToModelName(modelNameString);\n\n if (!modelGroups.has(convertedModelName)) {\n modelGroups.set(convertedModelName, []);\n }\n\n modelGroups.get(convertedModelName)!.push(doc);\n }\n }\n catch (error) {\n catchError(new Error(`Dynamic ref function failed for virtual \"${virtualName}\": ${error instanceof Error ? error.message : String(error)}`));\n }\n });\n\n return Array.from(modelGroups.entries(), ([model, docs]) => ({ model, docs }));\n}\n\n/**\n * Type guard to check if an object is a Mongoose Document (has toObject method).\n * @param obj - The object to check\n * @returns True if obj has a toObject function\n */\nexport function isMongooseDoc(obj: unknown): obj is { toObject: () => { [key: string]: unknown } } {\n return obj !== null && typeof obj === 'object' && 'toObject' in obj && typeof (obj as { toObject: unknown }).toObject === 'function';\n}\n\n/**\n * Optimized batch population for dynamic virtuals.\n *\n * - Groups documents by model and batches queries for each model.\n * - Populates all dynamic virtuals in parallel for maximum performance.\n * - Uses direct assignment for plain objects and skips already populated fields.\n * - Supports optional projection for population queries.\n * - Only populates virtuals that are explicitly requested in populate options.\n * - Reminder: Ensure indexes exist on foreignField in referenced collections for best performance.\n *\n * @template T - The document type (must be an object)\n * @template R - The model name type (usually string or enum)\n * @param {typeof mongooseRaw} mongoose - The Mongoose instance\n * @param {T[]} documents - The array of documents to populate\n * @param {I_DynamicVirtualConfig<T, R>[]} virtualConfigs - The dynamic virtual configurations to process\n * @param {T_Input_Populate} [populate] - Population options to determine which virtuals to populate\n * @param {Record<string, 0 | 1>} [projection] - Optional projection for population queries\n * @returns {Promise<object[]>} The array of documents with dynamic virtuals populated\n */\nexport async function populateDynamicVirtuals<T extends object, R extends string = string>(\n mongoose: typeof mongooseRaw,\n documents: T[],\n virtualConfigs: I_DynamicVirtualConfig<T, R>[],\n populate?: T_Input_Populate,\n projection?: Record<string, 0 | 1>,\n startModel?: any,\n): Promise<T[]> {\n if (!documents.length || !virtualConfigs.length) {\n return documents;\n }\n\n if (!populate) {\n return documents;\n }\n\n const requestedVirtuals = virtualConfigs.filter((config) => {\n if (Array.isArray(populate)) {\n return populate.length > 0 && populate.some((p) => {\n if (typeof p === 'string') {\n return p === config.name || p.startsWith(`${config.name}.`);\n }\n if (p && typeof p === 'object') {\n const popObj = p as { path?: string; populate?: string };\n const path = popObj.path || popObj.populate || '';\n\n return path === config.name || path.startsWith(`${config.name}.`);\n }\n\n return false;\n });\n }\n\n if (typeof populate === 'string') {\n return populate === config.name || populate.startsWith(`${config.name}.`);\n }\n\n if (typeof populate === 'object' && populate !== null) {\n const popObj = populate as { path?: string; populate?: string };\n const path = popObj.path || popObj.populate || '';\n\n return (path === config.name) || path.startsWith(`${config.name}.`);\n }\n\n return false;\n });\n\n if (requestedVirtuals.length === 0) {\n return documents;\n }\n\n const clonedDocuments = deepClone(documents.map(doc => isMongooseDoc(doc) ? doc.toObject() : doc)) as T[];\n\n clonedDocuments.forEach((doc) => {\n requestedVirtuals.forEach(({ name, options }) => {\n if (!(name in doc)) {\n (doc as { [key: string]: unknown })[name as string] = options.count ? 0 : (options.justOne ? null : []);\n }\n });\n });\n\n const modelProcessingMap = new Map<string, {\n virtuals: I_DynamicVirtualConfig<T, R>[];\n localValueSets: Map<string, Set<string>>;\n docsByLocalValue: Map<string, number[]>;\n }>();\n\n for (const virtualConfig of requestedVirtuals) {\n const { name, options } = virtualConfig;\n const populateGroups = remapDynamicPopulate(clonedDocuments, name, options);\n\n for (const group of populateGroups) {\n if (!modelProcessingMap.has(group.model)) {\n modelProcessingMap.set(group.model, {\n virtuals: [],\n localValueSets: new Map(),\n docsByLocalValue: new Map(),\n });\n }\n\n const processing = modelProcessingMap.get(group.model)!;\n\n if (!processing.virtuals.some(v => v.name === name)) {\n processing.virtuals.push(virtualConfig);\n processing.localValueSets.set(name as string, new Set());\n }\n\n const localValueSet = processing.localValueSets.get(name as string)!;\n group.docs.forEach((doc) => {\n const localVal = (doc as { [key: string]: unknown })[options.localField];\n\n if (localVal != null) {\n const strVal = String(localVal);\n localValueSet.add(strVal);\n\n let idx = -1;\n\n const docWithKeys = doc as { [key: string]: unknown };\n\n if (docWithKeys['id'] !== undefined) {\n idx = clonedDocuments.findIndex((d) => {\n const dWithKeys = d as { [key: string]: unknown };\n\n return dWithKeys['id'] === docWithKeys['id'];\n });\n }\n else if (docWithKeys['_id'] !== undefined) {\n idx = clonedDocuments.findIndex((d) => {\n const dWithKeys = d as { [key: string]: unknown };\n\n return dWithKeys['_id']?.toString?.() === docWithKeys['_id']?.toString?.();\n });\n }\n\n if (idx !== -1) {\n if (!processing.docsByLocalValue.has(strVal)) {\n processing.docsByLocalValue.set(strVal, []);\n }\n processing.docsByLocalValue.get(strVal)!.push(idx);\n }\n }\n });\n }\n }\n\n await Promise.all(Array.from(modelProcessingMap.entries(), async ([modelName, processing]) => {\n const Model = mongoose.models[modelName];\n\n if (!Model) {\n return;\n }\n\n const allLocalValues = new Set<string>();\n processing.localValueSets.forEach((localValueSet) => {\n localValueSet.forEach(val => allLocalValues.add(val));\n });\n\n if (allLocalValues.size === 0) {\n return;\n }\n\n const foreignFields = [...new Set(processing.virtuals.map(v => v.options.foreignField))];\n const localValuesArray = [...allLocalValues];\n let query;\n\n if (foreignFields.length === 1) {\n query = { [String(foreignFields[0])]: { $in: localValuesArray } };\n }\n else {\n query = { $or: foreignFields.map(field => ({ [field]: { $in: localValuesArray } })) };\n }\n\n const allPopulatedData = await Model.find(query, projection).lean();\n\n for (const virtualConfig of processing.virtuals) {\n const { name, options } = virtualConfig;\n const relevantData = allPopulatedData.filter((item) => {\n const foreignVal = (item)[options.foreignField];\n\n return foreignVal != null && allLocalValues.has(String(foreignVal));\n });\n\n if (options.count) {\n const countMap = new Map<string, number>();\n\n relevantData.forEach((item) => {\n const key = (item)[options.foreignField]?.toString();\n\n if (key) {\n countMap.set(key, (countMap.get(key) || 0) + 1);\n }\n });\n\n processing.localValueSets.get(name as string)!.forEach((localValue) => {\n const docs = processing.docsByLocalValue.get(localValue) || [];\n const count = countMap.get(localValue) || 0;\n\n docs.forEach((idx) => {\n const docToUpdate = clonedDocuments[idx] as { [key: string]: unknown };\n\n if (docToUpdate[name] === undefined) {\n docToUpdate[name] = count;\n }\n });\n });\n }\n else {\n const resultMap = new Map<string, T[]>();\n\n relevantData.forEach((item) => {\n const key = (item)[options.foreignField]?.toString();\n\n if (key) {\n if (!resultMap.has(key)) {\n resultMap.set(key, []);\n }\n resultMap.get(key)!.push(item);\n }\n });\n\n processing.localValueSets.get(name as string)!.forEach((localVal) => {\n const docs = processing.docsByLocalValue.get(localVal) || [];\n const results = resultMap.get(localVal) || [];\n const value = options.justOne ? (results[0] || null) : results;\n\n docs.forEach((idx) => {\n const docToUpdate = clonedDocuments[idx] as { [key: string]: unknown };\n docToUpdate[name] = value;\n });\n });\n }\n }\n }));\n\n if (populate) {\n const normalizePopulate = (pop: T_Input_Populate): T_Input_Populate => {\n const asArray = Array.isArray(pop) ? pop : [pop];\n const grouped = new Map<string, any[]>();\n const passthrough: any[] = [];\n\n for (const entry of asArray) {\n if (typeof entry === 'string') {\n if (entry.includes('.')) {\n const parts = entry.split('.');\n const first = parts[0] || '';\n const rest = parts.slice(1).join('.');\n\n if (first) {\n if (!grouped.has(first)) {\n grouped.set(first, []);\n }\n if (rest) {\n grouped.get(first)!.push(rest);\n }\n }\n }\n else {\n passthrough.push(entry);\n }\n }\n else if (entry && typeof entry === 'object') {\n const obj = entry as { path?: string; populate?: T_Input_Populate };\n\n if (obj.path && obj.path.includes('.')) {\n const parts = obj.path.split('.');\n const first = parts[0] || '';\n const rest = parts.slice(1).join('.');\n\n if (first) {\n if (!grouped.has(first)) {\n grouped.set(first, []);\n }\n if (rest) {\n grouped.get(first)!.push(rest);\n }\n if (obj.populate) {\n grouped.get(first)!.push(obj.populate as unknown as any);\n }\n }\n }\n else {\n passthrough.push(entry as any);\n }\n }\n }\n\n const normalized: any[] = [...passthrough];\n grouped.forEach((nested, root) => {\n const flat: any[] = [];\n\n for (const n of nested) {\n if (typeof n === 'string') {\n flat.push(n);\n }\n else if (n && typeof n === 'object') {\n flat.push(n);\n }\n }\n if (flat.length > 0) {\n normalized.push({ path: root as string, populate: flat as unknown as T_Input_Populate });\n }\n else {\n normalized.push(root);\n }\n });\n\n return normalized as unknown as T_Input_Populate;\n };\n\n const normalizedPopulate = normalizePopulate(populate);\n\n await applyNestedPopulate(mongoose, clonedDocuments, normalizedPopulate, virtualConfigs as I_DynamicVirtualConfig<unknown, string>[], startModel);\n }\n\n return clonedDocuments;\n}\n"],"names":["isObject","value","filterDynamicVirtualsFromPopulate","populate","dynamicVirtuals","dynamicVirtualNames","v","filtered","p","virtualName","popObj","path","remapDynamicPopulate","documents","virtualOptions","modelGroups","doc","modelName","modelNameString","convertedModelName","convertEnumToModelName","error","catchError","model","docs","isMongooseDoc","obj","populateDynamicVirtuals","mongoose","virtualConfigs","projection","startModel","requestedVirtuals","config","clonedDocuments","deepClone","name","options","modelProcessingMap","virtualConfig","populateGroups","group","processing","localValueSet","localVal","strVal","idx","docWithKeys","d","Model","allLocalValues","val","foreignFields","localValuesArray","query","field","allPopulatedData","relevantData","item","foreignVal","countMap","key","localValue","count","docToUpdate","resultMap","results","normalizedPopulate","pop","asArray","grouped","passthrough","entry","parts","first","rest","normalized","nested","root","flat","n","applyNestedPopulate"],"mappings":";;;;AAaO,SAASA,EAASC,GAAiC;AACtD,SAAOA,KAAS,QAAQ,OAAOA,KAAU;AAC7C;AAWO,SAASC,EACZC,GACAC,GAC4B;AAC5B,MAAI,CAACD,KAAY,CAACC,KAAmBA,EAAgB,WAAW;AAC5D,WAAOD;AAGX,QAAME,IAAsB,IAAI,IAAID,EAAgB,IAAI,CAAAE,MAAKA,EAAE,IAAI,CAAC;AAEpE,MAAI,MAAM,QAAQH,CAAQ,GAAG;AACzB,UAAMI,IAAWJ,EAAS,OAAO,CAACK,MAAM;AACpC,UAAI,OAAOA,KAAM;AACb,eAAO,CAAC,CAAC,GAAGH,CAAmB,EAAE;AAAA,UAAK,OAClCG,MAAMC,KAAeD,EAAE,WAAW,GAAGC,CAAW,GAAG;AAAA,QAAA;AAI3D,UAAI,OAAOD,KAAM,YAAYA,MAAM,MAAM;AACrC,cAAME,IAASF,GACTG,IAAOD,EAAO,QAAQA,EAAO,YAAY;AAE/C,eAAO,CAAC,CAAC,GAAGL,CAAmB,EAAE;AAAA,UAAK,OAClCM,MAASF,KAAeE,EAAK,WAAW,GAAGF,CAAW,GAAG;AAAA,QAAA;AAAA,MAEjE;AAEA,aAAO;AAAA,IACX,CAAC;AAED,WAAOF,EAAS,SAAS,IAAKA,IAAgC;AAAA,EAClE;AAEA,MAAI,OAAOJ,KAAa;AACpB,WAAO,CAAC,GAAGE,CAAmB,EAAE;AAAA,MAAK,OACjCF,MAAaM,KAAeN,EAAS,WAAW,GAAGM,CAAW,GAAG;AAAA,IAAA,IAE/D,SACAN;AAGV,MAAI,OAAOA,KAAa,YAAYA,MAAa,MAAM;AACnD,UAAMO,IAASP,GACTQ,IAAOD,EAAO,QAAQA,EAAO,YAAY;AAE/C,WAAO,CAAC,GAAGL,CAAmB,EAAE;AAAA,MAAK,OACjCM,MAASF,KAAeE,EAAK,WAAW,GAAGF,CAAW,GAAG;AAAA,IAAA,IAEvD,SACAN;AAAA,EACV;AAEA,SAAOA;AACX;AAaO,SAASS,EACZC,GACAJ,GACAK,GACmC;AACnC,MAAI,CAACD,EAAU,UAAU,CAACJ,KAAe,CAACK,GAAgB;AACtD,WAAO,CAAA;AAGX,QAAMC,wBAAkB,IAAA;AACxB,SAAAF,EAAU,QAAQ,CAACG,MAAQ;AACvB,QAAI;AACA,YAAMC,IAAYH,EAAe,IAAIE,CAAG;AAExC,UAA+BC,KAAc;AACzC;AAGJ,YAAMC,IAAkB,OAAOD,KAAc,WAAWA,IAAY,OAAOA,CAAS;AAEpF,UAAIC,KAAmBA,EAAgB,KAAA,MAAW,IAAI;AAClD,cAAMC,IAAqBC,EAAuBF,CAAe;AAEjE,QAAKH,EAAY,IAAII,CAAkB,KACnCJ,EAAY,IAAII,GAAoB,EAAE,GAG1CJ,EAAY,IAAII,CAAkB,EAAG,KAAKH,CAAG;AAAA,MACjD;AAAA,IACJ,SACOK,GAAO;AACV,MAAAC,EAAW,IAAI,MAAM,4CAA4Cb,CAAW,MAAMY,aAAiB,QAAQA,EAAM,UAAU,OAAOA,CAAK,CAAC,EAAE,CAAC;AAAA,IAC/I;AAAA,EACJ,CAAC,GAEM,MAAM,KAAKN,EAAY,QAAA,GAAW,CAAC,CAACQ,GAAOC,CAAI,OAAO,EAAE,OAAAD,GAAO,MAAAC,IAAO;AACjF;AAOO,SAASC,EAAcC,GAAqE;AAC/F,SAAOA,MAAQ,QAAQ,OAAOA,KAAQ,YAAY,cAAcA,KAAO,OAAQA,EAA8B,YAAa;AAC9H;AAqBA,eAAsBC,EAClBC,GACAf,GACAgB,GACA1B,GACA2B,GACAC,GACY;AAKZ,MAJI,CAAClB,EAAU,UAAU,CAACgB,EAAe,UAIrC,CAAC1B;AACD,WAAOU;AAGX,QAAMmB,IAAoBH,EAAe,OAAO,CAACI,MAAW;AACxD,QAAI,MAAM,QAAQ9B,CAAQ;AACtB,aAAOA,EAAS,SAAS,KAAKA,EAAS,KAAK,CAACK,MAAM;AAC/C,YAAI,OAAOA,KAAM;AACb,iBAAOA,MAAMyB,EAAO,QAAQzB,EAAE,WAAW,GAAGyB,EAAO,IAAI,GAAG;AAE9D,YAAIzB,KAAK,OAAOA,KAAM,UAAU;AAC5B,gBAAME,IAASF,GACTG,IAAOD,EAAO,QAAQA,EAAO,YAAY;AAE/C,iBAAOC,MAASsB,EAAO,QAAQtB,EAAK,WAAW,GAAGsB,EAAO,IAAI,GAAG;AAAA,QACpE;AAEA,eAAO;AAAA,MACX,CAAC;AAGL,QAAI,OAAO9B,KAAa;AACpB,aAAOA,MAAa8B,EAAO,QAAQ9B,EAAS,WAAW,GAAG8B,EAAO,IAAI,GAAG;AAG5E,QAAI,OAAO9B,KAAa,YAAYA,MAAa,MAAM;AACnD,YAAMO,IAASP,GACTQ,IAAOD,EAAO,QAAQA,EAAO,YAAY;AAE/C,aAAQC,MAASsB,EAAO,QAAStB,EAAK,WAAW,GAAGsB,EAAO,IAAI,GAAG;AAAA,IACtE;AAEA,WAAO;AAAA,EACX,CAAC;AAED,MAAID,EAAkB,WAAW;AAC7B,WAAOnB;AAGX,QAAMqB,IAAkBC,EAAUtB,EAAU,IAAI,CAAAG,MAAOS,EAAcT,CAAG,IAAIA,EAAI,SAAA,IAAaA,CAAG,CAAC;AAEjG,EAAAkB,EAAgB,QAAQ,CAAClB,MAAQ;AAC7B,IAAAgB,EAAkB,QAAQ,CAAC,EAAE,MAAAI,GAAM,SAAAC,QAAc;AAC7C,MAAMD,KAAQpB,MACTA,EAAmCoB,CAAc,IAAIC,EAAQ,QAAQ,IAAKA,EAAQ,UAAU,OAAO,CAAA;AAAA,IAE5G,CAAC;AAAA,EACL,CAAC;AAED,QAAMC,wBAAyB,IAAA;AAM/B,aAAWC,KAAiBP,GAAmB;AAC3C,UAAM,EAAE,MAAAI,GAAM,SAAAC,EAAA,IAAYE,GACpBC,IAAiB5B,EAAqBsB,GAAiBE,GAAMC,CAAO;AAE1E,eAAWI,KAASD,GAAgB;AAChC,MAAKF,EAAmB,IAAIG,EAAM,KAAK,KACnCH,EAAmB,IAAIG,EAAM,OAAO;AAAA,QAChC,UAAU,CAAA;AAAA,QACV,oCAAoB,IAAA;AAAA,QACpB,sCAAsB,IAAA;AAAA,MAAI,CAC7B;AAGL,YAAMC,IAAaJ,EAAmB,IAAIG,EAAM,KAAK;AAErD,MAAKC,EAAW,SAAS,KAAK,OAAKpC,EAAE,SAAS8B,CAAI,MAC9CM,EAAW,SAAS,KAAKH,CAAa,GACtCG,EAAW,eAAe,IAAIN,GAAgB,oBAAI,KAAK;AAG3D,YAAMO,IAAgBD,EAAW,eAAe,IAAIN,CAAc;AAClE,MAAAK,EAAM,KAAK,QAAQ,CAACzB,MAAQ;AACxB,cAAM4B,IAAY5B,EAAmCqB,EAAQ,UAAU;AAEvE,YAAIO,KAAY,MAAM;AAClB,gBAAMC,IAAS,OAAOD,CAAQ;AAC9B,UAAAD,EAAc,IAAIE,CAAM;AAExB,cAAIC,IAAM;AAEV,gBAAMC,IAAc/B;AAEpB,UAAI+B,EAAY,OAAU,SACtBD,IAAMZ,EAAgB,UAAU,CAACc,MACXA,EAED,OAAUD,EAAY,EAC1C,IAEIA,EAAY,QAAW,WAC5BD,IAAMZ,EAAgB,UAAU,CAACc,MACXA,EAED,KAAQ,WAAA,MAAiBD,EAAY,KAAQ,WAAA,CACjE,IAGDD,MAAQ,OACHJ,EAAW,iBAAiB,IAAIG,CAAM,KACvCH,EAAW,iBAAiB,IAAIG,GAAQ,CAAA,CAAE,GAE9CH,EAAW,iBAAiB,IAAIG,CAAM,EAAG,KAAKC,CAAG;AAAA,QAEzD;AAAA,MACJ,CAAC;AAAA,IACL;AAAA,EACJ;AA2FA,MAzFA,MAAM,QAAQ,IAAI,MAAM,KAAKR,EAAmB,QAAA,GAAW,OAAO,CAACrB,GAAWyB,CAAU,MAAM;AAC1F,UAAMO,IAAQrB,EAAS,OAAOX,CAAS;AAEvC,QAAI,CAACgC;AACD;AAGJ,UAAMC,wBAAqB,IAAA;AAK3B,QAJAR,EAAW,eAAe,QAAQ,CAACC,MAAkB;AACjD,MAAAA,EAAc,QAAQ,CAAAQ,MAAOD,EAAe,IAAIC,CAAG,CAAC;AAAA,IACxD,CAAC,GAEGD,EAAe,SAAS;AACxB;AAGJ,UAAME,IAAgB,CAAC,GAAG,IAAI,IAAIV,EAAW,SAAS,IAAI,CAAApC,MAAKA,EAAE,QAAQ,YAAY,CAAC,CAAC,GACjF+C,IAAmB,CAAC,GAAGH,CAAc;AAC3C,QAAII;AAEJ,IAAIF,EAAc,WAAW,IACzBE,IAAQ,EAAE,CAAC,OAAOF,EAAc,CAAC,CAAC,CAAC,GAAG,EAAE,KAAKC,IAAiB,IAG9DC,IAAQ,EAAE,KAAKF,EAAc,IAAI,QAAU,EAAE,CAACG,CAAK,GAAG,EAAE,KAAKF,EAAA,EAAiB,EAAI,EAAA;AAGtF,UAAMG,IAAmB,MAAMP,EAAM,KAAKK,GAAOxB,CAAU,EAAE,KAAA;AAE7D,eAAWS,KAAiBG,EAAW,UAAU;AAC7C,YAAM,EAAE,MAAAN,GAAM,SAAAC,EAAA,IAAYE,GACpBkB,IAAeD,EAAiB,OAAO,CAACE,MAAS;AACnD,cAAMC,IAAcD,EAAMrB,EAAQ,YAAY;AAE9C,eAAOsB,KAAc,QAAQT,EAAe,IAAI,OAAOS,CAAU,CAAC;AAAA,MACtE,CAAC;AAED,UAAItB,EAAQ,OAAO;AACf,cAAMuB,wBAAe,IAAA;AAErB,QAAAH,EAAa,QAAQ,CAACC,MAAS;AAC3B,gBAAMG,IAAOH,EAAMrB,EAAQ,YAAY,GAAG,SAAA;AAE1C,UAAIwB,KACAD,EAAS,IAAIC,IAAMD,EAAS,IAAIC,CAAG,KAAK,KAAK,CAAC;AAAA,QAEtD,CAAC,GAEDnB,EAAW,eAAe,IAAIN,CAAc,EAAG,QAAQ,CAAC0B,MAAe;AACnE,gBAAMtC,IAAOkB,EAAW,iBAAiB,IAAIoB,CAAU,KAAK,CAAA,GACtDC,IAAQH,EAAS,IAAIE,CAAU,KAAK;AAE1C,UAAAtC,EAAK,QAAQ,CAACsB,MAAQ;AAClB,kBAAMkB,IAAc9B,EAAgBY,CAAG;AAEvC,YAAIkB,EAAY5B,CAAI,MAAM,WACtB4B,EAAY5B,CAAI,IAAI2B;AAAA,UAE5B,CAAC;AAAA,QACL,CAAC;AAAA,MACL,OACK;AACD,cAAME,wBAAgB,IAAA;AAEtB,QAAAR,EAAa,QAAQ,CAACC,MAAS;AAC3B,gBAAMG,IAAOH,EAAMrB,EAAQ,YAAY,GAAG,SAAA;AAE1C,UAAIwB,MACKI,EAAU,IAAIJ,CAAG,KAClBI,EAAU,IAAIJ,GAAK,EAAE,GAEzBI,EAAU,IAAIJ,CAAG,EAAG,KAAKH,CAAI;AAAA,QAErC,CAAC,GAEDhB,EAAW,eAAe,IAAIN,CAAc,EAAG,QAAQ,CAACQ,MAAa;AACjE,gBAAMpB,IAAOkB,EAAW,iBAAiB,IAAIE,CAAQ,KAAK,CAAA,GACpDsB,IAAUD,EAAU,IAAIrB,CAAQ,KAAK,CAAA,GACrC3C,IAAQoC,EAAQ,UAAW6B,EAAQ,CAAC,KAAK,OAAQA;AAEvD,UAAA1C,EAAK,QAAQ,CAACsB,MAAQ;AAClB,kBAAMkB,IAAc9B,EAAgBY,CAAG;AACvC,YAAAkB,EAAY5B,CAAI,IAAInC;AAAA,UACxB,CAAC;AAAA,QACL,CAAC;AAAA,MACL;AAAA,IACJ;AAAA,EACJ,CAAC,CAAC,GAEEE,GAAU;AA2EV,UAAMgE,KA1EoB,CAACC,MAA4C;AACnE,YAAMC,IAAU,MAAM,QAAQD,CAAG,IAAIA,IAAM,CAACA,CAAG,GACzCE,wBAAc,IAAA,GACdC,IAAqB,CAAA;AAE3B,iBAAWC,KAASH;AAChB,YAAI,OAAOG,KAAU;AACjB,cAAIA,EAAM,SAAS,GAAG,GAAG;AACrB,kBAAMC,IAAQD,EAAM,MAAM,GAAG,GACvBE,IAAQD,EAAM,CAAC,KAAK,IACpBE,IAAOF,EAAM,MAAM,CAAC,EAAE,KAAK,GAAG;AAEpC,YAAIC,MACKJ,EAAQ,IAAII,CAAK,KAClBJ,EAAQ,IAAII,GAAO,EAAE,GAErBC,KACAL,EAAQ,IAAII,CAAK,EAAG,KAAKC,CAAI;AAAA,UAGzC;AAEI,YAAAJ,EAAY,KAAKC,CAAK;AAAA,iBAGrBA,KAAS,OAAOA,KAAU,UAAU;AACzC,gBAAM9C,IAAM8C;AAEZ,cAAI9C,EAAI,QAAQA,EAAI,KAAK,SAAS,GAAG,GAAG;AACpC,kBAAM+C,IAAQ/C,EAAI,KAAK,MAAM,GAAG,GAC1BgD,IAAQD,EAAM,CAAC,KAAK,IACpBE,IAAOF,EAAM,MAAM,CAAC,EAAE,KAAK,GAAG;AAEpC,YAAIC,MACKJ,EAAQ,IAAII,CAAK,KAClBJ,EAAQ,IAAII,GAAO,EAAE,GAErBC,KACAL,EAAQ,IAAII,CAAK,EAAG,KAAKC,CAAI,GAE7BjD,EAAI,YACJ4C,EAAQ,IAAII,CAAK,EAAG,KAAKhD,EAAI,QAA0B;AAAA,UAGnE;AAEI,YAAA6C,EAAY,KAAKC,CAAY;AAAA,QAErC;AAGJ,YAAMI,IAAoB,CAAC,GAAGL,CAAW;AACzC,aAAAD,EAAQ,QAAQ,CAACO,GAAQC,MAAS;AAC9B,cAAMC,IAAc,CAAA;AAEpB,mBAAWC,KAAKH;AACZ,WAAI,OAAOG,KAAM,YAGRA,KAAK,OAAOA,KAAM,aACvBD,EAAK,KAAKC,CAAC;AAGnB,QAAID,EAAK,SAAS,IACdH,EAAW,KAAK,EAAE,MAAME,GAAgB,UAAUC,GAAqC,IAGvFH,EAAW,KAAKE,CAAI;AAAA,MAE5B,CAAC,GAEMF;AAAA,IACX,GAE6CzE,CAAQ;AAErD,UAAM8E,EAAoBrD,GAAUM,GAAiBiC,GAAoBtC,GAA6DE,CAAU;AAAA,EACpJ;AAEA,SAAOG;AACX;"}
|
|
1
|
+
{"version":3,"file":"mongo.dynamic-populate.js","names":[],"sources":["../../../src/node/mongo/mongo.dynamic-populate.ts"],"sourcesContent":["import type mongooseRaw from 'mongoose';\n\nimport { deepClone } from '#util/index.js';\n\nimport type { I_DynamicVirtualConfig, I_DynamicVirtualOptions, T_Input_Populate } from './mongo.type.js';\n\nimport { catchError } from '../log/index.js';\nimport { applyNestedPopulate } from './mongo.populate.js';\nimport { convertEnumToModelName } from './mongo.util.js';\n\n/**\n * Checks if value is object-like (e.g., objects, arrays, etc.), not null.\n */\nexport function isObject(value: unknown): value is object {\n return value != null && typeof value === 'object';\n}\n\n/**\n * Filters out dynamic virtuals from populate options to prevent Mongoose from trying to populate them.\n * This function creates a new populate configuration that only includes regular virtuals.\n *\n * @template T - The document type\n * @param populate - The original populate options\n * @param dynamicVirtuals - Array of dynamic virtual configurations\n * @returns Filtered populate options excluding dynamic virtuals\n */\nexport function filterDynamicVirtualsFromPopulate<T>(\n populate: T_Input_Populate | undefined,\n dynamicVirtuals: I_DynamicVirtualConfig<T>[] | undefined,\n): T_Input_Populate | undefined {\n if (!populate || !dynamicVirtuals || dynamicVirtuals.length === 0) {\n return populate;\n }\n\n const dynamicVirtualNames = new Set(dynamicVirtuals.map(v => v.name));\n\n if (Array.isArray(populate)) {\n const filtered = populate.filter((p) => {\n if (typeof p === 'string') {\n return ![...dynamicVirtualNames].some(virtualName =>\n p === virtualName || p.startsWith(`${virtualName}.`),\n );\n }\n\n if (typeof p === 'object' && p !== null) {\n const popObj = p as { path?: string; populate?: string };\n const path = popObj.path || popObj.populate || '';\n\n return ![...dynamicVirtualNames].some(virtualName =>\n path === virtualName || path.startsWith(`${virtualName}.`),\n );\n }\n\n return true;\n });\n\n return filtered.length > 0 ? (filtered as T_Input_Populate) : undefined;\n }\n\n if (typeof populate === 'string') {\n return [...dynamicVirtualNames].some(virtualName =>\n populate === virtualName || populate.startsWith(`${virtualName}.`),\n )\n ? undefined\n : populate;\n }\n\n if (typeof populate === 'object' && populate !== null) {\n const popObj = populate as { path?: string; populate?: string };\n const path = popObj.path || popObj.populate || '';\n\n return [...dynamicVirtualNames].some(virtualName =>\n path === virtualName || path.startsWith(`${virtualName}.`),\n )\n ? undefined\n : populate;\n }\n\n return populate;\n}\n\n/**\n * Groups documents by the resolved model name for a dynamic virtual field.\n * Used to batch population queries for dynamic virtuals.\n *\n * @template T - The document type\n * @template R - The model name type (usually string or enum)\n * @param {T[]} documents - The array of documents to process\n * @param {string} virtualName - The name of the dynamic virtual field\n * @param {I_DynamicVirtualOptions<T, R>} virtualOptions - The dynamic virtual options (must include a ref function)\n * @returns {Array<{ model: string; docs: T[] }>} An array of groups, each with a model name and the docs for that model\n */\nexport function remapDynamicPopulate<T, R extends string = string>(\n documents: T[],\n virtualName: string,\n virtualOptions: I_DynamicVirtualOptions<T, R>,\n): Array<{ model: string; docs: T[] }> {\n if (!documents.length || !virtualName || !virtualOptions?.ref) {\n return [];\n }\n\n const modelGroups = new Map<string, T[]>();\n documents.forEach((doc) => {\n try {\n const modelName = virtualOptions.ref(doc);\n\n if (modelName === undefined || modelName === null) {\n return;\n }\n\n const modelNameString = typeof modelName === 'string' ? modelName : String(modelName);\n\n if (modelNameString && modelNameString.trim() !== '') {\n const convertedModelName = convertEnumToModelName(modelNameString);\n\n if (!modelGroups.has(convertedModelName)) {\n modelGroups.set(convertedModelName, []);\n }\n\n modelGroups.get(convertedModelName)!.push(doc);\n }\n }\n catch (error) {\n catchError(new Error(`Dynamic ref function failed for virtual \"${virtualName}\": ${error instanceof Error ? error.message : String(error)}`));\n }\n });\n\n return Array.from(modelGroups.entries(), ([model, docs]) => ({ model, docs }));\n}\n\n/**\n * Type guard to check if an object is a Mongoose Document (has toObject method).\n * @param obj - The object to check\n * @returns True if obj has a toObject function\n */\nexport function isMongooseDoc(obj: unknown): obj is { toObject: () => { [key: string]: unknown } } {\n return obj !== null && typeof obj === 'object' && 'toObject' in obj && typeof (obj as { toObject: unknown }).toObject === 'function';\n}\n\n/**\n * Optimized batch population for dynamic virtuals.\n *\n * - Groups documents by model and batches queries for each model.\n * - Populates all dynamic virtuals in parallel for maximum performance.\n * - Uses direct assignment for plain objects and skips already populated fields.\n * - Supports optional projection for population queries.\n * - Only populates virtuals that are explicitly requested in populate options.\n * - Reminder: Ensure indexes exist on foreignField in referenced collections for best performance.\n *\n * @template T - The document type (must be an object)\n * @template R - The model name type (usually string or enum)\n * @param {typeof mongooseRaw} mongoose - The Mongoose instance\n * @param {T[]} documents - The array of documents to populate\n * @param {I_DynamicVirtualConfig<T, R>[]} virtualConfigs - The dynamic virtual configurations to process\n * @param {T_Input_Populate} [populate] - Population options to determine which virtuals to populate\n * @param {Record<string, 0 | 1>} [projection] - Optional projection for population queries\n * @returns {Promise<object[]>} The array of documents with dynamic virtuals populated\n */\nexport async function populateDynamicVirtuals<T extends object, R extends string = string>(\n mongoose: typeof mongooseRaw,\n documents: T[],\n virtualConfigs: I_DynamicVirtualConfig<T, R>[],\n populate?: T_Input_Populate,\n projection?: Record<string, 0 | 1>,\n startModel?: any,\n): Promise<T[]> {\n if (!documents.length || !virtualConfigs.length) {\n return documents;\n }\n\n if (!populate) {\n return documents;\n }\n\n const requestedVirtuals = virtualConfigs.filter((config) => {\n if (Array.isArray(populate)) {\n return populate.length > 0 && populate.some((p) => {\n if (typeof p === 'string') {\n return p === config.name || p.startsWith(`${config.name}.`);\n }\n if (p && typeof p === 'object') {\n const popObj = p as { path?: string; populate?: string };\n const path = popObj.path || popObj.populate || '';\n\n return path === config.name || path.startsWith(`${config.name}.`);\n }\n\n return false;\n });\n }\n\n if (typeof populate === 'string') {\n return populate === config.name || populate.startsWith(`${config.name}.`);\n }\n\n if (typeof populate === 'object' && populate !== null) {\n const popObj = populate as { path?: string; populate?: string };\n const path = popObj.path || popObj.populate || '';\n\n return (path === config.name) || path.startsWith(`${config.name}.`);\n }\n\n return false;\n });\n\n if (requestedVirtuals.length === 0) {\n return documents;\n }\n\n const clonedDocuments = deepClone(documents.map(doc => isMongooseDoc(doc) ? doc.toObject() : doc)) as T[];\n\n clonedDocuments.forEach((doc) => {\n requestedVirtuals.forEach(({ name, options }) => {\n if (!(name in doc)) {\n (doc as { [key: string]: unknown })[name as string] = options.count ? 0 : (options.justOne ? null : []);\n }\n });\n });\n\n const modelProcessingMap = new Map<string, {\n virtuals: I_DynamicVirtualConfig<T, R>[];\n localValueSets: Map<string, Set<string>>;\n docsByLocalValue: Map<string, number[]>;\n }>();\n\n for (const virtualConfig of requestedVirtuals) {\n const { name, options } = virtualConfig;\n const populateGroups = remapDynamicPopulate(clonedDocuments, name, options);\n\n for (const group of populateGroups) {\n if (!modelProcessingMap.has(group.model)) {\n modelProcessingMap.set(group.model, {\n virtuals: [],\n localValueSets: new Map(),\n docsByLocalValue: new Map(),\n });\n }\n\n const processing = modelProcessingMap.get(group.model)!;\n\n if (!processing.virtuals.some(v => v.name === name)) {\n processing.virtuals.push(virtualConfig);\n processing.localValueSets.set(name as string, new Set());\n }\n\n const localValueSet = processing.localValueSets.get(name as string)!;\n group.docs.forEach((doc) => {\n const localVal = (doc as { [key: string]: unknown })[options.localField];\n\n if (localVal != null) {\n const strVal = String(localVal);\n localValueSet.add(strVal);\n\n let idx = -1;\n\n const docWithKeys = doc as { [key: string]: unknown };\n\n if (docWithKeys['id'] !== undefined) {\n idx = clonedDocuments.findIndex((d) => {\n const dWithKeys = d as { [key: string]: unknown };\n\n return dWithKeys['id'] === docWithKeys['id'];\n });\n }\n else if (docWithKeys['_id'] !== undefined) {\n idx = clonedDocuments.findIndex((d) => {\n const dWithKeys = d as { [key: string]: unknown };\n\n return dWithKeys['_id']?.toString?.() === docWithKeys['_id']?.toString?.();\n });\n }\n\n if (idx !== -1) {\n if (!processing.docsByLocalValue.has(strVal)) {\n processing.docsByLocalValue.set(strVal, []);\n }\n processing.docsByLocalValue.get(strVal)!.push(idx);\n }\n }\n });\n }\n }\n\n await Promise.all(Array.from(modelProcessingMap.entries(), async ([modelName, processing]) => {\n const Model = mongoose.models[modelName];\n\n if (!Model) {\n return;\n }\n\n const allLocalValues = new Set<string>();\n processing.localValueSets.forEach((localValueSet) => {\n localValueSet.forEach(val => allLocalValues.add(val));\n });\n\n if (allLocalValues.size === 0) {\n return;\n }\n\n const foreignFields = [...new Set(processing.virtuals.map(v => v.options.foreignField))];\n const localValuesArray = [...allLocalValues];\n let query;\n\n if (foreignFields.length === 1) {\n query = { [String(foreignFields[0])]: { $in: localValuesArray } };\n }\n else {\n query = { $or: foreignFields.map(field => ({ [field]: { $in: localValuesArray } })) };\n }\n\n const allPopulatedData = await Model.find(query, projection).lean();\n\n for (const virtualConfig of processing.virtuals) {\n const { name, options } = virtualConfig;\n const relevantData = allPopulatedData.filter((item) => {\n const foreignVal = (item)[options.foreignField];\n\n return foreignVal != null && allLocalValues.has(String(foreignVal));\n });\n\n if (options.count) {\n const countMap = new Map<string, number>();\n\n relevantData.forEach((item) => {\n const key = (item)[options.foreignField]?.toString();\n\n if (key) {\n countMap.set(key, (countMap.get(key) || 0) + 1);\n }\n });\n\n processing.localValueSets.get(name as string)!.forEach((localValue) => {\n const docs = processing.docsByLocalValue.get(localValue) || [];\n const count = countMap.get(localValue) || 0;\n\n docs.forEach((idx) => {\n const docToUpdate = clonedDocuments[idx] as { [key: string]: unknown };\n\n if (docToUpdate[name] === undefined) {\n docToUpdate[name] = count;\n }\n });\n });\n }\n else {\n const resultMap = new Map<string, T[]>();\n\n relevantData.forEach((item) => {\n const key = (item)[options.foreignField]?.toString();\n\n if (key) {\n if (!resultMap.has(key)) {\n resultMap.set(key, []);\n }\n resultMap.get(key)!.push(item);\n }\n });\n\n processing.localValueSets.get(name as string)!.forEach((localVal) => {\n const docs = processing.docsByLocalValue.get(localVal) || [];\n const results = resultMap.get(localVal) || [];\n const value = options.justOne ? (results[0] || null) : results;\n\n docs.forEach((idx) => {\n const docToUpdate = clonedDocuments[idx] as { [key: string]: unknown };\n docToUpdate[name] = value;\n });\n });\n }\n }\n }));\n\n if (populate) {\n const normalizePopulate = (pop: T_Input_Populate): T_Input_Populate => {\n const asArray = Array.isArray(pop) ? pop : [pop];\n const grouped = new Map<string, any[]>();\n const passthrough: any[] = [];\n\n for (const entry of asArray) {\n if (typeof entry === 'string') {\n if (entry.includes('.')) {\n const parts = entry.split('.');\n const first = parts[0] || '';\n const rest = parts.slice(1).join('.');\n\n if (first) {\n if (!grouped.has(first)) {\n grouped.set(first, []);\n }\n if (rest) {\n grouped.get(first)!.push(rest);\n }\n }\n }\n else {\n passthrough.push(entry);\n }\n }\n else if (entry && typeof entry === 'object') {\n const obj = entry as { path?: string; populate?: T_Input_Populate };\n\n if (obj.path && obj.path.includes('.')) {\n const parts = obj.path.split('.');\n const first = parts[0] || '';\n const rest = parts.slice(1).join('.');\n\n if (first) {\n if (!grouped.has(first)) {\n grouped.set(first, []);\n }\n if (rest) {\n grouped.get(first)!.push(rest);\n }\n if (obj.populate) {\n grouped.get(first)!.push(obj.populate as unknown as any);\n }\n }\n }\n else {\n passthrough.push(entry as any);\n }\n }\n }\n\n const normalized: any[] = [...passthrough];\n grouped.forEach((nested, root) => {\n const flat: any[] = [];\n\n for (const n of nested) {\n if (typeof n === 'string') {\n flat.push(n);\n }\n else if (n && typeof n === 'object') {\n flat.push(n);\n }\n }\n if (flat.length > 0) {\n normalized.push({ path: root as string, populate: flat as unknown as T_Input_Populate });\n }\n else {\n normalized.push(root);\n }\n });\n\n return normalized as unknown as T_Input_Populate;\n };\n\n const normalizedPopulate = normalizePopulate(populate);\n\n await applyNestedPopulate(mongoose, clonedDocuments, normalizedPopulate, virtualConfigs as I_DynamicVirtualConfig<unknown, string>[], startModel);\n }\n\n return clonedDocuments;\n}\n"],"mappings":"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"}
|