@nocobase/plugin-data-source-main 2.0.0-alpha.7 → 2.0.0-alpha.70

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 (33) hide show
  1. package/dist/client/index.js +1 -1
  2. package/dist/externalVersion.js +8 -6
  3. package/dist/locale/de-DE.json +46 -2
  4. package/dist/locale/en-US.json +46 -2
  5. package/dist/locale/es-ES.json +48 -0
  6. package/dist/locale/fr-FR.json +48 -0
  7. package/dist/locale/hu-HU.json +48 -0
  8. package/dist/locale/id-ID.json +48 -0
  9. package/dist/locale/it-IT.json +46 -2
  10. package/dist/locale/ja-JP.json +45 -1
  11. package/dist/locale/ko-KR.json +48 -0
  12. package/dist/locale/nl-NL.json +46 -2
  13. package/dist/locale/pt-BR.json +48 -0
  14. package/dist/locale/ru-RU.json +48 -0
  15. package/dist/locale/tr-TR.json +48 -0
  16. package/dist/locale/uk-UA.json +48 -0
  17. package/dist/locale/vi-VN.json +48 -0
  18. package/dist/locale/zh-CN.json +46 -2
  19. package/dist/locale/zh-TW.json +48 -0
  20. package/dist/server/{hooks/afterCreateForReverseField.d.ts → constants.d.ts} +1 -4
  21. package/dist/server/{hooks/afterCreateForReverseField.js → constants.js} +6 -16
  22. package/dist/server/hooks/afterCreateForForeignKeyField.js +5 -3
  23. package/dist/server/hooks/index.d.ts +0 -1
  24. package/dist/server/hooks/index.js +0 -2
  25. package/dist/server/migrations/20251214100636-id2integer.d.ts +14 -0
  26. package/dist/server/migrations/20251214100636-id2integer.js +48 -0
  27. package/dist/server/models/collection.js +16 -10
  28. package/dist/server/resourcers/main-data-source.d.ts +17 -0
  29. package/dist/server/resourcers/main-data-source.js +52 -0
  30. package/dist/server/resourcers/views.js +1 -1
  31. package/dist/server/server.d.ts +1 -0
  32. package/dist/server/server.js +154 -54
  33. package/package.json +5 -2
@@ -16,6 +16,7 @@ export declare class PluginDataSourceMainServer extends Plugin {
16
16
  beforeLoad(): Promise<void>;
17
17
  private db2cm;
18
18
  load(): Promise<void>;
19
+ registerErrorHandler(): void;
19
20
  install(): Promise<void>;
20
21
  }
21
22
  export default PluginDataSourceMainServer;
@@ -55,6 +55,10 @@ var import_beforeDestoryField = require("./hooks/beforeDestoryField");
55
55
  var import_models = require("./models");
56
56
  var import_collections = __toESM(require("./resourcers/collections"));
57
57
  var import_views = __toESM(require("./resourcers/views"));
58
+ var import_main_data_source = __toESM(require("./resourcers/main-data-source"));
59
+ var import_constants = require("./constants");
60
+ var import_json_schema = require("@formily/json-schema");
61
+ var import_lodash2 = __toESM(require("lodash"));
58
62
  class PluginDataSourceMainServer extends import_server.Plugin {
59
63
  loadFilter = {};
60
64
  db2cmCollections = [];
@@ -178,7 +182,24 @@ class PluginDataSourceMainServer extends import_server.Plugin {
178
182
  }
179
183
  });
180
184
  this.app.db.on("fields.beforeCreate", (0, import_beforeCreateForValidateField.beforeCreateForValidateField)(this.app.db));
