@nocobase/database 2.1.0-beta.13 → 2.1.0-beta.15

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.
@@ -75,16 +75,20 @@ const queryParentSQL = /* @__PURE__ */ __name((options) => {
75
75
  const targetKeyField = collection.model.rawAttributes[targetKey].field;
76
76
  const queryInterface = db.sequelize.getQueryInterface();
77
77
  const q = queryInterface.quoteIdentifier.bind(queryInterface);
78
- return `WITH RECURSIVE cte AS (
78
+ const placeholders = nodeIds.map((_, index) => `$${index + 1}`).join(", ");
79
+ return {
80
+ sql: `WITH RECURSIVE cte AS (
79
81
  SELECT ${q(targetKeyField)}, ${q(foreignKeyField)}
80
82
  FROM ${tableName}
81
- WHERE ${q(targetKeyField)} IN ('${nodeIds.join("','")}')
83
+ WHERE ${q(targetKeyField)} IN (${placeholders})
82
84
  UNION ALL
83
85
  SELECT t.${q(targetKeyField)}, t.${q(foreignKeyField)}
84
86
  FROM ${tableName} AS t
85
87
  INNER JOIN cte ON t.${q(targetKeyField)} = cte.${q(foreignKeyField)}
86
88
  )
87
- SELECT ${q(targetKeyField)} AS ${q(targetKey)}, ${q(foreignKeyField)} AS ${q(foreignKey)} FROM cte`;
89
+ SELECT ${q(targetKeyField)} AS ${q(targetKey)}, ${q(foreignKeyField)} AS ${q(foreignKey)} FROM cte`,
90
+ bind: nodeIds
91
+ };
88
92
  }, "queryParentSQL");
89
93
  const _EagerLoadingTree = class _EagerLoadingTree {
90
94
  root;
@@ -305,7 +309,7 @@ const _EagerLoadingTree = class _EagerLoadingTree {
305
309
  });
306
310
  if (node.includeOption.recursively && instances.length > 0) {
307
311
  const targetKey = association.targetKey;
308
- const sql = queryParentSQL({
312
+ const { sql, bind } = queryParentSQL({
309
313
  db: this.db,
310
314
  collection: collection2,
311
315
  foreignKey,
@@ -313,6 +317,7 @@ const _EagerLoadingTree = class _EagerLoadingTree {
313
317
  nodeIds: instances.map((instance) => instance.get(targetKey))
314
318
  });
315
319
  const results = await this.db.sequelize.query(sql, {
320
+ bind,
316
321
  type: "SELECT",
317
322
  transaction
318
323
  });
package/lib/repository.js CHANGED
@@ -151,12 +151,13 @@ const _Repository = class _Repository {
151
151
  [import_sequelize.Op.and]: [options["where"] || {}, optionParser.filterByTkToWhereOption()]
152
152
  };
153
153
  }
154
+ const hasInclude = Array.isArray(options["include"]) && options["include"].length > 0;
154
155
  const queryOptions = {
155
- ...options,
156
- distinct: Boolean(this.collection.model.primaryKeyAttribute) && !this.collection.isMultiFilterTargetKey()
156
+ ...options
157
157
  };
158
- if (Array.isArray(queryOptions.include) && queryOptions.include.length > 0) {
158
+ if (hasInclude) {
159
159
  queryOptions.include = (0, import_utils2.processIncludes)(queryOptions.include, this.collection.model);
160
+ queryOptions.distinct = Boolean(this.collection.model.primaryKeyAttribute) && !this.collection.isMultiFilterTargetKey();
160
161
  } else {
161
162
  delete queryOptions.include;
162
163
  }
@@ -42,6 +42,19 @@ __export(field_validation_exports, {
42
42
  module.exports = __toCommonJS(field_validation_exports);
43
43
  var import_joi = __toESM(require("joi"));
44
44
  var import_lodash = __toESM(require("lodash"));
45
+ function getFractionLength(value) {
46
+ const normalized = value.trim().replace(/,/g, "");
47
+ if (!normalized || /e/i.test(normalized)) {
48
+ return 0;
49
+ }
50
+ const unsignedValue = normalized.startsWith("+") || normalized.startsWith("-") ? normalized.slice(1) : normalized;
51
+ const dotIndex = unsignedValue.indexOf(".");
52
+ if (dotIndex < 0) {
53
+ return 0;
54
+ }
55
+ return unsignedValue.slice(dotIndex + 1).length;
56
+ }
57
+ __name(getFractionLength, "getFractionLength");
45
58
  function buildJoiSchema(validation, options) {
46
59
  const { type, rules } = validation;
47
60
  const { label, value } = options;
@@ -60,7 +73,21 @@ function buildJoiSchema(validation, options) {
60
73
  rules.forEach((rule) => {
61
74
  const args = import_lodash.default.cloneDeep(rule.args);
62
75
  if (rule.name === "precision") {
63
- schema = schema.strict();
76
+ const limit = Number(args == null ? void 0 : args.limit);
77
+ schema = schema.custom((currentValue, helpers) => {
78
+ if (Number.isNaN(limit)) {
79
+ return currentValue;
80
+ }
81
+ const originalValue = helpers.original;
82
+ if (originalValue === null || originalValue === void 0 || originalValue === "") {
83
+ return currentValue;
84
+ }
85
+ if (getFractionLength(String(originalValue)) > limit) {
86
+ return helpers.error("number.precision", { limit });
87
+ }
88
+ return currentValue;
89
+ });
90
+ return;
64
91
  }
65
92
  if (!import_lodash.default.isEmpty(args)) {
66
93
  if (rule.name === "pattern" && !import_lodash.default.isRegExp(args.regex)) {
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@nocobase/database",
3
- "version": "2.1.0-beta.13",
3
+ "version": "2.1.0-beta.15",
4
4
  "description": "",
5
5
  "main": "./lib/index.js",
6
6
  "types": "./lib/index.d.ts",
7
7
  "license": "Apache-2.0",
8
8
  "dependencies": {
9
- "@nocobase/logger": "2.1.0-beta.13",
10
- "@nocobase/utils": "2.1.0-beta.13",
9
+ "@nocobase/logger": "2.1.0-beta.15",
10
+ "@nocobase/utils": "2.1.0-beta.15",
11
11
  "async-mutex": "^0.3.2",
12
12
  "chalk": "^4.1.1",
13
13
  "cron-parser": "4.4.0",
@@ -38,5 +38,5 @@
38
38
  "url": "git+https://github.com/nocobase/nocobase.git",
39
39
  "directory": "packages/database"
40
40
  },
41
- "gitHead": "691716e5f4e5f8bd3859d65bc8a29b4e3c32209b"
41
+ "gitHead": "dc1aceea6357e6ab149976c2a236fc4b6bee1370"
42
42
  }