@nocobase/database 1.9.0-beta.5 → 1.9.0-beta.6
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/lib/index.d.ts
CHANGED
|
@@ -42,3 +42,4 @@ export { default as fieldTypeMap } from './view/field-type-map';
|
|
|
42
42
|
export * from './view/view-inference';
|
|
43
43
|
export * from './update-guard';
|
|
44
44
|
export { default as operators } from './operators';
|
|
45
|
+
export { filterIncludes, mergeIncludes } from './utils/filter-include';
|
package/lib/index.js
CHANGED
|
@@ -54,8 +54,10 @@ __export(src_exports, {
|
|
|
54
54
|
ValidationErrorItem: () => import_sequelize.ValidationErrorItem,
|
|
55
55
|
default: () => import_database.Database,
|
|
56
56
|
fieldTypeMap: () => import_field_type_map.default,
|
|
57
|
+
filterIncludes: () => import_filter_include.filterIncludes,
|
|
57
58
|
fn: () => import_sequelize.fn,
|
|
58
59
|
literal: () => import_sequelize.literal,
|
|
60
|
+
mergeIncludes: () => import_filter_include.mergeIncludes,
|
|
59
61
|
operators: () => import_operators.default,
|
|
60
62
|
snakeCase: () => import_utils.snakeCase,
|
|
61
63
|
sqlParser: () => import_sql_parser.default,
|
|
@@ -98,6 +100,7 @@ var import_field_type_map = __toESM(require("./view/field-type-map"));
|
|
|
98
100
|
__reExport(src_exports, require("./view/view-inference"), module.exports);
|
|
99
101
|
__reExport(src_exports, require("./update-guard"), module.exports);
|
|
100
102
|
var import_operators = __toESM(require("./operators"));
|
|
103
|
+
var import_filter_include = require("./utils/filter-include");
|
|
101
104
|
// Annotate the CommonJS export names for ESM import in node:
|
|
102
105
|
0 && (module.exports = {
|
|
103
106
|
BaseError,
|
|
@@ -116,8 +119,10 @@ var import_operators = __toESM(require("./operators"));
|
|
|
116
119
|
ValidationError,
|
|
117
120
|
ValidationErrorItem,
|
|
118
121
|
fieldTypeMap,
|
|
122
|
+
filterIncludes,
|
|
119
123
|
fn,
|
|
120
124
|
literal,
|
|
125
|
+
mergeIncludes,
|
|
121
126
|
operators,
|
|
122
127
|
snakeCase,
|
|
123
128
|
sqlParser,
|
|
@@ -111,7 +111,14 @@ const _PostgresQueryInterface = class _PostgresQueryInterface extends import_que
|
|
|
111
111
|
return results[0]["exists"];
|
|
112
112
|
}
|
|
113
113
|
async listViews() {
|
|
114
|
-
|
|
114
|
+
var _a;
|
|
115
|
+
const targetSchema = ((_a = this.db.options) == null ? void 0 : _a.schema) || "public";
|
|
116
|
+
const sql = targetSchema ? `
|
|
117
|
+
SELECT viewname as name, definition, schemaname as schema
|
|
118
|
+
FROM pg_views
|
|
119
|
+
WHERE schemaname = '${targetSchema}'
|
|
120
|
+
ORDER BY viewname;
|
|
121
|
+
` : `
|
|
115
122
|
SELECT viewname as name, definition, schemaname as schema
|
|
116
123
|
FROM pg_views
|
|
117
124
|
WHERE schemaname NOT IN ('pg_catalog', 'information_schema')
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Merge a flat list of include descriptors by association (alias) key.
|
|
11
|
+
* - Nodes with the same association are merged into one.
|
|
12
|
+
* - `required` is OR-ed (true if any source is true).
|
|
13
|
+
* - Child includes are recursively merged with the same rules.
|
|
14
|
+
* - Empty `include` arrays are removed to keep the payload minimal.
|
|
15
|
+
*
|
|
16
|
+
* Notes:
|
|
17
|
+
* - Association keys are normalized via snake_case to ensure consistent merging.
|
|
18
|
+
* - This function is idempotent and order-insensitive for equivalent input sets.
|
|
19
|
+
*
|
|
20
|
+
* Usage example (input and output):
|
|
21
|
+
*
|
|
22
|
+
* const includesA = [
|
|
23
|
+
* { association: 'posts', required: true, include: [{ association: 'comments' }] },
|
|
24
|
+
* { association: 'profile' },
|
|
25
|
+
* ];
|
|
26
|
+
*
|
|
27
|
+
* const includesB = [
|
|
28
|
+
* { association: 'posts', include: [
|
|
29
|
+
* { association: 'comments', required: true },
|
|
30
|
+
* { association: 'tags' },
|
|
31
|
+
* ]
|
|
32
|
+
* },
|
|
33
|
+
* { association: 'roles', required: true },
|
|
34
|
+
* ];
|
|
35
|
+
*
|
|
36
|
+
* const merged = mergeIncludes([...includesA, ...includesB]);
|
|
37
|
+
*
|
|
38
|
+
* Result:
|
|
39
|
+
* [
|
|
40
|
+
* {
|
|
41
|
+
* association: 'posts',
|
|
42
|
+
* required: true,
|
|
43
|
+
* include: [
|
|
44
|
+
* { association: 'comments', required: true },
|
|
45
|
+
* { association: 'tags' },
|
|
46
|
+
* ],
|
|
47
|
+
* },
|
|
48
|
+
* { association: 'profile' },
|
|
49
|
+
* { association: 'roles', required: true },
|
|
50
|
+
* ]
|
|
51
|
+
*/
|
|
52
|
+
export declare const mergeIncludes: (includes?: any[]) => any[];
|
|
53
|
+
export declare const filterIncludes: (where: any, includes: any, options: {
|
|
54
|
+
underscored: boolean;
|
|
55
|
+
}) => any[];
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
var __defProp = Object.defineProperty;
|
|
11
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
12
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
13
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
14
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
15
|
+
var __export = (target, all) => {
|
|
16
|
+
for (var name in all)
|
|
17
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
18
|
+
};
|
|
19
|
+
var __copyProps = (to, from, except, desc) => {
|
|
20
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
21
|
+
for (let key of __getOwnPropNames(from))
|
|
22
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
23
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
24
|
+
}
|
|
25
|
+
return to;
|
|
26
|
+
};
|
|
27
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
+
var filter_include_exports = {};
|
|
29
|
+
__export(filter_include_exports, {
|
|
30
|
+
filterIncludes: () => filterIncludes,
|
|
31
|
+
mergeIncludes: () => mergeIncludes
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(filter_include_exports);
|
|
34
|
+
var import_utils = require("../utils");
|
|
35
|
+
const collectAssociationPathsFromWhere = /* @__PURE__ */ __name((where) => {
|
|
36
|
+
const aliasPaths = /* @__PURE__ */ new Set();
|
|
37
|
+
const traverse = /* @__PURE__ */ __name((value) => {
|
|
38
|
+
if (value == null) return;
|
|
39
|
+
if (Array.isArray(value)) {
|
|
40
|
+
for (const item of value) traverse(item);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
if (typeof value === "object") {
|
|
44
|
+
for (const [rawKey, child] of Object.entries(value)) {
|
|
45
|
+
if (typeof rawKey === "string" && rawKey.startsWith("$") && rawKey.endsWith("$")) {
|
|
46
|
+
const inner = rawKey.slice(1, -1);
|
|
47
|
+
const segments = inner.split(".");
|
|
48
|
+
if (segments.length > 1) {
|
|
49
|
+
aliasPaths.add(segments.slice(0, -1).join("."));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
traverse(child);
|
|
53
|
+
}
|
|
54
|
+
for (const sym of Object.getOwnPropertySymbols(value)) {
|
|
55
|
+
traverse(value[sym]);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}, "traverse");
|
|
59
|
+
traverse(where);
|
|
60
|
+
return Array.from(aliasPaths);
|
|
61
|
+
}, "collectAssociationPathsFromWhere");
|
|
62
|
+
const pruneIncludeTreeByPaths = /* @__PURE__ */ __name((includes = [], requiredPathsRaw, options) => {
|
|
63
|
+
const normalizedPaths = options.underscored ? requiredPathsRaw.map(
|
|
64
|
+
(p) => p.split(".").map((s) => (0, import_utils.snakeCase)(s)).join(".")
|
|
65
|
+
) : requiredPathsRaw;
|
|
66
|
+
if (!(includes == null ? void 0 : includes.length) || !(normalizedPaths == null ? void 0 : normalizedPaths.length)) return [];
|
|
67
|
+
const pruned = [];
|
|
68
|
+
for (const inc of includes) {
|
|
69
|
+
const association = inc == null ? void 0 : inc.association;
|
|
70
|
+
if (!association) continue;
|
|
71
|
+
const assocKey = options.underscored ? (0, import_utils.snakeCase)(String(association)) : String(association);
|
|
72
|
+
const matched = normalizedPaths.filter((p) => p === assocKey || p.startsWith(assocKey + "."));
|
|
73
|
+
if (!matched.length) continue;
|
|
74
|
+
const childRemainders = matched.map((p) => p === assocKey ? null : p.slice(assocKey.length + 1)).filter(Boolean);
|
|
75
|
+
const children = pruneIncludeTreeByPaths(inc.include ?? [], childRemainders, options);
|
|
76
|
+
const copy = { ...inc };
|
|
77
|
+
if (children.length) {
|
|
78
|
+
copy.include = children;
|
|
79
|
+
} else if ("include" in copy) {
|
|
80
|
+
delete copy.include;
|
|
81
|
+
}
|
|
82
|
+
pruned.push(copy);
|
|
83
|
+
}
|
|
84
|
+
return pruned;
|
|
85
|
+
}, "pruneIncludeTreeByPaths");
|
|
86
|
+
const mergeIncludes = /* @__PURE__ */ __name((includes = []) => {
|
|
87
|
+
const byAssociation = /* @__PURE__ */ new Map();
|
|
88
|
+
const mergeAll = /* @__PURE__ */ __name((list = []) => {
|
|
89
|
+
for (const inc of list) {
|
|
90
|
+
const association = inc == null ? void 0 : inc.association;
|
|
91
|
+
if (!association) continue;
|
|
92
|
+
const key = (0, import_utils.snakeCase)(String(association));
|
|
93
|
+
if (!byAssociation.has(key)) {
|
|
94
|
+
byAssociation.set(key, { ...inc, include: void 0 });
|
|
95
|
+
}
|
|
96
|
+
const target = byAssociation.get(key);
|
|
97
|
+
if (inc.required) target.required = true;
|
|
98
|
+
const mergedChildren = mergeIncludes([...target.include ?? [], ...inc.include ?? []]);
|
|
99
|
+
if (mergedChildren.length) {
|
|
100
|
+
target.include = mergedChildren;
|
|
101
|
+
} else if ("include" in target) {
|
|
102
|
+
delete target.include;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}, "mergeAll");
|
|
106
|
+
mergeAll(includes);
|
|
107
|
+
return Array.from(byAssociation.values());
|
|
108
|
+
}, "mergeIncludes");
|
|
109
|
+
const filterIncludes = /* @__PURE__ */ __name((where, includes, options) => {
|
|
110
|
+
const path = collectAssociationPathsFromWhere(where);
|
|
111
|
+
const result = pruneIncludeTreeByPaths(includes, path, options);
|
|
112
|
+
return result;
|
|
113
|
+
}, "filterIncludes");
|
|
114
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
115
|
+
0 && (module.exports = {
|
|
116
|
+
filterIncludes,
|
|
117
|
+
mergeIncludes
|
|
118
|
+
});
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nocobase/database",
|
|
3
|
-
"version": "1.9.0-beta.
|
|
3
|
+
"version": "1.9.0-beta.6",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"types": "./lib/index.d.ts",
|
|
7
7
|
"license": "AGPL-3.0",
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"@nocobase/logger": "1.9.0-beta.
|
|
10
|
-
"@nocobase/utils": "1.9.0-beta.
|
|
9
|
+
"@nocobase/logger": "1.9.0-beta.6",
|
|
10
|
+
"@nocobase/utils": "1.9.0-beta.6",
|
|
11
11
|
"async-mutex": "^0.3.2",
|
|
12
12
|
"chalk": "^4.1.1",
|
|
13
13
|
"cron-parser": "4.4.0",
|
|
@@ -38,5 +38,5 @@
|
|
|
38
38
|
"url": "git+https://github.com/nocobase/nocobase.git",
|
|
39
39
|
"directory": "packages/database"
|
|
40
40
|
},
|
|
41
|
-
"gitHead": "
|
|
41
|
+
"gitHead": "ada5e359a91135cb9baf605c04c5c380f067a046"
|
|
42
42
|
}
|