181
- this.app.db.on("fields.afterCreate", (0, import_hooks.afterCreateForReverseField)(this.app.db));
185
+ this.app.db.on("fields.afterCreate", async (model, { transaction }) => {
186
+ const Field = this.app.db.getCollection("fields");
187
+ const reverseKey = model.get("reverseKey");
188
+ if (!reverseKey) {
189
+ return;
190
+ }
191
+ const reverse = await Field.model.findByPk(reverseKey, { transaction });
192
+ await reverse.update({ reverseKey: model.get("key") }, { hooks: false, transaction });
193
+ this.sendSyncMessage(
194
+ {
195
+ type: "syncCollection",
196
+ collectionName: model.get("collectionName")
197
+ },
198
+ {
199
+ transaction
200
+ }
201
+ );
202
+ });
182
203
  this.app.db.on("fields.beforeCreate", async (model, options) => {
183
204
  const { transaction } = options;
184
205
  const collectionName = model.get("collectionName");
@@ -357,7 +378,7 @@ class PluginDataSourceMainServer extends import_server.Plugin {
357
378
  this.app.acl.allow("collectionCategories", "list", "loggedIn");
358
379
  this.app.acl.registerSnippet({
359
380
  name: `pm.data-source-manager.data-source-main`,
360
- actions: ["collections:*", "collections.fields:*", "collectionCategories:*"]
381
+ actions: ["collections:*", "collections.fields:*", "collectionCategories:*", "mainDataSource:*"]
361
382
  });
362
383
  this.app.acl.registerSnippet({
363
384
  name: `pm.data-source-manager.collection-view `,
@@ -382,7 +403,98 @@ class PluginDataSourceMainServer extends import_server.Plugin {
382
403
  }
383
404
  async load() {
384
405
  this.db.getRepository("collections").setApp(this.app);
385
- const errorHandlerPlugin = this.app.getPlugin("error-handler");
406
+ this.registerErrorHandler();
407
+ this.app.resourceManager.use(async function mergeReverseFieldWhenSaveCollectionField(ctx, next) {
408
+ if (ctx.action.resourceName === "collections.fields" && ["create", "update"].includes(ctx.action.actionName)) {
409
+ ctx.action.mergeParams({
410
+ updateAssociationValues: ["reverseField"]
411
+ });
412
+ }
413
+ await next();
414
+ });
415
+ this.app.resourceManager.define(import_views.default);
416
+ this.app.resourceManager.registerActionHandlers(import_collections.default);
417
+ this.app.resourceManager.define(import_main_data_source.default);
418
+ const handleFieldSource = ({
419
+ fields,
420
+ isRawValue,
421
+ rawFields
422
+ }) => {
423
+ import_lodash.default.castArray(fields).forEach((field, index) => {
424
+ var _a;
425
+ const source = isRawValue ? field.source : field.get("source");
426
+ if (!source) {
427
+ return;
428
+ }
429
+ const [collectionSource, fieldSource] = source.split(".");
430
+ const collectionField = (_a = this.app.db.getCollection(collectionSource)) == null ? void 0 : _a.getField(fieldSource);
431
+ if (!collectionField) {
432
+ return;
433
+ }
434
+ const newOptions = {};
435
+ import_lodash.default.merge(newOptions, import_lodash.default.omit(collectionField.options, "name"));
436
+ const currentValues = isRawValue ? field : field.get();
437
+ import_lodash.default.mergeWith(newOptions, currentValues, (objValue, srcValue) => {
438
+ if (srcValue === null) {
439
+ return objValue;
440
+ }
441
+ });
442
+ if (isRawValue) {
443
+ fields[index] = {
444
+ ...field,
445
+ ...newOptions
446
+ };
447
+ } else {
448
+ field.set("options", newOptions);
449
+ }
450
+ const fieldTypes = import_database.fieldTypeMap[this.db.options.dialect];
451
+ if (rawFields && fieldTypes) {
452
+ const rawField = rawFields[field.get("name")];
453
+ if (rawField && !import_constants.PRESET_FIELDS_INTERFACES.includes(field.get("interface"))) {
454
+ const mappedType = (0, import_database.extractTypeFromDefinition)(rawField.type);
455
+ const possibleTypes = fieldTypes[mappedType];
456
+ field.set("possibleTypes", possibleTypes);
457
+ }
458
+ }
459
+ });
460
+ };
461
+ this.app.resourceManager.use(async function handleFieldSourceMiddleware(ctx, next) {
462
+ var _a;
463
+ await next();
464
+ if (ctx.action.resourceName === "collections" && ctx.action.actionName == "listMeta") {
465
+ for (const collection of ctx.body) {
466
+ if (collection.view === true) {
467
+ const fields = collection.fields;
468
+ handleFieldSource({ fields, isRawValue: true });
469
+ }
470
+ }
471
+ }
472
+ if (ctx.action.resourceName == "collections.fields" && ctx.action.actionName == "list") {
473
+ const collectionName = ctx.action.sourceId;
474
+ const collection = ctx.db.getCollection(collectionName);
475
+ let rawFields = {};
476
+ if (collection) {
477
+ try {
478
+ rawFields = await ctx.app.db.queryInterface.sequelizeQueryInterface.describeTable(
479
+ collection.getTableNameWithSchema()
480
+ );
481
+ } catch (err) {
482
+ }
483
+ }
484
+ handleFieldSource({ fields: ((_a = ctx.action.params) == null ? void 0 : _a.paginate) == "false" ? ctx.body : ctx.body.rows, rawFields });
485
+ }
486
+ if (ctx.action.resourceName == "collections.fields" && ctx.action.actionName == "get") {
487
+ handleFieldSource({ fields: ctx.body });
488
+ }
489
+ });
490
+ this.app.db.extendCollection({
491
+ name: "collectionCategory",
492
+ dumpRules: "required",
493
+ origin: this.options.packageName
494
+ });
495
+ }
496
+ registerErrorHandler() {
497
+ const errorHandlerPlugin = this.app.pm.get("error-handler");
386
498
  errorHandlerPlugin.errorHandler.register(
387
499
  (err) => {
388
500
  return err instanceof import_database.UniqueConstraintError;
@@ -428,59 +540,47 @@ class PluginDataSourceMainServer extends import_server.Plugin {
428
540
  };
429
541
  }
430
542
  );
431
- this.app.resourceManager.use(async function mergeReverseFieldWhenSaveCollectionField(ctx, next) {
432
- if (ctx.action.resourceName === "collections.fields" && ["create", "update"].includes(ctx.action.actionName)) {
433
- ctx.action.mergeParams({
434
- updateAssociationValues: ["reverseField"]
435
- });
436
- }
437
- await next();
438
- });
439
- this.app.resource(import_views.default);
440
- this.app.actions(import_collections.default);
441
- const handleFieldSource = (fields) => {
442
- var _a;
443
- for (const field of import_lodash.default.castArray(fields)) {
444
- if (field.get("source")) {
445
- const [collectionSource, fieldSource] = field.get("source").split(".");
446
- const collectionField = (_a = this.app.db.getCollection(collectionSource)) == null ? void 0 : _a.getField(fieldSource);
447
- if (!collectionField) {
448
- continue;
449
- }
450
- const newOptions = {};
451
- import_lodash.default.merge(newOptions, import_lodash.default.omit(collectionField.options, "name"));
452
- import_lodash.default.mergeWith(newOptions, field.get(), (objValue, srcValue) => {
453
- if (srcValue === null) {
454
- return objValue;
543
+ errorHandlerPlugin.errorHandler.register(
544
+ (err) => err instanceof import_database.JoiValidationError,
545
+ (err, ctx) => {
546
+ const t = ctx.i18n.t;
547
+ ctx.status = 400;
548
+ ctx.body = {
549
+ errors: err.details.map((detail) => {
550
+ const context = detail.context;
551
+ const label = context.label;
552
+ if (label) {
553
+ const [collectionName, fieldName] = label.split(".");
554
+ const collection = this.db.getCollection(collectionName);
555
+ if (collection) {
556
+ const collectionTitle = import_json_schema.Schema.compile(collection.options.title, { t });
557
+ const field = collection.getField(fieldName);
558
+ const fieldOptions = import_json_schema.Schema.compile(field == null ? void 0 : field.options, { t });
559
+ const fieldTitle = import_lodash2.default.get(fieldOptions, "uiSchema.title", fieldName);
560
+ context.label = `${t(collectionTitle, {
561
+ ns: ["lm-collections", "client"]
562
+ })}: ${t(fieldTitle, {
563
+ ns: ["lm-collections", "client"]
564
+ })}`;
565
+ }
455
566
  }
456
- });
457
- field.set("options", newOptions);
458
- }
459
- }
460
- };
461
- this.app.resourceManager.use(async function handleFieldSourceMiddleware(ctx, next) {
462
- var _a, _b;
463
- await next();
464
- if (ctx.action.resourceName === "collections" && ctx.action.actionName == "list" && ((_a = ctx.action.params) == null ? void 0 : _a.paginate) == "false") {
465
- for (const collection of ctx.body) {
466
- if (collection.get("view")) {
467
- const fields = collection.fields;
468
- handleFieldSource(fields);
469
- }
470
- }
471
- }
472
- if (ctx.action.resourceName == "collections.fields" && ctx.action.actionName == "list") {
473
- handleFieldSource(((_b = ctx.action.params) == null ? void 0 : _b.paginate) == "false" ? ctx.body : ctx.body.rows);
474
- }
475
- if (ctx.action.resourceName == "collections.fields" && ctx.action.actionName == "get") {
476
- handleFieldSource(ctx.body);
567
+ if (context.regex) {
568
+ context.regex = context.regex.source;
569
+ }
570
+ let message = ctx.i18n.t(detail.type, {
571
+ ...context,
572
+ ns: "data-source-main"
573
+ });
574
+ if (message === detail.type) {
575
+ message = err.message.replace(`"${label}"`, context.label);
576
+ }
577
+ return {
578
+ message
579
+ };
580
+ })
581
+ };
477
582
  }
478
- });
479
- this.app.db.extendCollection({
480
- name: "collectionCategory",
481
- dumpRules: "required",
482
- origin: this.options.packageName
483
- });
583
+ );
484
584
  }
485
585
  async install() {
486
586
  const dataSourcesCollection = this.app.db.getCollection("dataSources");
package/package.json CHANGED
@@ -1,12 +1,15 @@
1
1
  {
2
2
  "name": "@nocobase/plugin-data-source-main",
3
3
  "displayName": "Data source: Main",
4
+ "displayName.ru-RU": "Основной Источник данных",
4
5
  "displayName.zh-CN": "数据源:主数据库",
5
6
  "description": "NocoBase main database, supports relational databases such as PostgreSQL, MySQL, MariaDB and so on.",
7
+ "description.ru-RU": "Основная база данных NocoBase: поддерживает реляционные СУБД, включая PostgreSQL, MySQL, MariaDB и другие.",
6
8
  "description.zh-CN": "NocoBase 主数据库,支持 PostgreSQL、MySQL、MariaDB 等关系型数据库。",
7
- "version": "2.0.0-alpha.7",
9
+ "version": "2.0.0-alpha.70",
8
10
  "main": "./dist/server/index.js",
9
11
  "homepage": "https://docs.nocobase.com/handbook/data-source-main",
12
+ "homepage.ru-RU": "https://docs-ru.nocobase.com/handbook/data-source-main",
10
13
  "homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/data-source-main",
11
14
  "license": "AGPL-3.0",
12
15
  "devDependencies": {
@@ -22,7 +25,7 @@
22
25
  "@nocobase/test": "2.x",
23
26
  "@nocobase/utils": "2.x"
24
27
  },
25
- "gitHead": "cb012f93256f534472d3ae56e075839ca1675779",
28
+ "gitHead": "42556ed4b29d8410e104ffd8af4fa72c9b1bae7f",
26
29
  "keywords": [
27
30
  "Data sources"
28
31
  ]