@nocobase/plugin-multi-app-share-collection 0.11.1-alpha.5 → 0.12.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.
Files changed (56) hide show
  1. package/client.d.ts +2 -3
  2. package/client.js +1 -1
  3. package/dist/client/index.js +510 -0
  4. package/{lib → dist}/index.d.ts +1 -0
  5. package/dist/index.js +18 -0
  6. package/dist/locale/es-ES.js +16 -0
  7. package/dist/locale/pt-BR.js +16 -0
  8. package/dist/locale/zh-CN.js +16 -0
  9. package/dist/server/collections/applications.js +21 -0
  10. package/dist/server/collections/collections.js +21 -0
  11. package/dist/server/index.js +11 -0
  12. package/{src/server/migrations/20230319111111-update-apps-collections.ts → dist/server/migrations/20230319111111-update-apps-collections.js} +26 -33
  13. package/dist/server/plugin.js +278 -0
  14. package/package.json +16 -25
  15. package/server.d.ts +2 -3
  16. package/server.js +1 -1
  17. package/lib/client/MultiAppShareCollectionProvider.js +0 -122
  18. package/lib/client/TableTransfer.js +0 -487
  19. package/lib/client/index.js +0 -27
  20. package/lib/client/utils.js +0 -25
  21. package/lib/index.js +0 -13
  22. package/lib/locale/es-ES.js +0 -19
  23. package/lib/locale/pt-BR.js +0 -19
  24. package/lib/locale/zh-CN.js +0 -19
  25. package/lib/server/collections/applications.js +0 -27
  26. package/lib/server/collections/collections.js +0 -27
  27. package/lib/server/index.js +0 -13
  28. package/lib/server/migrations/20230319111111-update-apps-collections.js +0 -110
  29. package/lib/server/plugin.js +0 -408
  30. package/src/client/MultiAppShareCollectionProvider.tsx +0 -86
  31. package/src/client/TableTransfer.tsx +0 -398
  32. package/src/client/index.tsx +0 -10
  33. package/src/client/utils.tsx +0 -11
  34. package/src/index.ts +0 -1
  35. package/src/locale/es-ES.ts +0 -12
  36. package/src/locale/pt-BR.ts +0 -12
  37. package/src/locale/zh-CN.ts +0 -12
  38. package/src/server/__tests__/collection-sync.test.ts +0 -514
  39. package/src/server/__tests__/index.ts +0 -25
  40. package/src/server/collections/.gitkeep +0 -0
  41. package/src/server/collections/applications.ts +0 -17
  42. package/src/server/collections/collections.ts +0 -17
  43. package/src/server/index.ts +0 -1
  44. package/src/server/plugin.ts +0 -332
  45. /package/{lib → dist}/client/MultiAppShareCollectionProvider.d.ts +0 -0
  46. /package/{lib → dist}/client/TableTransfer.d.ts +0 -0
  47. /package/{lib → dist}/client/index.d.ts +0 -0
  48. /package/{lib → dist}/client/utils.d.ts +0 -0
  49. /package/{lib → dist}/locale/es-ES.d.ts +0 -0
  50. /package/{lib → dist}/locale/pt-BR.d.ts +0 -0
  51. /package/{lib → dist}/locale/zh-CN.d.ts +0 -0
  52. /package/{lib → dist}/server/collections/applications.d.ts +0 -0
  53. /package/{lib → dist}/server/collections/collections.d.ts +0 -0
  54. /package/{lib → dist}/server/index.d.ts +0 -0
  55. /package/{lib → dist}/server/migrations/20230319111111-update-apps-collections.d.ts +0 -0
  56. /package/{lib → dist}/server/plugin.d.ts +0 -0
