chore: add tsdoc (#3788)
* chore: tsdoc * chore: tsdoc * fix: error * chore: code format * chore: code format
This commit is contained in:
parent
b6ae528d80
commit
c4aa8b78c2
@ -45,14 +45,40 @@ interface CanArgs {
|
||||
}
|
||||
|
||||
export class ACL extends EventEmitter {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public availableStrategy = new Map<string, ACLAvailableStrategy>();
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public allowManager = new AllowManager(this);
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public snippetManager = new SnippetManager();
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
roles = new Map<string, ACLRole>();
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
actionAlias = new Map<string, string>();
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
configResources: string[] = [];
|
||||
|
||||
protected availableActions = new Map<string, ACLAvailableAction>();
|
||||
|
||||
protected fixedParamsManager = new FixedParamsManager();
|
||||
|
||||
protected middlewares: Toposort<any>;
|
||||
|
||||
constructor() {
|
||||
@ -114,14 +140,23 @@ export class ACL extends EventEmitter {
|
||||
return this.roles.delete(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
registerConfigResources(names: string[]) {
|
||||
names.forEach((name) => this.registerConfigResource(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
registerConfigResource(name: string) {
|
||||
this.configResources.push(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
isConfigResource(name: string) {
|
||||
return this.configResources.includes(name);
|
||||
}
|
||||
@ -227,6 +262,9 @@ export class ACL extends EventEmitter {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public resolveActionAlias(action: string) {
|
||||
return this.actionAlias.get(action) ? this.actionAlias.get(action) : action;
|
||||
}
|
||||
@ -242,6 +280,9 @@ export class ACL extends EventEmitter {
|
||||
return this.skip(resourceName, actionNames, condition);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
skip(resourceName: string, actionNames: string[] | string, condition?: string | ConditionFunc) {
|
||||
if (!Array.isArray(actionNames)) {
|
||||
actionNames = [actionNames];
|
||||
@ -252,6 +293,9 @@ export class ACL extends EventEmitter {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
async parseJsonTemplate(json: any, ctx: any) {
|
||||
if (json.filter) {
|
||||
ctx.logger?.info?.('parseJsonTemplate.raw', JSON.parse(JSON.stringify(json.filter)));
|
||||
@ -295,6 +339,9 @@ export class ACL extends EventEmitter {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
async getActionParams(ctx) {
|
||||
const roleName = ctx.state.currentRole || 'anonymous';
|
||||
const { resourceName, actionName } = ctx.action;
|
||||
@ -322,6 +369,9 @@ export class ACL extends EventEmitter {
|
||||
this.snippetManager.register(snippet);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
filterParams(ctx, resourceName, params) {
|
||||
if (params?.filter?.createdById) {
|
||||
const collection = ctx.db.getCollection(resourceName);
|
||||
|
@ -11,7 +11,7 @@ export const ADMIN_SETTINGS_PATH = '/admin/settings/';
|
||||
export const SNIPPET_PREFIX = 'pm.';
|
||||
|
||||
export interface PluginSettingOptions {
|
||||
title: string | React.ReactElement;
|
||||
title: any;
|
||||
/**
|
||||
* @default Outlet
|
||||
*/
|
||||
|
@ -1,10 +1,9 @@
|
||||
import { assign, MergeStrategies, prePerfHooksWrap, requireModule } from '@nocobase/utils';
|
||||
import { assign, MergeStrategies, requireModule } from '@nocobase/utils';
|
||||
import compose from 'koa-compose';
|
||||
import _ from 'lodash';
|
||||
import Middleware, { MiddlewareType } from './middleware';
|
||||
import Resource from './resource';
|
||||
import { HandlerType } from './resourcer';
|
||||
import { RecordableHistogram, performance } from 'perf_hooks';
|
||||
|
||||
export type ActionType = string | HandlerType | ActionOptions;
|
||||
|
||||
@ -161,27 +160,38 @@ export interface ActionParams {
|
||||
*/
|
||||
values?: any;
|
||||
/**
|
||||
* 当前资源的主体,对应的表名或 Model 名称
|
||||
* This method is deprecated and should not be used.
|
||||
* Use {@link action.resourceName.split(',')[0]} instead.
|
||||
* @deprecated
|
||||
*/
|
||||
resourceName?: string;
|
||||
/**
|
||||
* 资源标识符
|
||||
* This method is deprecated and should not be used.
|
||||
* Use {@link filterByTk} instead.
|
||||
* @deprecated
|
||||
*/
|
||||
resourceIndex?: string;
|
||||
/**
|
||||
* 资源的从属关系
|
||||
* This method is deprecated and should not be used.
|
||||
* Use {@link action.resourceName.split(',')[1]} instead.
|
||||
* @deprecated
|
||||
*/
|
||||
associatedName?: string;
|
||||
/**
|
||||
* 从属关系的标识符
|
||||
* This method is deprecated and should not be used.
|
||||
* Use {@link action.sourceId} instead.
|
||||
* @deprecated
|
||||
*/
|
||||
associatedIndex?: string;
|
||||
/**
|
||||
* 从属关系的当前实例
|
||||
* This method is deprecated and should not be used.
|
||||
* @deprecated
|
||||
*/
|
||||
associated?: any;
|
||||
/**
|
||||
* 资源提供哪些行为或方法
|
||||
* This method is deprecated and should not be used.
|
||||
* Use {@link action.actionName} instead.
|
||||
* @deprecated
|
||||
*/
|
||||
actionName?: string;
|
||||
/**
|
||||
@ -204,11 +214,23 @@ export class Action {
|
||||
public params: ActionParams = {};
|
||||
|
||||
public actionName: string;
|
||||
|
||||
public resourceName: string;
|
||||
|
||||
/**
|
||||
* This method is deprecated and should not be used.
|
||||
* Use {@link this.sourceId} instead.
|
||||
* @deprecated
|
||||
*/
|
||||
public resourceOf: any;
|
||||
|
||||
public sourceId: any;
|
||||
|
||||
public readonly middlewares: Array<Middleware> = [];
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
constructor(options: ActionOptions) {
|
||||
options = requireModule(options);
|
||||
if (typeof options === 'function') {
|
||||
@ -221,15 +243,22 @@ export class Action {
|
||||
this.mergeParams(params);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
toJSON() {
|
||||
return {
|
||||
actionName: this.actionName,
|
||||
resourceName: this.resourceName,
|
||||
resourceOf: this.resourceOf,
|
||||
resourceOf: this.sourceId,
|
||||
sourceId: this.sourceId,
|
||||
params: this.params,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
clone() {
|
||||
const options = _.cloneDeep(this.options);
|
||||
delete options.middleware;
|
||||
@ -241,6 +270,9 @@ export class Action {
|
||||
return action;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
setContext(context: any) {
|
||||
this.context = context;
|
||||
}
|
||||
@ -266,34 +298,55 @@ export class Action {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
setResource(resource: Resource) {
|
||||
this.resource = resource;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
getResource() {
|
||||
return this.resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
getOptions(): ActionOptions {
|
||||
return this.options;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
setName(name: ActionName) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
getMiddlewareHandlers() {
|
||||
return this.middlewares
|
||||
.filter((middleware) => middleware.canAccess(this.name))
|
||||
.map((middleware) => middleware.getHandler());
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
getHandler() {
|
||||
const handler = requireModule(this.handler || this.resource.resourcer.getRegisteredHandler(this.name));
|
||||
if (typeof handler !== 'function') {
|
||||
@ -303,6 +356,9 @@ export class Action {
|
||||
return handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
getHandlers() {
|
||||
const handlers = [
|
||||
...this.resource.resourcer.getMiddlewares(),
|
||||
@ -315,10 +371,16 @@ export class Action {
|
||||
return handlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
async execute(context: any, next?: any) {
|
||||
return await compose(this.getHandlers())(context, next);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
static toInstanceMap(actions: object, resource?: Resource) {
|
||||
return new Map(
|
||||
Object.entries(actions).map(([key, options]) => {
|
||||
|
@ -150,6 +150,9 @@ export interface ImportOptions {
|
||||
}
|
||||
|
||||
export class Resourcer {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public readonly options: ResourcerOptions;
|
||||
protected resources = new Map<string, Resource>();
|
||||
/**
|
||||
@ -173,6 +176,7 @@ export class Resourcer {
|
||||
* @param {object} [options]
|
||||
* @param {string} [options.directory] 指定配置所在路径
|
||||
* @param {array} [options.extensions = ['js', 'ts', 'json']] 文件后缀
|
||||
*
|
||||
*/
|
||||
public async import(options: ImportOptions): Promise<Map<string, Resource>> {
|
||||
const { extensions = ['js', 'ts', 'json'], directory } = options;
|
||||
@ -206,14 +210,27 @@ export class Resourcer {
|
||||
return this.resources.has(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
removeResource(name) {
|
||||
return this.resources.delete(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is deprecated and should not be used.
|
||||
* Use {@link this.registerActionHandler()} instead.
|
||||
* @deprecated
|
||||
*/
|
||||
registerAction(name: ActionName, handler: HandlerType) {
|
||||
this.registerActionHandler(name, handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is deprecated and should not be used.
|
||||
* Use {@link this.registerActionHandlers()} instead.
|
||||
* @deprecated
|
||||
*/
|
||||
registerActions(handlers: Handlers) {
|
||||
this.registerActionHandlers(handlers);
|
||||
}
|
||||
@ -233,14 +250,23 @@ export class Resourcer {
|
||||
this.actionHandlers.set(name, handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
getRegisteredHandler(name: ActionName) {
|
||||
return this.actionHandlers.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
getRegisteredHandlers() {
|
||||
return this.actionHandlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
getResource(name: string): Resource {
|
||||
if (!this.resources.has(name)) {
|
||||
throw new Error(`${name} resource does not exist`);
|
||||
@ -248,6 +274,9 @@ export class Resourcer {
|
||||
return this.resources.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
getAction(name: string, action: ActionName): Action {
|
||||
// 支持注册局部 action
|
||||
if (this.actionHandlers.has(`${name}:${action}`)) {
|
||||
@ -256,6 +285,9 @@ export class Resourcer {
|
||||
return this.getResource(name).getAction(action);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
getMiddlewares() {
|
||||
return this.middlewares.nodes;
|
||||
}
|
||||
@ -264,6 +296,11 @@ export class Resourcer {
|
||||
this.middlewares.add(middlewares, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is deprecated and should not be used.
|
||||
* Use {@link this.middleware()} instead.
|
||||
* @deprecated
|
||||
*/
|
||||
restApiMiddleware({ prefix, accessors, skipIfDataSourceExists = false }: KoaMiddlewareOptions = {}) {
|
||||
return async (ctx: ResourcerContext, next: () => Promise<any>) => {
|
||||
if (skipIfDataSourceExists) {
|
||||
@ -317,6 +354,7 @@ export class Resourcer {
|
||||
|
||||
ctx.action.setContext(ctx);
|
||||
ctx.action.actionName = params.actionName;
|
||||
ctx.action.sourceId = params.associatedIndex;
|
||||
ctx.action.resourceOf = params.associatedIndex;
|
||||
ctx.action.resourceName = params.associatedName
|
||||
? `${params.associatedName}.${params.resourceName}`
|
||||
@ -349,11 +387,7 @@ export class Resourcer {
|
||||
}
|
||||
|
||||
/**
|
||||
* 实验性 API
|
||||
*
|
||||
* @param options
|
||||
* @param context
|
||||
* @param next
|
||||
* @internal
|
||||
*/
|
||||
async execute(options: ExecuteOptions, context: ResourcerContext = {}, next?: any) {
|
||||
const { resource, action } = options;
|
||||
|
@ -139,19 +139,41 @@ export type MaintainingCommandStatus = {
|
||||
};
|
||||
|
||||
export class Application<StateT = DefaultState, ContextT = DefaultContext> extends Koa implements AsyncEmitter {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
declare middleware: any;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
stopped = false;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
ready = false;
|
||||
declare emitAsync: (event: string | symbol, ...args: any[]) => Promise<boolean>;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public rawOptions: ApplicationOptions;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public activatedCommand: {
|
||||
name: string;
|
||||
} = null;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public running = false;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public perfHistograms = new Map<string, RecordableHistogram>();
|
||||
protected plugins = new Map<string, Plugin>();
|
||||
protected _appSupervisor: AppSupervisor = AppSupervisor.getInstance();
|
||||
protected _started: boolean;
|
||||
protected _logger: SystemLogger;
|
||||
private _authenticated = false;
|
||||
private _maintaining = false;
|
||||
private _maintainingCommandStatus: MaintainingCommandStatus;
|
||||
@ -169,12 +191,18 @@ export class Application<StateT = DefaultState, ContextT = DefaultContext> exten
|
||||
|
||||
protected _loaded: boolean;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
get loaded() {
|
||||
return this._loaded;
|
||||
}
|
||||
|
||||
private _maintainingMessage: string;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
get maintainingMessage() {
|
||||
return this._maintainingMessage;
|
||||
}
|
||||
@ -198,8 +226,6 @@ export class Application<StateT = DefaultState, ContextT = DefaultContext> exten
|
||||
return this.mainDataSource.collectionManager.db;
|
||||
}
|
||||
|
||||
protected _logger: SystemLogger;
|
||||
|
||||
get logger() {
|
||||
return this._logger;
|
||||
}
|
||||
@ -220,6 +246,9 @@ export class Application<StateT = DefaultState, ContextT = DefaultContext> exten
|
||||
return this._cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
set cache(cache: Cache) {
|
||||
this._cache = cache;
|
||||
}
|
||||
@ -254,6 +283,11 @@ export class Application<StateT = DefaultState, ContextT = DefaultContext> exten
|
||||
|
||||
protected _locales: Locale;
|
||||
|
||||
/**
|
||||
* This method is deprecated and should not be used.
|
||||
* Use {@link #localeManager} instead.
|
||||
* @deprecated
|
||||
*/
|
||||
get locales() {
|
||||
return this._locales;
|
||||
}
|
||||
@ -288,10 +322,16 @@ export class Application<StateT = DefaultState, ContextT = DefaultContext> exten
|
||||
return this._dataSourceManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
getMaintaining() {
|
||||
return this._maintainingCommandStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
setMaintaining(_maintainingCommandStatus: MaintainingCommandStatus) {
|
||||
this._maintainingCommandStatus = _maintainingCommandStatus;
|
||||
|
||||
@ -305,6 +345,9 @@ export class Application<StateT = DefaultState, ContextT = DefaultContext> exten
|
||||
this._maintaining = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
setMaintainingMessage(message: string) {
|
||||
this._maintainingMessage = message;
|
||||
|
||||
@ -314,11 +357,18 @@ export class Application<StateT = DefaultState, ContextT = DefaultContext> exten
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is deprecated and should not be used.
|
||||
* Use {@link #this.version.get()} instead.
|
||||
* @deprecated
|
||||
*/
|
||||
getVersion() {
|
||||
return packageJson.version;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is deprecated and should not be used.
|
||||
* Use {@link #this.pm.addPreset()} instead.
|
||||
* @deprecated
|
||||
*/
|
||||
plugin<O = any>(pluginClass: any, options?: O) {
|
||||
@ -335,6 +385,9 @@ export class Application<StateT = DefaultState, ContextT = DefaultContext> exten
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
callback() {
|
||||
const fn = compose(this.middleware.nodes);
|
||||
|
||||
@ -348,14 +401,29 @@ export class Application<StateT = DefaultState, ContextT = DefaultContext> exten
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is deprecated and should not be used.
|
||||
* Use {@link #this.db.collection()} instead.
|
||||
* @deprecated
|
||||
*/
|
||||
collection(options: CollectionOptions) {
|
||||
return this.db.collection(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is deprecated and should not be used.
|
||||
* Use {@link #this.resourcer.define()} instead.
|
||||
* @deprecated
|
||||
*/
|
||||
resource(options: ResourceOptions) {
|
||||
return this.resourcer.define(options);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is deprecated and should not be used.
|
||||
* Use {@link #this.resourcer.registerActions()} instead.
|
||||
* @deprecated
|
||||
*/
|
||||
actions(handlers: any, options?: ActionsOptions) {
|
||||
return this.resourcer.registerActions(handlers);
|
||||
}
|
||||
@ -368,11 +436,9 @@ export class Application<StateT = DefaultState, ContextT = DefaultContext> exten
|
||||
return (this.cli as any)._findCommand(name);
|
||||
}
|
||||
|
||||
async preload() {
|
||||
// load core collections
|
||||
// load plugin commands
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
async reInit() {
|
||||
if (!this._loaded) {
|
||||
return;
|
||||
@ -476,12 +542,19 @@ export class Application<StateT = DefaultState, ContextT = DefaultContext> exten
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is deprecated and should not be used.
|
||||
* Use {@link this.pm.get()} instead.
|
||||
* @deprecated
|
||||
*/
|
||||
getPlugin<P extends Plugin>(name: string | typeof Plugin) {
|
||||
return this.pm.get(name) as P;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is deprecated and should not be used.
|
||||
* Use {@link this.runAsCLI()} instead.
|
||||
* @deprecated
|
||||
*/
|
||||
async parse(argv = process.argv) {
|
||||
return this.runAsCLI(argv);
|
||||
}
|
||||
@ -504,7 +577,7 @@ export class Application<StateT = DefaultState, ContextT = DefaultContext> exten
|
||||
return await this.runAsCLI([command, ...args], { from: 'user', throwError: true });
|
||||
}
|
||||
|
||||
createCli() {
|
||||
protected createCLI() {
|
||||
const command = new AppCommand('nocobase')
|
||||
.usage('[command] [options]')
|
||||
.hook('preAction', async (_, actionCommand) => {
|
||||
@ -544,6 +617,9 @@ export class Application<StateT = DefaultState, ContextT = DefaultContext> exten
|
||||
return command;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
async loadMigrations(options) {
|
||||
const { directory, context, namespace } = options;
|
||||
const migrations = {
|
||||
@ -570,6 +646,9 @@ export class Application<StateT = DefaultState, ContextT = DefaultContext> exten
|
||||
return migrations;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
async loadCoreMigrations() {
|
||||
const migrations = await this.loadMigrations({
|
||||
directory: resolve(__dirname, 'migrations'),
|
||||
@ -600,11 +679,17 @@ export class Application<StateT = DefaultState, ContextT = DefaultContext> exten
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
async loadPluginCommands() {
|
||||
this.log.debug('load plugin commands');
|
||||
await this.pm.loadCommands();
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
async runAsCLI(argv = process.argv, options?: ParseOptions & { throwError?: boolean; reqId?: string }) {
|
||||
if (this.activatedCommand) {
|
||||
return;
|
||||
@ -689,6 +774,9 @@ export class Application<StateT = DefaultState, ContextT = DefaultContext> exten
|
||||
this.stopped = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
async emitStartedEvent(options: StartOptions = {}) {
|
||||
await this.emitAsync('__started', this, {
|
||||
maintainingStatus: lodash.cloneDeep(this._maintainingCommandStatus),
|
||||
@ -700,6 +788,9 @@ export class Application<StateT = DefaultState, ContextT = DefaultContext> exten
|
||||
return this._started;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
async tryReloadOrRestart(options: StartOptions = {}) {
|
||||
if (this._started) {
|
||||
await this.restart(options);
|
||||
@ -898,6 +989,9 @@ export class Application<StateT = DefaultState, ContextT = DefaultContext> exten
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
reInitEvents() {
|
||||
for (const eventName of this.eventNames()) {
|
||||
for (const listener of this.listeners(eventName)) {
|
||||
@ -943,7 +1037,7 @@ export class Application<StateT = DefaultState, ContextT = DefaultContext> exten
|
||||
|
||||
this._cronJobManager = new CronJobManager(this);
|
||||
|
||||
this._cli = this.createCli();
|
||||
this._cli = this.createCLI();
|
||||
this._i18n = createI18n(options);
|
||||
this.context.db = this.db;
|
||||
|
||||
|
@ -3,12 +3,21 @@ import lodash from 'lodash';
|
||||
import { PluginManager } from './plugin-manager';
|
||||
|
||||
export class PluginManagerRepository extends Repository {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
pm: PluginManager;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
setPluginManager(pm: PluginManager) {
|
||||
this.pm = pm;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
async remove(name: string | string[]) {
|
||||
await this.destroy({
|
||||
filter: {
|
||||
@ -17,6 +26,9 @@ export class PluginManagerRepository extends Repository {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
async enable(name: string | string[]) {
|
||||
const pluginNames = lodash.castArray(name);
|
||||
const plugins = pluginNames.map((name) => this.pm.get(name));
|
||||
@ -56,6 +68,9 @@ export class PluginManagerRepository extends Repository {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
async disable(name: string | string[]) {
|
||||
name = lodash.cloneDeep(name);
|
||||
|
||||
|
@ -45,12 +45,39 @@ export interface InstallOptions {
|
||||
export class AddPresetError extends Error {}
|
||||
|
||||
export class PluginManager {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
app: Application;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
collection: Collection;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
pluginInstances = new Map<typeof Plugin, Plugin>();
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
pluginAliases = new Map<string, Plugin>();
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
server: net.Server;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
_repository: PluginManagerRepository;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
constructor(public options: PluginManagerOptions) {
|
||||
this.app = options.app;
|
||||
this.app.db.registerRepositories({
|
||||
@ -76,18 +103,22 @@ export class PluginManager {
|
||||
this.app.resourcer.use(uploadMiddleware);
|
||||
}
|
||||
|
||||
_repository: PluginManagerRepository;
|
||||
|
||||
get repository() {
|
||||
return this.app.db.getRepository('applicationPlugins') as PluginManagerRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
static async getPackageJson(packageName: string) {
|
||||
const file = await fs.promises.realpath(resolve(process.env.NODE_MODULES_PATH, packageName, 'package.json'));
|
||||
const data = await fs.promises.readFile(file, { encoding: 'utf-8' });
|
||||
return JSON.parse(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
static async getPackageName(name: string) {
|
||||
const prefixes = this.getPluginPkgPrefix();
|
||||
for (const prefix of prefixes) {
|
||||
@ -100,12 +131,18 @@ export class PluginManager {
|
||||
throw new Error(`${name} plugin does not exist`);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
static getPluginPkgPrefix() {
|
||||
return (process.env.PLUGIN_PACKAGE_PREFIX || '@nocobase/plugin-,@nocobase/preset-,@nocobase/plugin-pro-').split(
|
||||
',',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
static async findPackage(name: string) {
|
||||
try {
|
||||
const packageName = this.getPackageName(name);
|
||||
@ -130,6 +167,9 @@ export class PluginManager {
|
||||
throw new Error(`No available packages found, ${name} plugin does not exist`);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
static clearCache(packageName: string) {
|
||||
return;
|
||||
const packageNamePath = packageName.replace('/', sep);
|
||||
@ -140,6 +180,9 @@ export class PluginManager {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
static async resolvePlugin(pluginName: string | typeof Plugin, isUpgrade = false, isPkg = false) {
|
||||
if (typeof pluginName === 'string') {
|
||||
const packageName = isPkg ? pluginName : await this.getPackageName(pluginName);
|
||||
@ -296,11 +339,17 @@ export class PluginManager {
|
||||
await instance.afterAdd();
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
async initPlugins() {
|
||||
await this.initPresetPlugins();
|
||||
await this.initOtherPlugins();
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
async loadCommands() {
|
||||
this.app.log.debug('load commands');
|
||||
const items = await this.repository.find({
|
||||
@ -619,6 +668,9 @@ export class PluginManager {
|
||||
await execa('yarn', ['nocobase', 'refresh']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
async loadOne(plugin: Plugin) {
|
||||
this.app.setMaintainingMessage(`loading plugin ${plugin.name}...`);
|
||||
if (plugin.state.loaded || !plugin.enabled) {
|
||||
@ -637,6 +689,9 @@ export class PluginManager {
|
||||
this.app.setMaintainingMessage(`loaded plugin ${plugin.name}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
async addViaCLI(urlOrName: string, options?: PluginData) {
|
||||
if (isURL(urlOrName)) {
|
||||
await this.addByCompressedFileUrl({
|
||||
@ -679,6 +734,9 @@ export class PluginManager {
|
||||
await execa('yarn', ['nocobase', 'postinstall']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
async addByNpm(options: { packageName: string; name?: string; registry: string; authToken?: string }) {
|
||||
let { name = '', registry, packageName, authToken } = options;
|
||||
name = name.trim();
|
||||
@ -693,6 +751,9 @@ export class PluginManager {
|
||||
return this.addByCompressedFileUrl({ name, compressedFileUrl, registry, authToken, type: 'npm' });
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
async addByFile(options: { file: string; registry?: string; authToken?: string; type?: string; name?: string }) {
|
||||
const { file, authToken } = options;
|
||||
|
||||
@ -708,6 +769,9 @@ export class PluginManager {
|
||||
return this.add(name, { packageName }, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
async addByCompressedFileUrl(options: {
|
||||
compressedFileUrl: string;
|
||||
registry?: string;
|
||||
@ -748,6 +812,9 @@ export class PluginManager {
|
||||
await this.app.upgrade();
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
async upgradeByNpm(values: PluginData) {
|
||||
const name = values.name;
|
||||
const plugin = this.get(name);
|
||||
@ -769,6 +836,9 @@ export class PluginManager {
|
||||
return this.upgradeByCompressedFileUrl({ compressedFileUrl, name, version, registry, authToken });
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
async upgradeByCompressedFileUrl(options: PluginData) {
|
||||
const { name, compressedFileUrl, authToken } = options;
|
||||
const data = await this.repository.findOne({ filter: { name } });
|
||||
@ -780,6 +850,9 @@ export class PluginManager {
|
||||
await this.add(name, { version, packageName: data.packageName }, true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
getNameByPackageName(packageName: string) {
|
||||
const prefixes = PluginManager.getPluginPkgPrefix();
|
||||
const prefix = prefixes.find((prefix) => packageName.startsWith(prefix));
|
||||
@ -808,12 +881,18 @@ export class PluginManager {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
async getNpmVersionList(name: string) {
|
||||
const plugin = this.get(name);
|
||||
const npmInfo = await getNpmInfo(plugin.options.packageName, plugin.options.registry, plugin.options.authToken);
|
||||
return Object.keys(npmInfo.versions);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
async loadPresetMigrations() {
|
||||
const migrations = {
|
||||
beforeLoad: [],
|
||||
@ -854,6 +933,9 @@ export class PluginManager {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
async loadOtherMigrations() {
|
||||
const migrations = {
|
||||
beforeLoad: [],
|
||||
@ -897,6 +979,9 @@ export class PluginManager {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
async loadPresetPlugins() {
|
||||
await this.initPresetPlugins();
|
||||
await this.load();
|
||||
@ -931,6 +1016,9 @@ export class PluginManager {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
async initOtherPlugins() {
|
||||
if (this['_initOtherPlugins']) {
|
||||
return;
|
||||
@ -939,6 +1027,9 @@ export class PluginManager {
|
||||
this['_initOtherPlugins'] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
async initPresetPlugins() {
|
||||
if (this['_initPresetPlugins']) {
|
||||
return;
|
||||
|
@ -33,9 +33,22 @@ export interface PluginOptions {
|
||||
export abstract class Plugin<O = any> implements PluginInterface {
|
||||
options: any;
|
||||
app: Application;
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
model: Model;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
state: any = {};
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
private _sourceDir: string;
|
||||
|
||||
constructor(app: Application, options?: any) {
|
||||
this.app = app;
|
||||
this.setOptions(options);
|
||||
@ -80,10 +93,6 @@ export abstract class Plugin<O = any> implements PluginInterface {
|
||||
return this.options.isPreset;
|
||||
}
|
||||
|
||||
setOptions(options: any) {
|
||||
this.options = options || {};
|
||||
}
|
||||
|
||||
getName() {
|
||||
return (this.options as any).name;
|
||||
}
|
||||
@ -92,64 +101,6 @@ export abstract class Plugin<O = any> implements PluginInterface {
|
||||
return this.app.createLogger(options);
|
||||
}
|
||||
|
||||
protected _sourceDir: string;
|
||||
|
||||
protected async getSourceDir() {
|
||||
if (this._sourceDir) {
|
||||
return this._sourceDir;
|
||||
}
|
||||
if (await this.isDev()) {
|
||||
return (this._sourceDir = 'src');
|
||||
}
|
||||
if (basename(__dirname) === 'src') {
|
||||
return (this._sourceDir = 'src');
|
||||
}
|
||||
return (this._sourceDir = this.isPreset ? 'lib' : 'dist');
|
||||
}
|
||||
|
||||
async loadCommands() {
|
||||
const extensions = ['js', 'ts'];
|
||||
const directory = resolve(
|
||||
process.env.NODE_MODULES_PATH,
|
||||
this.options.packageName,
|
||||
await this.getSourceDir(),
|
||||
'server/commands',
|
||||
);
|
||||
const patten = `${directory}/*.{${extensions.join(',')}}`;
|
||||
const files = glob.sync(patten, {
|
||||
ignore: ['**/*.d.ts'],
|
||||
});
|
||||
for (const file of files) {
|
||||
let filename = basename(file);
|
||||
filename = filename.substring(0, filename.lastIndexOf('.')) || filename;
|
||||
const callback = await importModule(file);
|
||||
callback(this.app);
|
||||
}
|
||||
if (files.length) {
|
||||
this.app.log.debug(`load commands [${this.name}]`);
|
||||
}
|
||||
}
|
||||
|
||||
async loadMigrations() {
|
||||
this.app.log.debug(`load plugin migrations [${this.name}]`);
|
||||
if (!this.options.packageName) {
|
||||
return { beforeLoad: [], afterSync: [], afterLoad: [] };
|
||||
}
|
||||
const directory = resolve(
|
||||
process.env.NODE_MODULES_PATH,
|
||||
this.options.packageName,
|
||||
await this.getSourceDir(),
|
||||
'server/migrations',
|
||||
);
|
||||
return await this.app.loadMigrations({
|
||||
directory,
|
||||
namespace: this.options.packageName,
|
||||
context: {
|
||||
plugin: this,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
afterAdd() {}
|
||||
|
||||
beforeLoad() {}
|
||||
@ -172,13 +123,86 @@ export abstract class Plugin<O = any> implements PluginInterface {
|
||||
|
||||
async afterRemove() {}
|
||||
|
||||
async importCollections(collectionsPath: string) {
|
||||
// await this.db.import({
|
||||
// directory: collectionsPath,
|
||||
// from: `plugin:${this.getName()}`,
|
||||
// });
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
async importCollections(collectionsPath: string) {}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
setOptions(options: any) {
|
||||
this.options = options || {};
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
protected async getSourceDir() {
|
||||
if (this._sourceDir) {
|
||||
return this._sourceDir;
|
||||
}
|
||||
if (await this.isDev()) {
|
||||
return (this._sourceDir = 'src');
|
||||
}
|
||||
if (basename(__dirname) === 'src') {
|
||||
return (this._sourceDir = 'src');
|
||||
}
|
||||
return (this._sourceDir = this.isPreset ? 'lib' : 'dist');
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
async loadCommands() {
|
||||
const extensions = ['js', 'ts'];
|
||||
const directory = resolve(
|
||||
process.env.NODE_MODULES_PATH,
|
||||
this.options.packageName,
|
||||
await this.getSourceDir(),
|
||||
'server/commands',
|
||||
);
|
||||
const patten = `${directory}/*.{${extensions.join(',')}}`;
|
||||
const files = glob.sync(patten, {
|
||||
ignore: ['**/*.d.ts'],
|
||||
});
|
||||
for (const file of files) {
|
||||
let filename = basename(file);
|
||||
filename = filename.substring(0, filename.lastIndexOf('.')) || filename;
|
||||
const callback = await importModule(file);
|
||||
callback(this.app);
|
||||
}
|
||||
if (files.length) {
|
||||
this.app.log.debug(`load commands [${this.name}]`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
async loadMigrations() {
|
||||
this.app.log.debug(`load plugin migrations [${this.name}]`);
|
||||
if (!this.options.packageName) {
|
||||
return { beforeLoad: [], afterSync: [], afterLoad: [] };
|
||||
}
|
||||
const directory = resolve(
|
||||
process.env.NODE_MODULES_PATH,
|
||||
this.options.packageName,
|
||||
await this.getSourceDir(),
|
||||
'server/migrations',
|
||||
);
|
||||
return await this.app.loadMigrations({
|
||||
directory,
|
||||
namespace: this.options.packageName,
|
||||
context: {
|
||||
plugin: this,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
async loadCollections() {
|
||||
if (!this.options.packageName) {
|
||||
return;
|
||||
@ -197,6 +221,9 @@ export abstract class Plugin<O = any> implements PluginInterface {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
requiredPlugins() {
|
||||
return [];
|
||||
}
|
||||
@ -205,6 +232,9 @@ export abstract class Plugin<O = any> implements PluginInterface {
|
||||
return this.app.i18n.t(text, { ns: this.options['packageName'], ...(options as any) });
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
protected async isDev() {
|
||||
if (!this.options.packageName) {
|
||||
return false;
|
||||
@ -218,6 +248,9 @@ export abstract class Plugin<O = any> implements PluginInterface {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @experimental
|
||||
*/
|
||||
async toJSON(options: any = {}) {
|
||||
const { locale = 'en-US' } = options;
|
||||
const { name, packageName, packageJson } = this.options;
|
||||
|
@ -2,12 +2,12 @@ import { Plugin } from '@nocobase/client';
|
||||
import { RolesManagement } from './RolesManagement';
|
||||
import { RolesManager } from './roles-manager';
|
||||
|
||||
class ACLPlugin extends Plugin {
|
||||
export class PluginACLClient extends Plugin {
|
||||
rolesManager = new RolesManager();
|
||||
|
||||
async load() {
|
||||
this.app.pluginSettingsManager.add('users-permissions.roles', {
|
||||
title: '{{t("Roles & Permissions")}}',
|
||||
this.pluginSettingsManager.add('users-permissions.roles', {
|
||||
title: this.t('Roles & Permissions'),
|
||||
icon: 'LockOutlined',
|
||||
Component: RolesManagement,
|
||||
aclSnippet: 'pm.acl.roles',
|
||||
@ -16,5 +16,5 @@ class ACLPlugin extends Plugin {
|
||||
}
|
||||
}
|
||||
|
||||
export default ACLPlugin;
|
||||
export { RolesManagerContext } from './RolesManagerProvider';
|
||||
export default PluginACLClient;
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export function useACLTranslation() {
|
||||
return useTranslation(['acl', 'client'], { nsMode: 'fallback' });
|
||||
return useTranslation(['@nocobase/plugin-acl', 'client'], { nsMode: 'fallback' });
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { ISchema, useForm } from '@formily/react';
|
||||
import {
|
||||
CollectionContext,
|
||||
CollectionProvider,
|
||||
CollectionProvider_deprecated,
|
||||
ResourceActionContext,
|
||||
SchemaComponent,
|
||||
@ -8,17 +8,14 @@ import {
|
||||
useActionContext,
|
||||
useFilterFieldOptions,
|
||||
useFilterFieldProps,
|
||||
useCollectionRecord,
|
||||
useRecord,
|
||||
useRequest,
|
||||
useResourceActionContext,
|
||||
} from '@nocobase/client';
|
||||
import React, { useContext, useEffect } from 'react';
|
||||
import { roleCollectionsSchema } from '../schemas/roles';
|
||||
import { RolesManagerContext } from '../RolesManagerProvider';
|
||||
import { ISchema } from '@formily/react';
|
||||
import { roleCollectionsSchema } from '../schemas/roles';
|
||||
import { RolesResourcesActions } from './RolesResourcesActions';
|
||||
import { useForm } from '@formily/react';
|
||||
|
||||
const collection = {
|
||||
name: 'collections',
|
||||
|
@ -2,5 +2,10 @@
|
||||
"The current user has no roles. Please try another account.": "当前用户没有角色,请使用其他账号。",
|
||||
"The user role does not exist. Please try signing in again": "用户角色不存在,请尝试重新登录。",
|
||||
"New role": "新建角色",
|
||||
"Permissions": "权限"
|
||||
"Permissions": "权限",
|
||||
"Roles & Permissions": "角色和权限",
|
||||
"General": "通用",
|
||||
"Menu": "菜单",
|
||||
"Plugin settings": "插件设置",
|
||||
"Data sources": "数据源"
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
export { default } from './server';
|
||||
export * from './middlewares/setCurrentRole';
|
||||
export * from './middlewares/with-acl-meta';
|
||||
export { RoleResourceActionModel } from './model/RoleResourceActionModel';
|
||||
export { RoleResourceModel } from './model/RoleResourceModel';
|
||||
export * from './middlewares/with-acl-meta';
|
||||
export * from './middlewares/setCurrentRole';
|
||||
|
||||
export { default } from './server';
|
||||
|
@ -1,20 +1,20 @@
|
||||
import { Plugin, useCollection_deprecated } from '@nocobase/client';
|
||||
import { bulkEditActionSettings, deprecatedBulkEditActionSettings } from './BulkEditAction.Settings';
|
||||
import { BulkEditFormItemInitializers_deprecated, bulkEditFormItemInitializers } from './BulkEditFormItemInitializers';
|
||||
import { BulkEditActionInitializer } from './BulkEditActionInitializer';
|
||||
import {
|
||||
CreateFormBulkEditBlockInitializers,
|
||||
BulkEditBlockInitializers_deprecated,
|
||||
CreateFormBulkEditBlockInitializers,
|
||||
bulkEditBlockInitializers,
|
||||
} from './BulkEditBlockInitializers';
|
||||
import {
|
||||
BulkEditFormActionInitializers_deprecated,
|
||||
bulkEditFormActionInitializers,
|
||||
} from './BulkEditFormActionInitializers';
|
||||
import { BulkEditActionInitializer } from './BulkEditActionInitializer';
|
||||
import { BulkEditFormItemInitializers_deprecated, bulkEditFormItemInitializers } from './BulkEditFormItemInitializers';
|
||||
import { bulkEditFormItemSettings } from './bulkEditFormItemSettings';
|
||||
import { BulkEditField } from './component/BulkEditField';
|
||||
import { useCustomizeBulkEditActionProps } from './utils';
|
||||
export class BulkEditPlugin extends Plugin {
|
||||
export class PluginActionBulkEditClient extends Plugin {
|
||||
async load() {
|
||||
this.app.addComponents({ BulkEditField });
|
||||
this.app.addScopes({ useCustomizeBulkEditActionProps });
|
||||
@ -61,4 +61,4 @@ export class BulkEditPlugin extends Plugin {
|
||||
}
|
||||
}
|
||||
|
||||
export default BulkEditPlugin;
|
||||
export default PluginActionBulkEditClient;
|
||||
|
@ -1,10 +1,7 @@
|
||||
import { i18n } from '@nocobase/client';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export const NAMESPACE = 'bulk-edit';
|
||||
|
||||
// i18n.addResources('zh-CN', NAMESPACE, zhCN);
|
||||
// i18n.addResources('en-US', NAMESPACE, enUS);
|
||||
export const NAMESPACE = '@nocobase/plugin-bulk-edit';
|
||||
|
||||
export function lang(key: string) {
|
||||
return i18n.t(key, { ns: NAMESPACE });
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { Plugin, useCollection_deprecated } from '@nocobase/client';
|
||||
import { bulkUpdateActionSettings, deprecatedBulkUpdateActionSettings } from './BulkUpdateAction.Settings';
|
||||
import { BulkUpdateActionInitializer } from './BulkUpdateActionInitializer';
|
||||
import { CustomizeActionInitializer } from './CustomizeActionInitializer';
|
||||
import { useCustomizeBulkUpdateActionProps } from './utils';
|
||||
import { BulkUpdateActionInitializer } from './BulkUpdateActionInitializer';
|
||||
export class PluginBulkUpdateClient extends Plugin {
|
||||
export class PluginActionBulkUpdateClient extends Plugin {
|
||||
async load() {
|
||||
this.app.addComponents({ CustomizeActionInitializer });
|
||||
this.app.addScopes({ useCustomizeBulkUpdateActionProps });
|
||||
@ -31,4 +31,4 @@ export class PluginBulkUpdateClient extends Plugin {
|
||||
}
|
||||
}
|
||||
|
||||
export default PluginBulkUpdateClient;
|
||||
export default PluginActionBulkUpdateClient;
|
||||
|
@ -3,9 +3,6 @@ import { useTranslation } from 'react-i18next';
|
||||
|
||||
export const NAMESPACE = 'bulk-update';
|
||||
|
||||
// i18n.addResources('zh-CN', NAMESPACE, zhCN);
|
||||
// i18n.addResources('en-US', NAMESPACE, enUS);
|
||||
|
||||
export function lang(key: string) {
|
||||
return i18n.t(key, { ns: NAMESPACE });
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import { deprecatedDuplicateActionSettings, duplicateActionSettings } from './Du
|
||||
import { DuplicateActionInitializer } from './DuplicateActionInitializer';
|
||||
import { DuplicatePluginProvider } from './DuplicatePluginProvider';
|
||||
|
||||
export class PluginDuplicateClient extends Plugin {
|
||||
export class PluginActionDuplicateClient extends Plugin {
|
||||
async load() {
|
||||
this.app.use(DuplicatePluginProvider);
|
||||
this.app.addComponents({
|
||||
@ -64,5 +64,5 @@ export class PluginDuplicateClient extends Plugin {
|
||||
}
|
||||
}
|
||||
|
||||
export default PluginDuplicateClient;
|
||||
export default PluginActionDuplicateClient;
|
||||
export * from './DuplicateAction';
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Plugin } from '@nocobase/client';
|
||||
import { deprecatedPrintActionSettings, printActionSettings } from './PrintAction.Settings';
|
||||
import { PrintActionPluginProvider } from './PrintActionPluginProvider';
|
||||
export class PrintPlugin extends Plugin {
|
||||
export class PluginActionPrintClient extends Plugin {
|
||||
async load() {
|
||||
this.app.use(PrintActionPluginProvider);
|
||||
this.app.schemaSettingsManager.add(deprecatedPrintActionSettings);
|
||||
@ -23,4 +23,4 @@ export class PrintPlugin extends Plugin {
|
||||
}
|
||||
}
|
||||
|
||||
export default PrintPlugin;
|
||||
export default PluginActionPrintClient;
|
||||
|
@ -37,7 +37,7 @@ const SCDocumentation = () => {
|
||||
);
|
||||
};
|
||||
|
||||
export class APIDocumentationPlugin extends Plugin {
|
||||
export class PluginAPIDocClient extends Plugin {
|
||||
async load() {
|
||||
this.app.pluginSettingsManager.add(NAMESPACE, {
|
||||
title: `{{t("API documentation", { ns: "${NAMESPACE}" })}}`,
|
||||
@ -53,4 +53,4 @@ export class APIDocumentationPlugin extends Plugin {
|
||||
}
|
||||
}
|
||||
|
||||
export default APIDocumentationPlugin;
|
||||
export default PluginAPIDocClient;
|
||||
|
@ -2,7 +2,7 @@ import { Context } from '@nocobase/actions';
|
||||
import { Plugin } from '@nocobase/server';
|
||||
import { SwaggerManager } from './swagger';
|
||||
|
||||
export default class APIDoc extends Plugin {
|
||||
export class PluginAPIDocServer extends Plugin {
|
||||
swagger: SwaggerManager;
|
||||
constructor(app, options) {
|
||||
super(app, options);
|
||||
@ -10,7 +10,7 @@ export default class APIDoc extends Plugin {
|
||||
}
|
||||
async beforeLoad() {}
|
||||
async load() {
|
||||
this.app.resource({
|
||||
this.app.resourcer.define({
|
||||
name: 'swagger',
|
||||
type: 'single',
|
||||
actions: {
|
||||
@ -46,3 +46,5 @@ export default class APIDoc extends Plugin {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default PluginAPIDocServer;
|
||||
|
@ -2,15 +2,15 @@ import { Plugin } from '@nocobase/client';
|
||||
import { NAMESPACE } from '../constants';
|
||||
import { Configuration } from './Configuration';
|
||||
|
||||
class APIKeysPlugin extends Plugin {
|
||||
export class PluginAPIKeysClient extends Plugin {
|
||||
async load() {
|
||||
this.app.pluginSettingsManager.add(NAMESPACE, {
|
||||
this.pluginSettingsManager.add(NAMESPACE, {
|
||||
icon: 'KeyOutlined',
|
||||
title: '{{t("API keys", {"ns": "api-keys"})}}',
|
||||
title: this.t('API keys'),
|
||||
Component: Configuration,
|
||||
aclSnippet: 'pm.api-keys.configuration',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default APIKeysPlugin;
|
||||
export default PluginAPIKeysClient;
|
||||
|
@ -1 +1 @@
|
||||
export const NAMESPACE = 'api-keys';
|
||||
export const NAMESPACE = '@nocobase/plugin-api-keys';
|
||||
|
@ -1,24 +1,11 @@
|
||||
import { Plugin } from '@nocobase/server';
|
||||
import { resolve } from 'path';
|
||||
import { NAMESPACE } from '../constants';
|
||||
import { create, destroy } from './actions/api-keys';
|
||||
import { enUS, zhCN } from './locale';
|
||||
|
||||
export interface ApiKeysPluginConfig {
|
||||
name?: string;
|
||||
}
|
||||
|
||||
export default class ApiKeysPlugin extends Plugin<ApiKeysPluginConfig> {
|
||||
export class PluginAPIKeysServer extends Plugin {
|
||||
resourceName = 'apiKeys';
|
||||
constructor(app, options) {
|
||||
super(app, options);
|
||||
}
|
||||
|
||||
async beforeLoad() {
|
||||
this.app.i18n.addResources('zh-CN', NAMESPACE, zhCN);
|
||||
this.app.i18n.addResources('en-US', NAMESPACE, enUS);
|
||||
|
||||
await this.app.resourcer.define({
|
||||
this.app.resourcer.define({
|
||||
name: this.resourceName,
|
||||
actions: {
|
||||
create,
|
||||
@ -34,11 +21,9 @@ export default class ApiKeysPlugin extends Plugin<ApiKeysPluginConfig> {
|
||||
}
|
||||
|
||||
async load() {
|
||||
await this.importCollections(resolve(__dirname, '../collections'));
|
||||
|
||||
this.app.resourcer.use(async (ctx, next) => {
|
||||
const { resourceName, actionName } = ctx.action.params;
|
||||
if (resourceName == this.resourceName && ['list', 'destroy'].includes(actionName)) {
|
||||
const { resourceName, actionName } = ctx.action;
|
||||
if (resourceName === this.resourceName && ['list', 'destroy'].includes(actionName)) {
|
||||
ctx.action.mergeParams({
|
||||
filter: {
|
||||
createdById: ctx.auth.user.id,
|
||||
@ -49,3 +34,5 @@ export default class ApiKeysPlugin extends Plugin<ApiKeysPluginConfig> {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default PluginAPIKeysServer;
|
||||
|
@ -1,13 +1,13 @@
|
||||
import { Plugin } from '@nocobase/client';
|
||||
import { AuthProvider } from './AuthProvider';
|
||||
import { NAMESPACE } from './locale';
|
||||
import { Authenticator } from './settings/Authenticator';
|
||||
import { AuthLayout, SignInPage, SignUpPage } from './pages';
|
||||
import { ComponentType } from 'react';
|
||||
import { Registry } from '@nocobase/utils/client';
|
||||
import { ComponentType } from 'react';
|
||||
import { presetAuthType } from '../preset';
|
||||
import { SignInForm, SignUpForm, Options } from './basic';
|
||||
import { AuthProvider } from './AuthProvider';
|
||||
import { Authenticator as AuthenticatorType } from './authenticator';
|
||||
import { Options, SignInForm, SignUpForm } from './basic';
|
||||
import { NAMESPACE } from './locale';
|
||||
import { AuthLayout, SignInPage, SignUpPage } from './pages';
|
||||
import { Authenticator } from './settings/Authenticator';
|
||||
|
||||
export type AuthOptions = {
|
||||
components: Partial<{
|
||||
@ -18,7 +18,7 @@ export type AuthOptions = {
|
||||
}>;
|
||||
};
|
||||
|
||||
export class AuthPlugin extends Plugin {
|
||||
export class PluginAuthClient extends Plugin {
|
||||
authTypes = new Registry<AuthOptions>();
|
||||
|
||||
registerType(authType: string, options: AuthOptions) {
|
||||
@ -63,7 +63,8 @@ export class AuthPlugin extends Plugin {
|
||||
}
|
||||
}
|
||||
|
||||
export default AuthPlugin;
|
||||
export { useSignIn } from './basic';
|
||||
export { useAuthenticator, AuthenticatorsContext } from './authenticator';
|
||||
export { AuthenticatorsContext, useAuthenticator } from './authenticator';
|
||||
export type { Authenticator } from './authenticator';
|
||||
export { useSignIn } from './basic';
|
||||
|
||||
export default PluginAuthClient;
|
||||
|
@ -1,17 +1,17 @@
|
||||
import { Cache } from '@nocobase/cache';
|
||||
import { Model } from '@nocobase/database';
|
||||
import { InstallOptions, Plugin } from '@nocobase/server';
|
||||
import { resolve } from 'path';
|
||||
import { namespace, presetAuthenticator, presetAuthType } from '../preset';
|
||||
import { namespace, presetAuthType, presetAuthenticator } from '../preset';
|
||||
import authActions from './actions/auth';
|
||||
import authenticatorsActions from './actions/authenticators';
|
||||
import { BasicAuth } from './basic-auth';
|
||||
import { enUS, zhCN } from './locale';
|
||||
import { AuthModel } from './model/authenticator';
|
||||
import { TokenBlacklistService } from './token-blacklist';
|
||||
import { Cache } from '@nocobase/cache';
|
||||
import { Storer } from './storer';
|
||||
import { TokenBlacklistService } from './token-blacklist';
|
||||
|
||||
export class AuthPlugin extends Plugin {
|
||||
export class PluginAuthServer extends Plugin {
|
||||
cache: Cache;
|
||||
|
||||
afterAdd() {}
|
||||
@ -105,4 +105,4 @@ export class AuthPlugin extends Plugin {
|
||||
async remove() {}
|
||||
}
|
||||
|
||||
export default AuthPlugin;
|
||||
export default PluginAuthServer;
|
||||
|
@ -2,11 +2,12 @@ import { Plugin } from '@nocobase/client';
|
||||
import { BackupAndRestoreList } from './Configuration';
|
||||
import { DuplicatorProvider } from './DuplicatorProvider';
|
||||
import { NAMESPACE } from './locale';
|
||||
export class DuplicatorPlugin extends Plugin {
|
||||
|
||||
export class PluginBackupRestoreClient extends Plugin {
|
||||
async load() {
|
||||
this.app.use(DuplicatorProvider);
|
||||
this.app.pluginSettingsManager.add(NAMESPACE, {
|
||||
title: `{{t("Backup & Restore", { ns: "${NAMESPACE}" })}}`,
|
||||
title: this.t('Backup & Restore'),
|
||||
icon: 'CloudServerOutlined',
|
||||
Component: BackupAndRestoreList,
|
||||
aclSnippet: 'pm.backup.restore',
|
||||
@ -14,4 +15,4 @@ export class DuplicatorPlugin extends Plugin {
|
||||
}
|
||||
}
|
||||
|
||||
export default DuplicatorPlugin;
|
||||
export default PluginBackupRestoreClient;
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Plugin } from '@nocobase/server';
|
||||
import backupFilesResourcer from './resourcers/backup-files';
|
||||
|
||||
export default class Duplicator extends Plugin {
|
||||
export default class PluginBackupRestoreServer extends Plugin {
|
||||
beforeLoad() {
|
||||
this.app.acl.registerSnippet({
|
||||
name: `pm.${this.name}`,
|
||||
|
Loading…
Reference in New Issue
Block a user