tachybase_todo/packages/plugins/duplicator/src/server/app-migrator.ts
jack zhang 5df3b0e75d
refactor!: plugins build and plugins load (#2253)
* 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>
2023-08-02 00:07:52 +08:00

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 };