@nocobase/database 2.0.0-alpha.9 → 2.0.0-beta.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.
Files changed (44) hide show
  1. package/lib/belongs-to-array/belongs-to-array-repository.d.ts +0 -2
  2. package/lib/belongs-to-array/belongs-to-array-repository.js +0 -13
  3. package/lib/collection.d.ts +1 -3
  4. package/lib/collection.js +31 -30
  5. package/lib/database.d.ts +1 -0
  6. package/lib/database.js +19 -10
  7. package/lib/dialects/mariadb-dialect.js +6 -1
  8. package/lib/dialects/postgres-dialect.js +0 -3
  9. package/lib/eager-loading/eager-loading-tree.js +3 -2
  10. package/lib/fields/field.js +4 -0
  11. package/lib/fields/index.d.ts +1 -3
  12. package/lib/fields/index.js +0 -2
  13. package/lib/fields/snowflake-id-field.js +10 -2
  14. package/lib/index.d.ts +3 -1
  15. package/lib/index.js +8 -0
  16. package/lib/interfaces/time-interface.js +1 -1
  17. package/lib/operators/date.js +0 -3
  18. package/lib/{fields/encryption-field/index.d.ts → operators/in.d.ts} +2 -3
  19. package/lib/{fields/encryption-field/errors/EncryptionError.js → operators/in.js} +11 -15
  20. package/lib/operators/index.js +2 -0
  21. package/lib/options-parser.d.ts +3 -1
  22. package/lib/options-parser.js +14 -7
  23. package/lib/relation-repository/belongs-to-many-repository.js +1 -2
  24. package/lib/relation-repository/multiple-relation-repository.d.ts +1 -0
  25. package/lib/relation-repository/multiple-relation-repository.js +13 -0
  26. package/lib/relation-repository/relation-repository.js +1 -1
  27. package/lib/relation-repository/single-relation-repository.js +1 -2
  28. package/lib/repository.d.ts +2 -2
  29. package/lib/repository.js +3 -3
  30. package/lib/sync-runner.js +3 -0
  31. package/lib/update-associations.d.ts +2 -4
  32. package/lib/update-associations.js +6 -14
  33. package/lib/utils/field-validation.d.ts +0 -45
  34. package/lib/utils/field-validation.js +2 -60
  35. package/lib/utils.d.ts +1 -0
  36. package/lib/utils.js +10 -0
  37. package/lib/view/field-type-map.js +3 -3
  38. package/package.json +4 -4
  39. package/lib/fields/encryption-field/encryption-field.d.ts +0 -20
  40. package/lib/fields/encryption-field/encryption-field.js +0 -110
  41. package/lib/fields/encryption-field/errors/EncryptionError.d.ts +0 -11
  42. package/lib/fields/encryption-field/index.js +0 -34
  43. package/lib/fields/encryption-field/utils.d.ts +0 -6
  44. 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;
@@ -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, context, operation } = options;
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, _c;
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
- if ((_b = field.options) == null ? void 0 : _b.validation.rules) {
184
- const isRequired = (_c = field.options) == null ? void 0 : _c.validation.rules.some((rule) => rule.name === "required");
185
- if (isRequired && !val) {
186
- throw new Error(
187
- t("{{#label}} is required", {
188
- ns: "client",
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: `${t("Collection", { ns: "client" })}: ${this.name}, ${t("Field", { ns: "client" })}: ${t(fieldLabel, {
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) => this.model.rawAttributes[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) => this.model.rawAttributes[field].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.inDialect("postgres")) {
291
- await client.query("SET search_path = public");
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
- if (typeof options.underscored !== "boolean") {
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.sequelize.query(finalSQL, { bind, transaction });
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 = { ...options.dialectOptions || {}, supportBigNumbers: true, bigNumberStrings: true };
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
  });
@@ -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;
@@ -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 | EncryptionField | SnowflakeIdFieldOptions;
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;
@@ -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) => this.setId(name, 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.utc(value).format("HH:mm:ss");
50
+ const result = (0, import_dayjs.default)(value).format("HH:mm:ss");
51
51
  return result;
52
52
  }
53
53
  return value;
@@ -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
- export * from './encryption-field';
10
- export * from './utils';
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 EncryptionError_exports = {};
29
- __export(EncryptionError_exports, {
30
- EncryptionError: () => EncryptionError
27
+ var in_exports = {};
28
+ __export(in_exports, {
29
+ default: () => in_default
31
30
  });
32
- module.exports = __toCommonJS(EncryptionError_exports);
33
- const _EncryptionError = class _EncryptionError extends Error {
34
- constructor(message, options) {
35
- super(message, options);
36
- this.name = "EncryptionError";
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
- });
@@ -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
@@ -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;
@@ -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 (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;
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,