@nocobase/plugin-client 2.1.0-beta.9 → 2.2.0-alpha.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.
@@ -82,7 +82,7 @@ class PluginClientServer extends import_server.Plugin {
82
82
  this.app.acl.allow("app", "getInfo");
83
83
  this.app.acl.registerSnippet({
84
84
  name: "app",
85
- actions: ["app:restart", "app:refresh", "app:clearCache"]
85
+ actions: ["app:restart", "app:refresh", "app:clearCache", "app:publishEvent"]
86
86
  });
87
87
  const dialect = this.app.db.sequelize.getDialect();
88
88
  this.app.resourceManager.define({
@@ -139,10 +139,36 @@ class PluginClientServer extends import_server.Plugin {
139
139
  async refresh(ctx, next) {
140
140
  ctx.app.runCommand("refresh");
141
141
  await next();
142
+ },
143
+ async publishEvent(ctx, next) {
144
+ var _a, _b, _c;
145
+ const { plugin, command, payload } = ((_b = (_a = ctx.action) == null ? void 0 : _a.params) == null ? void 0 : _b.values) ?? {};
146
+ if (!plugin || typeof plugin !== "string") {
147
+ ctx.throw(400, "Plugin is required");
148
+ return;
149
+ }
150
+ if (!command || typeof command !== "string") {
151
+ ctx.throw(400, "Command is required");
152
+ return;
153
+ }
154
+ const { id, username } = ((_c = ctx.auth) == null ? void 0 : _c.user) ?? {};
155
+ const user = id ? { id, username } : void 0;
156
+ const eventName = `${command}@${plugin}`;
157
+ try {
158
+ await ctx.app.eventQueue.publish(eventName, {
159
+ plugin,
160
+ command,
161
+ user,
162
+ payload: payload ?? {}
163
+ });
164
+ } catch (err) {
165
+ ctx.app.logger.warn(`fail to publish event to [${eventName}]: ${err.message}`, payload);
166
+ }
167
+ await next();
142
168
  }
143
169
  }
144
170
  });
145
- this.app.auditManager.registerActions(["app:restart", "app:refresh", "app:clearCache"]);
171
+ this.app.auditManager.registerActions(["app:restart", "app:refresh", "app:clearCache", "app:publishEvent"]);
146
172
  this.registerActionHandlers();
147
173
  this.bindNewMenuToRoles();
148
174
  this.setACL();
@@ -189,15 +215,48 @@ class PluginClientServer extends import_server.Plugin {
189
215
  instance.allowNewMenu === void 0 ? ["admin", "member"].includes(instance.name) : !!instance.allowNewMenu
190
216
  );
191
217
  });
