@nocobase/database 2.0.0-alpha.9 → 2.0.0-beta.10
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 +4 -1
- package/lib/options-parser.js +47 -16
- 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 +44 -25
- 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
package/lib/options-parser.js
CHANGED
|
@@ -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
|
}
|
|
@@ -274,10 +281,26 @@ const _OptionsParser = class _OptionsParser {
|
|
|
274
281
|
}
|
|
275
282
|
return obj;
|
|
276
283
|
}
|
|
284
|
+
normalizeAppends(appends) {
|
|
285
|
+
if (Array.isArray(appends)) {
|
|
286
|
+
return appends.filter((item) => typeof item === "string" && item.length > 0);
|
|
287
|
+
}
|
|
288
|
+
if (import_lodash.default.isPlainObject(appends)) {
|
|
289
|
+
return Object.values(appends).filter((item) => typeof item === "string" && item.length > 0);
|
|
290
|
+
}
|
|
291
|
+
if (typeof appends === "string" && appends.length > 0) {
|
|
292
|
+
return [appends];
|
|
293
|
+
}
|
|
294
|
+
return [];
|
|
295
|
+
}
|
|
277
296
|
parseAppends(appends, filterParams) {
|
|
278
297
|
if (!appends) return filterParams;
|
|
279
|
-
|
|
280
|
-
|
|
298
|
+
const appendList = this.normalizeAppends(appends);
|
|
299
|
+
if (!appendList.length) {
|
|
300
|
+
return filterParams;
|
|
301
|
+
}
|
|
302
|
+
const sortedAppends = import_lodash.default.sortBy(appendList, (append) => append.split(".").length);
|
|
303
|
+
const setInclude = /* @__PURE__ */ __name((model, queryParams, append, parentAs) => {
|
|
281
304
|
var _a;
|
|
282
305
|
const appendWithOptions = this.parseAppendWithOptions(append);
|
|
283
306
|
append = appendWithOptions.name;
|
|
@@ -316,10 +339,21 @@ const _OptionsParser = class _OptionsParser {
|
|
|
316
339
|
return;
|
|
317
340
|
}
|
|
318
341
|
if (existIncludeIndex == -1) {
|
|
319
|
-
|
|
342
|
+
const association = associations[appendAssociation];
|
|
343
|
+
if (!association) {
|
|
344
|
+
throw new Error(`association ${appendAssociation} in ${model.name} not found`);
|
|
345
|
+
}
|
|
346
|
+
let includeOptions = {
|
|
320
347
|
association: appendAssociation,
|
|
321
348
|
options: appendWithOptions.options || {}
|
|
322
|
-
}
|
|
349
|
+
};
|
|
350
|
+
if (association.associationType === "BelongsToArray") {
|
|
351
|
+
includeOptions = {
|
|
352
|
+
...includeOptions,
|
|
353
|
+
...association.generateInclude(parentAs)
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
queryParams["include"].push(includeOptions);
|
|
323
357
|
existIncludeIndex = queryParams["include"].length - 1;
|
|
324
358
|
}
|
|
325
359
|
if (lastLevel) {
|
|
@@ -355,14 +389,11 @@ const _OptionsParser = class _OptionsParser {
|
|
|
355
389
|
if (appendWithOptions.raw) {
|
|
356
390
|
nextAppend += appendWithOptions.raw;
|
|
357
391
|
}
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
queryParams["include"][existIncludeIndex],
|
|
361
|
-
nextAppend
|
|
362
|
-
);
|
|
392
|
+
const association = model.associations[queryParams["include"][existIncludeIndex].association];
|
|
393
|
+
setInclude(association.target, queryParams["include"][existIncludeIndex], nextAppend, association.as);
|
|
363
394
|
}
|
|
364
395
|
}, "setInclude");
|
|
365
|
-
for (const append of
|
|
396
|
+
for (const append of sortedAppends) {
|
|
366
397
|
setInclude(this.model, filterParams, append);
|
|
367
398
|
}
|
|
368
399
|
debug("filter params: %o", filterParams);
|
|
@@ -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,
|
|
@@ -178,7 +178,7 @@ const _RelationRepository = class _RelationRepository {
|
|
|
178
178
|
const values = options.values;
|
|
179
179
|
const transaction2 = await this.getTransaction(options);
|
|
180
180
|
const sourceModel = await this.getSourceModel(transaction2);
|
|
181
|
-
this.collection.validate({ values,
|
|
181
|
+
this.collection.validate({ values, operation: "create" });
|
|
182
182
|
const instance = await sourceModel[createAccessor](guard.sanitize(options.values), { ...options, transaction: transaction2 });
|
|
183
183
|
await (0, import_update_associations.updateAssociations)(instance, values, { ...options, transaction: transaction2 });
|
|
184
184
|
if (options.hooks !== false) {
|
|
@@ -51,7 +51,6 @@ module.exports = __toCommonJS(single_relation_repository_exports);
|
|
|
51
51
|
var import_target_collection_decorator = __toESM(require("../decorators/target-collection-decorator"));
|
|
52
52
|
var import_update_associations = require("../update-associations");
|
|
53
53
|
var import_relation_repository = require("./relation-repository");
|
|
54
|
-
var import_lodash = __toESM(require("lodash"));
|
|
55
54
|
const _SingleRelationRepository = class _SingleRelationRepository extends import_relation_repository.RelationRepository {
|
|
56
55
|
async remove(options) {
|
|
57
56
|
const transaction2 = await this.getTransaction(options);
|
|
@@ -104,7 +103,7 @@ const _SingleRelationRepository = class _SingleRelationRepository extends import
|
|
|
104
103
|
throw new Error("The record does not exist");
|
|
105
104
|
}
|
|
106
105
|
await (0, import_update_associations.updateModelByValues)(target, options == null ? void 0 : options.values, {
|
|
107
|
-
...
|
|
106
|
+
...options,
|
|
108
107
|
transaction: transaction2
|
|
109
108
|
});
|
|
110
109
|
if (options.hooks !== false) {
|
package/lib/repository.d.ts
CHANGED
|
@@ -30,7 +30,7 @@ export interface FilterAble {
|
|
|
30
30
|
}
|
|
31
31
|
export type BaseTargetKey = string | number;
|
|
32
32
|
export type MultiTargetKey = Record<string, BaseTargetKey>;
|
|
33
|
-
export type TargetKey = BaseTargetKey | MultiTargetKey;
|
|
33
|
+
export type TargetKey = BaseTargetKey | MultiTargetKey | MultiTargetKey[];
|
|
34
34
|
export type TK = TargetKey | TargetKey[];
|
|
35
35
|
type FieldValue = string | number | bigint | boolean | Date | Buffer | null | FieldValue[] | FilterWithOperator;
|
|
36
36
|
type Operators = keyof typeof operators & keyof WhereOperators;
|
|
@@ -62,7 +62,7 @@ export type CountOptions = Omit<SequelizeCountOptions, 'distinct' | 'where' | 'i
|
|
|
62
62
|
context?: any;
|
|
63
63
|
} & FilterByTk;
|
|
64
64
|
export interface FilterByTk {
|
|
65
|
-
filterByTk?:
|
|
65
|
+
filterByTk?: TK;
|
|
66
66
|
targetCollection?: string;
|
|
67
67
|
}
|
|
68
68
|
export type FindOptions = SequelizeFindOptions & CommonFindOptions & FilterByTk;
|
package/lib/repository.js
CHANGED
|
@@ -71,8 +71,8 @@ var import_hasmany_repository = require("./relation-repository/hasmany-repositor
|
|
|
71
71
|
var import_hasone_repository = require("./relation-repository/hasone-repository");
|
|
72
72
|
var import_update_associations = require("./update-associations");
|
|
73
73
|
var import_update_guard = require("./update-guard");
|
|
74
|
-
var import_filter_utils = require("./utils/filter-utils");
|
|
75
74
|
var import_utils2 = require("./utils");
|
|
75
|
+
var import_filter_utils = require("./utils/filter-utils");
|
|
76
76
|
var import_sequelize2 = require("sequelize");
|
|
77
77
|
const debug = require("debug")("noco-database");
|
|
78
78
|
const transaction = (0, import_transaction_decorator.transactionWrapperBuilder)(function() {
|
|
@@ -453,7 +453,7 @@ const _Repository = class _Repository {
|
|
|
453
453
|
underscored: this.collection.options.underscored
|
|
454
454
|
});
|
|
455
455
|
const values = this.model.callSetters(guard.sanitize(options.values || {}), options);
|
|
456
|
-
this.validate({ values,
|
|
456
|
+
this.validate({ values, operation: "create" });
|
|
457
457
|
const instance = await this.model.create(values, {
|
|
458
458
|
...options,
|
|
459
459
|
transaction: transaction2
|
|
@@ -498,7 +498,7 @@ const _Repository = class _Repository {
|
|
|
498
498
|
const transaction2 = await this.getTransaction(options);
|
|
499
499
|
const guard = import_update_guard.UpdateGuard.fromOptions(this.model, { ...options, underscored: this.collection.options.underscored });
|
|
500
500
|
const values = this.model.callSetters(guard.sanitize(options.values || {}), options);
|
|
501
|
-
this.validate({ values,
|
|
501
|
+
this.validate({ values, operation: "update" });
|
|
502
502
|
if (options.individualHooks === false) {
|
|
503
503
|
const { model: Model2 } = this.collection;
|
|
504
504
|
const primaryKeyField = Model2.primaryKeyField || Model2.primaryKeyAttribute;
|
package/lib/sync-runner.js
CHANGED
|
@@ -162,6 +162,9 @@ const _SyncRunner = class _SyncRunner {
|
|
|
162
162
|
}, "isJSONColumn");
|
|
163
163
|
for (const columnName in columns) {
|
|
164
164
|
const column = columns[columnName];
|
|
165
|
+
if (isJSONColumn(column) && this.database.inDialect("mysql")) {
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
165
168
|
const isPrimaryKey = /* @__PURE__ */ __name(() => {
|
|
166
169
|
const attribute = this.findAttributeByColumnName(columnName);
|
|
167
170
|
return attribute && attribute.primaryKey || column.primaryKey;
|
|
@@ -13,9 +13,7 @@ export declare function modelAssociations(instance: Model): {
|
|
|
13
13
|
[key: string]: Association<import("sequelize").Model<any, any>, import("sequelize").Model<any, any>>;
|
|
14
14
|
};
|
|
15
15
|
export declare function belongsToManyAssociations(instance: Model): Array<BelongsToMany>;
|
|
16
|
-
export declare function modelAssociationByKey(instance: Model, key: string): Association
|
|
17
|
-
update?: (instance: Model, value: any, options: UpdateAssociationOptions) => Promise<any>;
|
|
18
|
-
};
|
|
16
|
+
export declare function modelAssociationByKey(instance: Model, key: string): Association;
|
|
19
17
|
type UpdateValue = {
|
|
20
18
|
[key: string]: any;
|
|
21
19
|
};
|
|
@@ -51,7 +49,7 @@ export declare function updateAssociations(instance: Model, values: any, options
|
|
|
51
49
|
* @param value
|
|
52
50
|
* @param options
|
|
53
51
|
*/
|
|
54
|
-
export declare function updateAssociation(instance: Model, key: string, value: any, options?: UpdateAssociationOptions): Promise<
|
|
52
|
+
export declare function updateAssociation(instance: Model, key: string, value: any, options?: UpdateAssociationOptions): Promise<boolean>;
|
|
55
53
|
/**
|
|
56
54
|
* update belongsTo and HasOne
|
|
57
55
|
* @param model
|
|
@@ -81,8 +81,7 @@ async function updateModelByValues(instance, values, options) {
|
|
|
81
81
|
}
|
|
82
82
|
instance.constructor.collection.validate({
|
|
83
83
|
values,
|
|
84
|
-
operation: "update"
|
|
85
|
-
context: options == null ? void 0 : options.context
|
|
84
|
+
operation: "update"
|
|
86
85
|
});
|
|
87
86
|
await instance.update(values, options);
|
|
88
87
|
await updateAssociations(instance, values, options);
|
|
@@ -177,9 +176,6 @@ async function updateAssociation(instance, key, value, options = {}) {
|
|
|
177
176
|
if (options.associationContext && isReverseAssociationPair(association, options.associationContext)) {
|
|
178
177
|
return false;
|
|
179
178
|
}
|
|
180
|
-
if (association.update) {
|
|
181
|
-
return association.update(instance, value, options);
|
|
182
|
-
}
|
|
183
179
|
switch (association.associationType) {
|
|
184
180
|
case "HasOne":
|
|
185
181
|
case "BelongsTo":
|
|
@@ -223,16 +219,6 @@ async function updateSingleAssociation(model, key, value, options = {}) {
|
|
|
223
219
|
);
|
|
224
220
|
}
|
|
225
221
|
}, "checkBelongsToForeignKeyValue");
|
|
226
|
-
if ((0, import_utils.isStringOrNumber)(value)) {
|
|
227
|
-
await model[setAccessor](value, { context, transaction });
|
|
228
|
-
return true;
|
|
229
|
-
}
|
|
230
|
-
if (value instanceof import_model.Model) {
|
|
231
|
-
await model[setAccessor](value, { context, transaction });
|
|
232
|
-
model.setDataValue(key, value);
|
|
233
|
-
return true;
|
|
234
|
-
}
|
|
235
|
-
const createAccessor = association.accessors.create;
|
|
236
222
|
let dataKey;
|
|
237
223
|
let M;
|
|
238
224
|
if (association.associationType === "BelongsTo") {
|
|
@@ -242,6 +228,24 @@ async function updateSingleAssociation(model, key, value, options = {}) {
|
|
|
242
228
|
M = association.target;
|
|
243
229
|
dataKey = M.primaryKeyAttribute;
|
|
244
230
|
}
|
|
231
|
+
if ((0, import_utils.isStringOrNumber)(value)) {
|
|
232
|
+
const instance2 = await M.findOne({
|
|
233
|
+
where: {
|
|
234
|
+
[dataKey]: value
|
|
235
|
+
},
|
|
236
|
+
transaction
|
|
237
|
+
});
|
|
238
|
+
if (instance2) {
|
|
239
|
+
await model[setAccessor](value, { context, transaction });
|
|
240
|
+
}
|
|
241
|
+
return true;
|
|
242
|
+
}
|
|
243
|
+
if (value instanceof import_model.Model) {
|
|
244
|
+
await model[setAccessor](value, { context, transaction });
|
|
245
|
+
model.setDataValue(key, value);
|
|
246
|
+
return true;
|
|
247
|
+
}
|
|
248
|
+
const createAccessor = association.accessors.create;
|
|
245
249
|
if ((0, import_utils.isStringOrNumber)(value[dataKey])) {
|
|
246
250
|
const instance2 = await M.findOne({
|
|
247
251
|
where: {
|
|
@@ -259,7 +263,7 @@ async function updateSingleAssociation(model, key, value, options = {}) {
|
|
|
259
263
|
if (association.associationType === "HasOne") {
|
|
260
264
|
delete updateValues[association.foreignKey];
|
|
261
265
|
}
|
|
262
|
-
await instance2.update(updateValues, { ...options, transaction });
|
|
266
|
+
await instance2.update(updateValues, { ...options, transaction, inputValues: updateValues });
|
|
263
267
|
}
|
|
264
268
|
await updateAssociations(instance2, value, {
|
|
265
269
|
...options,
|
|
@@ -273,10 +277,9 @@ async function updateSingleAssociation(model, key, value, options = {}) {
|
|
|
273
277
|
}
|
|
274
278
|
association.target.collection.validate({
|
|
275
279
|
values: value,
|
|
276
|
-
context: options.context,
|
|
277
280
|
operation: "create"
|
|
278
281
|
});
|
|
279
|
-
const instance = await model[createAccessor](value, { context, transaction });
|
|
282
|
+
const instance = await model[createAccessor](value, { context, transaction, inputValues: value });
|
|
280
283
|
await updateAssociations(instance, value, {
|
|
281
284
|
...options,
|
|
282
285
|
transaction,
|
|
@@ -316,7 +319,7 @@ async function updateMultipleAssociation(model, key, value, options = {}) {
|
|
|
316
319
|
return;
|
|
317
320
|
}
|
|
318
321
|
value = import_lodash.default.castArray(value);
|
|
319
|
-
|
|
322
|
+
let setItems = [];
|
|
320
323
|
const objectItems = [];
|
|
321
324
|
for (const item of value) {
|
|
322
325
|
if ((0, import_utils.isUndefinedOrNull)(item)) {
|
|
@@ -340,6 +343,25 @@ async function updateMultipleAssociation(model, key, value, options = {}) {
|
|
|
340
343
|
objectItems.push(item);
|
|
341
344
|
}
|
|
342
345
|
}
|
|
346
|
+
if (setItems.length > 0) {
|
|
347
|
+
const TargetModel = association.target;
|
|
348
|
+
const pk2 = TargetModel.primaryKeyAttribute;
|
|
349
|
+
const targetKey2 = association.targetKey || association.options.targetKey || pk2;
|
|
350
|
+
const rawKeys = [];
|
|
351
|
+
const instanceItems = [];
|
|
352
|
+
for (const item of setItems) {
|
|
353
|
+
if (item instanceof import_model.Model) {
|
|
354
|
+
instanceItems.push(item);
|
|
355
|
+
} else if ((0, import_utils.isStringOrNumber)(item)) {
|
|
356
|
+
rawKeys.push(item);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
const validInstances = rawKeys.length ? await TargetModel.findAll({
|
|
360
|
+
where: { [targetKey2]: rawKeys },
|
|
361
|
+
transaction
|
|
362
|
+
}) : [];
|
|
363
|
+
setItems = [...instanceItems, ...validInstances];
|
|
364
|
+
}
|
|
343
365
|
await model[setAccessor](setItems, { transaction, context, individualHooks: true, validate: false });
|
|
344
366
|
const newItems = [];
|
|
345
367
|
const pk = association.target.primaryKeyAttribute;
|
|
@@ -368,10 +390,9 @@ async function updateMultipleAssociation(model, key, value, options = {}) {
|
|
|
368
390
|
if ((0, import_utils.isUndefinedOrNull)(item[targetKey])) {
|
|
369
391
|
association.target.collection.validate({
|
|
370
392
|
values: item,
|
|
371
|
-
context: options.context,
|
|
372
393
|
operation: "create"
|
|
373
394
|
});
|
|
374
|
-
const instance = await model[createAccessor](item, accessorOptions);
|
|
395
|
+
const instance = await model[createAccessor](item, { ...accessorOptions, inputValues: item });
|
|
375
396
|
await updateAssociations(instance, item, {
|
|
376
397
|
...options,
|
|
377
398
|
transaction,
|
|
@@ -390,10 +411,9 @@ async function updateMultipleAssociation(model, key, value, options = {}) {
|
|
|
390
411
|
if (!instance) {
|
|
391
412
|
association.target.collection.validate({
|
|
392
413
|
values: item,
|
|
393
|
-
context: options.context,
|
|
394
414
|
operation: "create"
|
|
395
415
|
});
|
|
396
|
-
instance = await model[createAccessor](item, accessorOptions);
|
|
416
|
+
instance = await model[createAccessor](item, { ...accessorOptions, inputValues: item });
|
|
397
417
|
await updateAssociations(instance, item, {
|
|
398
418
|
...options,
|
|
399
419
|
transaction,
|
|
@@ -414,10 +434,9 @@ async function updateMultipleAssociation(model, key, value, options = {}) {
|
|
|
414
434
|
}
|
|
415
435
|
association.target.collection.validate({
|
|
416
436
|
values: item,
|
|
417
|
-
context: options.context,
|
|
418
437
|
operation: "update"
|
|
419
438
|
});
|
|
420
|
-
await instance.update(item, { ...options, transaction });
|
|
439
|
+
await instance.update(item, { ...options, transaction, inputValues: item });
|
|
421
440
|
}
|
|
422
441
|
await updateAssociations(instance, item, {
|
|
423
442
|
...options,
|
|
@@ -12,48 +12,3 @@ export declare function buildJoiSchema(validation: ValidationOptions, options: {
|
|
|
12
12
|
label?: string;
|
|
13
13
|
value: string;
|
|
14
14
|
}): AnySchema;
|
|
15
|
-
export declare function getJoiErrorMessage(t: Function): {
|
|
16
|
-
'string.base': any;
|
|
17
|
-
'string.empty': any;
|
|
18
|
-
'string.min': any;
|
|
19
|
-
'string.max': any;
|
|
20
|
-
'string.length': any;
|
|
21
|
-
'string.alphanum': any;
|
|
22
|
-
'string.token': any;
|
|
23
|
-
'string.regex': any;
|
|
24
|
-
'string.email': any;
|
|
25
|
-
'string.uri': any;
|
|
26
|
-
'string.uriCustomScheme': any;
|
|
27
|
-
'string.isoDate': any;
|
|
28
|
-
'string.guid': any;
|
|
29
|
-
'string.hex': any;
|
|
30
|
-
'string.hostname': any;
|
|
31
|
-
'string.lowercase': any;
|
|
32
|
-
'string.uppercase': any;
|
|
33
|
-
'string.trim': any;
|
|
34
|
-
'string.creditCard': any;
|
|
35
|
-
'string.pattern.base': any;
|
|
36
|
-
'string.pattern.name': any;
|
|
37
|
-
'string.pattern.invert.base': any;
|
|
38
|
-
'string.pattern.invert.name': any;
|
|
39
|
-
'any.required': any;
|
|
40
|
-
'number.base': any;
|
|
41
|
-
'number.min': any;
|
|
42
|
-
'number.max': any;
|
|
43
|
-
'number.less': any;
|
|
44
|
-
'number.greater': any;
|
|
45
|
-
'number.float': any;
|
|
46
|
-
'number.integer': any;
|
|
47
|
-
'number.negative': any;
|
|
48
|
-
'number.positive': any;
|
|
49
|
-
'number.precision': any;
|
|
50
|
-
'number.multiple': any;
|
|
51
|
-
'number.port': any;
|
|
52
|
-
'number.unsafe': any;
|
|
53
|
-
'date.base': any;
|
|
54
|
-
'date.format': any;
|
|
55
|
-
'date.greater': any;
|
|
56
|
-
'date.less': any;
|
|
57
|
-
'date.max': any;
|
|
58
|
-
'date.min': any;
|
|
59
|
-
};
|
|
@@ -37,8 +37,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
37
37
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
38
38
|
var field_validation_exports = {};
|
|
39
39
|
__export(field_validation_exports, {
|
|
40
|
-
buildJoiSchema: () => buildJoiSchema
|
|
41
|
-
getJoiErrorMessage: () => getJoiErrorMessage
|
|
40
|
+
buildJoiSchema: () => buildJoiSchema
|
|
42
41
|
});
|
|
43
42
|
module.exports = __toCommonJS(field_validation_exports);
|
|
44
43
|
var import_joi = __toESM(require("joi"));
|
|
@@ -80,64 +79,7 @@ function buildJoiSchema(validation, options) {
|
|
|
80
79
|
return schema;
|
|
81
80
|
}
|
|
82
81
|
__name(buildJoiSchema, "buildJoiSchema");
|
|
83
|
-
function getJoiErrorMessage(t) {
|
|
84
|
-
const tOptions = { ns: "client" };
|
|
85
|
-
const JoiErrorMessages = {
|
|
86
|
-
"string.base": t("{{#label}} must be a string", tOptions),
|
|
87
|
-
"string.empty": t("{{#label}} is not allowed to be empty", tOptions),
|
|
88
|
-
"string.min": t("{{#label}} length must be at least {{#limit}} characters long", tOptions),
|
|
89
|
-
"string.max": t("{{#label}} length must be less than or equal to {{#limit}} characters long", tOptions),
|
|
90
|
-
"string.length": t("{{#label}} length must be {{#limit}} characters long", tOptions),
|
|
91
|
-
"string.alphanum": t("{{#label}} must only contain alpha-numeric characters", tOptions),
|
|
92
|
-
"string.token": t("{{#label}} must only contain alpha-numeric and underscore characters", tOptions),
|
|
93
|
-
"string.regex": t("{{#label}} with value {{#value}} fails to match the required pattern", tOptions),
|
|
94
|
-
"string.email": t("{{#label}} email address doesn\u2019t meet the required format", tOptions),
|
|
95
|
-
"string.uri": t("{{#label}} must be a valid uri", tOptions),
|
|
96
|
-
"string.uriCustomScheme": t(
|
|
97
|
-
"{{#label}} must be a valid uri with a scheme matching the {{#scheme}} pattern",
|
|
98
|
-
tOptions
|
|
99
|
-
),
|
|
100
|
-
"string.isoDate": t("{{#label}} must be a valid ISO 8601 date", tOptions),
|
|
101
|
-
"string.guid": t("{{#label}} must be a valid UUID", tOptions),
|
|
102
|
-
"string.hex": t("{{#label}} must only contain hexadecimal characters", tOptions),
|
|
103
|
-
"string.hostname": t("{{#label}} must be a valid hostname", tOptions),
|
|
104
|
-
"string.lowercase": t("{{#label}} must only contain lowercase characters", tOptions),
|
|
105
|
-
"string.uppercase": t("{{#label}} must only contain uppercase characters", tOptions),
|
|
106
|
-
"string.trim": t("{{#label}} must not have leading or trailing whitespace", tOptions),
|
|
107
|
-
"string.creditCard": t("{{#label}} must be a credit card", tOptions),
|
|
108
|
-
"string.pattern.base": t('{{#label}} with value "{{#value}}" fails to match the required pattern', tOptions),
|
|
109
|
-
"string.pattern.name": t('{{#label}} with value "{{#value}}" fails to match the {{#name}} pattern', tOptions),
|
|
110
|
-
"string.pattern.invert.base": t('{{#label}} with value "{{#value}}" matches the inverted pattern', tOptions),
|
|
111
|
-
"string.pattern.invert.name": t(
|
|
112
|
-
'{{#label}} with value "{{#value}}" matches the inverted {{#name}} pattern',
|
|
113
|
-
tOptions
|
|
114
|
-
),
|
|
115
|
-
"any.required": t("{{#label}} is required", tOptions),
|
|
116
|
-
"number.base": t("{{#label}} must be a number", tOptions),
|
|
117
|
-
"number.min": t("{{#label}} must be greater than or equal to {{#limit}}", tOptions),
|
|
118
|
-
"number.max": t("{{#label}} must be less than or equal to {{#limit}}", tOptions),
|
|
119
|
-
"number.less": t("{{#label}} must be less than {{#limit}}", tOptions),
|
|
120
|
-
"number.greater": t("{{#label}} must be greater than {{#limit}}", tOptions),
|
|
121
|
-
"number.float": t("{{#label}} must be a float or double", tOptions),
|
|
122
|
-
"number.integer": t("{{#label}} must be an integer", tOptions),
|
|
123
|
-
"number.negative": t("{{#label}} must be a negative number", tOptions),
|
|
124
|
-
"number.positive": t("{{#label}} must be a positive number", tOptions),
|
|
125
|
-
"number.precision": t("{{#label}} must not have more than {{#limit}} decimal places", tOptions),
|
|
126
|
-
"number.multiple": t("{{#label}} must be a multiple of {{#multiple}}", tOptions),
|
|
127
|
-
"number.port": t("{{#label}} must be a valid port", tOptions),
|
|
128
|
-
"number.unsafe": t("{{#label}} must be a safe number", tOptions),
|
|
129
|
-
"date.base": t("{{#label}} must be a valid date", tOptions),
|
|
130
|
-
"date.format": t("{{#label}} must be in {{#format}} format", tOptions),
|
|
131
|
-
"date.greater": t("{{#label}} must be greater than {{#limit}}", tOptions),
|
|
132
|
-
"date.less": t("{{#label}} must be less than {{#limit}}", tOptions),
|
|
133
|
-
"date.max": t("{{#label}} must be less than or equal to {{#limit}}", tOptions),
|
|
134
|
-
"date.min": t("{{#label}} must be greater than or equal to {{#limit}}", tOptions)
|
|
135
|
-
};
|
|
136
|
-
return JoiErrorMessages;
|
|
137
|
-
}
|
|
138
|
-
__name(getJoiErrorMessage, "getJoiErrorMessage");
|
|
139
82
|
// Annotate the CommonJS export names for ESM import in node:
|
|
140
83
|
0 && (module.exports = {
|
|
141
|
-
buildJoiSchema
|
|
142
|
-
getJoiErrorMessage
|
|
84
|
+
buildJoiSchema
|
|
143
85
|
});
|
package/lib/utils.d.ts
CHANGED
|
@@ -16,4 +16,5 @@ export declare function percent2float(value: string): number;
|
|
|
16
16
|
export declare function isUndefinedOrNull(value: any): boolean;
|
|
17
17
|
export declare function isStringOrNumber(value: any): boolean;
|
|
18
18
|
export declare function getKeysByPrefix(keys: string[], prefix: string): string[];
|
|
19
|
+
export declare function extractTypeFromDefinition(rawType: string): string;
|
|
19
20
|
export declare function processIncludes(includes: any[], model: any, parentAs?: string): any[];
|
package/lib/utils.js
CHANGED
|
@@ -38,6 +38,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
38
38
|
var utils_exports = {};
|
|
39
39
|
__export(utils_exports, {
|
|
40
40
|
checkIdentifier: () => checkIdentifier,
|
|
41
|
+
extractTypeFromDefinition: () => extractTypeFromDefinition,
|
|
41
42
|
getKeysByPrefix: () => getKeysByPrefix,
|
|
42
43
|
getTableName: () => getTableName,
|
|
43
44
|
isStringOrNumber: () => isStringOrNumber,
|
|
@@ -141,6 +142,14 @@ function getKeysByPrefix(keys, prefix) {
|
|
|
141
142
|
return keys.filter((key) => key.startsWith(`${prefix}.`)).map((key) => key.substring(prefix.length + 1));
|
|
142
143
|
}
|
|
143
144
|
__name(getKeysByPrefix, "getKeysByPrefix");
|
|
145
|
+
function extractTypeFromDefinition(rawType) {
|
|
146
|
+
const leftParenIndex = rawType.indexOf("(");
|
|
147
|
+
if (leftParenIndex === -1) {
|
|
148
|
+
return rawType.toLowerCase();
|
|
149
|
+
}
|
|
150
|
+
return rawType.substring(0, leftParenIndex).toLowerCase().trim();
|
|
151
|
+
}
|
|
152
|
+
__name(extractTypeFromDefinition, "extractTypeFromDefinition");
|
|
144
153
|
function processIncludes(includes, model, parentAs = "") {
|
|
145
154
|
includes.forEach((include, index) => {
|
|
146
155
|
const association = model.associations[include.association];
|
|
@@ -164,6 +173,7 @@ __name(processIncludes, "processIncludes");
|
|
|
164
173
|
// Annotate the CommonJS export names for ESM import in node:
|
|
165
174
|
0 && (module.exports = {
|
|
166
175
|
checkIdentifier,
|
|
176
|
+
extractTypeFromDefinition,
|
|
167
177
|
getKeysByPrefix,
|
|
168
178
|
getTableName,
|
|
169
179
|
isStringOrNumber,
|
|
@@ -39,9 +39,9 @@ const postgres = {
|
|
|
39
39
|
name: "string",
|
|
40
40
|
smallint: ["integer", "sort"],
|
|
41
41
|
integer: ["integer", "unixTimestamp", "sort"],
|
|
42
|
-
bigint: ["bigInt", "unixTimestamp", "sort"],
|
|
42
|
+
bigint: ["bigInt", "snowflakeId", "unixTimestamp", "sort"],
|
|
43
43
|
decimal: "decimal",
|
|
44
|
-
numeric: "
|
|
44
|
+
numeric: "decimal",
|
|
45
45
|
real: "float",
|
|
46
46
|
"double precision": "float",
|
|
47
47
|
"timestamp without time zone": "datetimeNoTz",
|
|
@@ -77,7 +77,7 @@ const mysql = {
|
|
|
77
77
|
int: ["integer", "unixTimestamp", "sort"],
|
|
78
78
|
"int unsigned": ["integer", "unixTimestamp", "sort"],
|
|
79
79
|
integer: ["integer", "unixTimestamp", "sort"],
|
|
80
|
-
bigint: ["bigInt", "unixTimestamp", "sort"],
|
|
80
|
+
bigint: ["bigInt", "snowflakeId", "unixTimestamp", "sort"],
|
|
81
81
|
"bigint unsigned": ["bigInt", "unixTimestamp", "sort"],
|
|
82
82
|
float: "float",
|
|
83
83
|
double: "float",
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nocobase/database",
|
|
3
|
-
"version": "2.0.0-
|
|
3
|
+
"version": "2.0.0-beta.10",
|
|
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": "2.0.0-
|
|
10
|
-
"@nocobase/utils": "2.0.0-
|
|
9
|
+
"@nocobase/logger": "2.0.0-beta.10",
|
|
10
|
+
"@nocobase/utils": "2.0.0-beta.10",
|
|
11
11
|
"async-mutex": "^0.3.2",
|
|
12
12
|
"chalk": "^4.1.1",
|
|
13
13
|
"cron-parser": "4.4.0",
|
|
@@ -39,5 +39,5 @@
|
|
|
39
39
|
"url": "git+https://github.com/nocobase/nocobase.git",
|
|
40
40
|
"directory": "packages/database"
|
|
41
41
|
},
|
|
42
|
-
"gitHead": "
|
|
42
|
+
"gitHead": "9943dc4b0fdedcac3f304714b58635ae441e2560"
|
|
43
43
|
}
|
|
@@ -1,20 +0,0 @@
|
|
|
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
|
-
import { DataTypes } from 'sequelize';
|
|
10
|
-
import { BaseColumnFieldOptions, Field } from '../field';
|
|
11
|
-
export interface EncryptionFieldOptions extends BaseColumnFieldOptions {
|
|
12
|
-
type: 'encryption';
|
|
13
|
-
hidden?: boolean;
|
|
14
|
-
}
|
|
15
|
-
export declare class EncryptionField extends Field {
|
|
16
|
-
get dataType(): DataTypes.StringDataTypeConstructor;
|
|
17
|
-
init(): void;
|
|
18
|
-
bind(): void;
|
|
19
|
-
unbind(): void;
|
|
20
|
-
}
|