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