* refactor: plugin build and plugin template * refactor: plugins' deps * refactor: plugins bugs * feat: add plugin static middleware * fix: bugs * refactor: frontend plugin add from remote * refactor: delete useless app/client/plugins * fix: requirejs move to local * fix: tests case * refactor: add src/client and src/server dir check * fix: lodash tree shaking * refactor: add BUILD_TIP * refactor: add file size tip * fix: bugs * fix: bug * fix: change china-division * fix: change plugins response * fix: recover dynamicImport * fix: change server src entry * fix: test error * fix: plugins sourcemap => false * fix: production file error * refactor: change build tools to vite and tsup * fix: yarn.lock * fix: bugs * fix: server build bugs * fix: delete .fatherrc.ts * fix: bug * fix: bug * fix: bugs * fix: bugs * fix: bugs * refactor: add plugin d.ts * refactor: delete fatherrc * refactor: delete father scripts * refactor: build bug * fix: bug * fix: deps adjust * fix: add build tips * fix: bug * refactor: ignore plugins when build client * docs: update doc * refactor: docs and build * fix: bug * refactor: build deps * fix: add USER_REMOTE_PLUGIN env * feat: add plugin static cache * feat: add build deps cache * fix: bugs * test: add test * fix: add plugin depden on plugin tip * fix: adjust shouldDevDependencies * fix: deps * fix: ajust deps * fix: mobile style error * fix: map error * fix: test * fix: bug * feat: lodash and dayjs import from themself * feat: @emotion/css 、ahooks and lodash to global * fix: theme-editor plugin error * fix: review * feat: move all plugins' dependencies to devDependencies * feat: change build * feat: add devPlugins * fix: bug * fix: bugs * fix: bugs * fix: bugs * feat: build bugs * fix: bugs * fix: bugs * fix: review * fix: bug * fix: change deps build * fix: bugs * fix: bug * fix: bug * fix: bugs * fix: bug * fix: bug * fix: multi language * fix: dist * fix: cronstrue * fix: getPackageClientStaticUrl * fix: antd dayjs locale * fix: plugin' d.ts import from dist * fix: multi language * fix: build types error * fix: requireModule * fix: plugin lifecycle * fix: client resource * fix: improve code * fix: locale * feat: custom build * fix: require locale * fix: improve code * fix: improve code * fix: skip preset * fix: collection undefined * feat: yarn build * fix: remove enabled * fix: update dockerfile * fix: formily version * docs: update v12 changelog * fix: devDependencies * feat: @nocobase/app * feat: generateAppDir * fix: improve code * fix: 0.11.1-alpha.5 * fix: missing @nocobase/client * fix: error * fix: add .npmignore * feat: upgrade antd version * fix: dependencies * fix: peerDependencies * fix: remove china-division dep * fix: toposort deps * fix: update dockerfile * fix: plugin template * fix: app client outputPath * feat: update docs * fix: nginx server root * fix: storage/.app-dev * fix: getChinaDivisionData * feat: plugin info * feat: update docs * fix: docs menu --------- Co-authored-by: chenos <chenlinxh@gmail.com>
95 lines
2.7 KiB
TypeScript
95 lines
2.7 KiB
TypeScript
import { Application } from '@nocobase/server';
|
|
import { applyMixins, AsyncEmitter } from '@nocobase/utils';
|
|
import crypto from 'crypto';
|
|
import EventEmitter from 'events';
|
|
import fsPromises from 'fs/promises';
|
|
import lodash from 'lodash';
|
|
import * as os from 'os';
|
|
import path from 'path';
|
|
import { CollectionGroupManager } from './collection-group-manager';
|
|
|
|
export type AppMigratorOptions = {
|
|
workDir?: string;
|
|
};
|
|
abstract class AppMigrator extends EventEmitter {
|
|
protected workDir: string;
|
|
public app: Application;
|
|
|
|
abstract direction: 'restore' | 'dump';
|
|
|
|
declare emitAsync: (event: string | symbol, ...args: any[]) => Promise<boolean>;
|
|
|
|
constructor(app, options?: AppMigratorOptions) {
|
|
super();
|
|
|
|
this.app = app;
|
|
this.workDir = options?.workDir || this.tmpDir();
|
|
}
|
|
|
|
tmpDir() {
|
|
return path.resolve(os.tmpdir(), `nocobase-${crypto.randomUUID()}`);
|
|
}
|
|
|
|
getPluginCollections(plugins: string | string[]) {
|
|
return lodash
|
|
.castArray(plugins)
|
|
.map((pluginName) => {
|
|
return this.app.db.importedFrom.get(pluginName) || [];
|
|
})
|
|
.flat();
|
|
}
|
|
|
|
async getAppPlugins() {
|
|
const plugins = await this.app.db.getCollection('applicationPlugins').repository.find();
|
|
|
|
return lodash.uniq(['core', ...this.app.pm.plugins.keys(), ...plugins.map((plugin) => plugin.get('name'))]);
|
|
}
|
|
|
|
async getAppPluginCollectionGroups() {
|
|
const plugins = await this.getAppPlugins();
|
|
return CollectionGroupManager.collectionGroups.filter((collectionGroup) =>
|
|
plugins.includes(collectionGroup.namespace),
|
|
);
|
|
}
|
|
|
|
async getCustomCollections() {
|
|
const collections = await this.app.db.getCollection('collections').repository.find();
|
|
return collections.filter((collection) => !collection.get('isThrough')).map((collection) => collection.get('name'));
|
|
}
|
|
|
|
async rmDir(dir: string) {
|
|
await fsPromises.rm(dir, { recursive: true, force: true });
|
|
}
|
|
|
|
async clearWorkDir() {
|
|
await this.rmDir(this.workDir);
|
|
}
|
|
|
|
findThroughCollections(collections: string[]) {
|
|
return [
|
|
...new Set(
|
|
collections
|
|
.map((collectionName) => this.app.db.getCollection(collectionName))
|
|
.map((collection) =>
|
|
[...collection.fields.values()].filter((field) => field.through).map((field) => field.through),
|
|
)
|
|
.flat(),
|
|
),
|
|
];
|
|
}
|
|
|
|
findSequenceFields(collections: string[]) {
|
|
return [
|
|
...new Set(
|
|
collections
|
|
.map((collectionName) => this.app.db.getCollection(collectionName))
|
|
.map((collection) => [...collection.fields.values()].filter((field) => field.type === 'sequence'))
|
|
.flat(),
|
|
),
|
|
];
|
|
}
|
|
}
|
|
|
|
applyMixins(AppMigrator, [AsyncEmitter]);
|
|
export { AppMigrator };
|