mirror of
https://gitee.com/nocobase/nocobase.git
synced 2025-05-07 06:29:25 +08:00
* fix: add license code * fix: bug * fix: bug * fix: upgrade * fix: improve * chore: add copyright information to the file header * fix: d.ts bug * fix: bug * fix: e2e bug * fix: merge main --------- Co-authored-by: chenos <chenlinxh@gmail.com>
126 lines
3.0 KiB
TypeScript
126 lines
3.0 KiB
TypeScript
/**
|
|
* This file is part of the NocoBase (R) project.
|
|
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
* Authors: NocoBase Team.
|
|
*
|
|
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
*/
|
|
|
|
import _ from 'lodash';
|
|
import Action, { ActionName, ActionType } from './action';
|
|
import Middleware, { MiddlewareType } from './middleware';
|
|
import { HandlerType, ResourceManager } from './resourcer';
|
|
|
|
export type ResourceType = 'single' | 'hasOne' | 'hasMany' | 'belongsTo' | 'belongsToMany';
|
|
|
|
export interface ResourceOptions {
|
|
/**
|
|
* 资源名称
|
|
*/
|
|
name: string;
|
|
|
|
/**
|
|
* 资源类型,默认为 single
|
|
*/
|
|
type?: ResourceType;
|
|
|
|
/**
|
|
* 资源的行为
|
|
*/
|
|
actions?: {
|
|
[key: string]: ActionType;
|
|
};
|
|
|
|
/**
|
|
* actions 白名单,默认有 list、get、create、update、delete
|
|
*/
|
|
only?: Array<ActionName>;
|
|
|
|
/**
|
|
* actions 黑名单,默认有 list、get、create、update、delete
|
|
*/
|
|
except?: Array<ActionName>;
|
|
|
|
/**
|
|
* 中间件
|
|
*/
|
|
middleware?: MiddlewareType;
|
|
|
|
/**
|
|
* 中间件
|
|
*/
|
|
middlewares?: MiddlewareType;
|
|
|
|
/**
|
|
* 额外的一些参数
|
|
*/
|
|
[key: string]: any;
|
|
}
|
|
|
|
export class Resource {
|
|
public readonly resourcer: ResourceManager;
|
|
|
|
public readonly middlewares: Middleware[];
|
|
|
|
public readonly actions = new Map<ActionName, Action>();
|
|
|
|
public readonly options: ResourceOptions;
|
|
|
|
public readonly except: Array<ActionName>;
|
|
|
|
constructor(options: ResourceOptions, resourcer: ResourceManager) {
|
|
const { middleware, middlewares, actions = {}, only = [], except = [] } = options;
|
|
this.options = options;
|
|
this.resourcer = resourcer;
|
|
this.middlewares = Middleware.toInstanceArray(middleware || middlewares);
|
|
let excludes = [];
|
|
for (const [name, handler] of resourcer.getRegisteredHandlers()) {
|
|
if (!actions[name as string]) {
|
|
actions[name as string] = handler;
|
|
}
|
|
}
|
|
if (except.length > 0) {
|
|
excludes = except;
|
|
} else if (only.length > 0) {
|
|
excludes = Object.keys(actions).filter((name) => !only.includes(name));
|
|
}
|
|
this.except = excludes;
|
|
this.actions = Action.toInstanceMap(_.omit(actions, excludes), this);
|
|
}
|
|
|
|
getName() {
|
|
return this.options.name;
|
|
}
|
|
|
|
getExcept() {
|
|
return this.except;
|
|
}
|
|
|
|
addAction(name: ActionName, handler: HandlerType) {
|
|
if (this.except.includes(name)) {
|
|
throw new Error(`${name} action is not allowed`);
|
|
}
|
|
if (this.actions.has(name)) {
|
|
throw new Error(`${name} action already exists`);
|
|
}
|
|
const action = new Action(handler);
|
|
action.setName(name);
|
|
action.setResource(this);
|
|
action.middlewares.unshift(...this.middlewares);
|
|
this.actions.set(name, action);
|
|
}
|
|
|
|
getAction(action: ActionName) {
|
|
if (this.except.includes(action)) {
|
|
throw new Error(`${action} action is not allowed`);
|
|
}
|
|
if (!this.actions.has(action)) {
|
|
throw new Error(`${action} action does not exist`);
|
|
}
|
|
return this.actions.get(action);
|
|
}
|
|
}
|
|
|
|
export default Resource;
|