@nocobase/database 1.3.38-beta → 1.4.0-alpha
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/collection.d.ts +3 -2
- package/lib/collection.js +6 -0
- package/lib/database.d.ts +11 -23
- package/lib/database.js +21 -42
- package/lib/dialects/base-dialect.d.ts +20 -0
- package/lib/dialects/base-dialect.js +75 -0
- package/lib/dialects/index.d.ts +9 -0
- package/lib/dialects/index.js +30 -0
- package/lib/dialects/mariadb-dialect.d.ts +17 -0
- package/lib/dialects/mariadb-dialect.js +54 -0
- package/lib/dialects/mysql-dialect.d.ts +17 -0
- package/lib/dialects/mysql-dialect.js +54 -0
- package/lib/dialects/postgres-dialect.d.ts +18 -0
- package/lib/dialects/postgres-dialect.js +77 -0
- package/lib/dialects/sqlite-dialect.d.ts +17 -0
- package/lib/dialects/sqlite-dialect.js +51 -0
- package/lib/fields/date-field.d.ts +7 -2
- package/lib/fields/date-field.js +89 -0
- package/lib/fields/date-only-field.d.ts +15 -0
- package/lib/fields/date-only-field.js +45 -0
- package/lib/fields/datetime-field.d.ts +15 -0
- package/lib/fields/datetime-field.js +41 -0
- package/lib/fields/datetime-no-tz-field.d.ts +24 -0
- package/lib/fields/datetime-no-tz-field.js +128 -0
- package/lib/fields/datetime-tz-field.d.ts +15 -0
- package/lib/fields/datetime-tz-field.js +41 -0
- package/lib/fields/field.d.ts +1 -1
- package/lib/fields/field.js +3 -2
- package/lib/fields/index.d.ts +10 -1
- package/lib/fields/index.js +11 -1
- package/lib/fields/unix-timestamp-field.d.ts +22 -0
- package/lib/fields/unix-timestamp-field.js +94 -0
- package/lib/helpers.d.ts +2 -1
- package/lib/helpers.js +16 -49
- package/lib/index.d.ts +1 -0
- package/lib/index.js +3 -1
- package/lib/model.d.ts +1 -0
- package/lib/model.js +12 -0
- package/lib/operators/date.js +66 -24
- package/lib/options-parser.d.ts +1 -0
- package/lib/options-parser.js +32 -9
- package/lib/query-interface/query-interface-builder.js +3 -0
- package/lib/relation-repository/hasmany-repository.js +8 -11
- package/lib/relation-repository/multiple-relation-repository.d.ts +1 -0
- package/lib/relation-repository/multiple-relation-repository.js +11 -3
- package/lib/relation-repository/relation-repository.d.ts +6 -3
- package/lib/relation-repository/relation-repository.js +27 -4
- package/lib/repository.d.ts +5 -2
- package/lib/repository.js +27 -16
- package/lib/update-associations.d.ts +2 -1
- package/lib/view/field-type-map.d.ts +2 -2
- package/lib/view/field-type-map.js +17 -17
- package/package.json +4 -4
|
@@ -0,0 +1,94 @@
|
|
|
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 unix_timestamp_field_exports = {};
|
|
29
|
+
__export(unix_timestamp_field_exports, {
|
|
30
|
+
UnixTimestampField: () => UnixTimestampField
|
|
31
|
+
});
|
|
32
|
+
module.exports = __toCommonJS(unix_timestamp_field_exports);
|
|
33
|
+
var import_sequelize = require("sequelize");
|
|
34
|
+
var import_date_field = require("./date-field");
|
|
35
|
+
const _UnixTimestampField = class _UnixTimestampField extends import_date_field.DateField {
|
|
36
|
+
get dataType() {
|
|
37
|
+
return import_sequelize.DataTypes.BIGINT;
|
|
38
|
+
}
|
|
39
|
+
dateToValue(val) {
|
|
40
|
+
var _a, _b, _c, _d, _e;
|
|
41
|
+
if (val === null || val === void 0) {
|
|
42
|
+
return val;
|
|
43
|
+
}
|
|
44
|
+
let { accuracy } = this.options;
|
|
45
|
+
if ((_c = (_b = (_a = this.options) == null ? void 0 : _a.uiSchema) == null ? void 0 : _b["x-component-props"]) == null ? void 0 : _c.accuracy) {
|
|
46
|
+
accuracy = (_e = (_d = this.options) == null ? void 0 : _d.uiSchema["x-component-props"]) == null ? void 0 : _e.accuracy;
|
|
47
|
+
}
|
|
48
|
+
if (!accuracy) {
|
|
49
|
+
accuracy = "second";
|
|
50
|
+
}
|
|
51
|
+
let rationalNumber = 1e3;
|
|
52
|
+
if (accuracy === "millisecond") {
|
|
53
|
+
rationalNumber = 1;
|
|
54
|
+
}
|
|
55
|
+
return Math.floor(new Date(val).getTime() / rationalNumber);
|
|
56
|
+
}
|
|
57
|
+
additionalSequelizeOptions() {
|
|
58
|
+
var _a, _b, _c, _d, _e;
|
|
59
|
+
const { name } = this.options;
|
|
60
|
+
let { accuracy } = this.options;
|
|
61
|
+
if ((_c = (_b = (_a = this.options) == null ? void 0 : _a.uiSchema) == null ? void 0 : _b["x-component-props"]) == null ? void 0 : _c.accuracy) {
|
|
62
|
+
accuracy = (_e = (_d = this.options) == null ? void 0 : _d.uiSchema["x-component-props"]) == null ? void 0 : _e.accuracy;
|
|
63
|
+
}
|
|
64
|
+
if (!accuracy) {
|
|
65
|
+
accuracy = "second";
|
|
66
|
+
}
|
|
67
|
+
let rationalNumber = 1e3;
|
|
68
|
+
if (accuracy === "millisecond") {
|
|
69
|
+
rationalNumber = 1;
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
get() {
|
|
73
|
+
const value = this.getDataValue(name);
|
|
74
|
+
if (value === null || value === void 0) {
|
|
75
|
+
return value;
|
|
76
|
+
}
|
|
77
|
+
return new Date(value * rationalNumber);
|
|
78
|
+
},
|
|
79
|
+
set(value) {
|
|
80
|
+
if (value === null || value === void 0) {
|
|
81
|
+
this.setDataValue(name, value);
|
|
82
|
+
} else {
|
|
83
|
+
this.setDataValue(name, Math.floor(new Date(value).getTime() / rationalNumber));
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
__name(_UnixTimestampField, "UnixTimestampField");
|
|
90
|
+
let UnixTimestampField = _UnixTimestampField;
|
|
91
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
92
|
+
0 && (module.exports = {
|
|
93
|
+
UnixTimestampField
|
|
94
|
+
});
|
package/lib/helpers.d.ts
CHANGED
|
@@ -8,4 +8,5 @@
|
|
|
8
8
|
*/
|
|
9
9
|
import { Database, IDatabaseOptions } from './database';
|
|
10
10
|
export declare function parseDatabaseOptionsFromEnv(): Promise<IDatabaseOptions>;
|
|
11
|
-
export declare function checkDatabaseVersion(db: Database): Promise<
|
|
11
|
+
export declare function checkDatabaseVersion(db: Database): Promise<void>;
|
|
12
|
+
export declare function registerDialects(): void;
|
package/lib/helpers.js
CHANGED
|
@@ -38,11 +38,16 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
38
38
|
var helpers_exports = {};
|
|
39
39
|
__export(helpers_exports, {
|
|
40
40
|
checkDatabaseVersion: () => checkDatabaseVersion,
|
|
41
|
-
parseDatabaseOptionsFromEnv: () => parseDatabaseOptionsFromEnv
|
|
41
|
+
parseDatabaseOptionsFromEnv: () => parseDatabaseOptionsFromEnv,
|
|
42
|
+
registerDialects: () => registerDialects
|
|
42
43
|
});
|
|
43
44
|
module.exports = __toCommonJS(helpers_exports);
|
|
45
|
+
var import_database = require("./database");
|
|
44
46
|
var import_fs = __toESM(require("fs"));
|
|
45
|
-
var
|
|
47
|
+
var import_mysql_dialect = require("./dialects/mysql-dialect");
|
|
48
|
+
var import_sqlite_dialect = require("./dialects/sqlite-dialect");
|
|
49
|
+
var import_mariadb_dialect = require("./dialects/mariadb-dialect");
|
|
50
|
+
var import_postgres_dialect = require("./dialects/postgres-dialect");
|
|
46
51
|
/* istanbul ignore file -- @preserve */
|
|
47
52
|
function getEnvValue(key, defaultValue) {
|
|
48
53
|
return process.env[key] || defaultValue;
|
|
@@ -121,57 +126,19 @@ function customLogger(queryString, queryObject) {
|
|
|
121
126
|
}
|
|
122
127
|
}
|
|
123
128
|
__name(customLogger, "customLogger");
|
|
124
|
-
const dialectVersionAccessors = {
|
|
125
|
-
sqlite: {
|
|
126
|
-
sql: "select sqlite_version() as version",
|
|
127
|
-
get: /* @__PURE__ */ __name((v) => v, "get"),
|
|
128
|
-
version: "3.x"
|
|
129
|
-
},
|
|
130
|
-
mysql: {
|
|
131
|
-
sql: "select version() as version",
|
|
132
|
-
get: /* @__PURE__ */ __name((v) => {
|
|
133
|
-
const m = /([\d+.]+)/.exec(v);
|
|
134
|
-
return m[0];
|
|
135
|
-
}, "get"),
|
|
136
|
-
version: ">=8.0.17"
|
|
137
|
-
},
|
|
138
|
-
mariadb: {
|
|
139
|
-
sql: "select version() as version",
|
|
140
|
-
get: /* @__PURE__ */ __name((v) => {
|
|
141
|
-
const m = /([\d+.]+)/.exec(v);
|
|
142
|
-
return m[0];
|
|
143
|
-
}, "get"),
|
|
144
|
-
version: ">=10.9"
|
|
145
|
-
},
|
|
146
|
-
postgres: {
|
|
147
|
-
sql: "select version() as version",
|
|
148
|
-
get: /* @__PURE__ */ __name((v) => {
|
|
149
|
-
const m = /([\d+.]+)/.exec(v);
|
|
150
|
-
return import_semver.default.minVersion(m[0]).version;
|
|
151
|
-
}, "get"),
|
|
152
|
-
version: ">=10"
|
|
153
|
-
}
|
|
154
|
-
};
|
|
155
129
|
async function checkDatabaseVersion(db) {
|
|
156
|
-
|
|
157
|
-
const dialect = db.sequelize.getDialect();
|
|
158
|
-
const accessor = dialectVersionAccessors[dialect];
|
|
159
|
-
if (!accessor) {
|
|
160
|
-
throw new Error(`unsupported dialect ${dialect}`);
|
|
161
|
-
}
|
|
162
|
-
const result = await db.sequelize.query(accessor.sql, {
|
|
163
|
-
type: "SELECT"
|
|
164
|
-
});
|
|
165
|
-
const version = accessor.get((_a = result == null ? void 0 : result[0]) == null ? void 0 : _a.version);
|
|
166
|
-
const versionResult = import_semver.default.satisfies(version, accessor.version);
|
|
167
|
-
if (!versionResult) {
|
|
168
|
-
throw new Error(`to use ${dialect}, please ensure the version is ${accessor.version}`);
|
|
169
|
-
}
|
|
170
|
-
return true;
|
|
130
|
+
await db.dialect.checkDatabaseVersion(db);
|
|
171
131
|
}
|
|
172
132
|
__name(checkDatabaseVersion, "checkDatabaseVersion");
|
|
133
|
+
function registerDialects() {
|
|
134
|
+
[import_sqlite_dialect.SqliteDialect, import_mysql_dialect.MysqlDialect, import_mariadb_dialect.MariadbDialect, import_postgres_dialect.PostgresDialect].forEach((dialect) => {
|
|
135
|
+
import_database.Database.registerDialect(dialect);
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
__name(registerDialects, "registerDialects");
|
|
173
139
|
// Annotate the CommonJS export names for ESM import in node:
|
|
174
140
|
0 && (module.exports = {
|
|
175
141
|
checkDatabaseVersion,
|
|
176
|
-
parseDatabaseOptionsFromEnv
|
|
142
|
+
parseDatabaseOptionsFromEnv,
|
|
143
|
+
registerDialects
|
|
177
144
|
});
|
package/lib/index.d.ts
CHANGED
package/lib/index.js
CHANGED
|
@@ -92,6 +92,7 @@ __reExport(src_exports, require("./helpers"), module.exports);
|
|
|
92
92
|
var import_sql_parser = __toESM(require("./sql-parser"));
|
|
93
93
|
__reExport(src_exports, require("./interfaces"), module.exports);
|
|
94
94
|
var import_field_type_map = __toESM(require("./view/field-type-map"));
|
|
95
|
+
__reExport(src_exports, require("./dialects"), module.exports);
|
|
95
96
|
// Annotate the CommonJS export names for ESM import in node:
|
|
96
97
|
0 && (module.exports = {
|
|
97
98
|
BaseError,
|
|
@@ -139,5 +140,6 @@ var import_field_type_map = __toESM(require("./view/field-type-map"));
|
|
|
139
140
|
...require("./view-collection"),
|
|
140
141
|
...require("./view/view-inference"),
|
|
141
142
|
...require("./helpers"),
|
|
142
|
-
...require("./interfaces")
|
|
143
|
+
...require("./interfaces"),
|
|
144
|
+
...require("./dialects")
|
|
143
145
|
});
|
package/lib/model.d.ts
CHANGED
|
@@ -20,6 +20,7 @@ export declare class Model<TModelAttributes extends {} = any, TCreationAttribute
|
|
|
20
20
|
protected _previousDataValuesWithAssociations: {};
|
|
21
21
|
get db(): Database;
|
|
22
22
|
static sync(options: any): Promise<any>;
|
|
23
|
+
static callSetters(values: any, options: any): {};
|
|
23
24
|
toChangedWithAssociations(): void;
|
|
24
25
|
changedWithAssociations(key?: string, value?: any): boolean | unknown[] | this;
|
|
25
26
|
clearChangedWithAssociations(): void;
|
package/lib/model.js
CHANGED
|
@@ -56,6 +56,18 @@ const _Model = class _Model extends import_sequelize.Model {
|
|
|
56
56
|
const runner = new import_sync_runner.SyncRunner(this);
|
|
57
57
|
return await runner.runSync(options);
|
|
58
58
|
}
|
|
59
|
+
static callSetters(values, options) {
|
|
60
|
+
const result = {};
|
|
61
|
+
for (const key of Object.keys(values)) {
|
|
62
|
+
const field = this.collection.getField(key);
|
|
63
|
+
if (field && field.setter) {
|
|
64
|
+
result[key] = field.setter.call(field, values[key], options, values, key);
|
|
65
|
+
} else {
|
|
66
|
+
result[key] = values[key];
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return result;
|
|
70
|
+
}
|
|
59
71
|
// TODO
|
|
60
72
|
toChangedWithAssociations() {
|
|
61
73
|
this._changedWithAssociations = /* @__PURE__ */ new Set([...this._changedWithAssociations, ...this._changed]);
|
package/lib/operators/date.js
CHANGED
|
@@ -7,9 +7,11 @@
|
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
+
var __create = Object.create;
|
|
10
11
|
var __defProp = Object.defineProperty;
|
|
11
12
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
12
13
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
14
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
13
15
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
14
16
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
15
17
|
var __export = (target, all) => {
|
|
@@ -24,6 +26,14 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
24
26
|
}
|
|
25
27
|
return to;
|
|
26
28
|
};
|
|
29
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
30
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
31
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
32
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
33
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
34
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
35
|
+
mod
|
|
36
|
+
));
|
|
27
37
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
38
|
var date_exports = {};
|
|
29
39
|
__export(date_exports, {
|
|
@@ -32,116 +42,148 @@ __export(date_exports, {
|
|
|
32
42
|
module.exports = __toCommonJS(date_exports);
|
|
33
43
|
var import_utils = require("@nocobase/utils");
|
|
34
44
|
var import_sequelize = require("sequelize");
|
|
45
|
+
var import_moment = __toESM(require("moment"));
|
|
35
46
|
function isDate(input) {
|
|
36
47
|
return input instanceof Date || Object.prototype.toString.call(input) === "[object Date]";
|
|
37
48
|
}
|
|
38
49
|
__name(isDate, "isDate");
|
|
39
|
-
const toDate = /* @__PURE__ */ __name((date) => {
|
|
40
|
-
|
|
41
|
-
|
|
50
|
+
const toDate = /* @__PURE__ */ __name((date, options = {}) => {
|
|
51
|
+
const { ctx } = options;
|
|
52
|
+
let val = isDate(date) ? date : new Date(date);
|
|
53
|
+
const field = ctx.db.getFieldByPath(ctx.fieldPath);
|
|
54
|
+
if (!field) {
|
|
55
|
+
return val;
|
|
42
56
|
}
|
|
43
|
-
|
|
57
|
+
if (field.constructor.name === "UnixTimestampField") {
|
|
58
|
+
val = field.dateToValue(val);
|
|
59
|
+
}
|
|
60
|
+
if (field.constructor.name === "DatetimeNoTzField") {
|
|
61
|
+
val = (0, import_moment.default)(val).utcOffset("+00:00").format("YYYY-MM-DD HH:mm:ss");
|
|
62
|
+
}
|
|
63
|
+
if (field.constructor.name === "DateOnlyField") {
|
|
64
|
+
val = (0, import_moment.default)(val).format("YYYY-MM-DD HH:mm:ss");
|
|
65
|
+
}
|
|
66
|
+
const eventObj = {
|
|
67
|
+
val,
|
|
68
|
+
fieldType: field.type
|
|
69
|
+
};
|
|
70
|
+
ctx.db.emit("filterToDate", eventObj);
|
|
71
|
+
return eventObj.val;
|
|
44
72
|
}, "toDate");
|
|
73
|
+
function parseDateTimezone(ctx) {
|
|
74
|
+
const field = ctx.db.getFieldByPath(ctx.fieldPath);
|
|
75
|
+
if (!field) {
|
|
76
|
+
return ctx.db.options.timezone;
|
|
77
|
+
}
|
|
78
|
+
if (field.constructor.name === "DatetimeNoTzField") {
|
|
79
|
+
return "+00:00";
|
|
80
|
+
}
|
|
81
|
+
if (field.constructor.name === "DateOnlyField") {
|
|
82
|
+
return "+00:00";
|
|
83
|
+
}
|
|
84
|
+
return ctx.db.options.timezone;
|
|
85
|
+
}
|
|
86
|
+
__name(parseDateTimezone, "parseDateTimezone");
|
|
45
87
|
var date_default = {
|
|
46
88
|
$dateOn(value, ctx) {
|
|
47
89
|
const r = (0, import_utils.parseDate)(value, {
|
|
48
|
-
timezone: ctx
|
|
90
|
+
timezone: parseDateTimezone(ctx)
|
|
49
91
|
});
|
|
50
92
|
if (typeof r === "string") {
|
|
51
93
|
return {
|
|
52
|
-
[import_sequelize.Op.eq]: toDate(r)
|
|
94
|
+
[import_sequelize.Op.eq]: toDate(r, { ctx })
|
|
53
95
|
};
|
|
54
96
|
}
|
|
55
97
|
if (Array.isArray(r)) {
|
|
56
98
|
return {
|
|
57
|
-
[import_sequelize.Op.and]: [{ [import_sequelize.Op.gte]: toDate(r[0]) }, { [import_sequelize.Op.lt]: toDate(r[1]) }]
|
|
99
|
+
[import_sequelize.Op.and]: [{ [import_sequelize.Op.gte]: toDate(r[0], { ctx }) }, { [import_sequelize.Op.lt]: toDate(r[1], { ctx }) }]
|
|
58
100
|
};
|
|
59
101
|
}
|
|
60
102
|
throw new Error(`Invalid Date ${JSON.stringify(value)}`);
|
|
61
103
|
},
|
|
62
104
|
$dateNotOn(value, ctx) {
|
|
63
105
|
const r = (0, import_utils.parseDate)(value, {
|
|
64
|
-
timezone: ctx
|
|
106
|
+
timezone: parseDateTimezone(ctx)
|
|
65
107
|
});
|
|
66
108
|
if (typeof r === "string") {
|
|
67
109
|
return {
|
|
68
|
-
[import_sequelize.Op.ne]: toDate(r)
|
|
110
|
+
[import_sequelize.Op.ne]: toDate(r, { ctx })
|
|
69
111
|
};
|
|
70
112
|
}
|
|
71
113
|
if (Array.isArray(r)) {
|
|
72
114
|
return {
|
|
73
|
-
[import_sequelize.Op.or]: [{ [import_sequelize.Op.lt]: toDate(r[0]) }, { [import_sequelize.Op.gte]: toDate(r[1]) }]
|
|
115
|
+
[import_sequelize.Op.or]: [{ [import_sequelize.Op.lt]: toDate(r[0], { ctx }) }, { [import_sequelize.Op.gte]: toDate(r[1], { ctx }) }]
|
|
74
116
|
};
|
|
75
117
|
}
|
|
76
118
|
throw new Error(`Invalid Date ${JSON.stringify(value)}`);
|
|
77
119
|
},
|
|
78
120
|
$dateBefore(value, ctx) {
|
|
79
121
|
const r = (0, import_utils.parseDate)(value, {
|
|
80
|
-
timezone: ctx
|
|
122
|
+
timezone: parseDateTimezone(ctx)
|
|
81
123
|
});
|
|
82
124
|
if (typeof r === "string") {
|
|
83
125
|
return {
|
|
84
|
-
[import_sequelize.Op.lt]: toDate(r)
|
|
126
|
+
[import_sequelize.Op.lt]: toDate(r, { ctx })
|
|
85
127
|
};
|
|
86
128
|
} else if (Array.isArray(r)) {
|
|
87
129
|
return {
|
|
88
|
-
[import_sequelize.Op.lt]: toDate(r[0])
|
|
130
|
+
[import_sequelize.Op.lt]: toDate(r[0], { ctx })
|
|
89
131
|
};
|
|
90
132
|
}
|
|
91
133
|
throw new Error(`Invalid Date ${JSON.stringify(value)}`);
|
|
92
134
|
},
|
|
93
135
|
$dateNotBefore(value, ctx) {
|
|
94
136
|
const r = (0, import_utils.parseDate)(value, {
|
|
95
|
-
timezone: ctx
|
|
137
|
+
timezone: parseDateTimezone(ctx)
|
|
96
138
|
});
|
|
97
139
|
if (typeof r === "string") {
|
|
98
140
|
return {
|
|
99
|
-
[import_sequelize.Op.gte]: toDate(r)
|
|
141
|
+
[import_sequelize.Op.gte]: toDate(r, { ctx })
|
|
100
142
|
};
|
|
101
143
|
} else if (Array.isArray(r)) {
|
|
102
144
|
return {
|
|
103
|
-
[import_sequelize.Op.gte]: toDate(r[0])
|
|
145
|
+
[import_sequelize.Op.gte]: toDate(r[0], { ctx })
|
|
104
146
|
};
|
|
105
147
|
}
|
|
106
148
|
throw new Error(`Invalid Date ${JSON.stringify(value)}`);
|
|
107
149
|
},
|
|
108
150
|
$dateAfter(value, ctx) {
|
|
109
151
|
const r = (0, import_utils.parseDate)(value, {
|
|
110
|
-
timezone: ctx
|
|
152
|
+
timezone: parseDateTimezone(ctx)
|
|
111
153
|
});
|
|
112
154
|
if (typeof r === "string") {
|
|
113
155
|
return {
|
|
114
|
-
[import_sequelize.Op.gt]: toDate(r)
|
|
156
|
+
[import_sequelize.Op.gt]: toDate(r, { ctx })
|
|
115
157
|
};
|
|
116
158
|
} else if (Array.isArray(r)) {
|
|
117
159
|
return {
|
|
118
|
-
[import_sequelize.Op.gte]: toDate(r[1])
|
|
160
|
+
[import_sequelize.Op.gte]: toDate(r[1], { ctx })
|
|
119
161
|
};
|
|
120
162
|
}
|
|
121
163
|
throw new Error(`Invalid Date ${JSON.stringify(value)}`);
|
|
122
164
|
},
|
|
123
165
|
$dateNotAfter(value, ctx) {
|
|
124
166
|
const r = (0, import_utils.parseDate)(value, {
|
|
125
|
-
timezone: ctx
|
|
167
|
+
timezone: parseDateTimezone(ctx)
|
|
126
168
|
});
|
|
127
169
|
if (typeof r === "string") {
|
|
128
170
|
return {
|
|
129
|
-
[import_sequelize.Op.lte]: toDate(r)
|
|
171
|
+
[import_sequelize.Op.lte]: toDate(r, { ctx })
|
|
130
172
|
};
|
|
131
173
|
} else if (Array.isArray(r)) {
|
|
132
174
|
return {
|
|
133
|
-
[import_sequelize.Op.lt]: toDate(r[1])
|
|
175
|
+
[import_sequelize.Op.lt]: toDate(r[1], { ctx })
|
|
134
176
|
};
|
|
135
177
|
}
|
|
136
178
|
throw new Error(`Invalid Date ${JSON.stringify(value)}`);
|
|
137
179
|
},
|
|
138
180
|
$dateBetween(value, ctx) {
|
|
139
181
|
const r = (0, import_utils.parseDate)(value, {
|
|
140
|
-
timezone: ctx
|
|
182
|
+
timezone: parseDateTimezone(ctx)
|
|
141
183
|
});
|
|
142
184
|
if (r) {
|
|
143
185
|
return {
|
|
144
|
-
[import_sequelize.Op.and]: [{ [import_sequelize.Op.gte]: toDate(r[0]) }, { [import_sequelize.Op.lt]: toDate(r[1]) }]
|
|
186
|
+
[import_sequelize.Op.and]: [{ [import_sequelize.Op.gte]: toDate(r[0], { ctx }) }, { [import_sequelize.Op.lt]: toDate(r[1], { ctx }) }]
|
|
145
187
|
};
|
|
146
188
|
}
|
|
147
189
|
throw new Error(`Invalid Date ${JSON.stringify(value)}`);
|
package/lib/options-parser.d.ts
CHANGED
|
@@ -26,6 +26,7 @@ export declare class OptionsParser {
|
|
|
26
26
|
static appendInheritInspectAttribute(include: any, collection: any): any;
|
|
27
27
|
isAssociation(key: string): boolean;
|
|
28
28
|
isAssociationPath(path: string): boolean;
|
|
29
|
+
filterByTkToWhereOption(): {};
|
|
29
30
|
toSequelizeParams(): any;
|
|
30
31
|
/**
|
|
31
32
|
* parser sort options
|
package/lib/options-parser.js
CHANGED
|
@@ -90,17 +90,34 @@ const _OptionsParser = class _OptionsParser {
|
|
|
90
90
|
isAssociationPath(path) {
|
|
91
91
|
return this.isAssociation(path.split(".")[0]);
|
|
92
92
|
}
|
|
93
|
+
filterByTkToWhereOption() {
|
|
94
|
+
var _a;
|
|
95
|
+
const filterByTkOption = (_a = this.options) == null ? void 0 : _a.filterByTk;
|
|
96
|
+
if (!filterByTkOption) {
|
|
97
|
+
return {};
|
|
98
|
+
}
|
|
99
|
+
if (import_lodash.default.isPlainObject(this.options.filterByTk)) {
|
|
100
|
+
const where = {};
|
|
101
|
+
for (const [key, value] of Object.entries(filterByTkOption)) {
|
|
102
|
+
where[key] = value;
|
|
103
|
+
}
|
|
104
|
+
return where;
|
|
105
|
+
}
|
|
106
|
+
const filterTargetKey = this.context.targetKey || this.collection.filterTargetKey;
|
|
107
|
+
if (Array.isArray(filterTargetKey)) {
|
|
108
|
+
throw new Error("multi filter target key value must be object");
|
|
109
|
+
}
|
|
110
|
+
return {
|
|
111
|
+
[filterTargetKey]: filterByTkOption
|
|
112
|
+
};
|
|
113
|
+
}
|
|
93
114
|
toSequelizeParams() {
|
|
94
115
|
var _a, _b;
|
|
95
116
|
const queryParams = this.filterParser.toSequelizeParams();
|
|
96
117
|
if ((_a = this.options) == null ? void 0 : _a.filterByTk) {
|
|
118
|
+
const filterByTkWhere = this.filterByTkToWhereOption();
|
|
97
119
|
queryParams.where = {
|
|
98
|
-
[import_sequelize.Op.and]: [
|
|
99
|
-
queryParams.where,
|
|
100
|
-
{
|
|
101
|
-
[this.context.targetKey || this.collection.filterTargetKey]: this.options.filterByTk
|
|
102
|
-
}
|
|
103
|
-
]
|
|
120
|
+
[import_sequelize.Op.and]: [queryParams.where, filterByTkWhere]
|
|
104
121
|
};
|
|
105
122
|
}
|
|
106
123
|
if ((_b = this.options) == null ? void 0 : _b.include) {
|
|
@@ -123,12 +140,18 @@ const _OptionsParser = class _OptionsParser {
|
|
|
123
140
|
sort = sort.split(",");
|
|
124
141
|
}
|
|
125
142
|
let defaultSortField = this.model.primaryKeyAttribute;
|
|
126
|
-
if (
|
|
143
|
+
if (Array.isArray(this.collection.filterTargetKey)) {
|
|
144
|
+
defaultSortField = this.collection.filterTargetKey;
|
|
145
|
+
}
|
|
146
|
+
if (!defaultSortField && this.collection.filterTargetKey && !Array.isArray(this.collection.filterTargetKey)) {
|
|
127
147
|
defaultSortField = this.collection.filterTargetKey;
|
|
128
148
|
}
|
|
129
149
|
if (defaultSortField && !((_b = this.options) == null ? void 0 : _b.group)) {
|
|
130
|
-
|
|
131
|
-
|
|
150
|
+
defaultSortField = import_lodash.default.castArray(defaultSortField);
|
|
151
|
+
for (const key of defaultSortField) {
|
|
152
|
+
if (!sort.includes(key)) {
|
|
153
|
+
sort.push(key);
|
|
154
|
+
}
|
|
132
155
|
}
|
|
133
156
|
}
|
|
134
157
|
const orderParams = [];
|
|
@@ -50,6 +50,9 @@ function buildQueryInterface(db) {
|
|
|
50
50
|
postgres: import_postgres_query_interface.default,
|
|
51
51
|
sqlite: import_sqlite_query_interface.default
|
|
52
52
|
};
|
|
53
|
+
if (db.isPostgresCompatibleDialect()) {
|
|
54
|
+
return new import_postgres_query_interface.default(db);
|
|
55
|
+
}
|
|
53
56
|
const dialect = db.options.dialect;
|
|
54
57
|
if (!map[dialect]) {
|
|
55
58
|
return null;
|
|
@@ -45,29 +45,26 @@ var import_relation_repository = require("./relation-repository");
|
|
|
45
45
|
const _HasManyRepository = class _HasManyRepository extends import_multiple_relation_repository.MultipleRelationRepository {
|
|
46
46
|
async find(options) {
|
|
47
47
|
const targetRepository = this.targetCollection.repository;
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
48
|
+
const targetFilterOptions = await this.targetRepositoryFilterOptionsBySourceValue();
|
|
49
|
+
const findOptionsOmit = ["where", "values", "attributes"];
|
|
50
|
+
if ((options == null ? void 0 : options.filterByTk) && !this.isMultiTargetKey(options.filterByTk)) {
|
|
51
|
+
targetFilterOptions[this.associationField.targetKey] = options.filterByTk;
|
|
52
|
+
findOptionsOmit.push("filterByTk");
|
|
53
53
|
}
|
|
54
54
|
const findOptions = {
|
|
55
|
-
...(0, import_lodash.omit)(options,
|
|
55
|
+
...(0, import_lodash.omit)(options, findOptionsOmit),
|
|
56
56
|
filter: {
|
|
57
|
-
$and: [options.filter || {},
|
|
57
|
+
$and: [(options == null ? void 0 : options.filter) || {}, targetFilterOptions]
|
|
58
58
|
}
|
|
59
59
|
};
|
|
60
60
|
return await targetRepository.find(findOptions);
|
|
61
61
|
}
|
|
62
62
|
async aggregate(options) {
|
|
63
63
|
const targetRepository = this.targetCollection.repository;
|
|
64
|
-
const addFilter = {
|
|
65
|
-
[this.association.foreignKey]: this.sourceKeyValue
|
|
66
|
-
};
|
|
67
64
|
const aggOptions = {
|
|
68
65
|
...options,
|
|
69
66
|
filter: {
|
|
70
|
-
$and: [options.filter || {},
|
|
67
|
+
$and: [options.filter || {}, await this.targetRepositoryFilterOptionsBySourceValue()]
|
|
71
68
|
}
|
|
72
69
|
};
|
|
73
70
|
return await targetRepository.aggregate(aggOptions);
|
|
@@ -14,6 +14,7 @@ export interface AssociatedOptions extends Transactionable {
|
|
|
14
14
|
tk?: TK;
|
|
15
15
|
}
|
|
16
16
|
export declare abstract class MultipleRelationRepository extends RelationRepository {
|
|
17
|
+
targetRepositoryFilterOptionsBySourceValue(): Promise<any>;
|
|
17
18
|
find(options?: FindOptions): Promise<any>;
|
|
18
19
|
findAndCount(options?: FindAndCountOptions): Promise<[any[], number]>;
|
|
19
20
|
count(options?: CountOptions): Promise<number>;
|
|
@@ -55,6 +55,16 @@ var import_update_associations = require("../update-associations");
|
|
|
55
55
|
var import_update_guard = require("../update-guard");
|
|
56
56
|
var import_relation_repository = require("./relation-repository");
|
|
57
57
|
const _MultipleRelationRepository = class _MultipleRelationRepository extends import_relation_repository.RelationRepository {
|
|
58
|
+
async targetRepositoryFilterOptionsBySourceValue() {
|
|
59
|
+
let filterForeignKeyValue = this.sourceKeyValue;
|
|
60
|
+
if (this.isMultiTargetKey()) {
|
|
61
|
+
const sourceModel = await this.getSourceModel();
|
|
62
|
+
filterForeignKeyValue = sourceModel.get(this.association.sourceKey);
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
[this.association.foreignKey]: filterForeignKeyValue
|
|
66
|
+
};
|
|
67
|
+
}
|
|
58
68
|
async find(options) {
|
|
59
69
|
const targetRepository = this.targetCollection.repository;
|
|
60
70
|
const association = this.association;
|
|
@@ -68,9 +78,7 @@ const _MultipleRelationRepository = class _MultipleRelationRepository extends im
|
|
|
68
78
|
const appendFilter = {
|
|
69
79
|
isPivotFilter: true,
|
|
70
80
|
association: pivotAssoc,
|
|
71
|
-
where:
|
|
72
|
-
[association.foreignKey]: this.sourceKeyValue
|
|
73
|
-
}
|
|
81
|
+
where: await this.targetRepositoryFilterOptionsBySourceValue()
|
|
74
82
|
};
|
|
75
83
|
return targetRepository.find({
|
|
76
84
|
include: [appendFilter],
|
|
@@ -11,7 +11,7 @@ import { Collection } from '../collection';
|
|
|
11
11
|
import Database from '../database';
|
|
12
12
|
import { RelationField } from '../fields/relation-field';
|
|
13
13
|
import { Model } from '../model';
|
|
14
|
-
import { CreateOptions, Filter, FindOptions } from '../repository';
|
|
14
|
+
import { CreateOptions, Filter, FindOptions, TargetKey } from '../repository';
|
|
15
15
|
export declare const transaction: (transactionInjector?: any) => (target: any, name: any, descriptor: any) => any;
|
|
16
16
|
export declare abstract class RelationRepository {
|
|
17
17
|
sourceCollection: Collection;
|
|
@@ -20,11 +20,14 @@ export declare abstract class RelationRepository {
|
|
|
20
20
|
targetCollection: Collection;
|
|
21
21
|
associationName: string;
|
|
22
22
|
associationField: RelationField;
|
|
23
|
-
sourceKeyValue:
|
|
23
|
+
sourceKeyValue: TargetKey;
|
|
24
24
|
sourceInstance: Model;
|
|
25
25
|
db: Database;
|
|
26
26
|
database: Database;
|
|
27
|
-
constructor(sourceCollection: Collection, association: string, sourceKeyValue:
|
|
27
|
+
constructor(sourceCollection: Collection, association: string, sourceKeyValue: TargetKey);
|
|
28
|
+
decodeMultiTargetKey(str: string): any;
|
|
29
|
+
setSourceKeyValue(sourceKeyValue: TargetKey): void;
|
|
30
|
+
isMultiTargetKey(value?: any): boolean;
|
|
28
31
|
get collection(): Collection<any, any>;
|
|
29
32
|
abstract find(options?: FindOptions): Promise<any>;
|
|
30
33
|
chunk(options: FindOptions & {
|