192
- this.db.on("desktopRoutes.afterDestroy", async (instance, { transaction }) => {
193
- const r = this.db.getRepository("flowModels");
194
- if (r) {
195
- await r.destroy({
218
+ const collectDesktopRouteSchemaUids = async (instance, transaction) => {
219
+ const routeRepo = this.db.getRepository("desktopRoutes");
220
+ const schemaUids = /* @__PURE__ */ new Set();
221
+ const pendingIds = [];
222
+ const rootId = instance.get("id");
223
+ const rootSchemaUid = instance.get("schemaUid");
224
+ if (rootSchemaUid) {
225
+ schemaUids.add(rootSchemaUid);
226
+ }
227
+ if (rootId) {
228
+ pendingIds.push(rootId);
229
+ }
230
+ while (pendingIds.length) {
231
+ const routes = await routeRepo.find({
232
+ fields: ["id", "schemaUid"],
196
233
  filter: {
197
- uid: instance.get("schemaUid")
234
+ parentId: {
235
+ $in: pendingIds.splice(0, pendingIds.length)
236
+ }
198
237
  },
199
238
  transaction
200
239
  });
240
+ for (const route of routes) {
241
+ const schemaUid = route.get("schemaUid");
242
+ const id = route.get("id");
243
+ if (schemaUid) {
244
+ schemaUids.add(schemaUid);
245
+ }
246
+ if (id) {
247
+ pendingIds.push(id);
248
+ }
249
+ }
250
+ }
251
+ return Array.from(schemaUids);
252
+ };
253
+ this.db.on("desktopRoutes.beforeDestroy", async (instance, { transaction }) => {
254
+ const r = this.db.getRepository("flowModels");
255
+ if (r == null ? void 0 : r.remove) {
256
+ const schemaUids = await collectDesktopRouteSchemaUids(instance, transaction);
257
+ for (const schemaUid of schemaUids) {
258
+ await r.remove(schemaUid, { transaction });
259
+ }
201
260
  }
202
261
  });
203
262
  this.db.on("desktopRoutes.afterCreate", async (instance, { transaction }) => {
@@ -346,11 +405,7 @@ class PluginClientServer extends import_server.Plugin {
346
405
  });
347
406
  }
348
407
  registerLocalizationSource() {
349
- const localizationPlugin = this.app.pm.get("localization");
350
- if (!localizationPlugin) {
351
- return;
352
- }
353
- localizationPlugin.sourceManager.registerSource("desktop-routes", {
408
+ this.app.localeManager.registerSource("desktop-routes", {
354
409
  title: (0, import_utils.tval)("Desktop routes"),
355
410
  sync: async (ctx) => {
356
411
  const desktopRoutes = await ctx.db.getRepository("desktopRoutes").find({
@@ -0,0 +1,248 @@
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
+ declare const _default: {
10
+ openapi: string;
11
+ info: {
12
+ title: string;
13
+ version: string;
14
+ };
15
+ paths: {
16
+ '/roles/{roleName}/desktopRoutes:add': {
17
+ post: {
18
+ tags: string[];
19
+ summary: string;
20
+ parameters: {
21
+ $ref: string;
22
+ }[];
23
+ requestBody: {
24
+ required: boolean;
25
+ content: {
26
+ 'application/json': {
27
+ schema: {
28
+ $ref: string;
29
+ };
30
+ };
31
+ };
32
+ };
33
+ responses: {
34
+ 200: {
35
+ description: string;
36
+ };
37
+ };
38
+ };
39
+ };
40
+ '/roles/{roleName}/desktopRoutes:remove': {
41
+ post: {
42
+ tags: string[];
43
+ summary: string;
44
+ parameters: {
45
+ $ref: string;
46
+ }[];
47
+ requestBody: {
48
+ required: boolean;
49
+ content: {
50
+ 'application/json': {
51
+ schema: {
52
+ $ref: string;
53
+ };
54
+ };
55
+ };
56
+ };
57
+ responses: {
58
+ 200: {
59
+ description: string;
60
+ };
61
+ };
62
+ };
63
+ };
64
+ '/roles/{roleName}/desktopRoutes:set': {
65
+ post: {
66
+ tags: string[];
67
+ summary: string;
68
+ parameters: {
69
+ $ref: string;
70
+ }[];
71
+ requestBody: {
72
+ required: boolean;
73
+ content: {
74
+ 'application/json': {
75
+ schema: {
76
+ $ref: string;
77
+ };
78
+ };
79
+ };
80
+ };
81
+ responses: {
82
+ 200: {
83
+ description: string;
84
+ };
85
+ };
86
+ };
87
+ };
88
+ '/roles/{roleName}/desktopRoutes:list': {
89
+ get: {
90
+ tags: string[];
91
+ summary: string;
92
+ parameters: {
93
+ $ref: string;
94
+ }[];
95
+ responses: {
96
+ 200: {
97
+ description: string;
98
+ content: {
99
+ 'application/json': {
100
+ schema: {
101
+ type: string;
102
+ properties: {
103
+ data: {
104
+ type: string;
105
+ items: {
106
+ $ref: string;
107
+ };
108
+ };
109
+ meta: {
110
+ type: string;
111
+ additionalProperties: boolean;
112
+ };
113
+ };
114
+ };
115
+ };
116
+ };
117
+ };
118
+ };
119
+ };
120
+ };
121
+ '/desktopRoutes:listAccessible': {
122
+ get: {
123
+ tags: string[];
124
+ summary: string;
125
+ parameters: {
126
+ $ref: string;
127
+ }[];
128
+ responses: {
129
+ 200: {
130
+ description: string;
131
+ content: {
132
+ 'application/json': {
133
+ schema: {
134
+ type: string;
135
+ properties: {
136
+ data: {
137
+ type: string;
138
+ items: {
139
+ $ref: string;
140
+ };
141
+ };
142
+ meta: {
143
+ type: string;
144
+ additionalProperties: boolean;
145
+ };
146
+ };
147
+ };
148
+ };
149
+ };
150
+ };
151
+ };
152
+ };
153
+ };
154
+ };
155
+ components: {
156
+ parameters: {
157
+ RoleNamePath: {
158
+ name: string;
159
+ in: string;
160
+ description: string;
161
+ required: boolean;
162
+ schema: {
163
+ type: string;
164
+ };
165
+ };
166
+ PaginateQuery: {
167
+ name: string;
168
+ in: string;
169
+ description: string;
170
+ required: boolean;
171
+ schema: {
172
+ type: string;
173
+ };
174
+ };
175
+ TreeQuery: {
176
+ name: string;
177
+ in: string;
178
+ description: string;
179
+ required: boolean;
180
+ schema: {
181
+ type: string;
182
+ };
183
+ };
184
+ SortScalarQuery: {
185
+ name: string;
186
+ in: string;
187
+ description: string;
188
+ required: boolean;
189
+ schema: {
190
+ type: string;
191
+ };
192
+ };
193
+ FilterQuery: {
194
+ name: string;
195
+ in: string;
196
+ description: string;
197
+ required: boolean;
198
+ schema: {
199
+ type: string;
200
+ additionalProperties: boolean;
201
+ };
202
+ };
203
+ };
204
+ schemas: {
205
+ RouteIdList: {
206
+ type: string;
207
+ description: string;
208
+ items: {
209
+ type: string;
210
+ };
211
+ };
212
+ DesktopRoute: {
213
+ type: string;
214
+ properties: {
215
+ id: {
216
+ type: string;
217
+ };
218
+ title: {
219
+ type: string;
220
+ };
221
+ type: {
222
+ type: string;
223
+ };
224
+ path: {
225
+ type: string;
226
+ nullable: boolean;
227
+ };
228
+ parentId: {
229
+ type: string;
230
+ nullable: boolean;
231
+ };
232
+ hidden: {
233
+ type: string;
234
+ nullable: boolean;
235
+ };
236
+ children: {
237
+ type: string;
238
+ items: {
239
+ $ref: string;
240
+ };
241
+ };
242
+ };
243
+ additionalProperties: boolean;
244
+ };
245
+ };
246
+ };
247
+ };
248
+ export default _default;
@@ -0,0 +1,222 @@
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 __defProp = Object.defineProperty;
11
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
12
+ var __getOwnPropNames = Object.getOwnPropertyNames;
13
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
14
+ var __export = (target, all) => {
15
+ for (var name in all)
16
+ __defProp(target, name, { get: all[name], enumerable: true });
17
+ };
18
+ var __copyProps = (to, from, except, desc) => {
19
+ if (from && typeof from === "object" || typeof from === "function") {
20
+ for (let key of __getOwnPropNames(from))
21
+ if (!__hasOwnProp.call(to, key) && key !== except)
22
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
23
+ }
24
+ return to;
25
+ };
26
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
27
+ var swagger_exports = {};
28
+ __export(swagger_exports, {
29
+ default: () => swagger_default
30
+ });
31
+ module.exports = __toCommonJS(swagger_exports);
32
+ var swagger_default = {
33
+ openapi: "3.0.2",
34
+ info: {
35
+ title: "NocoBase API - Client plugin",
36
+ version: "1.0.0"
37
+ },
38
+ paths: {
39
+ "/roles/{roleName}/desktopRoutes:add": {
40
+ post: {
41
+ tags: ["roles.desktopRoutes"],
42
+ summary: "Add desktop route permissions to a role",
43
+ parameters: [{ $ref: "#/components/parameters/RoleNamePath" }],
44
+ requestBody: {
45
+ required: true,
46
+ content: {
47
+ "application/json": {
48
+ schema: { $ref: "#/components/schemas/RouteIdList" }
49
+ }
50
+ }
51
+ },
52
+ responses: {
53
+ 200: { description: "OK" }
54
+ }
55
+ }
56
+ },
57
+ "/roles/{roleName}/desktopRoutes:remove": {
58
+ post: {
59
+ tags: ["roles.desktopRoutes"],
60
+ summary: "Remove desktop route permissions from a role",
61
+ parameters: [{ $ref: "#/components/parameters/RoleNamePath" }],
62
+ requestBody: {
63
+ required: true,
64
+ content: {
65
+ "application/json": {
66
+ schema: { $ref: "#/components/schemas/RouteIdList" }
67
+ }
68
+ }
69
+ },
70
+ responses: {
71
+ 200: { description: "OK" }
72
+ }
73
+ }
74
+ },
75
+ "/roles/{roleName}/desktopRoutes:set": {
76
+ post: {
77
+ tags: ["roles.desktopRoutes"],
78
+ summary: "Set desktop route permissions for a role",
79
+ parameters: [{ $ref: "#/components/parameters/RoleNamePath" }],
80
+ requestBody: {
81
+ required: true,
82
+ content: {
83
+ "application/json": {
84
+ schema: { $ref: "#/components/schemas/RouteIdList" }
85
+ }
86
+ }
87
+ },
88
+ responses: {
89
+ 200: { description: "OK" }
90
+ }
91
+ }
92
+ },
93
+ "/roles/{roleName}/desktopRoutes:list": {
94
+ get: {
95
+ tags: ["roles.desktopRoutes"],
96
+ summary: "List desktop routes granted to a role",
97
+ parameters: [
98
+ { $ref: "#/components/parameters/RoleNamePath" },
99
+ { $ref: "#/components/parameters/PaginateQuery" },
100
+ { $ref: "#/components/parameters/FilterQuery" }
101
+ ],
102
+ responses: {
103
+ 200: {
104
+ description: "OK",
105
+ content: {
106
+ "application/json": {
107
+ schema: {
108
+ type: "object",
109
+ properties: {
110
+ data: {
111
+ type: "array",
112
+ items: { $ref: "#/components/schemas/DesktopRoute" }
113
+ },
114
+ meta: {
115
+ type: "object",
116
+ additionalProperties: true
117
+ }
118
+ }
119
+ }
120
+ }
121
+ }
122
+ }
123
+ }
124
+ }
125
+ },
126
+ "/desktopRoutes:listAccessible": {
127
+ get: {
128
+ tags: ["desktopRoutes"],
129
+ summary: "List desktop routes accessible to the current user",
130
+ parameters: [
131
+ { $ref: "#/components/parameters/TreeQuery" },
132
+ { $ref: "#/components/parameters/SortScalarQuery" },
133
+ { $ref: "#/components/parameters/FilterQuery" }
134
+ ],
135
+ responses: {
136
+ 200: {
137
+ description: "OK",
138
+ content: {
139
+ "application/json": {
140
+ schema: {
141
+ type: "object",
142
+ properties: {
143
+ data: {
144
+ type: "array",
145
+ items: { $ref: "#/components/schemas/DesktopRoute" }
146
+ },
147
+ meta: {
148
+ type: "object",
149
+ additionalProperties: true
150
+ }
151
+ }
152
+ }
153
+ }
154
+ }
155
+ }
156
+ }
157
+ }
158
+ }
159
+ },
160
+ components: {
161
+ parameters: {
162
+ RoleNamePath: {
163
+ name: "roleName",
164
+ in: "path",
165
+ description: "Role name.",
166
+ required: true,
167
+ schema: { type: "string" }
168
+ },
169
+ PaginateQuery: {
170
+ name: "paginate",
171
+ in: "query",
172
+ description: "Whether to return paginated result format.",
173
+ required: false,
174
+ schema: { type: "boolean" }
175
+ },
176
+ TreeQuery: {
177
+ name: "tree",
178
+ in: "query",
179
+ description: "Whether to return routes as a tree.",
180
+ required: false,
181
+ schema: { type: "boolean" }
182
+ },
183
+ SortScalarQuery: {
184
+ name: "sort",
185
+ in: "query",
186
+ description: "Sort field, for example `sort`.",
187
+ required: false,
188
+ schema: { type: "string" }
189
+ },
190
+ FilterQuery: {
191
+ name: "filter",
192
+ in: "query",
193
+ description: "JSON filter object.",
194
+ required: false,
195
+ schema: { type: "object", additionalProperties: true }
196
+ }
197
+ },
198
+ schemas: {
199
+ RouteIdList: {
200
+ type: "array",
201
+ description: "Desktop route id list.",
202
+ items: { type: "integer" }
203
+ },
204
+ DesktopRoute: {
205
+ type: "object",
206
+ properties: {
207
+ id: { type: "integer" },
208
+ title: { type: "string" },
209
+ type: { type: "string" },
210
+ path: { type: "string", nullable: true },
211
+ parentId: { type: "integer", nullable: true },
212
+ hidden: { type: "boolean", nullable: true },
213
+ children: {
214
+ type: "array",
215
+ items: { $ref: "#/components/schemas/DesktopRoute" }
216
+ }
217
+ },
218
+ additionalProperties: true
219
+ }
220
+ }
221
+ }
222
+ };
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.9",
9
+ "version": "2.2.0-alpha.1",
10
10
  "main": "./dist/server/index.js",
11
11
  "license": "Apache-2.0",
12
12
  "devDependencies": {
@@ -17,11 +17,11 @@
17
17
  },
18
18
  "peerDependencies": {
19
19
  "@nocobase/client": "2.x",
20
+ "@nocobase/client-v2": "2.x",
20
21
  "@nocobase/database": "2.x",
21
- "@nocobase/plugin-localization": "2.x",
22
22
  "@nocobase/server": "2.x",
23
23
  "@nocobase/test": "2.x",
24
24
  "@nocobase/utils": "2.x"
25
25
  },
26
- "gitHead": "c3a2875e4cbbb43b1f2361e6f9f5f84a7d3f3c3c"
26
+ "gitHead": "303663aba6c6eefa27e6a6435b4c0352074ec40f"
27
27
  }
@@ -1,7 +0,0 @@
1
- {
2
- "openapi": "3.0.2",
3
- "info": {
4
- "title": "NocoBase API - Client plugin"
5
- },
6
- "paths": {}
7
- }