mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-05-05 13:39:24 +08:00
feat: improve pm.add
This commit is contained in:
parent
5278017fff
commit
8f1831ecea
@ -25,7 +25,7 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
modulePathIgnorePatterns: ['/esm/', '/es/', '/dist/', '/lib/', '/client/', '/sdk/', '\\.test\\.tsx$'],
|
modulePathIgnorePatterns: ['/storage/', '/esm/', '/es/', '/dist/', '/lib/', '/client/', '/sdk/', '\\.test\\.tsx$'],
|
||||||
coveragePathIgnorePatterns: [
|
coveragePathIgnorePatterns: [
|
||||||
'/node_modules/',
|
'/node_modules/',
|
||||||
'/__tests__/',
|
'/__tests__/',
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
const { Command } = require('commander');
|
const { Command } = require('commander');
|
||||||
const { run, isDev, isPackageValid } = require('../util');
|
const { run, isDev, isPackageValid, createStoragePluginsSymlink } = require('../util');
|
||||||
const { resolve } = require('path');
|
const { resolve, dirname } = require('path');
|
||||||
const { existsSync } = require('fs');
|
const { existsSync } = require('fs');
|
||||||
const { readFile, writeFile } = require('fs').promises;
|
const { readFile, writeFile } = require('fs').promises;
|
||||||
|
|
||||||
@ -13,10 +13,11 @@ module.exports = (cli) => {
|
|||||||
.command('postinstall')
|
.command('postinstall')
|
||||||
.allowUnknownOption()
|
.allowUnknownOption()
|
||||||
.action(async () => {
|
.action(async () => {
|
||||||
|
const cwd = process.cwd();
|
||||||
|
await createStoragePluginsSymlink();
|
||||||
if (!isDev()) {
|
if (!isDev()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const cwd = process.cwd();
|
|
||||||
if (!existsSync(resolve(cwd, '.env')) && existsSync(resolve(cwd, '.env.example'))) {
|
if (!existsSync(resolve(cwd, '.env')) && existsSync(resolve(cwd, '.env.example'))) {
|
||||||
const content = await readFile(resolve(cwd, '.env.example'), 'utf-8');
|
const content = await readFile(resolve(cwd, '.env.example'), 'utf-8');
|
||||||
await writeFile(resolve(cwd, '.env'), content, 'utf-8');
|
await writeFile(resolve(cwd, '.env'), content, 'utf-8');
|
||||||
|
@ -2,8 +2,8 @@ const net = require('net');
|
|||||||
const chalk = require('chalk');
|
const chalk = require('chalk');
|
||||||
const execa = require('execa');
|
const execa = require('execa');
|
||||||
const { dirname, resolve } = require('path');
|
const { dirname, resolve } = require('path');
|
||||||
const { readFile, writeFile } = require('fs').promises;
|
|
||||||
const { existsSync, mkdirSync, cpSync } = require('fs');
|
const { existsSync, mkdirSync, cpSync } = require('fs');
|
||||||
|
const { readFile, writeFile, readdir, symlink, unlink, mkdir, stat } = require('fs').promises;
|
||||||
|
|
||||||
exports.isPackageValid = (package) => {
|
exports.isPackageValid = (package) => {
|
||||||
try {
|
try {
|
||||||
@ -174,3 +174,56 @@ exports.generateAppDir = function generateAppDir() {
|
|||||||
process.env.APP_PACKAGE_ROOT = appPkgPath;
|
process.env.APP_PACKAGE_ROOT = appPkgPath;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
async function getStoragePluginNames(target) {
|
||||||
|
const plugins = [];
|
||||||
|
const items = await readdir(target);
|
||||||
|
for (const item of items) {
|
||||||
|
if (item.startsWith('@')) {
|
||||||
|
const children = await getStoragePluginNames(resolve(target, item));
|
||||||
|
plugins.push(
|
||||||
|
...children.map((child) => {
|
||||||
|
return `${item}/${child}`;
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
} else if (await fsExists(resolve(target, item, 'package.json'))) {
|
||||||
|
plugins.push(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return plugins;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fsExists(path) {
|
||||||
|
try {
|
||||||
|
await stat(path);
|
||||||
|
return true;
|
||||||
|
} catch (error) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function createStoragePluginSymLink(pluginName) {
|
||||||
|
const storagePluginsPath = resolve(process.cwd(), 'storage/plugins');
|
||||||
|
// const nodeModulesPath = resolve(dirname(require.resolve('@nocobase/server/package.json')), 'node_modules');
|
||||||
|
const nodeModulesPath = resolve(process.cwd(), 'node_modules');
|
||||||
|
if (pluginName.startsWith('@')) {
|
||||||
|
const [orgName] = pluginName.split('/');
|
||||||
|
if (!(await fsExists(resolve(nodeModulesPath, orgName)))) {
|
||||||
|
await mkdir(resolve(nodeModulesPath, orgName), { recursive: true });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const link = resolve(nodeModulesPath, pluginName);
|
||||||
|
if (await fsExists(link)) {
|
||||||
|
await unlink(link);
|
||||||
|
}
|
||||||
|
await symlink(resolve(storagePluginsPath, pluginName), link);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function createStoragePluginsSymlink() {
|
||||||
|
const pluginNames = await getStoragePluginNames(resolve(process.cwd(), 'storage/plugins'));
|
||||||
|
for (const pluginName of pluginNames) {
|
||||||
|
await createStoragePluginSymLink(pluginName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.createStoragePluginsSymlink = createStoragePluginsSymlink;
|
||||||
|
@ -3,16 +3,16 @@ import lodash from 'lodash';
|
|||||||
import {
|
import {
|
||||||
Association,
|
Association,
|
||||||
BulkCreateOptions,
|
BulkCreateOptions,
|
||||||
CountOptions as SequelizeCountOptions,
|
|
||||||
CreateOptions as SequelizeCreateOptions,
|
|
||||||
DestroyOptions as SequelizeDestroyOptions,
|
|
||||||
FindAndCountOptions as SequelizeAndCountOptions,
|
|
||||||
FindOptions as SequelizeFindOptions,
|
|
||||||
ModelStatic,
|
ModelStatic,
|
||||||
Op,
|
Op,
|
||||||
Sequelize,
|
Sequelize,
|
||||||
Transactionable,
|
FindAndCountOptions as SequelizeAndCountOptions,
|
||||||
|
CountOptions as SequelizeCountOptions,
|
||||||
|
CreateOptions as SequelizeCreateOptions,
|
||||||
|
DestroyOptions as SequelizeDestroyOptions,
|
||||||
|
FindOptions as SequelizeFindOptions,
|
||||||
UpdateOptions as SequelizeUpdateOptions,
|
UpdateOptions as SequelizeUpdateOptions,
|
||||||
|
Transactionable,
|
||||||
WhereOperators,
|
WhereOperators,
|
||||||
} from 'sequelize';
|
} from 'sequelize';
|
||||||
import { Collection } from './collection';
|
import { Collection } from './collection';
|
||||||
@ -37,6 +37,7 @@ import { UpdateGuard } from './update-guard';
|
|||||||
|
|
||||||
const debug = require('debug')('noco-database');
|
const debug = require('debug')('noco-database');
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||||
export interface IRepository {}
|
export interface IRepository {}
|
||||||
|
|
||||||
interface CreateManyOptions extends BulkCreateOptions {
|
interface CreateManyOptions extends BulkCreateOptions {
|
||||||
@ -216,7 +217,12 @@ export interface AggregateOptions {
|
|||||||
distinct?: boolean;
|
distinct?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface FirstOrCreateOptions extends Transactionable {
|
export interface FirstOrCreateOptions extends Transactionable {
|
||||||
|
filterKeys: string[];
|
||||||
|
values?: Values;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UpdateOrCreateOptions extends Transactionable {
|
||||||
filterKeys: string[];
|
filterKeys: string[];
|
||||||
values?: Values;
|
values?: Values;
|
||||||
}
|
}
|
||||||
@ -242,7 +248,7 @@ export class Repository<TModelAttributes extends {} = any, TCreationAttributes e
|
|||||||
const chunks = key.split('.');
|
const chunks = key.split('.');
|
||||||
return chunks
|
return chunks
|
||||||
.filter((chunk) => {
|
.filter((chunk) => {
|
||||||
return !Boolean(chunk.match(/\d+/));
|
return !chunk.match(/\d+/);
|
||||||
})
|
})
|
||||||
.join('.');
|
.join('.');
|
||||||
};
|
};
|
||||||
@ -503,7 +509,7 @@ export class Repository<TModelAttributes extends {} = any, TCreationAttributes e
|
|||||||
return this.create({ values, transaction });
|
return this.create({ values, transaction });
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateOrCreate(options: FirstOrCreateOptions) {
|
async updateOrCreate(options: UpdateOrCreateOptions) {
|
||||||
const { filterKeys, values, transaction } = options;
|
const { filterKeys, values, transaction } = options;
|
||||||
const filter = Repository.valuesToFilter(values, filterKeys);
|
const filter = Repository.valuesToFilter(values, filterKeys);
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
"commander": "^9.2.0",
|
"commander": "^9.2.0",
|
||||||
"cronstrue": "^2.11.0",
|
"cronstrue": "^2.11.0",
|
||||||
"dayjs": "^1.11.8",
|
"dayjs": "^1.11.8",
|
||||||
|
"decompress": "^4.2.1",
|
||||||
"find-package-json": "^1.2.0",
|
"find-package-json": "^1.2.0",
|
||||||
"i18next": "^22.4.9",
|
"i18next": "^22.4.9",
|
||||||
"koa": "^2.13.4",
|
"koa": "^2.13.4",
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import { Repository } from '@nocobase/database';
|
import { Repository, UpdateOrCreateOptions } from '@nocobase/database';
|
||||||
import lodash from 'lodash';
|
import lodash, { isBoolean } from 'lodash';
|
||||||
import { PluginManager } from './plugin-manager';
|
import { PluginManager } from './plugin-manager';
|
||||||
|
|
||||||
export class PluginManagerRepository extends Repository {
|
export class PluginManagerRepository extends Repository {
|
||||||
pm: PluginManager;
|
pm: PluginManager;
|
||||||
|
_authenticated: boolean;
|
||||||
|
|
||||||
setPluginManager(pm: PluginManager) {
|
setPluginManager(pm: PluginManager) {
|
||||||
this.pm = pm;
|
this.pm = pm;
|
||||||
@ -68,6 +69,9 @@ export class PluginManagerRepository extends Repository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getItems() {
|
async getItems() {
|
||||||
|
if (!(await this.authenticate())) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
// sort plugins by id
|
// sort plugins by id
|
||||||
return await this.find({
|
return await this.find({
|
||||||
@ -86,9 +90,22 @@ export class PluginManagerRepository extends Repository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async authenticate() {
|
||||||
|
if (!isBoolean(this._authenticated)) {
|
||||||
|
this._authenticated = await this.collection.existsInDb();
|
||||||
|
}
|
||||||
|
return this._authenticated;
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateOrCreate(options: UpdateOrCreateOptions) {
|
||||||
|
if (!(await this.authenticate())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return super.updateOrCreate(options);
|
||||||
|
}
|
||||||
|
|
||||||
async init() {
|
async init() {
|
||||||
const exists = await this.collection.existsInDb();
|
if (!(await this.authenticate())) {
|
||||||
if (!exists) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,10 +6,11 @@ import net from 'net';
|
|||||||
import { resolve } from 'path';
|
import { resolve } from 'path';
|
||||||
import Application from '../application';
|
import Application from '../application';
|
||||||
import { createAppProxy } from '../helper';
|
import { createAppProxy } from '../helper';
|
||||||
import { Plugin } from '../plugin';
|
import { Plugin, PluginOptions } from '../plugin';
|
||||||
import collectionOptions from './options/collection';
|
import collectionOptions from './options/collection';
|
||||||
import resourceOptions from './options/resource';
|
import resourceOptions from './options/resource';
|
||||||
import { PluginManagerRepository } from './plugin-manager-repository';
|
import { PluginManagerRepository } from './plugin-manager-repository';
|
||||||
|
import { PluginResolver } from './plugin-resolver';
|
||||||
|
|
||||||
export interface PluginManagerOptions {
|
export interface PluginManagerOptions {
|
||||||
app: Application;
|
app: Application;
|
||||||
@ -22,17 +23,39 @@ export interface InstallOptions {
|
|||||||
sync?: SyncOptions;
|
sync?: SyncOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type PluginResolverResult = {
|
||||||
|
name?: string;
|
||||||
|
packageName?: string;
|
||||||
|
version?: string;
|
||||||
|
Plugin: any;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type PluginResolverHandleOptions = {
|
||||||
|
isPackageName?: boolean;
|
||||||
|
pluginName?: string;
|
||||||
|
packageName?: string;
|
||||||
|
authToken?: string;
|
||||||
|
registry?: string;
|
||||||
|
upgrading?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type AddingPluginType = string | typeof Plugin;
|
||||||
|
|
||||||
|
export type PMAddOptions = PluginOptions & {};
|
||||||
|
|
||||||
export class AddPresetError extends Error {}
|
export class AddPresetError extends Error {}
|
||||||
|
|
||||||
export class PluginManager {
|
export class PluginManager {
|
||||||
app: Application;
|
app: Application;
|
||||||
collection: Collection;
|
|
||||||
_repository: PluginManagerRepository;
|
|
||||||
pluginInstances = new Map<typeof Plugin, Plugin>();
|
|
||||||
pluginAliases = new Map<string, Plugin>();
|
|
||||||
server: net.Server;
|
server: net.Server;
|
||||||
|
collection: Collection;
|
||||||
|
protected pluginInstances = new Map<typeof Plugin, Plugin>();
|
||||||
|
protected pluginAliases = new Map<string, Plugin>();
|
||||||
|
protected PluginResolver: typeof PluginResolver;
|
||||||
|
protected _repository: PluginManagerRepository;
|
||||||
|
|
||||||
constructor(public options: PluginManagerOptions) {
|
constructor(public options: PluginManagerOptions) {
|
||||||
|
this.PluginResolver = PluginResolver;
|
||||||
this.app = options.app;
|
this.app = options.app;
|
||||||
this.app.db.registerRepositories({
|
this.app.db.registerRepositories({
|
||||||
PluginManagerRepository,
|
PluginManagerRepository,
|
||||||
@ -75,6 +98,8 @@ export class PluginManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static getPackageJson(packageName: string) {
|
static getPackageJson(packageName: string) {
|
||||||
|
const file = require.resolve(`${packageName}/package.json`);
|
||||||
|
delete require.cache[file];
|
||||||
return require(`${packageName}/package.json`);
|
return require(`${packageName}/package.json`);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,6 +146,16 @@ export class PluginManager {
|
|||||||
throw new Error(`No available packages found, ${name} plugin does not exist`);
|
throw new Error(`No available packages found, ${name} plugin does not exist`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setPluginResolver(Resolver: typeof PluginResolver) {
|
||||||
|
this.PluginResolver = Resolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
async resolvePlugin(pluginName: AddingPluginType, options) {
|
||||||
|
const Resolver = this.PluginResolver;
|
||||||
|
const resolver = new Resolver(this.app);
|
||||||
|
return resolver.handle(pluginName, options);
|
||||||
|
}
|
||||||
|
|
||||||
static resolvePlugin(pluginName: string | typeof Plugin) {
|
static resolvePlugin(pluginName: string | typeof Plugin) {
|
||||||
if (typeof pluginName === 'string') {
|
if (typeof pluginName === 'string') {
|
||||||
const packageName = this.getPackageName(pluginName);
|
const packageName = this.getPackageName(pluginName);
|
||||||
@ -189,7 +224,7 @@ export class PluginManager {
|
|||||||
await run('yarn', ['install']);
|
await run('yarn', ['install']);
|
||||||
}
|
}
|
||||||
|
|
||||||
async add(plugin?: any, options: any = {}) {
|
async add(plugin?: AddingPluginType, options: PMAddOptions = {}) {
|
||||||
if (this.has(plugin)) {
|
if (this.has(plugin)) {
|
||||||
const name = typeof plugin === 'string' ? plugin : plugin.name;
|
const name = typeof plugin === 'string' ? plugin : plugin.name;
|
||||||
this.app.log.warn(`plugin [${name}] added`);
|
this.app.log.warn(`plugin [${name}] added`);
|
||||||
@ -199,19 +234,24 @@ export class PluginManager {
|
|||||||
options.name = plugin;
|
options.name = plugin;
|
||||||
}
|
}
|
||||||
this.app.log.debug(`adding plugin [${options.name}]...`);
|
this.app.log.debug(`adding plugin [${options.name}]...`);
|
||||||
let P: any;
|
|
||||||
try {
|
try {
|
||||||
P = PluginManager.resolvePlugin(plugin);
|
const { Plugin: P, ...opts } = await this.resolvePlugin(plugin, options);
|
||||||
|
const instance: Plugin = new P(createAppProxy(this.app), opts);
|
||||||
|
this.pluginInstances.set(P, instance);
|
||||||
|
if (!options.isPreset && opts.name) {
|
||||||
|
await this.repository.updateOrCreate({
|
||||||
|
values: {
|
||||||
|
...options,
|
||||||
|
...opts,
|
||||||
|
},
|
||||||
|
filterKeys: ['name'],
|
||||||
|
});
|
||||||
|
this.pluginAliases.set(options.name, instance);
|
||||||
|
}
|
||||||
|
await instance.afterAdd();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.app.log.warn('plugin not found', error);
|
this.app.log.warn('plugin not found', error);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
const instance: Plugin = new P(createAppProxy(this.app), options);
|
|
||||||
this.pluginInstances.set(P, instance);
|
|
||||||
if (options.name) {
|
|
||||||
this.pluginAliases.set(options.name, instance);
|
|
||||||
}
|
|
||||||
await instance.afterAdd();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async initPlugins() {
|
async initPlugins() {
|
||||||
|
135
packages/core/server/src/plugin-manager/plugin-resolver.ts
Normal file
135
packages/core/server/src/plugin-manager/plugin-resolver.ts
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
import { CleanOptions, SyncOptions } from '@nocobase/database';
|
||||||
|
import { requireModule } from '@nocobase/utils';
|
||||||
|
import Application from '../application';
|
||||||
|
import { Plugin } from '../plugin';
|
||||||
|
import { PluginManager } from './plugin-manager';
|
||||||
|
|
||||||
|
export interface PluginManagerOptions {
|
||||||
|
app: Application;
|
||||||
|
plugins?: any[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface InstallOptions {
|
||||||
|
cliArgs?: any[];
|
||||||
|
clean?: CleanOptions | boolean;
|
||||||
|
sync?: SyncOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type PluginResolverResult = {
|
||||||
|
name?: string;
|
||||||
|
packageName?: string;
|
||||||
|
version?: string;
|
||||||
|
Plugin: any;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type PluginResolverHandleOptions = {
|
||||||
|
isPackageName?: boolean;
|
||||||
|
pluginName?: string;
|
||||||
|
packageName?: string;
|
||||||
|
authToken?: string;
|
||||||
|
registry?: string;
|
||||||
|
upgrading?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type PluginType = string | typeof Plugin;
|
||||||
|
|
||||||
|
export class PluginResolver {
|
||||||
|
constructor(protected app: Application) {}
|
||||||
|
|
||||||
|
async handlePluginClass(pluginName: PluginType, options: PluginResolverHandleOptions): Promise<PluginResolverResult> {
|
||||||
|
return {
|
||||||
|
Plugin: pluginName,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async handleLocalPackage(pluginName: string, options: PluginResolverHandleOptions): Promise<PluginResolverResult> {
|
||||||
|
const { packageName } = options;
|
||||||
|
const packageJson = PluginManager.getPackageJson(packageName);
|
||||||
|
return {
|
||||||
|
name: pluginName,
|
||||||
|
packageName,
|
||||||
|
version: packageJson.version,
|
||||||
|
Plugin: requireModule(packageName),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async handleCompressedPackage(pkgPath: string, options: PluginResolverHandleOptions): Promise<PluginResolverResult> {
|
||||||
|
return {
|
||||||
|
Plugin: '',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async handle(pluginName: PluginType, options: PluginResolverHandleOptions): Promise<PluginResolverResult> {
|
||||||
|
if (typeof pluginName !== 'string') {
|
||||||
|
return this.handlePluginClass(pluginName, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!options.isPackageName) {
|
||||||
|
options.packageName = PluginManager.getPackageName(pluginName);
|
||||||
|
return this.handleLocalPackage(pluginName, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
let pkgPath = pluginName;
|
||||||
|
|
||||||
|
if (options.isPackageName) {
|
||||||
|
if (options.upgrading && !this.isStoragePackage(pluginName)) {
|
||||||
|
options.packageName = pluginName;
|
||||||
|
return this.handleLocalPackage(this.getPluginNameViaPackageName(pluginName), options);
|
||||||
|
}
|
||||||
|
if (this.packageExists(pluginName)) {
|
||||||
|
options.packageName = pluginName;
|
||||||
|
return this.handleLocalPackage(this.getPluginNameViaPackageName(pluginName), options);
|
||||||
|
}
|
||||||
|
pkgPath = await this.downloadNpmPackage(pluginName, options);
|
||||||
|
} else if (this.isURL(pluginName)) {
|
||||||
|
pkgPath = await this.download(pluginName, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.isCompressedPackage(pkgPath)) {
|
||||||
|
throw new Error('invalid');
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.handleCompressedPackage(pkgPath, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
getPluginNameViaPackageName(packageName: string) {
|
||||||
|
return packageName;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async download(url: string, options) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async downloadNpmPackage(packageName: string, options) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
isStoragePackage(packageName: string) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
packageExists(packageName: string) {
|
||||||
|
try {
|
||||||
|
require.resolve(packageName);
|
||||||
|
return true;
|
||||||
|
} catch (error) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected isCompressedPackage(file) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected isURL(string) {
|
||||||
|
let url;
|
||||||
|
|
||||||
|
try {
|
||||||
|
url = new URL(string);
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return url.protocol === 'http:' || url.protocol === 'https:';
|
||||||
|
}
|
||||||
|
}
|
@ -11,25 +11,22 @@ export interface PluginInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface PluginOptions {
|
export interface PluginOptions {
|
||||||
activate?: boolean;
|
name?: string;
|
||||||
displayName?: string;
|
packageName?: string;
|
||||||
description?: string;
|
|
||||||
version?: string;
|
version?: string;
|
||||||
enabled?: boolean;
|
enabled?: boolean;
|
||||||
install?: (this: Plugin) => void;
|
installed?: boolean;
|
||||||
load?: (this: Plugin) => void;
|
isPreset?: boolean;
|
||||||
plugin?: typeof Plugin;
|
|
||||||
|
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export abstract class Plugin<O = any> implements PluginInterface {
|
export abstract class Plugin implements PluginInterface {
|
||||||
options: any;
|
options: any;
|
||||||
app: Application;
|
app: Application;
|
||||||
model: Model;
|
model: Model;
|
||||||
state: any = {};
|
state: any = {};
|
||||||
|
|
||||||
constructor(app: Application, options?: any) {
|
constructor(app: Application, options?: PluginOptions) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
this.setOptions(options);
|
this.setOptions(options);
|
||||||
}
|
}
|
||||||
|
3
storage/.gitignore
vendored
3
storage/.gitignore
vendored
@ -1 +1,2 @@
|
|||||||
.pm2
|
.pm2
|
||||||
|
plugins
|
||||||
|
Loading…
x
Reference in New Issue
Block a user