@@ -1,332 +0,0 @@
1
- import PluginMultiAppManager from '@nocobase/plugin-multi-app-manager';
2
- import { Application, Plugin } from '@nocobase/server';
3
- import { lodash } from '@nocobase/utils';
4
- import { resolve } from 'path';
5
-
6
- const subAppFilteredPlugins = ['multi-app-share-collection', 'multi-app-manager'];
7
-
8
- class SubAppPlugin extends Plugin {
9
- beforeLoad() {
10
- const mainApp = this.options.mainApp;
11
- const subApp = this.app;
12
-
13
- const sharedCollectionGroups = [
14
- 'audit-logs',
15
- 'workflow',
16
- 'charts',
17
- 'collection-manager',
18
- 'file-manager',
19
- 'graph-collection-manager',
20
- 'map',
21
- 'sequence-field',
22
- 'snapshot-field',
23
- 'verification',
24
- 'localization-management',
25
- ];
26
-
27
- const collectionGroups = mainApp.db.collectionGroupManager.getGroups();
28
-
29
- const sharedCollectionGroupsCollections = [];
30
-
31
- for (const group of collectionGroups) {
32
- if (sharedCollectionGroups.includes(group.namespace)) {
33
- sharedCollectionGroupsCollections.push(...group.collections);
34
- }
35
- }
36
-
37
- const sharedCollections = [...sharedCollectionGroupsCollections.flat(), 'users', 'users_jobs'];
38
-
39
- subApp.db.on('beforeDefineCollection', (options) => {
40
- const name = options.name;
41
-
42
- // 指向主应用的 系统schema
43
- if (sharedCollections.includes(name)) {
44
- options.schema = mainApp.db.options.schema || 'public';
45
- }
46
- });
47
-
48
- subApp.db.on('beforeUpdateCollection', (collection, newOptions) => {
49
- if (collection.name === 'roles') {
50
- newOptions.schema = subApp.db.options.schema;
51
- }
52
- });
53
-
54
- this.app.resourcer.use(async (ctx, next) => {
55
- const { actionName, resourceName } = ctx.action;
56
- if (actionName === 'list' && resourceName === 'applicationPlugins') {
57
- ctx.action.mergeParams({
58
- filter: {
59
- 'name.$notIn': subAppFilteredPlugins,
60
- },
61
- });
62
- }
63
-
64
- if (actionName === 'list' && resourceName === 'collections') {
65
- const appCollectionBlacklistCollection = mainApp.db.getCollection('appCollectionBlacklist');
66
-
67
- const blackList = await appCollectionBlacklistCollection.model.findAll({
68
- where: {
69
- applicationName: subApp.name,
70
- },
71
- });
72
-
73
- if (blackList.length > 0) {
74
- ctx.action.mergeParams({
75
- filter: {
76
- 'name.$notIn': blackList.map((item) => item.get('collectionName')),
77
- },
78
- });
79
- }
80
- }
81
- await next();
82
- });
83
-
84
- // new subApp sync plugins from mainApp
85
- subApp.on('beforeInstall', async () => {
86
- const subAppPluginsCollection = subApp.db.getCollection('applicationPlugins');
87
- const mainAppPluginsCollection = mainApp.db.getCollection('applicationPlugins');
88
-
89
- // delete old collection
90
- await subApp.db.sequelize.query(`TRUNCATE ${subAppPluginsCollection.quotedTableName()}`);
91
-
92
- await subApp.db.sequelize.query(`
93
- INSERT INTO ${subAppPluginsCollection.quotedTableName()}
94
- SELECT *
95
- FROM ${mainAppPluginsCollection.quotedTableName()}
96
- WHERE "name" not in ('multi-app-manager', 'multi-app-share-collection');
97
- `);
98
-
99
- const sequenceNameSql = `SELECT pg_get_serial_sequence('"${subAppPluginsCollection.collectionSchema()}"."${
100
- subAppPluginsCollection.model.tableName
101
- }"', 'id')`;
102
-
103
- const sequenceName = (await subApp.db.sequelize.query(sequenceNameSql, { type: 'SELECT' })) as any;
104
- await subApp.db.sequelize.query(`
105
- SELECT setval('${
106
- sequenceName[0]['pg_get_serial_sequence']
107
- }', (SELECT max("id") FROM ${subAppPluginsCollection.quotedTableName()}));
108
- `);
109
-
110
- console.log(`sync plugins from ${mainApp.name} app to sub app ${subApp.name}`);
111
- });
112
- }
113
- }
114
-
115
- export class MultiAppShareCollectionPlugin extends Plugin {
116
- afterAdd() {}
117
-
118
- async beforeEnable() {
119
- if (!this.db.inDialect('postgres')) {
120
- throw new Error('multi-app-share-collection plugin only support postgres');
121
- }
122
- }
123
-
124
- async beforeLoad() {
125
- if (!this.db.inDialect('postgres')) {
126
- throw new Error('multi-app-share-collection plugin only support postgres');
127
- }
128
-
129
- const traverseSubApps = async (
130
- callback: (subApp: Application) => void,
131
- options?: {
132
- loadFromDatabase: boolean;
133
- },
134
- ) => {
135
- if (lodash.get(options, 'loadFromDatabase')) {
136
- for (const application of await this.app.db.getCollection('applications').repository.find()) {
137
- const appName = application.get('name');
138
- const subApp = await this.app.appManager.getApplication(appName);
139
- await callback(subApp);
140
- }
141
-
142
- return;
143
- }
144
-
145
- const subApps = [...this.app.appManager.applications.values()];
146
-
147
- for (const subApp of subApps) {
148
- await callback(subApp);
149
- }
150
- };
151
-
152
- this.app.on('afterSubAppAdded', (subApp) => {
153
- subApp.plugin(SubAppPlugin, { name: 'sub-app', mainApp: this.app });
154
- });
155
-
156
- this.app.db.on('users.afterCreateWithAssociations', async (model, options) => {
157
- await traverseSubApps(async (subApp) => {
158
- const { transaction } = options;
159
- const repository = subApp.db.getRepository('roles');
160
- const subAppModel = await subApp.db.getCollection('users').repository.findOne({
161
- filter: {
162
- id: model.get('id'),
163
- },
164
- transaction,
165
- });
166
- const defaultRole = await repository.findOne({
167
- filter: {
168
- default: true,
169
- },
170
- transaction,
171
- });
172
-
173
- if (defaultRole && (await subAppModel.countRoles({ transaction })) == 0) {
174
- await subAppModel.addRoles(defaultRole, { transaction });
175
- }
176
- });
177
- });
178
-
179
- this.app.db.on('collection:loaded', async ({ transaction, collection }) => {
180
- await traverseSubApps(async (subApp) => {
181
- const name = collection.name;
182
-
183
- const collectionRecord = await subApp.db.getRepository('collections').findOne({
184
- filter: {
185
- name,
186
- },
187
- transaction,
188
- });
189
-
190
- await collectionRecord.load({ transaction });
191
- });
192
- });
193
-
194
- this.app.db.on('field:loaded', async ({ transaction, fieldKey }) => {
195
- await traverseSubApps(async (subApp) => {
196
- const fieldRecord = await subApp.db.getRepository('fields').findOne({
197
- filterByTk: fieldKey,
198
- transaction,
199
- });
200
-
201
- if (fieldRecord) {
202
- await fieldRecord.load({ transaction });
203
- }
204
- });
205
- });
206
-
207
- this.app.on('afterEnablePlugin', async (pluginName) => {
208
- await traverseSubApps(
209
- async (subApp) => {
210
- if (subAppFilteredPlugins.includes(pluginName)) return;
211
- await subApp.pm.enable(pluginName);
212
- },
213
- {
214
- loadFromDatabase: true,
215
- },
216
- );
217
- });
218
-
219
- this.app.on('afterDisablePlugin', async (pluginName) => {
220
- await traverseSubApps(
221
- async (subApp) => {
222
- if (subAppFilteredPlugins.includes(pluginName)) return;
223
- await subApp.pm.disable(pluginName);
224
- },
225
- {
226
- loadFromDatabase: true,
227
- },
228
- );
229
- });
230
-
231
- this.app.db.on('field.afterRemove', (removedField) => {
232
- const subApps = [...this.app.appManager.applications.values()];
233
- for (const subApp of subApps) {
234
- const collectionName = removedField.collection.name;
235
- const collection = subApp.db.getCollection(collectionName);
236
- if (!collection) {
237
- subApp.log.warn(`collection ${collectionName} not found in ${subApp.name}`);
238
- continue;
239
- }
240
-
241
- collection.removeField(removedField.name);
242
- }
243
- });
244
-
245
- this.app.db.on(`afterRemoveCollection`, (collection) => {
246
- const subApps = [...this.app.appManager.applications.values()];
247
- for (const subApp of subApps) {
248
- subApp.db.removeCollection(collection.name);
249
- }
250
- });
251
- }
252
-
253
- async load() {
254
- const multiAppManager = this.app.getPlugin<any>('multi-app-manager');
255
-
256
- if (!multiAppManager) {
257
- this.app.log.warn('multi-app-share-collection plugin need multi-app-manager plugin enabled');
258
- return;
259
- }
260
-
261
- await this.db.import({
262
- directory: resolve(__dirname, 'collections'),
263
- });
264
-
265
- // this.db.addMigrations({
266
- // namespace: 'multi-app-share-collection',
267
- // directory: resolve(__dirname, './migrations'),
268
- // });
269
-
270
- this.app.resourcer.registerActionHandlers({
271
- 'applications:shareCollections': async (ctx, next) => {
272
- const { filterByTk, values } = ctx.action.params;
273
- ctx.body = {
274
- filterByTk,
275
- values,
276
- };
277
- await next();
278
- },
279
- });
280
-
281
- // 子应用启动参数
282
- multiAppManager.setAppOptionsFactory((appName, mainApp) => {
283
- const mainAppDbConfig = PluginMultiAppManager.getDatabaseConfig(mainApp);
284
-
285
- const databaseOptions = {
286
- ...mainAppDbConfig,
287
- schema: appName,
288
- };
289
-
290
- const plugins = [...mainApp.pm.getPlugins().keys()].filter(
291
- (name) => name !== 'multi-app-manager' && name !== 'multi-app-share-collection',
292
- );
293
-
294
- return {
295
- database: lodash.merge(databaseOptions, {
296
- dialectOptions: {
297
- application_name: `nocobase.${appName}`,
298
- },
299
- }),
300
- plugins: plugins.includes('nocobase') ? ['nocobase'] : plugins,
301
- resourcer: {
302
- prefix: '/api',
303
- },
304
- logger: {
305
- ...mainApp.options.logger,
306
- requestWhitelist: [
307
- 'action',
308
- 'header.x-role',
309
- 'header.x-hostname',
310
- 'header.x-timezone',
311
- 'header.x-locale',
312
- 'referer',
313
- 'header.x-app',
314
- ],
315
- },
316
- // pmSock: resolve(process.cwd(), 'storage', `${appName}.sock`),
317
- };
318
- });
319
-
320
- // 子应用数据库创建
321
- multiAppManager.setAppDbCreator(async (app) => {
322
- const schema = app.options.database.schema;
323
- await this.app.db.sequelize.query(`CREATE SCHEMA IF NOT EXISTS ${schema}`);
324
- });
325
- }
326
-
327
- requiredPlugins(): any[] {
328
- return ['multi-app-manager'];
329
- }
330
- }
331
-
332
- export default MultiAppShareCollectionPlugin;
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes