@nocobase/plugin-client 2.1.0-beta.33 → 2.1.0-beta.35

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.
@@ -10,13 +10,13 @@
10
10
  module.exports = {
11
11
  "react": "18.2.0",
12
12
  "react-i18next": "11.18.6",
13
- "@nocobase/client": "2.1.0-beta.33",
13
+ "@nocobase/client": "2.1.0-beta.35",
14
14
  "antd": "5.24.2",
15
15
  "@ant-design/icons": "5.6.1",
16
16
  "@formily/react": "2.3.7",
17
- "@nocobase/utils": "2.1.0-beta.33",
17
+ "@nocobase/utils": "2.1.0-beta.35",
18
18
  "lodash": "4.18.1",
19
- "@nocobase/database": "2.1.0-beta.33",
20
- "@nocobase/client-v2": "2.1.0-beta.33",
21
- "@nocobase/server": "2.1.0-beta.33"
19
+ "@nocobase/database": "2.1.0-beta.35",
20
+ "@nocobase/client-v2": "2.1.0-beta.35",
21
+ "@nocobase/server": "2.1.0-beta.35"
22
22
  };
@@ -1 +1 @@
1
- {"name":"cronstrue","title":"cRonstrue","version":"2.47.0","description":"Convert cron expressions into human readable descriptions","author":"Brady Holt","license":"MIT","bugs":{"url":"https://github.com/bradymholt/cronstrue/issues"},"homepage":"https://github.com/bradymholt/cronstrue","keywords":["cron","cronjob","crontab","schedule","parser","cron expression","cron description","pretty cron","cron for humans","cron translated","cron english","cron schedule","cron english","cron schedule"],"main":"dist/cronstrue.js","bin":{"cronstrue":"bin/cli.js"},"typings":"dist/cronstrue.d.ts","files":["dist/","locales/","i18n.js","i18n.d.ts"],"repository":{"type":"git","url":"git+https://github.com/bradymholt/cronstrue.git"},"publishConfig":{"access":"public"},"prettier":{"printWidth":120},"devDependencies":{"@types/chai":"^4.2.11","@types/mocha":"^8.0.0","chai":"^4.2.0","handlebars":"^4.7.6","marked":"^4.0.10","mocha":"^10.1.0","pixl-xml":"^1.0.13","prettier":"^2.1.1","terser-webpack-plugin":"^5.3.1","ts-loader":"^9.2.6","ts-node":"^10.5.0","typescript":"^4.6.2","webpack":"^5.69.1","webpack-cli":"^4.9.2","xml2js":"^0.5.0"},"scripts":{"start":"npm run build","build":"npx tsc -p ./src --emitDeclarationOnly","test":"npx mocha --reporter spec --require ts-node/register \"./test/**/*.ts\"","prepublishOnly":"rm -rf ./dist && ./node_modules/webpack-cli/bin/cli.js && git add -A"},"dependencies":{},"_lastModified":"2026-05-15T15:53:48.192Z"}
1
+ {"name":"cronstrue","title":"cRonstrue","version":"2.47.0","description":"Convert cron expressions into human readable descriptions","author":"Brady Holt","license":"MIT","bugs":{"url":"https://github.com/bradymholt/cronstrue/issues"},"homepage":"https://github.com/bradymholt/cronstrue","keywords":["cron","cronjob","crontab","schedule","parser","cron expression","cron description","pretty cron","cron for humans","cron translated","cron english","cron schedule","cron english","cron schedule"],"main":"dist/cronstrue.js","bin":{"cronstrue":"bin/cli.js"},"typings":"dist/cronstrue.d.ts","files":["dist/","locales/","i18n.js","i18n.d.ts"],"repository":{"type":"git","url":"git+https://github.com/bradymholt/cronstrue.git"},"publishConfig":{"access":"public"},"prettier":{"printWidth":120},"devDependencies":{"@types/chai":"^4.2.11","@types/mocha":"^8.0.0","chai":"^4.2.0","handlebars":"^4.7.6","marked":"^4.0.10","mocha":"^10.1.0","pixl-xml":"^1.0.13","prettier":"^2.1.1","terser-webpack-plugin":"^5.3.1","ts-loader":"^9.2.6","ts-node":"^10.5.0","typescript":"^4.6.2","webpack":"^5.69.1","webpack-cli":"^4.9.2","xml2js":"^0.5.0"},"scripts":{"start":"npm run build","build":"npx tsc -p ./src --emitDeclarationOnly","test":"npx mocha --reporter spec --require ts-node/register \"./test/**/*.ts\"","prepublishOnly":"rm -rf ./dist && ./node_modules/webpack-cli/bin/cli.js && git add -A"},"dependencies":{},"_lastModified":"2026-05-19T16:48:48.419Z"}
@@ -0,0 +1,13 @@
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 { Migration } from '@nocobase/server';
10
+ export default class extends Migration {
11
+ on: string;
12
+ up(): Promise<void>;
13
+ }
@@ -0,0 +1,131 @@
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
+
10
+ var __create = Object.create;
11
+ var __defProp = Object.defineProperty;
12
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
13
+ var __getOwnPropNames = Object.getOwnPropertyNames;
14
+ var __getProtoOf = Object.getPrototypeOf;
15
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
16
+ var __export = (target, all) => {
17
+ for (var name in all)
18
+ __defProp(target, name, { get: all[name], enumerable: true });
19
+ };
20
+ var __copyProps = (to, from, except, desc) => {
21
+ if (from && typeof from === "object" || typeof from === "function") {
22
+ for (let key of __getOwnPropNames(from))
23
+ if (!__hasOwnProp.call(to, key) && key !== except)
24
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
25
+ }
26
+ return to;
27
+ };
28
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
29
+ // If the importer is in node compatibility mode or this is not an ESM
30
+ // file that has been converted to a CommonJS file using a Babel-
31
+ // compatible transform (i.e. "__esModule" has not been set), then set
32
+ // "default" to the CommonJS "module.exports" for node compatibility.
33
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
34
+ mod
35
+ ));
36
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
37
+ var clean_orphan_flow_route_models_exports = {};
38
+ __export(clean_orphan_flow_route_models_exports, {
39
+ default: () => clean_orphan_flow_route_models_default
40
+ });
41
+ module.exports = __toCommonJS(clean_orphan_flow_route_models_exports);
42
+ var import_server = require("@nocobase/server");
43
+ var _ = __toESM(require("lodash"));
44
+ const parseOptions = (value) => {
45
+ if (!value) return {};
46
+ if (typeof value === "string") {
47
+ try {
48
+ return JSON.parse(value);
49
+ } catch (error) {
50
+ return {};
51
+ }
52
+ }
53
+ return value;
54
+ };
55
+ const isRouteModelOptions = (value) => {
56
+ var _a;
57
+ const options = parseOptions(value);
58
+ return (options == null ? void 0 : options.use) === "RouteModel" || ((_a = options == null ? void 0 : options.schema) == null ? void 0 : _a.use) === "RouteModel";
59
+ };
60
+ class clean_orphan_flow_route_models_default extends import_server.Migration {
61
+ on = "afterLoad";
62
+ async up() {
63
+ if (!this.db.hasCollection("desktopRoutes") || !this.db.hasCollection("flowModels") || !this.db.hasCollection("flowModelTreePath")) {
64
+ return;
65
+ }
66
+ await this.db.sequelize.transaction(async (transaction) => {
67
+ const desktopRoutesRepo = this.db.getRepository("desktopRoutes");
68
+ const flowRepo = this.db.getRepository("flowModels");
69
+ const treePathRepo = this.db.getRepository("flowModelTreePath");
70
+ const desktopRoutes = await desktopRoutesRepo.find({ fields: ["schemaUid"], transaction });
71
+ const routeSchemaUids = new Set(desktopRoutes.map((route) => route.get("schemaUid")).filter(Boolean));
72
+ const flowModels = await flowRepo.find({ fields: ["uid", "options"], transaction });
73
+ const routeModelUids = flowModels.filter((model) => isRouteModelOptions(model.get("options"))).map((model) => model.get("uid")).filter(Boolean);
74
+ if (routeModelUids.length) {
75
+ const childRouteModels = /* @__PURE__ */ new Set();
76
+ for (const chunk of _.chunk(routeModelUids, 500)) {
77
+ const parentPaths = await treePathRepo.find({
78
+ filter: {
79
+ descendant: {
80
+ $in: chunk
81
+ },
82
+ depth: 1
83
+ },
84
+ fields: ["descendant"],
85
+ transaction
86
+ });
87
+ for (const path of parentPaths) {
88
+ const descendant = path.get("descendant");
89
+ if (descendant) {
90
+ childRouteModels.add(descendant);
91
+ }
92
+ }
93
+ }
94
+ const orphanRouteModelUids = routeModelUids.filter(
95
+ (uid) => !routeSchemaUids.has(uid) && !childRouteModels.has(uid)
96
+ );
97
+ for (const uid of orphanRouteModelUids) {
98
+ await flowRepo.remove(uid, { transaction });
99
+ }
100
+ }
101
+ if (this.db.hasCollection("flowModelTemplateUsages")) {
102
+ const usageRepo = this.db.getRepository("flowModelTemplateUsages");
103
+ const usages = await usageRepo.find({ fields: ["modelUid"], transaction });
104
+ const usageModelUids = _.uniq(usages.map((usage) => usage.get("modelUid")).filter(Boolean));
105
+ for (const chunk of _.chunk(usageModelUids, 500)) {
106
+ const existingModels = await flowRepo.find({
107
+ fields: ["uid"],
108
+ filter: {
109
+ uid: {
110
+ $in: chunk
111
+ }
112
+ },
113
+ transaction
114
+ });
115
+ const existingUids = new Set(existingModels.map((model) => model.get("uid")).filter(Boolean));
116
+ const missingUids = chunk.filter((uid) => !existingUids.has(uid));
117
+ if (missingUids.length) {
118
+ await usageRepo.destroy({
119
+ filter: {
120
+ modelUid: {
121
+ $in: missingUids
122
+ }
123
+ },
124
+ transaction
125
+ });
126
+ }
127
+ }
128
+ }
129
+ });
130
+ }
131
+ }
@@ -189,15 +189,48 @@ class PluginClientServer extends import_server.Plugin {
189
189
  instance.allowNewMenu === void 0 ? ["admin", "member"].includes(instance.name) : !!instance.allowNewMenu
190
190
  );
191
191
  });
192
- this.db.on("desktopRoutes.afterDestroy", async (instance, { transaction }) => {
193
- const r = this.db.getRepository("flowModels");
194
- if (r) {
195
- await r.destroy({
192
+ const collectDesktopRouteSchemaUids = async (instance, transaction) => {
193
+ const routeRepo = this.db.getRepository("desktopRoutes");
194
+ const schemaUids = /* @__PURE__ */ new Set();
195
+ const pendingIds = [];
196
+ const rootId = instance.get("id");
197
+ const rootSchemaUid = instance.get("schemaUid");
198
+ if (rootSchemaUid) {
199
+ schemaUids.add(rootSchemaUid);
200
+ }
201
+ if (rootId) {
202
+ pendingIds.push(rootId);
203
+ }
204
+ while (pendingIds.length) {
205
+ const routes = await routeRepo.find({
206
+ fields: ["id", "schemaUid"],
196
207
  filter: {
197
- uid: instance.get("schemaUid")
208
+ parentId: {
209
+ $in: pendingIds.splice(0, pendingIds.length)
210
+ }
198
211
  },
199
212
  transaction
200
213
  });
214
+ for (const route of routes) {
215
+ const schemaUid = route.get("schemaUid");
216
+ const id = route.get("id");
217
+ if (schemaUid) {
218
+ schemaUids.add(schemaUid);
219
+ }
220
+ if (id) {
221
+ pendingIds.push(id);
222
+ }
223
+ }
224
+ }
225
+ return Array.from(schemaUids);
226
+ };
227
+ this.db.on("desktopRoutes.beforeDestroy", async (instance, { transaction }) => {
228
+ const r = this.db.getRepository("flowModels");
229
+ if (r == null ? void 0 : r.remove) {
230
+ const schemaUids = await collectDesktopRouteSchemaUids(instance, transaction);
231
+ for (const schemaUid of schemaUids) {
232
+ await r.remove(schemaUid, { transaction });
233
+ }
201
234
  }
202
235
  });
203
236
  this.db.on("desktopRoutes.afterCreate", async (instance, { transaction }) => {
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "description": "Provides a client interface for the NocoBase server",
7
7
  "description.ru-RU": "Предоставляет клиентский интерфейс для сервера NocoBase",
8
8
  "description.zh-CN": "为 NocoBase 服务端提供客户端界面",
9
- "version": "2.1.0-beta.33",
9
+ "version": "2.1.0-beta.35",
10
10
  "main": "./dist/server/index.js",
11
11
  "license": "Apache-2.0",
12
12
  "devDependencies": {
@@ -23,5 +23,5 @@
23
23
  "@nocobase/test": "2.x",
24
24
  "@nocobase/utils": "2.x"
25
25
  },
26
- "gitHead": "4815c394e80a264fa8ed619246280923c47aeb72"
26
+ "gitHead": "74310d8b9e9581fcde14b5a93d12b41ddb5bb325"
27
27
  }