@nocobase/database 2.0.0-alpha.8 → 2.1.0-alpha.1
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/belongs-to-array/belongs-to-array-repository.d.ts +0 -2
- package/lib/belongs-to-array/belongs-to-array-repository.js +0 -13
- package/lib/collection.d.ts +1 -3
- package/lib/collection.js +31 -30
- package/lib/database.d.ts +1 -0
- package/lib/database.js +19 -10
- package/lib/dialects/mariadb-dialect.js +6 -1
- package/lib/dialects/postgres-dialect.js +0 -3
- package/lib/eager-loading/eager-loading-tree.js +3 -2
- package/lib/fields/field.js +4 -0
- package/lib/fields/index.d.ts +1 -3
- package/lib/fields/index.js +0 -2
- package/lib/fields/snowflake-id-field.js +10 -2
- package/lib/index.d.ts +3 -1
- package/lib/index.js +8 -0
- package/lib/interfaces/time-interface.js +1 -1
- package/lib/operators/date.js +0 -3
- package/lib/{fields/encryption-field/index.d.ts → operators/in.d.ts} +2 -3
- package/lib/{fields/encryption-field/errors/EncryptionError.js → operators/in.js} +11 -15
- package/lib/operators/index.js +2 -0
- package/lib/options-parser.d.ts +3 -1
- package/lib/options-parser.js +14 -7
- package/lib/relation-repository/belongs-to-many-repository.js +1 -2
- package/lib/relation-repository/multiple-relation-repository.d.ts +1 -0
- package/lib/relation-repository/multiple-relation-repository.js +13 -0
- package/lib/relation-repository/relation-repository.js +1 -1
- package/lib/relation-repository/single-relation-repository.js +1 -2
- package/lib/repository.d.ts +2 -2
- package/lib/repository.js +3 -3
- package/lib/sync-runner.js +3 -0
- package/lib/update-associations.d.ts +2 -4
- package/lib/update-associations.js +6 -14
- package/lib/utils/field-validation.d.ts +0 -45
- package/lib/utils/field-validation.js +2 -60
- package/lib/utils.d.ts +1 -0
- package/lib/utils.js +10 -0
- package/lib/view/field-type-map.js +3 -3
- package/package.json +4 -4
- package/lib/fields/encryption-field/encryption-field.d.ts +0 -20
- package/lib/fields/encryption-field/encryption-field.js +0 -110
- package/lib/fields/encryption-field/errors/EncryptionError.d.ts +0 -11
- package/lib/fields/encryption-field/index.js +0 -34
- package/lib/fields/encryption-field/utils.d.ts +0 -6
- package/lib/fields/encryption-field/utils.js +0 -152
|
@@ -12,7 +12,6 @@ import { FindOptions } from '../repository';
|
|
|
12
12
|
import { MultipleRelationRepository } from '../relation-repository/multiple-relation-repository';
|
|
13
13
|
import Database from '../database';
|
|
14
14
|
import { Model } from '../model';
|
|
15
|
-
import { UpdateAssociationOptions } from '../update-associations';
|
|
16
15
|
export declare class BelongsToArrayAssociation {
|
|
17
16
|
db: Database;
|
|
18
17
|
associationType: string;
|
|
@@ -35,7 +34,6 @@ export declare class BelongsToArrayAssociation {
|
|
|
35
34
|
generateInclude(parentAs?: string): {
|
|
36
35
|
on: void;
|
|
37
36
|
};
|
|
38
|
-
update(instance: Model, value: any, options?: UpdateAssociationOptions): Promise<void>;
|
|
39
37
|
}
|
|
40
38
|
export declare class BelongsToArrayRepository extends MultipleRelationRepository {
|
|
41
39
|
private belongsToArrayAssociation;
|
|
@@ -94,19 +94,6 @@ const _BelongsToArrayAssociation = class _BelongsToArrayAssociation {
|
|
|
94
94
|
on: this.db.queryInterface.generateJoinOnForJSONArray(left, right)
|
|
95
95
|
};
|
|
96
96
|
}
|
|
97
|
-
async update(instance, value, options = {}) {
|
|
98
|
-
await instance.update(
|
|
99
|
-
{
|
|
100
|
-
[this.as]: value
|
|
101
|
-
},
|
|
102
|
-
{
|
|
103
|
-
values: {
|
|
104
|
-
[this.as]: value
|
|
105
|
-
},
|
|
106
|
-
transaction: options == null ? void 0 : options.transaction
|
|
107
|
-
}
|
|
108
|
-
);
|
|
109
|
-
}
|
|
110
97
|
};
|
|
111
98
|
__name(_BelongsToArrayAssociation, "BelongsToArrayAssociation");
|
|
112
99
|
let BelongsToArrayAssociation = _BelongsToArrayAssociation;
|
package/lib/collection.d.ts
CHANGED
|
@@ -93,9 +93,6 @@ export declare class Collection<TModelAttributes extends {} = any, TCreationAttr
|
|
|
93
93
|
validate(options: {
|
|
94
94
|
values: Record<string, any> | Record<string, any>[];
|
|
95
95
|
operation: 'create' | 'update';
|
|
96
|
-
context: {
|
|
97
|
-
t: Function;
|
|
98
|
-
};
|
|
99
96
|
}): void;
|
|
100
97
|
isMultiFilterTargetKey(): boolean;
|
|
101
98
|
tableName(): any;
|
|
@@ -129,6 +126,7 @@ export declare class Collection<TModelAttributes extends {} = any, TCreationAttr
|
|
|
129
126
|
updateOptions(options: CollectionOptions, mergeOptions?: any): this;
|
|
130
127
|
setSortable(sortable: any): void;
|
|
131
128
|
updateField(name: string, options: FieldOptions): void;
|
|
129
|
+
private normalizeFieldName;
|
|
132
130
|
addIndex(index: string | string[] | {
|
|
133
131
|
fields: string[];
|
|
134
132
|
unique?: boolean;
|
package/lib/collection.js
CHANGED
|
@@ -58,6 +58,7 @@ var import_model = require("./model");
|
|
|
58
58
|
var import_repository = require("./repository");
|
|
59
59
|
var import_utils = require("./utils");
|
|
60
60
|
var import_field_validation = require("./utils/field-validation");
|
|
61
|
+
var import_joi = __toESM(require("joi"));
|
|
61
62
|
function EnsureAtomicity(target, propertyKey, descriptor) {
|
|
62
63
|
const originalMethod = descriptor.value;
|
|
63
64
|
descriptor.value = function(...args) {
|
|
@@ -161,50 +162,33 @@ const _Collection = class _Collection extends import_events.EventEmitter {
|
|
|
161
162
|
}
|
|
162
163
|
}
|
|
163
164
|
validate(options) {
|
|
164
|
-
const { values: updateValues,
|
|
165
|
+
const { values: updateValues, operation } = options;
|
|
165
166
|
if (!updateValues) {
|
|
166
167
|
return;
|
|
167
168
|
}
|
|
168
169
|
const values = Array.isArray(updateValues) ? updateValues : [updateValues];
|
|
169
|
-
const { t } = context || { t: /* @__PURE__ */ __name((key, options2) => key, "t") };
|
|
170
|
-
const unwrapTplLabel = /* @__PURE__ */ __name((label) => {
|
|
171
|
-
if (typeof label !== "string") return label;
|
|
172
|
-
const m = label.match(/^[\s\t]*\{\{\s*t\(\s*(['"])(.*?)\1(?:\s*,[\s\S]*)?\)\s*\}\}[\s\t]*$/);
|
|
173
|
-
return m ? m[2] : label;
|
|
174
|
-
}, "unwrapTplLabel");
|
|
175
170
|
const helper = /* @__PURE__ */ __name((field, value) => {
|
|
176
|
-
var _a, _b
|
|
171
|
+
var _a, _b;
|
|
177
172
|
const val = value[field.name];
|
|
178
173
|
if (!field.options.validation) {
|
|
179
174
|
return;
|
|
180
175
|
}
|
|
181
|
-
const fieldLabel = unwrapTplLabel(((_a = field.options.uiSchema) == null ? void 0 : _a.title) || field.name);
|
|
182
176
|
if (field instanceof import_fields.RelationField) {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
"#label": `${t("Collection", { ns: "client" })}: ${this.name}, ${t("Field", { ns: "client" })}: ${t(
|
|
190
|
-
fieldLabel,
|
|
191
|
-
{ ns: "client" }
|
|
192
|
-
)}`
|
|
193
|
-
})
|
|
194
|
-
);
|
|
177
|
+
const rules = ((_b = (_a = field.options) == null ? void 0 : _a.validation) == null ? void 0 : _b.rules) || [];
|
|
178
|
+
const required = rules.some((rule) => rule.name === "required");
|
|
179
|
+
if (required) {
|
|
180
|
+
const { error: error2 } = import_joi.default.any().empty(null).required().label(`${this.name}.${field.name}`).validate(val);
|
|
181
|
+
if (error2) {
|
|
182
|
+
throw error2;
|
|
195
183
|
}
|
|
196
184
|
}
|
|
197
185
|
return;
|
|
198
186
|
}
|
|
199
187
|
const joiSchema = (0, import_field_validation.buildJoiSchema)(field.options.validation, {
|
|
200
|
-
label: `${
|
|
201
|
-
ns: "client"
|
|
202
|
-
})}`,
|
|
188
|
+
label: `${this.name}.${field.name}`,
|
|
203
189
|
value: val
|
|
204
190
|
});
|
|
205
|
-
const { error } = joiSchema.validate(val
|
|
206
|
-
messages: (0, import_field_validation.getJoiErrorMessage)(t)
|
|
207
|
-
});
|
|
191
|
+
const { error } = joiSchema.validate(val);
|
|
208
192
|
if (error) {
|
|
209
193
|
throw error;
|
|
210
194
|
}
|
|
@@ -311,6 +295,7 @@ const _Collection = class _Collection extends import_events.EventEmitter {
|
|
|
311
295
|
this.model.options.modelName = this.options.name;
|
|
312
296
|
if (!autoGenId) {
|
|
313
297
|
this.model.removeAttribute("id");
|
|
298
|
+
this.model.autoIncrementAttribute = null;
|
|
314
299
|
}
|
|
315
300
|
this.model.database = this.context.database;
|
|
316
301
|
this.model.collection = this;
|
|
@@ -613,6 +598,12 @@ const _Collection = class _Collection extends import_events.EventEmitter {
|
|
|
613
598
|
}
|
|
614
599
|
this.setField(options.name || name, options);
|
|
615
600
|
}
|
|
601
|
+
normalizeFieldName(val) {
|
|
602
|
+
if (!this.options.underscored) {
|
|
603
|
+
return val;
|
|
604
|
+
}
|
|
605
|
+
return Array.isArray(val) ? val.map((v) => (0, import_utils.snakeCase)(v)) : (0, import_utils.snakeCase)(val);
|
|
606
|
+
}
|
|
616
607
|
addIndex(index) {
|
|
617
608
|
if (!index) {
|
|
618
609
|
return;
|
|
@@ -642,7 +633,7 @@ const _Collection = class _Collection extends import_events.EventEmitter {
|
|
|
642
633
|
return;
|
|
643
634
|
}
|
|
644
635
|
for (const item of indexes) {
|
|
645
|
-
if (import_lodash.default.isEqual(item.fields, indexName)) {
|
|
636
|
+
if (import_lodash.default.isEqual(this.normalizeFieldName(item.fields), this.normalizeFieldName(indexName))) {
|
|
646
637
|
return;
|
|
647
638
|
}
|
|
648
639
|
const name2 = item.fields.join(",");
|
|
@@ -678,11 +669,21 @@ const _Collection = class _Collection extends import_events.EventEmitter {
|
|
|
678
669
|
*/
|
|
679
670
|
refreshIndexes() {
|
|
680
671
|
const indexes = this.model._indexes;
|
|
672
|
+
const attributes = {};
|
|
673
|
+
for (const [name, field] of Object.entries(this.model.getAttributes())) {
|
|
674
|
+
attributes[this.normalizeFieldName(name)] = field;
|
|
675
|
+
}
|
|
681
676
|
this.model._indexes = import_lodash.default.uniqBy(
|
|
682
677
|
indexes.filter((item) => {
|
|
683
|
-
return item.fields.every((field) =>
|
|
678
|
+
return item.fields.every((field) => {
|
|
679
|
+
const name = this.normalizeFieldName(field);
|
|
680
|
+
return attributes[name];
|
|
681
|
+
});
|
|
684
682
|
}).map((item) => {
|
|
685
|
-
item.fields = item.fields.map((field) =>
|
|
683
|
+
item.fields = item.fields.map((field) => {
|
|
684
|
+
const name = this.normalizeFieldName(field);
|
|
685
|
+
return attributes[name].field;
|
|
686
|
+
});
|
|
686
687
|
return item;
|
|
687
688
|
}),
|
|
688
689
|
"name"
|
package/lib/database.d.ts
CHANGED
|
@@ -215,6 +215,7 @@ export declare class Database extends EventEmitter implements AsyncEmitter {
|
|
|
215
215
|
private registerCollectionType;
|
|
216
216
|
quoteIdentifier(identifier: string): string;
|
|
217
217
|
quoteTable(tableName: string): string;
|
|
218
|
+
private runSQLWithSchema;
|
|
218
219
|
runSQL(sql: string, options?: RunSQLOptions): Promise<any>;
|
|
219
220
|
}
|
|
220
221
|
export declare function extendCollection(collectionOptions: CollectionOptions, mergeOptions?: MergeOptions): {
|
package/lib/database.js
CHANGED
|
@@ -287,8 +287,8 @@ const _Database = class _Database extends import_events.EventEmitter {
|
|
|
287
287
|
*/
|
|
288
288
|
initListener() {
|
|
289
289
|
this.on("afterConnect", async (client) => {
|
|
290
|
-
if (this.
|
|
291
|
-
await client.query("SET search_path
|
|
290
|
+
if (this.isPostgresCompatibleDialect()) {
|
|
291
|
+
await client.query("SET search_path TO public");
|
|
292
292
|
}
|
|
293
293
|
});
|
|
294
294
|
this.on("beforeDefine", (model, options) => {
|
|
@@ -431,18 +431,14 @@ const _Database = class _Database extends import_events.EventEmitter {
|
|
|
431
431
|
*/
|
|
432
432
|
collection(options) {
|
|
433
433
|
options = import_lodash.default.cloneDeep(options);
|
|
434
|
-
|
|
435
|
-
if (this.options.underscored) {
|
|
436
|
-
options.underscored = true;
|
|
437
|
-
}
|
|
438
|
-
}
|
|
434
|
+
options.underscored = options.underscored ?? this.options.underscored;
|
|
439
435
|
this.logger.trace(`beforeDefineCollection: ${(0, import_safe_json_stringify.default)(options)}`, {
|
|
440
436
|
databaseInstanceId: this.instanceId
|
|
441
437
|
});
|
|
442
438
|
this.emit("beforeDefineCollection", options);
|
|
443
439
|
const collection = this.collectionFactory.createCollection(options);
|
|
444
440
|
this.collections.set(collection.name, collection);
|
|
445
|
-
this.emit("afterDefineCollection", collection);
|
|
441
|
+
this.emit("afterDefineCollection", collection, { fieldModels: options.fieldModels });
|
|
446
442
|
return collection;
|
|
447
443
|
}
|
|
448
444
|
getTablePrefix() {
|
|
@@ -491,6 +487,9 @@ const _Database = class _Database extends import_events.EventEmitter {
|
|
|
491
487
|
}
|
|
492
488
|
removeCollection(name) {
|
|
493
489
|
const collection = this.collections.get(name);
|
|
490
|
+
if (!collection) {
|
|
491
|
+
return;
|
|
492
|
+
}
|
|
494
493
|
this.emit("beforeRemoveCollection", collection);
|
|
495
494
|
collection.resetFields();
|
|
496
495
|
const result = this.collections.delete(name);
|
|
@@ -791,18 +790,28 @@ const _Database = class _Database extends import_events.EventEmitter {
|
|
|
791
790
|
quoteTable(tableName) {
|
|
792
791
|
return this.sequelize.getQueryInterface().quoteIdentifiers(tableName);
|
|
793
792
|
}
|
|
793
|
+
async runSQLWithSchema(finalSQL, bind, transaction) {
|
|
794
|
+
if (!this.options.schema || !this.isPostgresCompatibleDialect()) {
|
|
795
|
+
return this.sequelize.query(finalSQL, { bind, transaction });
|
|
796
|
+
}
|
|
797
|
+
const execute = /* @__PURE__ */ __name(async (t) => {
|
|
798
|
+
await this.sequelize.query(`SET LOCAL search_path TO ${this.options.schema}`, { transaction: t });
|
|
799
|
+
return this.sequelize.query(finalSQL, { bind, transaction: t });
|
|
800
|
+
}, "execute");
|
|
801
|
+
return transaction ? execute(transaction) : this.sequelize.transaction(execute);
|
|
802
|
+
}
|
|
794
803
|
async runSQL(sql, options = {}) {
|
|
795
804
|
const { filter, bind, type, transaction } = options;
|
|
796
805
|
let finalSQL = sql;
|
|
797
806
|
if (!finalSQL.replace(/\s+/g, " ").trim()) {
|
|
798
807
|
throw new Error("SQL cannot be empty");
|
|
799
808
|
}
|
|
809
|
+
const queryGenerator = this.sequelize.getQueryInterface().queryGenerator;
|
|
800
810
|
if (filter) {
|
|
801
811
|
let where = {};
|
|
802
812
|
const tmpCollection = new import_collection.Collection({ name: "tmp", underscored: false }, { database: this });
|
|
803
813
|
const r = tmpCollection.repository;
|
|
804
814
|
where = r.buildQueryOptions({ filter }).where;
|
|
805
|
-
const queryGenerator = this.sequelize.getQueryInterface().queryGenerator;
|
|
806
815
|
const wSQL = queryGenerator.getWhereConditions(where, null, null, { bindParam: true });
|
|
807
816
|
if (wSQL) {
|
|
808
817
|
let normalizedSQL = sql.replace(/\s+/g, " ").trim();
|
|
@@ -813,7 +822,7 @@ const _Database = class _Database extends import_events.EventEmitter {
|
|
|
813
822
|
}
|
|
814
823
|
}
|
|
815
824
|
this.logger.debug("runSQL", { finalSQL });
|
|
816
|
-
const result = await this.
|
|
825
|
+
const result = await this.runSQLWithSchema(finalSQL, bind, transaction);
|
|
817
826
|
let data = result[0];
|
|
818
827
|
if (type === "selectVar") {
|
|
819
828
|
if (Array.isArray(data)) {
|
|
@@ -35,7 +35,12 @@ module.exports = __toCommonJS(mariadb_dialect_exports);
|
|
|
35
35
|
var import_base_dialect = require("./base-dialect");
|
|
36
36
|
const _MariadbDialect = class _MariadbDialect extends import_base_dialect.BaseDialect {
|
|
37
37
|
getSequelizeOptions(options) {
|
|
38
|
-
options.dialectOptions = {
|
|
38
|
+
options.dialectOptions = {
|
|
39
|
+
...options.dialectOptions || {},
|
|
40
|
+
multipleStatements: true,
|
|
41
|
+
supportBigNumbers: true,
|
|
42
|
+
bigNumberStrings: true
|
|
43
|
+
};
|
|
39
44
|
return options;
|
|
40
45
|
}
|
|
41
46
|
getVersionGuard() {
|
|
@@ -52,9 +52,6 @@ const _PostgresDialect = class _PostgresDialect extends import_base_dialect.Base
|
|
|
52
52
|
if (!options.hooks["afterConnect"]) {
|
|
53
53
|
options.hooks["afterConnect"] = [];
|
|
54
54
|
}
|
|
55
|
-
options.hooks["afterConnect"].push(async (connection) => {
|
|
56
|
-
await connection.query("SET search_path TO public;");
|
|
57
|
-
});
|
|
58
55
|
return options;
|
|
59
56
|
}
|
|
60
57
|
getVersionGuard() {
|
|
@@ -78,7 +78,7 @@ const queryParentSQL = /* @__PURE__ */ __name((options) => {
|
|
|
78
78
|
return `WITH RECURSIVE cte AS (
|
|
79
79
|
SELECT ${q(targetKeyField)}, ${q(foreignKeyField)}
|
|
80
80
|
FROM ${tableName}
|
|
81
|
-
WHERE ${q(targetKeyField)} IN (${nodeIds.join(",")})
|
|
81
|
+
WHERE ${q(targetKeyField)} IN ('${nodeIds.join("','")}')
|
|
82
82
|
UNION ALL
|
|
83
83
|
SELECT t.${q(targetKeyField)}, t.${q(foreignKeyField)}
|
|
84
84
|
FROM ${tableName} AS t
|
|
@@ -215,7 +215,8 @@ const _EagerLoadingTree = class _EagerLoadingTree {
|
|
|
215
215
|
attributes: [primaryKeyField],
|
|
216
216
|
group: `${node.model.name}.${primaryKeyField}`,
|
|
217
217
|
transaction,
|
|
218
|
-
include: (0, import_utils.processIncludes)(includeForFilter, node.model)
|
|
218
|
+
include: (0, import_utils.processIncludes)(includeForFilter, node.model),
|
|
219
|
+
raw: true
|
|
219
220
|
})).map((row) => {
|
|
220
221
|
return { row, pk: row[primaryKeyField] };
|
|
221
222
|
});
|
package/lib/fields/field.js
CHANGED
|
@@ -131,12 +131,16 @@ const _Field = class _Field {
|
|
|
131
131
|
Object.assign(this.options, obj);
|
|
132
132
|
}
|
|
133
133
|
bind() {
|
|
134
|
+
var _a;
|
|
134
135
|
const { model } = this.context.collection;
|
|
135
136
|
model.rawAttributes[this.name] = this.toSequelize();
|
|
136
137
|
model.refreshAttributes();
|
|
137
138
|
if (this.options.index) {
|
|
138
139
|
this.context.collection.addIndex([this.name]);
|
|
139
140
|
}
|
|
141
|
+
if (((_a = this.options) == null ? void 0 : _a.autoIncrement) === true && !model.autoIncrementAttribute) {
|
|
142
|
+
model._findAutoIncrementAttribute();
|
|
143
|
+
}
|
|
140
144
|
}
|
|
141
145
|
unbind() {
|
|
142
146
|
const { model } = this.context.collection;
|
package/lib/fields/index.d.ts
CHANGED
|
@@ -27,7 +27,6 @@ import { UidFieldOptions } from './uid-field';
|
|
|
27
27
|
import { UUIDFieldOptions } from './uuid-field';
|
|
28
28
|
import { VirtualFieldOptions } from './virtual-field';
|
|
29
29
|
import { NanoidFieldOptions } from './nanoid-field';
|
|
30
|
-
import { EncryptionField } from './encryption-field';
|
|
31
30
|
import { UnixTimestampFieldOptions } from './unix-timestamp-field';
|
|
32
31
|
import { DateOnlyFieldOptions } from './date-only-field';
|
|
33
32
|
import { DatetimeNoTzFieldOptions } from './datetime-no-tz-field';
|
|
@@ -59,7 +58,6 @@ export * from './uid-field';
|
|
|
59
58
|
export * from './uuid-field';
|
|
60
59
|
export * from './virtual-field';
|
|
61
60
|
export * from './nanoid-field';
|
|
62
|
-
export * from './encryption-field';
|
|
63
61
|
export * from './unix-timestamp-field';
|
|
64
62
|
export * from './snowflake-id-field';
|
|
65
|
-
export type FieldOptions = BaseFieldOptions | StringFieldOptions | IntegerFieldOptions | FloatFieldOptions | DecimalFieldOptions | DoubleFieldOptions | RealFieldOptions | JsonFieldOptions | JsonbFieldOptions | BooleanFieldOptions | RadioFieldOptions | TextFieldOptions | VirtualFieldOptions | ArrayFieldOptions | SetFieldOptions | TimeFieldOptions | DateFieldOptions | DatetimeTzFieldOptions | DatetimeNoTzFieldOptions | DateOnlyFieldOptions | UnixTimestampFieldOptions | UidFieldOptions | UUIDFieldOptions | NanoidFieldOptions | PasswordFieldOptions | ContextFieldOptions | BelongsToFieldOptions | HasOneFieldOptions | HasManyFieldOptions | BelongsToManyFieldOptions |
|
|
63
|
+
export type FieldOptions = BaseFieldOptions | StringFieldOptions | IntegerFieldOptions | FloatFieldOptions | DecimalFieldOptions | DoubleFieldOptions | RealFieldOptions | JsonFieldOptions | JsonbFieldOptions | BooleanFieldOptions | RadioFieldOptions | TextFieldOptions | VirtualFieldOptions | ArrayFieldOptions | SetFieldOptions | TimeFieldOptions | DateFieldOptions | DatetimeTzFieldOptions | DatetimeNoTzFieldOptions | DateOnlyFieldOptions | UnixTimestampFieldOptions | UidFieldOptions | UUIDFieldOptions | NanoidFieldOptions | PasswordFieldOptions | ContextFieldOptions | BelongsToFieldOptions | HasOneFieldOptions | HasManyFieldOptions | BelongsToManyFieldOptions | SnowflakeIdFieldOptions;
|
package/lib/fields/index.js
CHANGED
|
@@ -49,7 +49,6 @@ __reExport(fields_exports, require("./uid-field"), module.exports);
|
|
|
49
49
|
__reExport(fields_exports, require("./uuid-field"), module.exports);
|
|
50
50
|
__reExport(fields_exports, require("./virtual-field"), module.exports);
|
|
51
51
|
__reExport(fields_exports, require("./nanoid-field"), module.exports);
|
|
52
|
-
__reExport(fields_exports, require("./encryption-field"), module.exports);
|
|
53
52
|
__reExport(fields_exports, require("./unix-timestamp-field"), module.exports);
|
|
54
53
|
__reExport(fields_exports, require("./snowflake-id-field"), module.exports);
|
|
55
54
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -80,7 +79,6 @@ __reExport(fields_exports, require("./snowflake-id-field"), module.exports);
|
|
|
80
79
|
...require("./uuid-field"),
|
|
81
80
|
...require("./virtual-field"),
|
|
82
81
|
...require("./nanoid-field"),
|
|
83
|
-
...require("./encryption-field"),
|
|
84
82
|
...require("./unix-timestamp-field"),
|
|
85
83
|
...require("./snowflake-id-field")
|
|
86
84
|
});
|
|
@@ -49,9 +49,17 @@ const _SnowflakeIdField = class _SnowflakeIdField extends import_field.Field {
|
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
init() {
|
|
52
|
-
const { name } = this.options;
|
|
53
|
-
this.listener = (instance) =>
|
|
52
|
+
const { name, autoFill } = this.options;
|
|
53
|
+
this.listener = (instance) => {
|
|
54
|
+
if (autoFill === false) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
this.setId(name, instance);
|
|
58
|
+
};
|
|
54
59
|
this.bulkListener = async (instances) => {
|
|
60
|
+
if (autoFill === false) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
55
63
|
for (const instance of instances) {
|
|
56
64
|
this.setId(name, instance);
|
|
57
65
|
}
|
package/lib/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
9
|
export { BaseError, BelongsToGetAssociationMixin, DataTypes, fn, HasManyCountAssociationsMixin, HasManyCreateAssociationMixin, HasManyGetAssociationsMixin, literal, ModelStatic, Op, SyncOptions, Transaction, UniqueConstraintError, ValidationError, ValidationErrorItem, where, } from 'sequelize';
|
|
10
|
+
export { ValidationError as JoiValidationError } from 'joi';
|
|
10
11
|
export * from './belongs-to-array/belongs-to-array-repository';
|
|
11
12
|
export * from './collection';
|
|
12
13
|
export * from './collection-group-manager';
|
|
@@ -35,11 +36,12 @@ export * from './repository';
|
|
|
35
36
|
export * from './relation-repository/relation-repository';
|
|
36
37
|
export { default as sqlParser, SQLParserTypes } from './sql-parser';
|
|
37
38
|
export * from './update-associations';
|
|
38
|
-
export { snakeCase } from './utils';
|
|
39
|
+
export { snakeCase, extractTypeFromDefinition } from './utils';
|
|
39
40
|
export * from './value-parsers';
|
|
40
41
|
export * from './view-collection';
|
|
41
42
|
export { default as fieldTypeMap } from './view/field-type-map';
|
|
42
43
|
export * from './view/view-inference';
|
|
43
44
|
export * from './update-guard';
|
|
45
|
+
export { TableInfo } from './query-interface/query-interface';
|
|
44
46
|
export { default as operators } from './operators';
|
|
45
47
|
export { filterIncludes, mergeIncludes } from './utils/filter-include';
|
package/lib/index.js
CHANGED
|
@@ -44,15 +44,18 @@ __export(src_exports, {
|
|
|
44
44
|
HasManyCountAssociationsMixin: () => import_sequelize.HasManyCountAssociationsMixin,
|
|
45
45
|
HasManyCreateAssociationMixin: () => import_sequelize.HasManyCreateAssociationMixin,
|
|
46
46
|
HasManyGetAssociationsMixin: () => import_sequelize.HasManyGetAssociationsMixin,
|
|
47
|
+
JoiValidationError: () => import_joi.ValidationError,
|
|
47
48
|
ModelStatic: () => import_sequelize.ModelStatic,
|
|
48
49
|
Op: () => import_sequelize.Op,
|
|
49
50
|
SQLParserTypes: () => import_sql_parser.SQLParserTypes,
|
|
50
51
|
SyncOptions: () => import_sequelize.SyncOptions,
|
|
52
|
+
TableInfo: () => import_query_interface.TableInfo,
|
|
51
53
|
Transaction: () => import_sequelize.Transaction,
|
|
52
54
|
UniqueConstraintError: () => import_sequelize.UniqueConstraintError,
|
|
53
55
|
ValidationError: () => import_sequelize.ValidationError,
|
|
54
56
|
ValidationErrorItem: () => import_sequelize.ValidationErrorItem,
|
|
55
57
|
default: () => import_database.Database,
|
|
58
|
+
extractTypeFromDefinition: () => import_utils.extractTypeFromDefinition,
|
|
56
59
|
fieldTypeMap: () => import_field_type_map.default,
|
|
57
60
|
filterIncludes: () => import_filter_include.filterIncludes,
|
|
58
61
|
fn: () => import_sequelize.fn,
|
|
@@ -65,6 +68,7 @@ __export(src_exports, {
|
|
|
65
68
|
});
|
|
66
69
|
module.exports = __toCommonJS(src_exports);
|
|
67
70
|
var import_sequelize = require("sequelize");
|
|
71
|
+
var import_joi = require("joi");
|
|
68
72
|
__reExport(src_exports, require("./belongs-to-array/belongs-to-array-repository"), module.exports);
|
|
69
73
|
__reExport(src_exports, require("./collection"), module.exports);
|
|
70
74
|
__reExport(src_exports, require("./collection-group-manager"), module.exports);
|
|
@@ -99,6 +103,7 @@ __reExport(src_exports, require("./view-collection"), module.exports);
|
|
|
99
103
|
var import_field_type_map = __toESM(require("./view/field-type-map"));
|
|
100
104
|
__reExport(src_exports, require("./view/view-inference"), module.exports);
|
|
101
105
|
__reExport(src_exports, require("./update-guard"), module.exports);
|
|
106
|
+
var import_query_interface = require("./query-interface/query-interface");
|
|
102
107
|
var import_operators = __toESM(require("./operators"));
|
|
103
108
|
var import_filter_include = require("./utils/filter-include");
|
|
104
109
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -110,14 +115,17 @@ var import_filter_include = require("./utils/filter-include");
|
|
|
110
115
|
HasManyCountAssociationsMixin,
|
|
111
116
|
HasManyCreateAssociationMixin,
|
|
112
117
|
HasManyGetAssociationsMixin,
|
|
118
|
+
JoiValidationError,
|
|
113
119
|
ModelStatic,
|
|
114
120
|
Op,
|
|
115
121
|
SQLParserTypes,
|
|
116
122
|
SyncOptions,
|
|
123
|
+
TableInfo,
|
|
117
124
|
Transaction,
|
|
118
125
|
UniqueConstraintError,
|
|
119
126
|
ValidationError,
|
|
120
127
|
ValidationErrorItem,
|
|
128
|
+
extractTypeFromDefinition,
|
|
121
129
|
fieldTypeMap,
|
|
122
130
|
filterIncludes,
|
|
123
131
|
fn,
|
|
@@ -47,7 +47,7 @@ import_dayjs.default.extend(import_utc.default);
|
|
|
47
47
|
const _TimeInterface = class _TimeInterface extends import_base_interface.BaseInterface {
|
|
48
48
|
toValue(value, ctx) {
|
|
49
49
|
if (this.validate(value)) {
|
|
50
|
-
const result = import_dayjs.default
|
|
50
|
+
const result = (0, import_dayjs.default)(value).format("HH:mm:ss");
|
|
51
51
|
return result;
|
|
52
52
|
}
|
|
53
53
|
return value;
|
package/lib/operators/date.js
CHANGED
|
@@ -95,9 +95,6 @@ var date_default = {
|
|
|
95
95
|
};
|
|
96
96
|
}
|
|
97
97
|
if (Array.isArray(r)) {
|
|
98
|
-
console.log(11111111, {
|
|
99
|
-
[import_sequelize.Op.and]: [{ [import_sequelize.Op.gte]: toDate(r[0], { ctx }) }, { [import_sequelize.Op.lt]: toDate(r[1], { ctx }) }]
|
|
100
|
-
});
|
|
101
98
|
return {
|
|
102
99
|
[import_sequelize.Op.and]: [{ [import_sequelize.Op.gte]: toDate(r[0], { ctx }) }, { [import_sequelize.Op.lt]: toDate(r[1], { ctx }) }]
|
|
103
100
|
};
|
|
@@ -6,6 +6,5 @@
|
|
|
6
6
|
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
|
-
|
|
10
|
-
export
|
|
11
|
-
export * from './errors/EncryptionError';
|
|
9
|
+
declare const _default: Record<string, any>;
|
|
10
|
+
export default _default;
|
|
@@ -11,7 +11,6 @@ var __defProp = Object.defineProperty;
|
|
|
11
11
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
12
12
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
13
13
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
14
|
-
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
15
14
|
var __export = (target, all) => {
|
|
16
15
|
for (var name in all)
|
|
17
16
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -25,20 +24,17 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
25
24
|
return to;
|
|
26
25
|
};
|
|
27
26
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
28
|
-
var
|
|
29
|
-
__export(
|
|
30
|
-
|
|
27
|
+
var in_exports = {};
|
|
28
|
+
__export(in_exports, {
|
|
29
|
+
default: () => in_default
|
|
31
30
|
});
|
|
32
|
-
module.exports = __toCommonJS(
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
31
|
+
module.exports = __toCommonJS(in_exports);
|
|
32
|
+
var import_lodash = require("lodash");
|
|
33
|
+
var import_sequelize = require("sequelize");
|
|
34
|
+
var in_default = {
|
|
35
|
+
$in(val, ctx) {
|
|
36
|
+
return {
|
|
37
|
+
[import_sequelize.Op.in]: val == null ? [] : (0, import_lodash.castArray)(val)
|
|
38
|
+
};
|
|
37
39
|
}
|
|
38
40
|
};
|
|
39
|
-
__name(_EncryptionError, "EncryptionError");
|
|
40
|
-
let EncryptionError = _EncryptionError;
|
|
41
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
42
|
-
0 && (module.exports = {
|
|
43
|
-
EncryptionError
|
|
44
|
-
});
|
package/lib/operators/index.js
CHANGED
|
@@ -46,6 +46,7 @@ var import_empty = __toESM(require("./empty"));
|
|
|
46
46
|
var import_string = __toESM(require("./string"));
|
|
47
47
|
var import_eq = __toESM(require("./eq"));
|
|
48
48
|
var import_ne = __toESM(require("./ne"));
|
|
49
|
+
var import_in = __toESM(require("./in"));
|
|
49
50
|
var import_notIn = __toESM(require("./notIn"));
|
|
50
51
|
var import_boolean = __toESM(require("./boolean"));
|
|
51
52
|
var import_child_collection = __toESM(require("./child-collection"));
|
|
@@ -57,6 +58,7 @@ var operators_default = {
|
|
|
57
58
|
...import_string.default,
|
|
58
59
|
...import_eq.default,
|
|
59
60
|
...import_ne.default,
|
|
61
|
+
...import_in.default,
|
|
60
62
|
...import_notIn.default,
|
|
61
63
|
...import_boolean.default,
|
|
62
64
|
...import_child_collection.default
|
package/lib/options-parser.d.ts
CHANGED
|
@@ -26,7 +26,9 @@ 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
|
+
filterByTkToWhereOption(): string | number | import("./repository").TargetKey[] | {
|
|
30
|
+
[x: string]: import("./repository").TK;
|
|
31
|
+
};
|
|
30
32
|
toSequelizeParams(options?: {
|
|
31
33
|
parseSort?: boolean;
|
|
32
34
|
}): any;
|
package/lib/options-parser.js
CHANGED
|
@@ -41,9 +41,9 @@ __export(options_parser_exports, {
|
|
|
41
41
|
});
|
|
42
42
|
module.exports = __toCommonJS(options_parser_exports);
|
|
43
43
|
var import_lodash = __toESM(require("lodash"));
|
|
44
|
+
var import_qs = __toESM(require("qs"));
|
|
44
45
|
var import_sequelize = require("sequelize");
|
|
45
46
|
var import_filter_parser = __toESM(require("./filter-parser"));
|
|
46
|
-
var import_qs = __toESM(require("qs"));
|
|
47
47
|
const debug = require("debug")("noco-database");
|
|
48
48
|
const _OptionsParser = class _OptionsParser {
|
|
49
49
|
options;
|
|
@@ -96,14 +96,21 @@ const _OptionsParser = class _OptionsParser {
|
|
|
96
96
|
if (!filterByTkOption) {
|
|
97
97
|
return {};
|
|
98
98
|
}
|
|
99
|
-
if (
|
|
100
|
-
|
|
101
|
-
for (const [key, value] of Object.entries(filterByTkOption)) {
|
|
102
|
-
where[key] = value;
|
|
103
|
-
}
|
|
104
|
-
return where;
|
|
99
|
+
if (Array.isArray(filterByTkOption) && filterByTkOption.length === 0) {
|
|
100
|
+
return {};
|
|
105
101
|
}
|
|
106
102
|
const filterTargetKey = this.context.targetKey || this.collection.filterTargetKey;
|
|
103
|
+
if (Array.isArray(filterByTkOption) && Array.isArray(filterTargetKey)) {
|
|
104
|
+
if (!filterByTkOption.every(import_lodash.default.isPlainObject)) {
|
|
105
|
+
throw new Error("filterByTk array item must be plain object");
|
|
106
|
+
}
|
|
107
|
+
return {
|
|
108
|
+
[import_sequelize.Op.or]: filterByTkOption
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
if (import_lodash.default.isPlainObject(filterByTkOption)) {
|
|
112
|
+
return filterByTkOption;
|
|
113
|
+
}
|
|
107
114
|
if (Array.isArray(filterTargetKey)) {
|
|
108
115
|
throw new Error("multi filter target key value must be object");
|
|
109
116
|
}
|
|
@@ -88,8 +88,7 @@ const _BelongsToManyRepository = class _BelongsToManyRepository extends import_m
|
|
|
88
88
|
};
|
|
89
89
|
this.collection.validate({
|
|
90
90
|
values,
|
|
91
|
-
operation: "create"
|
|
92
|
-
context: options.context
|
|
91
|
+
operation: "create"
|
|
93
92
|
});
|
|
94
93
|
const instance = await sourceModel[createAccessor](values, createOptions);
|
|
95
94
|
await (0, import_update_associations.updateAssociations)(instance, values, { ...options, transaction: transaction2 });
|
|
@@ -11,6 +11,7 @@ import { RelationRepository } from './relation-repository';
|
|
|
11
11
|
import { AssociatedOptions, CountOptions, DestroyOptions, Filter, FindOptions, TargetKey, UpdateOptions, FirstOrCreateOptions } from './types';
|
|
12
12
|
export declare abstract class MultipleRelationRepository extends RelationRepository {
|
|
13
13
|
targetRepositoryFilterOptionsBySourceValue(): Promise<any>;
|
|
14
|
+
private normalizeScope;
|
|
14
15
|
find(options?: FindOptions): Promise<any>;
|
|
15
16
|
findAndCount(options?: FindOptions): Promise<[any[], number]>;
|
|
16
17
|
count(options?: CountOptions): Promise<number>;
|
|
@@ -65,6 +65,16 @@ const _MultipleRelationRepository = class _MultipleRelationRepository extends im
|
|
|
65
65
|
[this.association.foreignKey]: filterForeignKeyValue
|
|
66
66
|
};
|
|
67
67
|
}
|
|
68
|
+
normalizeScope(scope, model) {
|
|
69
|
+
const result = {};
|
|
70
|
+
for (const [key, value] of Object.entries(scope)) {
|
|
71
|
+
const attr = model.getAttributes()[key];
|
|
72
|
+
if (attr == null ? void 0 : attr.field) {
|
|
73
|
+
result[attr.field] = value;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return result;
|
|
77
|
+
}
|
|
68
78
|
async find(options) {
|
|
69
79
|
const targetRepository = this.targetCollection.repository;
|
|
70
80
|
const association = this.association;
|
|
@@ -74,6 +84,9 @@ const _MultipleRelationRepository = class _MultipleRelationRepository extends im
|
|
|
74
84
|
sourceKey: association.targetKey,
|
|
75
85
|
realAs: association.through.model.name
|
|
76
86
|
};
|
|
87
|
+
if (association.through.scope) {
|
|
88
|
+
oneFromTargetOptions["scope"] = this.normalizeScope(association.through.scope, association.through.model);
|
|
89
|
+
}
|
|
77
90
|
const pivotAssoc = new import_sequelize.HasOne(association.target, association.through.model, oneFromTargetOptions);
|
|
78
91
|
const appendFilter = {
|
|
79
92
|
isPivotFilter: true,
|