@nocobase/resourcer 0.5.0-alpha.32 → 0.5.0-alpha.36

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/action.d.ts CHANGED
@@ -47,9 +47,9 @@ export interface ActionParams {
47
47
  perPage?: number;
48
48
  values?: any;
49
49
  resourceName?: string;
50
- resourceKey?: string;
50
+ resourceIndex?: string;
51
51
  associatedName?: string;
52
- associatedKey?: string;
52
+ associatedIndex?: string;
53
53
  associated?: any;
54
54
  actionName?: string;
55
55
  [key: string]: any;
@@ -1 +1 @@
1
- {"version":3,"sources":["action.ts"],"names":[],"mappings":"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","file":"action.d.ts","sourcesContent":["import _ from 'lodash';\nimport compose from 'koa-compose';\nimport Resource from './resource';\nimport { requireModule } from './utils';\nimport { HandlerType } from './resourcer';\nimport Middleware, { MiddlewareType } from './middleware';\nimport { ActionParameterTypes, ActionParameter, UnknownParameter, PageParameter } from './parameter';\n\nexport type ActionType = string | HandlerType | ActionOptions;\n\nexport type DefaultActionType = 'list' | 'create' | 'get' | 'update' | 'destroy' | 'set' | 'add' | 'remove';\n\nexport type ActionName = DefaultActionType | Omit<String, DefaultActionType>;\n\nexport interface ActionContext {\n action?: Action;\n [key: string]: any;\n}\n\nexport type FieldsOptions = string[] | {\n only?: string[];\n appends?: string[];\n} | {\n except?: string[];\n appends?: string[];\n};\n\nexport type FieldsOptionsFn = (ctx: ActionContext) => FieldsOptions | Promise<FieldsOptions>;\n\n/**\n * 过滤参数\n * \n * TODO:细节待定\n */\nexport interface FilterOptions {\n [key: string]: any;\n}\n\nexport type FilterOptionsFn = (ctx: ActionContext) => FilterOptions | Promise<FieldsOptions>;\n\nexport type ParamsCallback = (ctx: ActionContext) => ActionParams | Promise<ActionParams>;\n\nexport interface ActionOptions {\n /**\n * 默认数据\n */\n values?: any;\n /**\n * 字段\n * \n * 示例一:\n * ['col1', 'col2', 'relation.col1'];\n * \n * 示例二:\n * {\n * only: ['col1'],\n * }\n * \n * 示例三:\n * {\n * except: ['col1'],\n * }\n */\n fields?: FieldsOptions;\n /**\n * 过滤\n */\n filter?: FilterOptions;\n /**\n * 排序\n */\n sort?: string | string[];\n /**\n * 当前页码\n */\n page?: number;\n /**\n * 每页显示数量\n */\n perPage?: number;\n /**\n * 最大每页显示数量\n */\n maxPerPage?: number;\n /**\n * 中间件\n */\n middleware?: MiddlewareType;\n /**\n * 中间件\n * \n * 与 middleware 用法相同\n */\n middlewares?: MiddlewareType;\n /**\n * 当前 Action 待执行的方法\n * \n * 支持 Function 和 require 调用\n */\n handler?: HandlerType;\n /**\n * 其他扩展配置\n */\n [key: string]: any;\n}\n\n/**\n * action params 与 action options 略有不同\n * - options 的参数更灵活,主要用于开发配置\n * - params 是开发配置参数 + 客户端参数的结合体\n */\nexport interface ActionParams {\n /**\n * 输出哪些字段\n * \n * 与 ActionOptions 的不同,这里的 fields 是 object,提供 only,except,appends 三种情况\n */\n fields?: {\n only?: string[];\n except?: string[];\n appends?: string[];\n };\n /**\n * 过滤\n */\n filter?: FilterOptions;\n /**\n * 排序\n * \n * 与 ActionOptions 的不同,这里的 sort 只有一种 array 类型\n */\n sort?: string[];\n /**\n * 当前页码\n */\n page?: number;\n /**\n * 每页显示数量\n */\n perPage?: number;\n /**\n * 数据,默认为 options.defaultValues + request.body\n */\n values?: any;\n /**\n * 当前资源的主体,对应的表名或 Model 名称\n */\n resourceName?: string;\n /**\n * 资源标识符\n */\n resourceKey?: string;\n /**\n * 资源的从属关系\n */\n associatedName?: string;\n /**\n * 从属关系的标识符\n */\n associatedKey?: string;\n /**\n * 从属关系的当前实例\n */\n associated?: any;\n /**\n * 资源提供哪些行为或方法\n */\n actionName?: string;\n /**\n * 其他扩展配置\n */\n [key: string]: any;\n}\n\nexport class Action {\n\n protected handler: any;\n\n protected resource: Resource;\n\n protected name: ActionName;\n\n protected options: ActionOptions;\n\n protected parameters: Map<string, ActionParameter | UnknownParameter> = new Map();\n\n protected context: ActionContext = {};\n\n public readonly middlewares: Array<Middleware> = [];\n\n constructor(options: ActionOptions) {\n options = requireModule(options);\n if (typeof options === 'function') {\n options = { handler: options };\n }\n const {\n middleware,\n middlewares = [],\n handler,\n ...params\n } = options;\n this.middlewares = Middleware.toInstanceArray(middleware || middlewares);\n this.handler = handler;\n this.options = options;\n this.mergeParams(params, {});\n }\n\n get params(): ActionParams {\n const result = this.parameters.get('_').get();\n for (const paramType of this.parameters.values()) {\n Object.assign(result, paramType.get());\n }\n return result;\n }\n\n clone() {\n const options = _.cloneDeep(this.options);\n delete options.middleware;\n delete options.middlewares;\n const action = new Action(options);\n action.setName(this.name);\n action.setResource(this.resource);\n action.middlewares.push(...this.middlewares);\n return action;\n }\n\n setContext(context: any) {\n this.context = context;\n }\n\n async mergeParams(params, strategies = {}) {\n const typeKeys = new Set<string>();\n Object.keys(params).forEach(key => {\n for (const typeKey of ActionParameterTypes.getAllKeys()) {\n if (typeof params[key] !== 'undefined' && key in ActionParameterTypes.get(typeKey).picking) {\n typeKeys.add(typeKey);\n }\n }\n });\n let type;\n for (const key of typeKeys) {\n const strategy = strategies[key];\n type = this.parameters.get(key);\n if (!type) {\n const Type = ActionParameterTypes.get(key);\n if (!Type) {\n throw new Error(`parameter type ${key} is unregistered`);\n }\n // @ts-ignore\n type = new Type(params);\n this.parameters.set(key, type);\n }\n type.merge(params, strategy);\n }\n type = this.parameters.get('_');\n if (!type) {\n type = new UnknownParameter(params);\n this.parameters.set('_', type);\n }\n type.merge(params, strategies['_']);\n }\n\n setResource(resource: Resource) {\n this.resource = resource;\n return this;\n }\n\n getResource() {\n return this.resource;\n }\n\n getOptions(): ActionOptions {\n return this.options;\n }\n\n setName(name: ActionName) {\n this.name = name;\n return this;\n }\n\n getName() {\n return this.name;\n }\n\n getMiddlewareHandlers() {\n return this.middlewares\n .filter(middleware => middleware.canAccess(this.name))\n .map(middleware => middleware.getHandler());\n }\n\n getHandler() {\n const handler = requireModule(this.handler || this.resource.resourcer.getRegisteredHandler(this.name));\n if (typeof handler !== 'function') {\n throw new Error('Handler must be a function!');\n }\n return handler;\n }\n\n getHandlers() {\n return [...this.resource.resourcer.getMiddlewares(), ...this.getMiddlewareHandlers(), this.getHandler()].filter(Boolean);\n }\n\n async execute(context: any, next?: any) {\n return await compose(this.getHandlers())(context, next);\n }\n\n static toInstanceMap(actions: object, resource?: Resource) {\n return new Map(Object.entries(actions).map(([key, options]) => {\n let action: Action;\n if (options instanceof Action) {\n action = options;\n } else {\n action = new Action(options);\n }\n action.setName(key);\n action.setResource(resource);\n resource && action.middlewares.unshift(...resource.middlewares);\n return [key, action];\n }));\n }\n}\n\nexport default Action;\n"]}
1
+ {"version":3,"sources":["action.ts"],"names":[],"mappings":"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","file":"action.d.ts","sourcesContent":["import _ from 'lodash';\nimport compose from 'koa-compose';\nimport Resource from './resource';\nimport { requireModule } from './utils';\nimport { HandlerType } from './resourcer';\nimport Middleware, { MiddlewareType } from './middleware';\nimport { ActionParameterTypes, ActionParameter, UnknownParameter, PageParameter } from './parameter';\n\nexport type ActionType = string | HandlerType | ActionOptions;\n\nexport type DefaultActionType = 'list' | 'create' | 'get' | 'update' | 'destroy' | 'set' | 'add' | 'remove';\n\nexport type ActionName = DefaultActionType | Omit<String, DefaultActionType>;\n\nexport interface ActionContext {\n action?: Action;\n [key: string]: any;\n}\n\nexport type FieldsOptions = string[] | {\n only?: string[];\n appends?: string[];\n} | {\n except?: string[];\n appends?: string[];\n};\n\nexport type FieldsOptionsFn = (ctx: ActionContext) => FieldsOptions | Promise<FieldsOptions>;\n\n/**\n * 过滤参数\n * \n * TODO:细节待定\n */\nexport interface FilterOptions {\n [key: string]: any;\n}\n\nexport type FilterOptionsFn = (ctx: ActionContext) => FilterOptions | Promise<FieldsOptions>;\n\nexport type ParamsCallback = (ctx: ActionContext) => ActionParams | Promise<ActionParams>;\n\nexport interface ActionOptions {\n /**\n * 默认数据\n */\n values?: any;\n /**\n * 字段\n * \n * 示例一:\n * ['col1', 'col2', 'relation.col1'];\n * \n * 示例二:\n * {\n * only: ['col1'],\n * }\n * \n * 示例三:\n * {\n * except: ['col1'],\n * }\n */\n fields?: FieldsOptions;\n /**\n * 过滤\n */\n filter?: FilterOptions;\n /**\n * 排序\n */\n sort?: string | string[];\n /**\n * 当前页码\n */\n page?: number;\n /**\n * 每页显示数量\n */\n perPage?: number;\n /**\n * 最大每页显示数量\n */\n maxPerPage?: number;\n /**\n * 中间件\n */\n middleware?: MiddlewareType;\n /**\n * 中间件\n * \n * 与 middleware 用法相同\n */\n middlewares?: MiddlewareType;\n /**\n * 当前 Action 待执行的方法\n * \n * 支持 Function 和 require 调用\n */\n handler?: HandlerType;\n /**\n * 其他扩展配置\n */\n [key: string]: any;\n}\n\n/**\n * action params 与 action options 略有不同\n * - options 的参数更灵活,主要用于开发配置\n * - params 是开发配置参数 + 客户端参数的结合体\n */\nexport interface ActionParams {\n /**\n * 输出哪些字段\n * \n * 与 ActionOptions 的不同,这里的 fields 是 object,提供 only,except,appends 三种情况\n */\n fields?: {\n only?: string[];\n except?: string[];\n appends?: string[];\n };\n /**\n * 过滤\n */\n filter?: FilterOptions;\n /**\n * 排序\n * \n * 与 ActionOptions 的不同,这里的 sort 只有一种 array 类型\n */\n sort?: string[];\n /**\n * 当前页码\n */\n page?: number;\n /**\n * 每页显示数量\n */\n perPage?: number;\n /**\n * 数据,默认为 options.defaultValues + request.body\n */\n values?: any;\n /**\n * 当前资源的主体,对应的表名或 Model 名称\n */\n resourceName?: string;\n /**\n * 资源标识符\n */\n resourceIndex?: string;\n /**\n * 资源的从属关系\n */\n associatedName?: string;\n /**\n * 从属关系的标识符\n */\n associatedIndex?: string;\n /**\n * 从属关系的当前实例\n */\n associated?: any;\n /**\n * 资源提供哪些行为或方法\n */\n actionName?: string;\n /**\n * 其他扩展配置\n */\n [key: string]: any;\n}\n\nexport class Action {\n\n protected handler: any;\n\n protected resource: Resource;\n\n protected name: ActionName;\n\n protected options: ActionOptions;\n\n protected parameters: Map<string, ActionParameter | UnknownParameter> = new Map();\n\n protected context: ActionContext = {};\n\n public readonly middlewares: Array<Middleware> = [];\n\n constructor(options: ActionOptions) {\n options = requireModule(options);\n if (typeof options === 'function') {\n options = { handler: options };\n }\n const {\n middleware,\n middlewares = [],\n handler,\n ...params\n } = options;\n this.middlewares = Middleware.toInstanceArray(middleware || middlewares);\n this.handler = handler;\n this.options = options;\n this.mergeParams(params, {});\n }\n\n get params(): ActionParams {\n const result = this.parameters.get('_').get();\n for (const paramType of this.parameters.values()) {\n Object.assign(result, paramType.get());\n }\n return result;\n }\n\n clone() {\n const options = _.cloneDeep(this.options);\n delete options.middleware;\n delete options.middlewares;\n const action = new Action(options);\n action.setName(this.name);\n action.setResource(this.resource);\n action.middlewares.push(...this.middlewares);\n return action;\n }\n\n setContext(context: any) {\n this.context = context;\n }\n\n async mergeParams(params, strategies = {}) {\n const typeKeys = new Set<string>();\n Object.keys(params).forEach(key => {\n for (const typeKey of ActionParameterTypes.getAllKeys()) {\n if (typeof params[key] !== 'undefined' && key in ActionParameterTypes.get(typeKey).picking) {\n typeKeys.add(typeKey);\n }\n }\n });\n let type;\n for (const key of typeKeys) {\n const strategy = strategies[key];\n type = this.parameters.get(key);\n if (!type) {\n const Type = ActionParameterTypes.get(key);\n if (!Type) {\n throw new Error(`parameter type ${key} is unregistered`);\n }\n // @ts-ignore\n type = new Type(params);\n this.parameters.set(key, type);\n }\n type.merge(params, strategy);\n }\n type = this.parameters.get('_');\n if (!type) {\n type = new UnknownParameter(params);\n this.parameters.set('_', type);\n }\n type.merge(params, strategies['_']);\n }\n\n setResource(resource: Resource) {\n this.resource = resource;\n return this;\n }\n\n getResource() {\n return this.resource;\n }\n\n getOptions(): ActionOptions {\n return this.options;\n }\n\n setName(name: ActionName) {\n this.name = name;\n return this;\n }\n\n getName() {\n return this.name;\n }\n\n getMiddlewareHandlers() {\n return this.middlewares\n .filter(middleware => middleware.canAccess(this.name))\n .map(middleware => middleware.getHandler());\n }\n\n getHandler() {\n const handler = requireModule(this.handler || this.resource.resourcer.getRegisteredHandler(this.name));\n if (typeof handler !== 'function') {\n throw new Error('Handler must be a function!');\n }\n return handler;\n }\n\n getHandlers() {\n return [...this.resource.resourcer.getMiddlewares(), ...this.getMiddlewareHandlers(), this.getHandler()].filter(Boolean);\n }\n\n async execute(context: any, next?: any) {\n return await compose(this.getHandlers())(context, next);\n }\n\n static toInstanceMap(actions: object, resource?: Resource) {\n return new Map(Object.entries(actions).map(([key, options]) => {\n let action: Action;\n if (options instanceof Action) {\n action = options;\n } else {\n action = new Action(options);\n }\n action.setName(key);\n action.setResource(resource);\n resource && action.middlewares.unshift(...resource.middlewares);\n return [key, action];\n }));\n }\n}\n\nexport default Action;\n"]}
package/lib/action.js CHANGED
@@ -87,7 +87,7 @@ class Action {
87
87
  this.parameters = new Map();
88
88
  this.context = {};
89
89
  this.middlewares = [];
90
- options = utils_1.requireModule(options);
90
+ options = (0, utils_1.requireModule)(options);
91
91
 
92
92
  if (typeof options === 'function') {
93
93
  options = {
@@ -232,7 +232,7 @@ class Action {
232
232
  }
233
233
 
234
234
  getHandler() {
235
- const handler = utils_1.requireModule(this.handler || this.resource.resourcer.getRegisteredHandler(this.name));
235
+ const handler = (0, utils_1.requireModule)(this.handler || this.resource.resourcer.getRegisteredHandler(this.name));
236
236
 
237
237
  if (typeof handler !== 'function') {
238
238
  throw new Error('Handler must be a function!');
@@ -247,7 +247,7 @@ class Action {
247
247
 
248
248
  execute(context, next) {
249
249
  return __awaiter(this, void 0, void 0, function* () {
250
- return yield koa_compose_1.default(this.getHandlers())(context, next);
250
+ return yield (0, koa_compose_1.default)(this.getHandlers())(context, next);
251
251
  });
252
252
  }
253
253
 
package/lib/action.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["action.ts"],"names":[],"mappings":"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","file":"action.js","sourcesContent":["import _ from 'lodash';\nimport compose from 'koa-compose';\nimport Resource from './resource';\nimport { requireModule } from './utils';\nimport { HandlerType } from './resourcer';\nimport Middleware, { MiddlewareType } from './middleware';\nimport { ActionParameterTypes, ActionParameter, UnknownParameter, PageParameter } from './parameter';\n\nexport type ActionType = string | HandlerType | ActionOptions;\n\nexport type DefaultActionType = 'list' | 'create' | 'get' | 'update' | 'destroy' | 'set' | 'add' | 'remove';\n\nexport type ActionName = DefaultActionType | Omit<String, DefaultActionType>;\n\nexport interface ActionContext {\n action?: Action;\n [key: string]: any;\n}\n\nexport type FieldsOptions = string[] | {\n only?: string[];\n appends?: string[];\n} | {\n except?: string[];\n appends?: string[];\n};\n\nexport type FieldsOptionsFn = (ctx: ActionContext) => FieldsOptions | Promise<FieldsOptions>;\n\n/**\n * 过滤参数\n * \n * TODO:细节待定\n */\nexport interface FilterOptions {\n [key: string]: any;\n}\n\nexport type FilterOptionsFn = (ctx: ActionContext) => FilterOptions | Promise<FieldsOptions>;\n\nexport type ParamsCallback = (ctx: ActionContext) => ActionParams | Promise<ActionParams>;\n\nexport interface ActionOptions {\n /**\n * 默认数据\n */\n values?: any;\n /**\n * 字段\n * \n * 示例一:\n * ['col1', 'col2', 'relation.col1'];\n * \n * 示例二:\n * {\n * only: ['col1'],\n * }\n * \n * 示例三:\n * {\n * except: ['col1'],\n * }\n */\n fields?: FieldsOptions;\n /**\n * 过滤\n */\n filter?: FilterOptions;\n /**\n * 排序\n */\n sort?: string | string[];\n /**\n * 当前页码\n */\n page?: number;\n /**\n * 每页显示数量\n */\n perPage?: number;\n /**\n * 最大每页显示数量\n */\n maxPerPage?: number;\n /**\n * 中间件\n */\n middleware?: MiddlewareType;\n /**\n * 中间件\n * \n * 与 middleware 用法相同\n */\n middlewares?: MiddlewareType;\n /**\n * 当前 Action 待执行的方法\n * \n * 支持 Function 和 require 调用\n */\n handler?: HandlerType;\n /**\n * 其他扩展配置\n */\n [key: string]: any;\n}\n\n/**\n * action params 与 action options 略有不同\n * - options 的参数更灵活,主要用于开发配置\n * - params 是开发配置参数 + 客户端参数的结合体\n */\nexport interface ActionParams {\n /**\n * 输出哪些字段\n * \n * 与 ActionOptions 的不同,这里的 fields 是 object,提供 only,except,appends 三种情况\n */\n fields?: {\n only?: string[];\n except?: string[];\n appends?: string[];\n };\n /**\n * 过滤\n */\n filter?: FilterOptions;\n /**\n * 排序\n * \n * 与 ActionOptions 的不同,这里的 sort 只有一种 array 类型\n */\n sort?: string[];\n /**\n * 当前页码\n */\n page?: number;\n /**\n * 每页显示数量\n */\n perPage?: number;\n /**\n * 数据,默认为 options.defaultValues + request.body\n */\n values?: any;\n /**\n * 当前资源的主体,对应的表名或 Model 名称\n */\n resourceName?: string;\n /**\n * 资源标识符\n */\n resourceKey?: string;\n /**\n * 资源的从属关系\n */\n associatedName?: string;\n /**\n * 从属关系的标识符\n */\n associatedKey?: string;\n /**\n * 从属关系的当前实例\n */\n associated?: any;\n /**\n * 资源提供哪些行为或方法\n */\n actionName?: string;\n /**\n * 其他扩展配置\n */\n [key: string]: any;\n}\n\nexport class Action {\n\n protected handler: any;\n\n protected resource: Resource;\n\n protected name: ActionName;\n\n protected options: ActionOptions;\n\n protected parameters: Map<string, ActionParameter | UnknownParameter> = new Map();\n\n protected context: ActionContext = {};\n\n public readonly middlewares: Array<Middleware> = [];\n\n constructor(options: ActionOptions) {\n options = requireModule(options);\n if (typeof options === 'function') {\n options = { handler: options };\n }\n const {\n middleware,\n middlewares = [],\n handler,\n ...params\n } = options;\n this.middlewares = Middleware.toInstanceArray(middleware || middlewares);\n this.handler = handler;\n this.options = options;\n this.mergeParams(params, {});\n }\n\n get params(): ActionParams {\n const result = this.parameters.get('_').get();\n for (const paramType of this.parameters.values()) {\n Object.assign(result, paramType.get());\n }\n return result;\n }\n\n clone() {\n const options = _.cloneDeep(this.options);\n delete options.middleware;\n delete options.middlewares;\n const action = new Action(options);\n action.setName(this.name);\n action.setResource(this.resource);\n action.middlewares.push(...this.middlewares);\n return action;\n }\n\n setContext(context: any) {\n this.context = context;\n }\n\n async mergeParams(params, strategies = {}) {\n const typeKeys = new Set<string>();\n Object.keys(params).forEach(key => {\n for (const typeKey of ActionParameterTypes.getAllKeys()) {\n if (typeof params[key] !== 'undefined' && key in ActionParameterTypes.get(typeKey).picking) {\n typeKeys.add(typeKey);\n }\n }\n });\n let type;\n for (const key of typeKeys) {\n const strategy = strategies[key];\n type = this.parameters.get(key);\n if (!type) {\n const Type = ActionParameterTypes.get(key);\n if (!Type) {\n throw new Error(`parameter type ${key} is unregistered`);\n }\n // @ts-ignore\n type = new Type(params);\n this.parameters.set(key, type);\n }\n type.merge(params, strategy);\n }\n type = this.parameters.get('_');\n if (!type) {\n type = new UnknownParameter(params);\n this.parameters.set('_', type);\n }\n type.merge(params, strategies['_']);\n }\n\n setResource(resource: Resource) {\n this.resource = resource;\n return this;\n }\n\n getResource() {\n return this.resource;\n }\n\n getOptions(): ActionOptions {\n return this.options;\n }\n\n setName(name: ActionName) {\n this.name = name;\n return this;\n }\n\n getName() {\n return this.name;\n }\n\n getMiddlewareHandlers() {\n return this.middlewares\n .filter(middleware => middleware.canAccess(this.name))\n .map(middleware => middleware.getHandler());\n }\n\n getHandler() {\n const handler = requireModule(this.handler || this.resource.resourcer.getRegisteredHandler(this.name));\n if (typeof handler !== 'function') {\n throw new Error('Handler must be a function!');\n }\n return handler;\n }\n\n getHandlers() {\n return [...this.resource.resourcer.getMiddlewares(), ...this.getMiddlewareHandlers(), this.getHandler()].filter(Boolean);\n }\n\n async execute(context: any, next?: any) {\n return await compose(this.getHandlers())(context, next);\n }\n\n static toInstanceMap(actions: object, resource?: Resource) {\n return new Map(Object.entries(actions).map(([key, options]) => {\n let action: Action;\n if (options instanceof Action) {\n action = options;\n } else {\n action = new Action(options);\n }\n action.setName(key);\n action.setResource(resource);\n resource && action.middlewares.unshift(...resource.middlewares);\n return [key, action];\n }));\n }\n}\n\nexport default Action;\n"]}
1
+ {"version":3,"sources":["action.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,oDAAuB;AACvB,8DAAkC;AAElC,mCAAwC;AAExC,8DAA0D;AAC1D,2CAAqG;AAwKrG,MAAa,MAAM;IAgBjB,YAAY,OAAsB;QANxB,eAAU,GAAoD,IAAI,GAAG,EAAE,CAAC;QAExE,YAAO,GAAkB,EAAE,CAAC;QAEtB,gBAAW,GAAsB,EAAE,CAAC;QAGlD,OAAO,GAAG,IAAA,qBAAa,EAAC,OAAO,CAAC,CAAC;QACjC,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE;YACjC,OAAO,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;SAChC;QACD,MAAM,EACJ,UAAU,EACV,WAAW,GAAG,EAAE,EAChB,OAAO,KAEL,OAAO,EADN,MAAM,UACP,OAAO,EALL,wCAKL,CAAU,CAAC;QACZ,IAAI,CAAC,WAAW,GAAG,oBAAU,CAAC,eAAe,CAAC,UAAU,IAAI,WAAW,CAAC,CAAC;QACzE,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC/B,CAAC;IAED,IAAI,MAAM;QACR,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;QAC9C,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE;YAChD,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,EAAE,CAAC,CAAC;SACxC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK;QACH,MAAM,OAAO,GAAG,gBAAC,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC1C,OAAO,OAAO,CAAC,UAAU,CAAC;QAC1B,OAAO,OAAO,CAAC,WAAW,CAAC;QAC3B,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC;QACnC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1B,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAClC,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC;QAC7C,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,UAAU,CAAC,OAAY;QACrB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAEK,WAAW,CAAC,MAAM,EAAE,UAAU,GAAG,EAAE;;YACvC,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;YACnC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;gBAChC,KAAK,MAAM,OAAO,IAAI,gCAAoB,CAAC,UAAU,EAAE,EAAE;oBACvD,IAAI,OAAO,MAAM,CAAC,GAAG,CAAC,KAAK,WAAW,IAAI,GAAG,IAAI,gCAAoB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE;wBAC1F,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;qBACvB;iBACF;YACH,CAAC,CAAC,CAAC;YACH,IAAI,IAAI,CAAC;YACT,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE;gBAC1B,MAAM,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;gBACjC,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBAChC,IAAI,CAAC,IAAI,EAAE;oBACT,MAAM,IAAI,GAAG,gCAAoB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;oBAC3C,IAAI,CAAC,IAAI,EAAE;wBACT,MAAM,IAAI,KAAK,CAAC,kBAAkB,GAAG,kBAAkB,CAAC,CAAC;qBAC1D;oBAED,IAAI,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC;oBACxB,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;iBAChC;gBACD,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;aAC9B;YACD,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAChC,IAAI,CAAC,IAAI,EAAE;gBACT,IAAI,GAAG,IAAI,4BAAgB,CAAC,MAAM,CAAC,CAAC;gBACpC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;aAChC;YACD,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;QACtC,CAAC;KAAA;IAED,WAAW,CAAC,QAAkB;QAC5B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,WAAW;QACT,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED,UAAU;QACR,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED,OAAO,CAAC,IAAgB;QACtB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;IAED,qBAAqB;QACnB,OAAO,IAAI,CAAC,WAAW;aACpB,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;aACrD,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC,CAAC;IAChD,CAAC;IAED,UAAU;QACR,MAAM,OAAO,GAAG,IAAA,qBAAa,EAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACvG,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE;YACjC,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;SAChD;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,WAAW;QACT,OAAO,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,cAAc,EAAE,EAAE,GAAG,IAAI,CAAC,qBAAqB,EAAE,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC3H,CAAC;IAEK,OAAO,CAAC,OAAY,EAAE,IAAU;;YACpC,OAAO,MAAM,IAAA,qBAAO,EAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC1D,CAAC;KAAA;IAED,MAAM,CAAC,aAAa,CAAC,OAAe,EAAE,QAAmB;QACvD,OAAO,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,EAAE;YAC5D,IAAI,MAAc,CAAC;YACnB,IAAI,OAAO,YAAY,MAAM,EAAE;gBAC7B,MAAM,GAAG,OAAO,CAAC;aAClB;iBAAM;gBACL,MAAM,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC;aAC9B;YACD,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACpB,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;YAC7B,QAAQ,IAAI,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC;YAChE,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACvB,CAAC,CAAC,CAAC,CAAC;IACN,CAAC;CACF;AAlJD,wBAkJC;AAED,kBAAe,MAAM,CAAC","file":"action.js","sourcesContent":["import _ from 'lodash';\nimport compose from 'koa-compose';\nimport Resource from './resource';\nimport { requireModule } from './utils';\nimport { HandlerType } from './resourcer';\nimport Middleware, { MiddlewareType } from './middleware';\nimport { ActionParameterTypes, ActionParameter, UnknownParameter, PageParameter } from './parameter';\n\nexport type ActionType = string | HandlerType | ActionOptions;\n\nexport type DefaultActionType = 'list' | 'create' | 'get' | 'update' | 'destroy' | 'set' | 'add' | 'remove';\n\nexport type ActionName = DefaultActionType | Omit<String, DefaultActionType>;\n\nexport interface ActionContext {\n action?: Action;\n [key: string]: any;\n}\n\nexport type FieldsOptions = string[] | {\n only?: string[];\n appends?: string[];\n} | {\n except?: string[];\n appends?: string[];\n};\n\nexport type FieldsOptionsFn = (ctx: ActionContext) => FieldsOptions | Promise<FieldsOptions>;\n\n/**\n * 过滤参数\n * \n * TODO:细节待定\n */\nexport interface FilterOptions {\n [key: string]: any;\n}\n\nexport type FilterOptionsFn = (ctx: ActionContext) => FilterOptions | Promise<FieldsOptions>;\n\nexport type ParamsCallback = (ctx: ActionContext) => ActionParams | Promise<ActionParams>;\n\nexport interface ActionOptions {\n /**\n * 默认数据\n */\n values?: any;\n /**\n * 字段\n * \n * 示例一:\n * ['col1', 'col2', 'relation.col1'];\n * \n * 示例二:\n * {\n * only: ['col1'],\n * }\n * \n * 示例三:\n * {\n * except: ['col1'],\n * }\n */\n fields?: FieldsOptions;\n /**\n * 过滤\n */\n filter?: FilterOptions;\n /**\n * 排序\n */\n sort?: string | string[];\n /**\n * 当前页码\n */\n page?: number;\n /**\n * 每页显示数量\n */\n perPage?: number;\n /**\n * 最大每页显示数量\n */\n maxPerPage?: number;\n /**\n * 中间件\n */\n middleware?: MiddlewareType;\n /**\n * 中间件\n * \n * 与 middleware 用法相同\n */\n middlewares?: MiddlewareType;\n /**\n * 当前 Action 待执行的方法\n * \n * 支持 Function 和 require 调用\n */\n handler?: HandlerType;\n /**\n * 其他扩展配置\n */\n [key: string]: any;\n}\n\n/**\n * action params 与 action options 略有不同\n * - options 的参数更灵活,主要用于开发配置\n * - params 是开发配置参数 + 客户端参数的结合体\n */\nexport interface ActionParams {\n /**\n * 输出哪些字段\n * \n * 与 ActionOptions 的不同,这里的 fields 是 object,提供 only,except,appends 三种情况\n */\n fields?: {\n only?: string[];\n except?: string[];\n appends?: string[];\n };\n /**\n * 过滤\n */\n filter?: FilterOptions;\n /**\n * 排序\n * \n * 与 ActionOptions 的不同,这里的 sort 只有一种 array 类型\n */\n sort?: string[];\n /**\n * 当前页码\n */\n page?: number;\n /**\n * 每页显示数量\n */\n perPage?: number;\n /**\n * 数据,默认为 options.defaultValues + request.body\n */\n values?: any;\n /**\n * 当前资源的主体,对应的表名或 Model 名称\n */\n resourceName?: string;\n /**\n * 资源标识符\n */\n resourceIndex?: string;\n /**\n * 资源的从属关系\n */\n associatedName?: string;\n /**\n * 从属关系的标识符\n */\n associatedIndex?: string;\n /**\n * 从属关系的当前实例\n */\n associated?: any;\n /**\n * 资源提供哪些行为或方法\n */\n actionName?: string;\n /**\n * 其他扩展配置\n */\n [key: string]: any;\n}\n\nexport class Action {\n\n protected handler: any;\n\n protected resource: Resource;\n\n protected name: ActionName;\n\n protected options: ActionOptions;\n\n protected parameters: Map<string, ActionParameter | UnknownParameter> = new Map();\n\n protected context: ActionContext = {};\n\n public readonly middlewares: Array<Middleware> = [];\n\n constructor(options: ActionOptions) {\n options = requireModule(options);\n if (typeof options === 'function') {\n options = { handler: options };\n }\n const {\n middleware,\n middlewares = [],\n handler,\n ...params\n } = options;\n this.middlewares = Middleware.toInstanceArray(middleware || middlewares);\n this.handler = handler;\n this.options = options;\n this.mergeParams(params, {});\n }\n\n get params(): ActionParams {\n const result = this.parameters.get('_').get();\n for (const paramType of this.parameters.values()) {\n Object.assign(result, paramType.get());\n }\n return result;\n }\n\n clone() {\n const options = _.cloneDeep(this.options);\n delete options.middleware;\n delete options.middlewares;\n const action = new Action(options);\n action.setName(this.name);\n action.setResource(this.resource);\n action.middlewares.push(...this.middlewares);\n return action;\n }\n\n setContext(context: any) {\n this.context = context;\n }\n\n async mergeParams(params, strategies = {}) {\n const typeKeys = new Set<string>();\n Object.keys(params).forEach(key => {\n for (const typeKey of ActionParameterTypes.getAllKeys()) {\n if (typeof params[key] !== 'undefined' && key in ActionParameterTypes.get(typeKey).picking) {\n typeKeys.add(typeKey);\n }\n }\n });\n let type;\n for (const key of typeKeys) {\n const strategy = strategies[key];\n type = this.parameters.get(key);\n if (!type) {\n const Type = ActionParameterTypes.get(key);\n if (!Type) {\n throw new Error(`parameter type ${key} is unregistered`);\n }\n // @ts-ignore\n type = new Type(params);\n this.parameters.set(key, type);\n }\n type.merge(params, strategy);\n }\n type = this.parameters.get('_');\n if (!type) {\n type = new UnknownParameter(params);\n this.parameters.set('_', type);\n }\n type.merge(params, strategies['_']);\n }\n\n setResource(resource: Resource) {\n this.resource = resource;\n return this;\n }\n\n getResource() {\n return this.resource;\n }\n\n getOptions(): ActionOptions {\n return this.options;\n }\n\n setName(name: ActionName) {\n this.name = name;\n return this;\n }\n\n getName() {\n return this.name;\n }\n\n getMiddlewareHandlers() {\n return this.middlewares\n .filter(middleware => middleware.canAccess(this.name))\n .map(middleware => middleware.getHandler());\n }\n\n getHandler() {\n const handler = requireModule(this.handler || this.resource.resourcer.getRegisteredHandler(this.name));\n if (typeof handler !== 'function') {\n throw new Error('Handler must be a function!');\n }\n return handler;\n }\n\n getHandlers() {\n return [...this.resource.resourcer.getMiddlewares(), ...this.getMiddlewareHandlers(), this.getHandler()].filter(Boolean);\n }\n\n async execute(context: any, next?: any) {\n return await compose(this.getHandlers())(context, next);\n }\n\n static toInstanceMap(actions: object, resource?: Resource) {\n return new Map(Object.entries(actions).map(([key, options]) => {\n let action: Action;\n if (options instanceof Action) {\n action = options;\n } else {\n action = new Action(options);\n }\n action.setName(key);\n action.setResource(resource);\n resource && action.middlewares.unshift(...resource.middlewares);\n return [key, action];\n }));\n }\n}\n\nexport default Action;\n"]}
package/lib/middleware.js CHANGED
@@ -21,7 +21,7 @@ const utils_1 = require("./utils");
21
21
 
22
22
  class Middleware {
23
23
  constructor(options) {
24
- options = utils_1.requireModule(options);
24
+ options = (0, utils_1.requireModule)(options);
25
25
 
26
26
  if (typeof options === 'function') {
27
27
  this.options = {
@@ -33,7 +33,7 @@ class Middleware {
33
33
  }
34
34
 
35
35
  getHandler() {
36
- const handler = utils_1.requireModule(this.options.handler);
36
+ const handler = (0, utils_1.requireModule)(this.options.handler);
37
37
 
38
38
  if (typeof handler !== 'function') {
39
39
  throw new Error('Handler must be a function!');
@@ -1 +1 @@
1
- {"version":3,"sources":["middleware.ts"],"names":[],"mappings":";;;AACA,mCAAwC;AAuBxC,MAAa,UAAU;IAIrB,YAAY,OAAqC;QAC/C,OAAO,GAAG,qBAAa,CAAC,OAAO,CAAC,CAAC;QACjC,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE;YACjC,IAAI,CAAC,OAAO,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;SACrC;aAAM;YACL,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;SACxB;IACH,CAAC;IAED,UAAU;QACR,MAAM,OAAO,GAAG,qBAAa,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACpD,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE;YACjC,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;SAChD;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,SAAS,CAAC,IAAgB;QACxB,MAAM,EAAE,IAAI,GAAG,EAAE,EAAE,MAAM,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;QAChD,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE;YACnB,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;SAC5B;QACD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE;YACrB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;SAC/B;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,CAAC,eAAe,CAAC,WAAgB;QACrC,IAAI,CAAC,WAAW,EAAE;YAChB,OAAO,EAAE,CAAC;SACX;QACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE;YAC/B,WAAW,GAAG,CAAC,WAAW,CAAC,CAAC;SAC7B;QACD,OAAO,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE;YAClC,IAAI,UAAU,YAAY,UAAU,EAAE;gBACpC,OAAO,UAAU,CAAC;aACnB;YACD,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE;gBAClC,OAAO,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC;aACnC;YACD,IAAI,OAAO,UAAU,KAAK,UAAU,EAAE;gBACpC,OAAO,IAAI,UAAU,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;aAChD;QACH,CAAC,CAAC,CAAC;IACL,CAAC;CACF;AAnDD,gCAmDC;AAED,kBAAe,UAAU,CAAC","file":"middleware.js","sourcesContent":["import { ActionName } from './action';\nimport { requireModule } from './utils';\nimport { HandlerType } from './resourcer';\n\nexport type MiddlewareType = string | string[] | HandlerType | HandlerType[]\n | MiddlewareOptions | MiddlewareOptions[];\n\nexport interface MiddlewareOptions {\n\n /**\n * actions 白名单,默认有 list、get、create、update、delete\n */\n only?: Array<ActionName>;\n\n /**\n * actions 黑名单,默认有 list、get、create、update、delete\n */\n except?: Array<ActionName>;\n\n handler?: HandlerType | Function;\n\n [key: string]: any;\n}\n\nexport class Middleware {\n\n protected options: MiddlewareOptions;\n\n constructor(options: MiddlewareOptions | Function) {\n options = requireModule(options);\n if (typeof options === 'function') {\n this.options = { handler: options };\n } else {\n this.options = options;\n }\n }\n\n getHandler() {\n const handler = requireModule(this.options.handler);\n if (typeof handler !== 'function') {\n throw new Error('Handler must be a function!');\n }\n return handler;\n }\n\n canAccess(name: ActionName) {\n const { only = [], except = [] } = this.options;\n if (only.length > 0) {\n return only.includes(name);\n }\n if (except.length > 0) {\n return !except.includes(name);\n }\n return true;\n }\n\n static toInstanceArray(middlewares: any): Middleware[] {\n if (!middlewares) {\n return [];\n }\n if (!Array.isArray(middlewares)) {\n middlewares = [middlewares];\n }\n return middlewares.map(middleware => {\n if (middleware instanceof Middleware) {\n return middleware;\n }\n if (typeof middleware === 'object') {\n return new Middleware(middleware);\n }\n if (typeof middleware === 'function') {\n return new Middleware({ handler: middleware });\n }\n });\n }\n}\n\nexport default Middleware;"]}
1
+ {"version":3,"sources":["middleware.ts"],"names":[],"mappings":";;;AACA,mCAAwC;AAuBxC,MAAa,UAAU;IAIrB,YAAY,OAAqC;QAC/C,OAAO,GAAG,IAAA,qBAAa,EAAC,OAAO,CAAC,CAAC;QACjC,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE;YACjC,IAAI,CAAC,OAAO,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;SACrC;aAAM;YACL,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;SACxB;IACH,CAAC;IAED,UAAU;QACR,MAAM,OAAO,GAAG,IAAA,qBAAa,EAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACpD,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE;YACjC,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;SAChD;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,SAAS,CAAC,IAAgB;QACxB,MAAM,EAAE,IAAI,GAAG,EAAE,EAAE,MAAM,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;QAChD,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE;YACnB,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;SAC5B;QACD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE;YACrB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;SAC/B;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,CAAC,eAAe,CAAC,WAAgB;QACrC,IAAI,CAAC,WAAW,EAAE;YAChB,OAAO,EAAE,CAAC;SACX;QACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE;YAC/B,WAAW,GAAG,CAAC,WAAW,CAAC,CAAC;SAC7B;QACD,OAAO,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE;YAClC,IAAI,UAAU,YAAY,UAAU,EAAE;gBACpC,OAAO,UAAU,CAAC;aACnB;YACD,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE;gBAClC,OAAO,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC;aACnC;YACD,IAAI,OAAO,UAAU,KAAK,UAAU,EAAE;gBACpC,OAAO,IAAI,UAAU,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;aAChD;QACH,CAAC,CAAC,CAAC;IACL,CAAC;CACF;AAnDD,gCAmDC;AAED,kBAAe,UAAU,CAAC","file":"middleware.js","sourcesContent":["import { ActionName } from './action';\nimport { requireModule } from './utils';\nimport { HandlerType } from './resourcer';\n\nexport type MiddlewareType = string | string[] | HandlerType | HandlerType[]\n | MiddlewareOptions | MiddlewareOptions[];\n\nexport interface MiddlewareOptions {\n\n /**\n * actions 白名单,默认有 list、get、create、update、delete\n */\n only?: Array<ActionName>;\n\n /**\n * actions 黑名单,默认有 list、get、create、update、delete\n */\n except?: Array<ActionName>;\n\n handler?: HandlerType | Function;\n\n [key: string]: any;\n}\n\nexport class Middleware {\n\n protected options: MiddlewareOptions;\n\n constructor(options: MiddlewareOptions | Function) {\n options = requireModule(options);\n if (typeof options === 'function') {\n this.options = { handler: options };\n } else {\n this.options = options;\n }\n }\n\n getHandler() {\n const handler = requireModule(this.options.handler);\n if (typeof handler !== 'function') {\n throw new Error('Handler must be a function!');\n }\n return handler;\n }\n\n canAccess(name: ActionName) {\n const { only = [], except = [] } = this.options;\n if (only.length > 0) {\n return only.includes(name);\n }\n if (except.length > 0) {\n return !except.includes(name);\n }\n return true;\n }\n\n static toInstanceArray(middlewares: any): Middleware[] {\n if (!middlewares) {\n return [];\n }\n if (!Array.isArray(middlewares)) {\n middlewares = [middlewares];\n }\n return middlewares.map(middleware => {\n if (middleware instanceof Middleware) {\n return middleware;\n }\n if (typeof middleware === 'object') {\n return new Middleware(middleware);\n }\n if (typeof middleware === 'function') {\n return new Middleware({ handler: middleware });\n }\n });\n }\n}\n\nexport default Middleware;"]}
package/lib/resourcer.js CHANGED
@@ -99,7 +99,7 @@ class Resourcer {
99
99
  });
100
100
  const resources = new Map();
101
101
  files.forEach(file => {
102
- const options = utils_1.requireModule(file);
102
+ const options = (0, utils_1.requireModule)(file);
103
103
  const table = this.define(typeof options === 'function' ? options(this) : options);
104
104
  resources.set(table.getName(), table);
105
105
  });
@@ -181,7 +181,7 @@ class Resourcer {
181
181
 
182
182
  const restApiMiddleware = (ctx, next) => __awaiter(this, void 0, void 0, function* () {
183
183
  ctx.resourcer = this;
184
- let params = utils_1.parseRequest({
184
+ let params = (0, utils_1.parseRequest)({
185
185
  path: ctx.request.path,
186
186
  method: ctx.request.method
187
187
  }, {
@@ -194,10 +194,10 @@ class Resourcer {
194
194
  }
195
195
 
196
196
  try {
197
- const resource = this.getResource(utils_1.getNameByParams(params));
197
+ const resource = this.getResource((0, utils_1.getNameByParams)(params));
198
198
 
199
199
  if (resource.options.type && resource.options.type !== 'single') {
200
- params = utils_1.parseRequest({
200
+ params = (0, utils_1.parseRequest)({
201
201
  path: ctx.request.path,
202
202
  method: ctx.request.method,
203
203
  type: resource.options.type
@@ -211,11 +211,11 @@ class Resourcer {
211
211
  }
212
212
  }
213
213
 
214
- ctx.action = this.getAction(utils_1.getNameByParams(params), params.actionName).clone();
214
+ ctx.action = this.getAction((0, utils_1.getNameByParams)(params), params.actionName).clone();
215
215
  ctx.action.setContext(ctx);
216
- const query = utils_1.parseQuery(ctx.request.querystring);
216
+ const query = (0, utils_1.parseQuery)(ctx.request.querystring);
217
217
 
218
- if (path_to_regexp_1.pathToRegexp('/resourcer/{:associatedName.}?:resourceName{\\::actionName}').test(ctx.request.path)) {
218
+ if ((0, path_to_regexp_1.pathToRegexp)('/resourcer/{:associatedName.}?:resourceName{\\::actionName}').test(ctx.request.path)) {
219
219
  yield ctx.action.mergeParams(Object.assign(Object.assign(Object.assign({}, query), params), ctx.request.body));
220
220
  } else {
221
221
  yield ctx.action.mergeParams(Object.assign(Object.assign(Object.assign({}, query), params), lodash_1.default.isEmpty(ctx.request.body) ? {} : {
@@ -223,7 +223,7 @@ class Resourcer {
223
223
  }));
224
224
  }
225
225
 
226
- return koa_compose_1.default(ctx.action.getHandlers())(ctx, next);
226
+ return (0, koa_compose_1.default)(ctx.action.getHandlers())(ctx, next);
227
227
  } catch (error) {
228
228
  return next();
229
229
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["resourcer.ts"],"names":[],"mappings":"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","file":"resourcer.js","sourcesContent":["import qs from 'qs';\nimport glob from 'glob';\nimport compose from 'koa-compose';\nimport Action, { ActionName } from './action';\nimport Resource, { ResourceOptions } from './resource';\nimport { parseRequest, getNameByParams, ParsedParams, requireModule, parseQuery } from './utils';\nimport { pathToRegexp } from 'path-to-regexp';\nimport _ from 'lodash';\n\nexport interface ResourcerContext {\n resourcer?: Resourcer;\n action?: Action;\n [key: string]: any;\n}\n\nexport interface KoaMiddlewareOptions {\n\n /**\n * 前缀\n */\n prefix?: string;\n\n /**\n * 自定义 resource name 的获取规则\n * \n * 默认规则 relatedTable ? relatedTable.table : table\n */\n nameRule?: (params: ParsedParams) => string;\n\n /**\n * 自定义 action name\n * \n * 默认为\n * \n * - list 查看列表\n * - create 新增数据\n * - get 查看数据详情\n * - update 更新数据\n * - delete 删除数据\n */\n accessors?: {\n\n /**\n * 查看列表\n */\n list?: string;\n\n /**\n * 新增数据\n */\n create?: string;\n\n /**\n * 查看数据详情\n */\n get?: string;\n\n /**\n * 更新数据\n */\n update?: string;\n\n /**\n * 删除数据\n */\n delete?: string;\n };\n}\n\nexport interface ResourcerOptions {\n\n /**\n * 前缀\n */\n prefix?: string;\n\n /**\n * 自定义 action name\n * \n * 默认为\n * \n * - list 查看列表\n * - create 新增数据\n * - get 查看数据详情\n * - update 更新数据\n * - delete 删除数据\n */\n accessors?: {\n\n /**\n * 查看列表\n */\n list?: string;\n\n /**\n * 新增数据\n */\n create?: string;\n\n /**\n * 查看数据详情\n */\n get?: string;\n\n /**\n * 更新数据\n */\n update?: string;\n\n /**\n * 删除数据\n */\n delete?: string;\n };\n}\n\nexport interface ExecuteOptions {\n\n /**\n * 资源名称\n */\n resource: string;\n\n /**\n * 自定义 action name\n * \n * 默认\n * - list 查看列表\n * - create 新增数据\n * - get 查看数据详情\n * - update 更新数据\n * - delete 删除数据\n */\n action: ActionName;\n}\n\nexport type HandlerType = (ctx: ResourcerContext, next: () => Promise<any>) => any;\n\nexport interface Handlers {\n [key: string]: HandlerType;\n}\n\nexport interface ImportOptions {\n\n /**\n * 指定配置所在路径\n */\n directory: string;\n\n /**\n * 文件后缀,默认值 ['js', 'ts', 'json']\n */\n extensions?: string[];\n}\n\nexport class Resourcer {\n\n protected resources = new Map<string, Resource>();\n\n /**\n * 全局定义的 action handlers\n */\n protected handlers = new Map<ActionName, any>();\n\n protected actionHandlers = new Map<ActionName, any>();\n\n protected middlewareHandlers = new Map<string, any>();\n\n protected middlewares = [];\n\n public readonly options: ResourcerOptions;\n\n constructor(options: ResourcerOptions = {}) {\n this.options = options;\n }\n\n /**\n * 载入指定目录下的 resource 配置(配置的文件驱动)\n * \n * TODO: 配置的文件驱动现在会全部初始化,大数据时可能存在性能瓶颈,后续可以加入动态加载\n * \n * @param {object} [options]\n * @param {string} [options.directory] 指定配置所在路径\n * @param {array} [options.extensions = ['js', 'ts', 'json']] 文件后缀\n */\n public import(options: ImportOptions): Map<string, Resource> {\n const { extensions = ['js', 'ts', 'json'], directory } = options;\n const patten = `${directory}/*.{${extensions.join(',')}}`;\n const files = glob.sync(patten, {\n ignore: [\n '**/*.d.ts'\n ]\n });\n const resources = new Map<string, Resource>();\n files.forEach((file: string) => {\n const options = requireModule(file);\n const table = this.define(typeof options === 'function' ? options(this) : options);\n resources.set(table.getName(), table);\n });\n return resources;\n }\n\n /**\n * resource 配置\n * \n * @param name \n * @param options \n */\n define(options: ResourceOptions) {\n const { name } = options;\n const resource = new Resource(options, this);\n this.resources.set(name, resource);\n return resource;\n }\n\n isDefined(name: string) {\n return this.resources.has(name);\n }\n\n registerAction(name: ActionName, handler: HandlerType) {\n this.registerActionHandler(name, handler);\n }\n\n registerActions(handlers: Handlers) {\n this.registerActionHandlers(handlers);\n }\n\n /**\n * 注册全局的 action handlers\n * \n * @param handlers \n */\n registerActionHandlers(handlers: Handlers) {\n for (const [name, handler] of Object.entries(handlers)) {\n this.registerActionHandler(name, handler);\n }\n }\n\n registerActionHandler(name: ActionName, handler: HandlerType) {\n this.actionHandlers.set(name, handler);\n }\n\n getRegisteredHandler(name: ActionName) {\n return this.actionHandlers.get(name);\n }\n\n getRegisteredHandlers() {\n return this.actionHandlers;\n }\n\n getResource(name: string): Resource {\n if (!this.resources.has(name)) {\n throw new Error(`${name} resource does not exist`);\n }\n return this.resources.get(name);\n }\n\n getAction(name: string, action: ActionName): Action {\n // 支持注册局部 action\n if (this.actionHandlers.has(`${name}:${action}`)) {\n return this.getResource(name).getAction(`${name}:${action}`);\n }\n return this.getResource(name).getAction(action);\n }\n\n getMiddlewares() {\n return this.middlewares;\n }\n\n use(middlewares: HandlerType | HandlerType[]) {\n if (typeof middlewares === 'function') {\n this.middlewares.push(middlewares);\n } else if (Array.isArray(middlewares)) {\n this.middlewares.push(...middlewares);\n }\n }\n\n restApiMiddleware(options: KoaMiddlewareOptions = {}) {\n const { prefix, accessors } = options;\n const restApiMiddleware = async (ctx: ResourcerContext, next: () => Promise<any>) => {\n ctx.resourcer = this;\n let params = parseRequest({\n path: ctx.request.path,\n method: ctx.request.method,\n }, {\n prefix: this.options.prefix || prefix,\n accessors: this.options.accessors || accessors,\n });\n if (!params) {\n return next();\n }\n try {\n const resource = this.getResource(getNameByParams(params));\n // 为关系资源时,暂时需要再执行一遍 parseRequest\n if (resource.options.type && resource.options.type !== 'single') {\n params = parseRequest({\n path: ctx.request.path,\n method: ctx.request.method,\n type: resource.options.type,\n }, {\n prefix: this.options.prefix || prefix,\n accessors: this.options.accessors || accessors,\n });\n if (!params) {\n return next();\n }\n }\n // action 需要 clone 之后再赋给 ctx\n ctx.action = this.getAction(getNameByParams(params), params.actionName).clone();\n ctx.action.setContext(ctx);\n const query = parseQuery(ctx.request.querystring);\n if (pathToRegexp('/resourcer/{:associatedName.}?:resourceName{\\\\::actionName}').test(ctx.request.path)) {\n await ctx.action.mergeParams({\n ...query,\n ...params,\n ...ctx.request.body,\n });\n } else {\n await ctx.action.mergeParams({\n ...query,\n ...params,\n ...(_.isEmpty(ctx.request.body) ? {} : { values: ctx.request.body }),\n });\n }\n return compose(ctx.action.getHandlers())(ctx, next);\n } catch (error) {\n return next();\n }\n };\n return restApiMiddleware;\n }\n\n middleware(options: KoaMiddlewareOptions = {}) {\n return this.restApiMiddleware(options);\n }\n\n /**\n * 实验性 API\n * \n * @param options \n * @param context \n * @param next \n */\n async execute(options: ExecuteOptions, context: ResourcerContext = {}, next?: any) {\n const { resource, action } = options;\n context.resourcer = this;\n context.action = this.getAction(resource, action);\n return await context.action.execute(context, next);\n }\n}\n\nexport default Resourcer;\n"]}
1
+ {"version":3,"sources":["resourcer.ts"],"names":[],"mappings":"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","file":"resourcer.js","sourcesContent":["import qs from 'qs';\nimport glob from 'glob';\nimport compose from 'koa-compose';\nimport Action, { ActionName } from './action';\nimport Resource, { ResourceOptions } from './resource';\nimport { parseRequest, getNameByParams, ParsedParams, requireModule, parseQuery } from './utils';\nimport { pathToRegexp } from 'path-to-regexp';\nimport _ from 'lodash';\n\nexport interface ResourcerContext {\n resourcer?: Resourcer;\n action?: Action;\n [key: string]: any;\n}\n\nexport interface KoaMiddlewareOptions {\n\n /**\n * 前缀\n */\n prefix?: string;\n\n /**\n * 自定义 resource name 的获取规则\n * \n * 默认规则 relatedTable ? relatedTable.table : table\n */\n nameRule?: (params: ParsedParams) => string;\n\n /**\n * 自定义 action name\n * \n * 默认为\n * \n * - list 查看列表\n * - create 新增数据\n * - get 查看数据详情\n * - update 更新数据\n * - delete 删除数据\n */\n accessors?: {\n\n /**\n * 查看列表\n */\n list?: string;\n\n /**\n * 新增数据\n */\n create?: string;\n\n /**\n * 查看数据详情\n */\n get?: string;\n\n /**\n * 更新数据\n */\n update?: string;\n\n /**\n * 删除数据\n */\n delete?: string;\n };\n}\n\nexport interface ResourcerOptions {\n\n /**\n * 前缀\n */\n prefix?: string;\n\n /**\n * 自定义 action name\n * \n * 默认为\n * \n * - list 查看列表\n * - create 新增数据\n * - get 查看数据详情\n * - update 更新数据\n * - delete 删除数据\n */\n accessors?: {\n\n /**\n * 查看列表\n */\n list?: string;\n\n /**\n * 新增数据\n */\n create?: string;\n\n /**\n * 查看数据详情\n */\n get?: string;\n\n /**\n * 更新数据\n */\n update?: string;\n\n /**\n * 删除数据\n */\n delete?: string;\n };\n}\n\nexport interface ExecuteOptions {\n\n /**\n * 资源名称\n */\n resource: string;\n\n /**\n * 自定义 action name\n * \n * 默认\n * - list 查看列表\n * - create 新增数据\n * - get 查看数据详情\n * - update 更新数据\n * - delete 删除数据\n */\n action: ActionName;\n}\n\nexport type HandlerType = (ctx: ResourcerContext, next: () => Promise<any>) => any;\n\nexport interface Handlers {\n [key: string]: HandlerType;\n}\n\nexport interface ImportOptions {\n\n /**\n * 指定配置所在路径\n */\n directory: string;\n\n /**\n * 文件后缀,默认值 ['js', 'ts', 'json']\n */\n extensions?: string[];\n}\n\nexport class Resourcer {\n\n protected resources = new Map<string, Resource>();\n\n /**\n * 全局定义的 action handlers\n */\n protected handlers = new Map<ActionName, any>();\n\n protected actionHandlers = new Map<ActionName, any>();\n\n protected middlewareHandlers = new Map<string, any>();\n\n protected middlewares = [];\n\n public readonly options: ResourcerOptions;\n\n constructor(options: ResourcerOptions = {}) {\n this.options = options;\n }\n\n /**\n * 载入指定目录下的 resource 配置(配置的文件驱动)\n * \n * TODO: 配置的文件驱动现在会全部初始化,大数据时可能存在性能瓶颈,后续可以加入动态加载\n * \n * @param {object} [options]\n * @param {string} [options.directory] 指定配置所在路径\n * @param {array} [options.extensions = ['js', 'ts', 'json']] 文件后缀\n */\n public import(options: ImportOptions): Map<string, Resource> {\n const { extensions = ['js', 'ts', 'json'], directory } = options;\n const patten = `${directory}/*.{${extensions.join(',')}}`;\n const files = glob.sync(patten, {\n ignore: [\n '**/*.d.ts'\n ]\n });\n const resources = new Map<string, Resource>();\n files.forEach((file: string) => {\n const options = requireModule(file);\n const table = this.define(typeof options === 'function' ? options(this) : options);\n resources.set(table.getName(), table);\n });\n return resources;\n }\n\n /**\n * resource 配置\n * \n * @param name \n * @param options \n */\n define(options: ResourceOptions) {\n const { name } = options;\n const resource = new Resource(options, this);\n this.resources.set(name, resource);\n return resource;\n }\n\n isDefined(name: string) {\n return this.resources.has(name);\n }\n\n registerAction(name: ActionName, handler: HandlerType) {\n this.registerActionHandler(name, handler);\n }\n\n registerActions(handlers: Handlers) {\n this.registerActionHandlers(handlers);\n }\n\n /**\n * 注册全局的 action handlers\n * \n * @param handlers \n */\n registerActionHandlers(handlers: Handlers) {\n for (const [name, handler] of Object.entries(handlers)) {\n this.registerActionHandler(name, handler);\n }\n }\n\n registerActionHandler(name: ActionName, handler: HandlerType) {\n this.actionHandlers.set(name, handler);\n }\n\n getRegisteredHandler(name: ActionName) {\n return this.actionHandlers.get(name);\n }\n\n getRegisteredHandlers() {\n return this.actionHandlers;\n }\n\n getResource(name: string): Resource {\n if (!this.resources.has(name)) {\n throw new Error(`${name} resource does not exist`);\n }\n return this.resources.get(name);\n }\n\n getAction(name: string, action: ActionName): Action {\n // 支持注册局部 action\n if (this.actionHandlers.has(`${name}:${action}`)) {\n return this.getResource(name).getAction(`${name}:${action}`);\n }\n return this.getResource(name).getAction(action);\n }\n\n getMiddlewares() {\n return this.middlewares;\n }\n\n use(middlewares: HandlerType | HandlerType[]) {\n if (typeof middlewares === 'function') {\n this.middlewares.push(middlewares);\n } else if (Array.isArray(middlewares)) {\n this.middlewares.push(...middlewares);\n }\n }\n\n restApiMiddleware(options: KoaMiddlewareOptions = {}) {\n const { prefix, accessors } = options;\n const restApiMiddleware = async (ctx: ResourcerContext, next: () => Promise<any>) => {\n ctx.resourcer = this;\n let params = parseRequest({\n path: ctx.request.path,\n method: ctx.request.method,\n }, {\n prefix: this.options.prefix || prefix,\n accessors: this.options.accessors || accessors,\n });\n if (!params) {\n return next();\n }\n try {\n const resource = this.getResource(getNameByParams(params));\n // 为关系资源时,暂时需要再执行一遍 parseRequest\n if (resource.options.type && resource.options.type !== 'single') {\n params = parseRequest({\n path: ctx.request.path,\n method: ctx.request.method,\n type: resource.options.type,\n }, {\n prefix: this.options.prefix || prefix,\n accessors: this.options.accessors || accessors,\n });\n if (!params) {\n return next();\n }\n }\n // action 需要 clone 之后再赋给 ctx\n ctx.action = this.getAction(getNameByParams(params), params.actionName).clone();\n ctx.action.setContext(ctx);\n const query = parseQuery(ctx.request.querystring);\n if (pathToRegexp('/resourcer/{:associatedName.}?:resourceName{\\\\::actionName}').test(ctx.request.path)) {\n await ctx.action.mergeParams({\n ...query,\n ...params,\n ...ctx.request.body,\n });\n } else {\n await ctx.action.mergeParams({\n ...query,\n ...params,\n ...(_.isEmpty(ctx.request.body) ? {} : { values: ctx.request.body }),\n });\n }\n return compose(ctx.action.getHandlers())(ctx, next);\n } catch (error) {\n return next();\n }\n };\n return restApiMiddleware;\n }\n\n middleware(options: KoaMiddlewareOptions = {}) {\n return this.restApiMiddleware(options);\n }\n\n /**\n * 实验性 API\n * \n * @param options \n * @param context \n * @param next \n */\n async execute(options: ExecuteOptions, context: ResourcerContext = {}, next?: any) {\n const { resource, action } = options;\n context.resourcer = this;\n context.action = this.getAction(resource, action);\n return await context.action.execute(context, next);\n }\n}\n\nexport default Resourcer;\n"]}
package/lib/utils.d.ts CHANGED
@@ -19,9 +19,9 @@ export interface ParseOptions {
19
19
  export interface ParsedParams {
20
20
  actionName?: string;
21
21
  resourceName?: string;
22
- resourceKey?: string;
22
+ resourceIndex?: string;
23
23
  associatedName?: string;
24
- associatedKey?: string;
24
+ associatedIndex?: string;
25
25
  }
26
26
  export declare function getNameByParams(params: ParsedParams): string;
27
27
  export declare function parseRequest(request: ParseRequest, options?: ParseOptions): ParsedParams | false;
@@ -1 +1 @@
1
- {"version":3,"sources":["utils.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IAEf,IAAI,CAAC,EAAE,YAAY,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE;QACV,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,CAAC;CACH;AAED,MAAM,WAAW,YAAY;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;CAMxB;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAG5D;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,YAAY,EAAE,OAAO,GAAE,YAAiB,GAAG,YAAY,GAAG,KAAK,CA4IpG;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,GAAG,OAQxC;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,CAc7C;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,GAAG,OAmCtC;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,OAuCrD","file":"utils.d.ts","sourcesContent":["import _ from 'lodash';\nimport { pathToRegexp } from 'path-to-regexp';\nimport qs from 'qs';\nimport { ResourceType } from './resource';\n\nexport interface ParseRequest {\n path: string;\n method: string;\n // 资源类型\n type?: ResourceType;\n}\n\nexport interface ParseOptions {\n prefix?: string;\n accessors?: {\n list?: string;\n create?: string;\n get?: string;\n update?: string;\n delete?: string;\n set?: string;\n add?: string;\n };\n}\n\nexport interface ParsedParams {\n actionName?: string;\n resourceName?: string;\n resourceKey?: string;\n associatedName?: string;\n associatedKey?: string;\n // table: string;\n // tableKey?: string | number;\n // relatedTable?: string;\n // relatedKey?: string | number;\n // action?: ActionName,\n}\n\nexport function getNameByParams(params: ParsedParams): string {\n const { resourceName, associatedName } = params;\n return associatedName ? `${associatedName}.${resourceName}` : resourceName;\n}\n\nexport function parseRequest(request: ParseRequest, options: ParseOptions = {}): ParsedParams | false {\n\n const accessors = {\n // 常规 actions\n list: 'list',\n create: 'create',\n get: 'get',\n update: 'update',\n delete: 'destroy',\n // associate 操作\n add: 'add',\n set: 'set',\n remove: 'remove',\n ...(options.accessors || {}),\n };\n const keys = [];\n const regexp = pathToRegexp('/resourcer/{:associatedName.}?:resourceName{\\\\::actionName}', keys);\n const matches = regexp.exec(request.path);\n if (matches) {\n const params = {};\n keys.forEach((obj, index) => {\n if (matches[index + 1] === undefined) {\n return;\n }\n params[obj.name] = matches[index + 1];\n });\n return params;\n }\n const defaults = {\n single: {\n '/:resourceName': {\n get: accessors.list,\n post: accessors.create,\n delete: accessors.delete\n },\n '/:resourceName/:resourceKey': {\n get: accessors.get,\n put: accessors.update,\n patch: accessors.update,\n delete: accessors.delete,\n },\n '/:associatedName/:associatedKey/:resourceName': {\n get: accessors.list,\n post: accessors.create,\n delete: accessors.delete,\n },\n '/:associatedName/:associatedKey/:resourceName/:resourceKey': {\n get: accessors.get,\n post: accessors.create,\n put: accessors.update,\n patch: accessors.update,\n delete: accessors.delete,\n },\n },\n hasOne: {\n '/:associatedName/:associatedKey/:resourceName': {\n get: accessors.get,\n post: accessors.update,\n put: accessors.update,\n patch: accessors.update,\n delete: accessors.delete,\n },\n },\n hasMany: {\n '/:associatedName/:associatedKey/:resourceName': {\n get: accessors.list,\n post: accessors.create,\n delete: accessors.delete,\n },\n '/:associatedName/:associatedKey/:resourceName/:resourceKey': {\n get: accessors.get,\n post: accessors.create,\n put: accessors.update,\n patch: accessors.update,\n delete: accessors.delete,\n },\n },\n belongsTo: {\n '/:associatedName/:associatedKey/:resourceName': {\n get: accessors.get,\n delete: accessors.remove,\n },\n '/:associatedName/:associatedKey/:resourceName/:resourceKey': {\n post: accessors.set,\n },\n },\n belongsToMany: {\n '/:associatedName/:associatedKey/:resourceName': {\n get: accessors.list,\n post: accessors.set,\n },\n '/:associatedName/:associatedKey/:resourceName/:resourceKey': {\n get: accessors.get,\n post: accessors.add,\n put: accessors.update, // Many to Many 的 update 是针对 through\n patch: accessors.update, // Many to Many 的 update 是针对 through\n delete: accessors.remove,\n },\n },\n };\n\n const params: ParsedParams = {};\n\n let prefix = (options.prefix || '').trim();\n\n if (prefix && !prefix.startsWith('/')) {\n prefix = `/${prefix}`;\n }\n\n const { type = 'single' } = request;\n\n for (const path in defaults[type]) {\n const keys = [];\n const regexp = pathToRegexp(`${prefix}${path}`, keys, {});\n const matches = regexp.exec(request.path);\n if (!matches) {\n continue;\n }\n keys.forEach((obj, index) => {\n if (matches[index + 1] === undefined) {\n return;\n }\n params[obj.name] = matches[index + 1];\n });\n params.actionName = _.get(defaults, [type, path, request.method.toLowerCase()]);\n }\n\n if (Object.keys(params).length === 0) {\n return false;\n }\n\n if (params.resourceName) {\n const [resourceName, actionName] = params.resourceName.split(':');\n if (actionName) {\n params.resourceName = resourceName;\n params.actionName = actionName;\n }\n }\n\n return params;\n}\n\nexport function requireModule(module: any) {\n if (typeof module === 'string') {\n module = require(module);\n }\n if (typeof module !== 'object') {\n return module;\n }\n return module.__esModule ? module.default : module;\n}\n\nexport function parseQuery(input: string): any {\n // 自带 query 处理的不太给力,需要用 qs 转一下\n const query = qs.parse(input, {\n // 原始 query string 中如果一个键连等号“=”都没有可以被认为是 null 类型\n strictNullHandling: true,\n // 逗号分隔转换为数组\n comma: true\n });\n // filter 支持 json string\n if (typeof query.filter === 'string') {\n query.filter = JSON.parse(query.filter);\n }\n\n return query;\n}\n\nexport function parseFields(fields: any) {\n if (!fields) {\n return {}\n }\n if (typeof fields === 'string') {\n fields = fields.split(',').map(field => field.trim());\n }\n if (Array.isArray(fields)) {\n const onlyFields = [];\n const output: any = {};\n fields.forEach(item => {\n if (typeof item === 'string') {\n onlyFields.push(item);\n } else if (typeof item === 'object') {\n if (item.only) {\n onlyFields.push(...item.only.toString().split(','));\n }\n Object.assign(output, parseFields(item));\n }\n });\n if (onlyFields.length) {\n output.only = onlyFields;\n }\n return output;\n }\n if (fields.only && typeof fields.only === 'string') {\n fields.only = fields.only.split(',').map(field => field.trim());\n }\n if (fields.except && typeof fields.except === 'string') {\n fields.except = fields.except.split(',').map(field => field.trim());\n }\n if (fields.appends && typeof fields.appends === 'string') {\n fields.appends = fields.appends.split(',').map(field => field.trim());\n }\n return fields;\n}\n\nexport function mergeFields(defaults: any, inputs: any) {\n let fields: any = {};\n defaults = parseFields(defaults);\n inputs = parseFields(inputs);\n if (inputs.only) {\n // 前端提供 only,后端提供 only\n if (defaults.only) {\n fields.only = defaults.only.filter(field => inputs.only.includes(field))\n }\n // 前端提供 only,后端提供 except,输出 only 排除 except\n else if (defaults.except) {\n fields.only = inputs.only.filter(field => !defaults.except.includes(field))\n }\n // 前端提供 only,后端没有提供 only 或 except\n else {\n fields.only = inputs.only;\n }\n } else if (inputs.except) {\n // 前端提供 except,后端提供 only,只输出 only 里排除 except 的字段\n if (defaults.only) {\n fields.only = defaults.only.filter(field => !inputs.except.includes(field))\n }\n // 前端提供 except,后端提供 except 或不提供,合并 except\n else {\n fields.except = _.uniq([...inputs.except, ...(defaults.except || [])]);\n }\n }\n // 前端没提供 only 或 except\n else {\n fields = defaults;\n }\n // 如果前端提供了 appends\n if (!_.isEmpty(inputs.appends)) {\n fields.appends = _.uniq([...inputs.appends, ...(defaults.appends || [])]);\n }\n if (!fields.appends) {\n fields.appends = [];\n }\n return fields;\n}\n"]}
1
+ {"version":3,"sources":["utils.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IAEf,IAAI,CAAC,EAAE,YAAY,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE;QACV,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,CAAC;CACH;AAED,MAAM,WAAW,YAAY;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;CAM1B;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAG5D;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,YAAY,EAAE,OAAO,GAAE,YAAiB,GAAG,YAAY,GAAG,KAAK,CA4IpG;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,GAAG,OAQxC;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,GAAG,CAc7C;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,GAAG,OAmCtC;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,OAuCrD","file":"utils.d.ts","sourcesContent":["import _ from 'lodash';\nimport { pathToRegexp } from 'path-to-regexp';\nimport qs from 'qs';\nimport { ResourceType } from './resource';\n\nexport interface ParseRequest {\n path: string;\n method: string;\n // 资源类型\n type?: ResourceType;\n}\n\nexport interface ParseOptions {\n prefix?: string;\n accessors?: {\n list?: string;\n create?: string;\n get?: string;\n update?: string;\n delete?: string;\n set?: string;\n add?: string;\n };\n}\n\nexport interface ParsedParams {\n actionName?: string;\n resourceName?: string;\n resourceIndex?: string;\n associatedName?: string;\n associatedIndex?: string;\n // table: string;\n // tableKey?: string | number;\n // relatedTable?: string;\n // relatedKey?: string | number;\n // action?: ActionName,\n}\n\nexport function getNameByParams(params: ParsedParams): string {\n const { resourceName, associatedName } = params;\n return associatedName ? `${associatedName}.${resourceName}` : resourceName;\n}\n\nexport function parseRequest(request: ParseRequest, options: ParseOptions = {}): ParsedParams | false {\n\n const accessors = {\n // 常规 actions\n list: 'list',\n create: 'create',\n get: 'get',\n update: 'update',\n delete: 'destroy',\n // associate 操作\n add: 'add',\n set: 'set',\n remove: 'remove',\n ...(options.accessors || {}),\n };\n const keys = [];\n const regexp = pathToRegexp('/resourcer/{:associatedName.}?:resourceName{\\\\::actionName}', keys);\n const matches = regexp.exec(request.path);\n if (matches) {\n const params = {};\n keys.forEach((obj, index) => {\n if (matches[index + 1] === undefined) {\n return;\n }\n params[obj.name] = matches[index + 1];\n });\n return params;\n }\n const defaults = {\n single: {\n '/:resourceName': {\n get: accessors.list,\n post: accessors.create,\n delete: accessors.delete\n },\n '/:resourceName/:resourceIndex': {\n get: accessors.get,\n put: accessors.update,\n patch: accessors.update,\n delete: accessors.delete,\n },\n '/:associatedName/:associatedIndex/:resourceName': {\n get: accessors.list,\n post: accessors.create,\n delete: accessors.delete,\n },\n '/:associatedName/:associatedIndex/:resourceName/:resourceIndex': {\n get: accessors.get,\n post: accessors.create,\n put: accessors.update,\n patch: accessors.update,\n delete: accessors.delete,\n },\n },\n hasOne: {\n '/:associatedName/:associatedIndex/:resourceName': {\n get: accessors.get,\n post: accessors.update,\n put: accessors.update,\n patch: accessors.update,\n delete: accessors.delete,\n },\n },\n hasMany: {\n '/:associatedName/:associatedIndex/:resourceName': {\n get: accessors.list,\n post: accessors.create,\n delete: accessors.delete,\n },\n '/:associatedName/:associatedIndex/:resourceName/:resourceIndex': {\n get: accessors.get,\n post: accessors.create,\n put: accessors.update,\n patch: accessors.update,\n delete: accessors.delete,\n },\n },\n belongsTo: {\n '/:associatedName/:associatedIndex/:resourceName': {\n get: accessors.get,\n delete: accessors.remove,\n },\n '/:associatedName/:associatedIndex/:resourceName/:resourceIndex': {\n post: accessors.set,\n },\n },\n belongsToMany: {\n '/:associatedName/:associatedIndex/:resourceName': {\n get: accessors.list,\n post: accessors.set,\n },\n '/:associatedName/:associatedIndex/:resourceName/:resourceIndex': {\n get: accessors.get,\n post: accessors.add,\n put: accessors.update, // Many to Many 的 update 是针对 through\n patch: accessors.update, // Many to Many 的 update 是针对 through\n delete: accessors.remove,\n },\n },\n };\n\n const params: ParsedParams = {};\n\n let prefix = (options.prefix || '').trim().replace(/\\/$/, '');\n\n if (prefix && !prefix.startsWith('/')) {\n prefix = `/${prefix}`;\n }\n\n const { type = 'single' } = request;\n\n for (const path in defaults[type]) {\n const keys = [];\n const regexp = pathToRegexp(`${prefix}${path}`, keys, {});\n const matches = regexp.exec(request.path);\n if (!matches) {\n continue;\n }\n keys.forEach((obj, index) => {\n if (matches[index + 1] === undefined) {\n return;\n }\n params[obj.name] = matches[index + 1];\n });\n params.actionName = _.get(defaults, [type, path, request.method.toLowerCase()]);\n }\n\n if (Object.keys(params).length === 0) {\n return false;\n }\n\n if (params.resourceName) {\n const [resourceName, actionName] = params.resourceName.split(':');\n if (actionName) {\n params.resourceName = resourceName;\n params.actionName = actionName;\n }\n }\n\n return params;\n}\n\nexport function requireModule(module: any) {\n if (typeof module === 'string') {\n module = require(module);\n }\n if (typeof module !== 'object') {\n return module;\n }\n return module.__esModule ? module.default : module;\n}\n\nexport function parseQuery(input: string): any {\n // 自带 query 处理的不太给力,需要用 qs 转一下\n const query = qs.parse(input, {\n // 原始 query string 中如果一个键连等号“=”都没有可以被认为是 null 类型\n strictNullHandling: true,\n // 逗号分隔转换为数组\n comma: true\n });\n // filter 支持 json string\n if (typeof query.filter === 'string') {\n query.filter = JSON.parse(query.filter);\n }\n\n return query;\n}\n\nexport function parseFields(fields: any) {\n if (!fields) {\n return {}\n }\n if (typeof fields === 'string') {\n fields = fields.split(',').map(field => field.trim());\n }\n if (Array.isArray(fields)) {\n const onlyFields = [];\n const output: any = {};\n fields.forEach(item => {\n if (typeof item === 'string') {\n onlyFields.push(item);\n } else if (typeof item === 'object') {\n if (item.only) {\n onlyFields.push(...item.only.toString().split(','));\n }\n Object.assign(output, parseFields(item));\n }\n });\n if (onlyFields.length) {\n output.only = onlyFields;\n }\n return output;\n }\n if (fields.only && typeof fields.only === 'string') {\n fields.only = fields.only.split(',').map(field => field.trim());\n }\n if (fields.except && typeof fields.except === 'string') {\n fields.except = fields.except.split(',').map(field => field.trim());\n }\n if (fields.appends && typeof fields.appends === 'string') {\n fields.appends = fields.appends.split(',').map(field => field.trim());\n }\n return fields;\n}\n\nexport function mergeFields(defaults: any, inputs: any) {\n let fields: any = {};\n defaults = parseFields(defaults);\n inputs = parseFields(inputs);\n if (inputs.only) {\n // 前端提供 only,后端提供 only\n if (defaults.only) {\n fields.only = defaults.only.filter(field => inputs.only.includes(field))\n }\n // 前端提供 only,后端提供 except,输出 only 排除 except\n else if (defaults.except) {\n fields.only = inputs.only.filter(field => !defaults.except.includes(field))\n }\n // 前端提供 only,后端没有提供 only 或 except\n else {\n fields.only = inputs.only;\n }\n } else if (inputs.except) {\n // 前端提供 except,后端提供 only,只输出 only 里排除 except 的字段\n if (defaults.only) {\n fields.only = defaults.only.filter(field => !inputs.except.includes(field))\n }\n // 前端提供 except,后端提供 except 或不提供,合并 except\n else {\n fields.except = _.uniq([...inputs.except, ...(defaults.except || [])]);\n }\n }\n // 前端没提供 only 或 except\n else {\n fields = defaults;\n }\n // 如果前端提供了 appends\n if (!_.isEmpty(inputs.appends)) {\n fields.appends = _.uniq([...inputs.appends, ...(defaults.appends || [])]);\n }\n if (!fields.appends) {\n fields.appends = [];\n }\n return fields;\n}\n"]}
package/lib/utils.js CHANGED
@@ -61,7 +61,7 @@ function parseRequest(request, options = {}) {
61
61
  remove: 'remove'
62
62
  }, options.accessors || {});
63
63
  const keys = [];
64
- const regexp = path_to_regexp_1.pathToRegexp('/resourcer/{:associatedName.}?:resourceName{\\::actionName}', keys);
64
+ const regexp = (0, path_to_regexp_1.pathToRegexp)('/resourcer/{:associatedName.}?:resourceName{\\::actionName}', keys);
65
65
  const matches = regexp.exec(request.path);
66
66
 
67
67
  if (matches) {
@@ -83,18 +83,18 @@ function parseRequest(request, options = {}) {
83
83
  post: accessors.create,
84
84
  delete: accessors.delete
85
85
  },
86
- '/:resourceName/:resourceKey': {
86
+ '/:resourceName/:resourceIndex': {
87
87
  get: accessors.get,
88
88
  put: accessors.update,
89
89
  patch: accessors.update,
90
90
  delete: accessors.delete
91
91
  },
92
- '/:associatedName/:associatedKey/:resourceName': {
92
+ '/:associatedName/:associatedIndex/:resourceName': {
93
93
  get: accessors.list,
94
94
  post: accessors.create,
95
95
  delete: accessors.delete
96
96
  },
97
- '/:associatedName/:associatedKey/:resourceName/:resourceKey': {
97
+ '/:associatedName/:associatedIndex/:resourceName/:resourceIndex': {
98
98
  get: accessors.get,
99
99
  post: accessors.create,
100
100
  put: accessors.update,
@@ -103,7 +103,7 @@ function parseRequest(request, options = {}) {
103
103
  }
104
104
  },
105
105
  hasOne: {
106
- '/:associatedName/:associatedKey/:resourceName': {
106
+ '/:associatedName/:associatedIndex/:resourceName': {
107
107
  get: accessors.get,
108
108
  post: accessors.update,
109
109
  put: accessors.update,
@@ -112,12 +112,12 @@ function parseRequest(request, options = {}) {
112
112
  }
113
113
  },
114
114
  hasMany: {
115
- '/:associatedName/:associatedKey/:resourceName': {
115
+ '/:associatedName/:associatedIndex/:resourceName': {
116
116
  get: accessors.list,
117
117
  post: accessors.create,
118
118
  delete: accessors.delete
119
119
  },
120
- '/:associatedName/:associatedKey/:resourceName/:resourceKey': {
120
+ '/:associatedName/:associatedIndex/:resourceName/:resourceIndex': {
121
121
  get: accessors.get,
122
122
  post: accessors.create,
123
123
  put: accessors.update,
@@ -126,20 +126,20 @@ function parseRequest(request, options = {}) {
126
126
  }
127
127
  },
128
128
  belongsTo: {
129
- '/:associatedName/:associatedKey/:resourceName': {
129
+ '/:associatedName/:associatedIndex/:resourceName': {
130
130
  get: accessors.get,
131
131
  delete: accessors.remove
132
132
  },
133
- '/:associatedName/:associatedKey/:resourceName/:resourceKey': {
133
+ '/:associatedName/:associatedIndex/:resourceName/:resourceIndex': {
134
134
  post: accessors.set
135
135
  }
136
136
  },
137
137
  belongsToMany: {
138
- '/:associatedName/:associatedKey/:resourceName': {
138
+ '/:associatedName/:associatedIndex/:resourceName': {
139
139
  get: accessors.list,
140
140
  post: accessors.set
141
141
  },
142
- '/:associatedName/:associatedKey/:resourceName/:resourceKey': {
142
+ '/:associatedName/:associatedIndex/:resourceName/:resourceIndex': {
143
143
  get: accessors.get,
144
144
  post: accessors.add,
145
145
  put: accessors.update,
@@ -149,7 +149,7 @@ function parseRequest(request, options = {}) {
149
149
  }
150
150
  };
151
151
  const params = {};
152
- let prefix = (options.prefix || '').trim();
152
+ let prefix = (options.prefix || '').trim().replace(/\/$/, '');
153
153
 
154
154
  if (prefix && !prefix.startsWith('/')) {
155
155
  prefix = `/${prefix}`;
@@ -160,7 +160,7 @@ function parseRequest(request, options = {}) {
160
160
 
161
161
  for (const path in defaults[type]) {
162
162
  const keys = [];
163
- const regexp = path_to_regexp_1.pathToRegexp(`${prefix}${path}`, keys, {});
163
+ const regexp = (0, path_to_regexp_1.pathToRegexp)(`${prefix}${path}`, keys, {});
164
164
  const matches = regexp.exec(request.path);
165
165
 
166
166
  if (!matches) {
package/lib/utils.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["utils.ts"],"names":[],"mappings":"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","file":"utils.js","sourcesContent":["import _ from 'lodash';\nimport { pathToRegexp } from 'path-to-regexp';\nimport qs from 'qs';\nimport { ResourceType } from './resource';\n\nexport interface ParseRequest {\n path: string;\n method: string;\n // 资源类型\n type?: ResourceType;\n}\n\nexport interface ParseOptions {\n prefix?: string;\n accessors?: {\n list?: string;\n create?: string;\n get?: string;\n update?: string;\n delete?: string;\n set?: string;\n add?: string;\n };\n}\n\nexport interface ParsedParams {\n actionName?: string;\n resourceName?: string;\n resourceKey?: string;\n associatedName?: string;\n associatedKey?: string;\n // table: string;\n // tableKey?: string | number;\n // relatedTable?: string;\n // relatedKey?: string | number;\n // action?: ActionName,\n}\n\nexport function getNameByParams(params: ParsedParams): string {\n const { resourceName, associatedName } = params;\n return associatedName ? `${associatedName}.${resourceName}` : resourceName;\n}\n\nexport function parseRequest(request: ParseRequest, options: ParseOptions = {}): ParsedParams | false {\n\n const accessors = {\n // 常规 actions\n list: 'list',\n create: 'create',\n get: 'get',\n update: 'update',\n delete: 'destroy',\n // associate 操作\n add: 'add',\n set: 'set',\n remove: 'remove',\n ...(options.accessors || {}),\n };\n const keys = [];\n const regexp = pathToRegexp('/resourcer/{:associatedName.}?:resourceName{\\\\::actionName}', keys);\n const matches = regexp.exec(request.path);\n if (matches) {\n const params = {};\n keys.forEach((obj, index) => {\n if (matches[index + 1] === undefined) {\n return;\n }\n params[obj.name] = matches[index + 1];\n });\n return params;\n }\n const defaults = {\n single: {\n '/:resourceName': {\n get: accessors.list,\n post: accessors.create,\n delete: accessors.delete\n },\n '/:resourceName/:resourceKey': {\n get: accessors.get,\n put: accessors.update,\n patch: accessors.update,\n delete: accessors.delete,\n },\n '/:associatedName/:associatedKey/:resourceName': {\n get: accessors.list,\n post: accessors.create,\n delete: accessors.delete,\n },\n '/:associatedName/:associatedKey/:resourceName/:resourceKey': {\n get: accessors.get,\n post: accessors.create,\n put: accessors.update,\n patch: accessors.update,\n delete: accessors.delete,\n },\n },\n hasOne: {\n '/:associatedName/:associatedKey/:resourceName': {\n get: accessors.get,\n post: accessors.update,\n put: accessors.update,\n patch: accessors.update,\n delete: accessors.delete,\n },\n },\n hasMany: {\n '/:associatedName/:associatedKey/:resourceName': {\n get: accessors.list,\n post: accessors.create,\n delete: accessors.delete,\n },\n '/:associatedName/:associatedKey/:resourceName/:resourceKey': {\n get: accessors.get,\n post: accessors.create,\n put: accessors.update,\n patch: accessors.update,\n delete: accessors.delete,\n },\n },\n belongsTo: {\n '/:associatedName/:associatedKey/:resourceName': {\n get: accessors.get,\n delete: accessors.remove,\n },\n '/:associatedName/:associatedKey/:resourceName/:resourceKey': {\n post: accessors.set,\n },\n },\n belongsToMany: {\n '/:associatedName/:associatedKey/:resourceName': {\n get: accessors.list,\n post: accessors.set,\n },\n '/:associatedName/:associatedKey/:resourceName/:resourceKey': {\n get: accessors.get,\n post: accessors.add,\n put: accessors.update, // Many to Many 的 update 是针对 through\n patch: accessors.update, // Many to Many 的 update 是针对 through\n delete: accessors.remove,\n },\n },\n };\n\n const params: ParsedParams = {};\n\n let prefix = (options.prefix || '').trim();\n\n if (prefix && !prefix.startsWith('/')) {\n prefix = `/${prefix}`;\n }\n\n const { type = 'single' } = request;\n\n for (const path in defaults[type]) {\n const keys = [];\n const regexp = pathToRegexp(`${prefix}${path}`, keys, {});\n const matches = regexp.exec(request.path);\n if (!matches) {\n continue;\n }\n keys.forEach((obj, index) => {\n if (matches[index + 1] === undefined) {\n return;\n }\n params[obj.name] = matches[index + 1];\n });\n params.actionName = _.get(defaults, [type, path, request.method.toLowerCase()]);\n }\n\n if (Object.keys(params).length === 0) {\n return false;\n }\n\n if (params.resourceName) {\n const [resourceName, actionName] = params.resourceName.split(':');\n if (actionName) {\n params.resourceName = resourceName;\n params.actionName = actionName;\n }\n }\n\n return params;\n}\n\nexport function requireModule(module: any) {\n if (typeof module === 'string') {\n module = require(module);\n }\n if (typeof module !== 'object') {\n return module;\n }\n return module.__esModule ? module.default : module;\n}\n\nexport function parseQuery(input: string): any {\n // 自带 query 处理的不太给力,需要用 qs 转一下\n const query = qs.parse(input, {\n // 原始 query string 中如果一个键连等号“=”都没有可以被认为是 null 类型\n strictNullHandling: true,\n // 逗号分隔转换为数组\n comma: true\n });\n // filter 支持 json string\n if (typeof query.filter === 'string') {\n query.filter = JSON.parse(query.filter);\n }\n\n return query;\n}\n\nexport function parseFields(fields: any) {\n if (!fields) {\n return {}\n }\n if (typeof fields === 'string') {\n fields = fields.split(',').map(field => field.trim());\n }\n if (Array.isArray(fields)) {\n const onlyFields = [];\n const output: any = {};\n fields.forEach(item => {\n if (typeof item === 'string') {\n onlyFields.push(item);\n } else if (typeof item === 'object') {\n if (item.only) {\n onlyFields.push(...item.only.toString().split(','));\n }\n Object.assign(output, parseFields(item));\n }\n });\n if (onlyFields.length) {\n output.only = onlyFields;\n }\n return output;\n }\n if (fields.only && typeof fields.only === 'string') {\n fields.only = fields.only.split(',').map(field => field.trim());\n }\n if (fields.except && typeof fields.except === 'string') {\n fields.except = fields.except.split(',').map(field => field.trim());\n }\n if (fields.appends && typeof fields.appends === 'string') {\n fields.appends = fields.appends.split(',').map(field => field.trim());\n }\n return fields;\n}\n\nexport function mergeFields(defaults: any, inputs: any) {\n let fields: any = {};\n defaults = parseFields(defaults);\n inputs = parseFields(inputs);\n if (inputs.only) {\n // 前端提供 only,后端提供 only\n if (defaults.only) {\n fields.only = defaults.only.filter(field => inputs.only.includes(field))\n }\n // 前端提供 only,后端提供 except,输出 only 排除 except\n else if (defaults.except) {\n fields.only = inputs.only.filter(field => !defaults.except.includes(field))\n }\n // 前端提供 only,后端没有提供 only 或 except\n else {\n fields.only = inputs.only;\n }\n } else if (inputs.except) {\n // 前端提供 except,后端提供 only,只输出 only 里排除 except 的字段\n if (defaults.only) {\n fields.only = defaults.only.filter(field => !inputs.except.includes(field))\n }\n // 前端提供 except,后端提供 except 或不提供,合并 except\n else {\n fields.except = _.uniq([...inputs.except, ...(defaults.except || [])]);\n }\n }\n // 前端没提供 only 或 except\n else {\n fields = defaults;\n }\n // 如果前端提供了 appends\n if (!_.isEmpty(inputs.appends)) {\n fields.appends = _.uniq([...inputs.appends, ...(defaults.appends || [])]);\n }\n if (!fields.appends) {\n fields.appends = [];\n }\n return fields;\n}\n"]}
1
+ {"version":3,"sources":["utils.ts"],"names":[],"mappings":"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","file":"utils.js","sourcesContent":["import _ from 'lodash';\nimport { pathToRegexp } from 'path-to-regexp';\nimport qs from 'qs';\nimport { ResourceType } from './resource';\n\nexport interface ParseRequest {\n path: string;\n method: string;\n // 资源类型\n type?: ResourceType;\n}\n\nexport interface ParseOptions {\n prefix?: string;\n accessors?: {\n list?: string;\n create?: string;\n get?: string;\n update?: string;\n delete?: string;\n set?: string;\n add?: string;\n };\n}\n\nexport interface ParsedParams {\n actionName?: string;\n resourceName?: string;\n resourceIndex?: string;\n associatedName?: string;\n associatedIndex?: string;\n // table: string;\n // tableKey?: string | number;\n // relatedTable?: string;\n // relatedKey?: string | number;\n // action?: ActionName,\n}\n\nexport function getNameByParams(params: ParsedParams): string {\n const { resourceName, associatedName } = params;\n return associatedName ? `${associatedName}.${resourceName}` : resourceName;\n}\n\nexport function parseRequest(request: ParseRequest, options: ParseOptions = {}): ParsedParams | false {\n\n const accessors = {\n // 常规 actions\n list: 'list',\n create: 'create',\n get: 'get',\n update: 'update',\n delete: 'destroy',\n // associate 操作\n add: 'add',\n set: 'set',\n remove: 'remove',\n ...(options.accessors || {}),\n };\n const keys = [];\n const regexp = pathToRegexp('/resourcer/{:associatedName.}?:resourceName{\\\\::actionName}', keys);\n const matches = regexp.exec(request.path);\n if (matches) {\n const params = {};\n keys.forEach((obj, index) => {\n if (matches[index + 1] === undefined) {\n return;\n }\n params[obj.name] = matches[index + 1];\n });\n return params;\n }\n const defaults = {\n single: {\n '/:resourceName': {\n get: accessors.list,\n post: accessors.create,\n delete: accessors.delete\n },\n '/:resourceName/:resourceIndex': {\n get: accessors.get,\n put: accessors.update,\n patch: accessors.update,\n delete: accessors.delete,\n },\n '/:associatedName/:associatedIndex/:resourceName': {\n get: accessors.list,\n post: accessors.create,\n delete: accessors.delete,\n },\n '/:associatedName/:associatedIndex/:resourceName/:resourceIndex': {\n get: accessors.get,\n post: accessors.create,\n put: accessors.update,\n patch: accessors.update,\n delete: accessors.delete,\n },\n },\n hasOne: {\n '/:associatedName/:associatedIndex/:resourceName': {\n get: accessors.get,\n post: accessors.update,\n put: accessors.update,\n patch: accessors.update,\n delete: accessors.delete,\n },\n },\n hasMany: {\n '/:associatedName/:associatedIndex/:resourceName': {\n get: accessors.list,\n post: accessors.create,\n delete: accessors.delete,\n },\n '/:associatedName/:associatedIndex/:resourceName/:resourceIndex': {\n get: accessors.get,\n post: accessors.create,\n put: accessors.update,\n patch: accessors.update,\n delete: accessors.delete,\n },\n },\n belongsTo: {\n '/:associatedName/:associatedIndex/:resourceName': {\n get: accessors.get,\n delete: accessors.remove,\n },\n '/:associatedName/:associatedIndex/:resourceName/:resourceIndex': {\n post: accessors.set,\n },\n },\n belongsToMany: {\n '/:associatedName/:associatedIndex/:resourceName': {\n get: accessors.list,\n post: accessors.set,\n },\n '/:associatedName/:associatedIndex/:resourceName/:resourceIndex': {\n get: accessors.get,\n post: accessors.add,\n put: accessors.update, // Many to Many 的 update 是针对 through\n patch: accessors.update, // Many to Many 的 update 是针对 through\n delete: accessors.remove,\n },\n },\n };\n\n const params: ParsedParams = {};\n\n let prefix = (options.prefix || '').trim().replace(/\\/$/, '');\n\n if (prefix && !prefix.startsWith('/')) {\n prefix = `/${prefix}`;\n }\n\n const { type = 'single' } = request;\n\n for (const path in defaults[type]) {\n const keys = [];\n const regexp = pathToRegexp(`${prefix}${path}`, keys, {});\n const matches = regexp.exec(request.path);\n if (!matches) {\n continue;\n }\n keys.forEach((obj, index) => {\n if (matches[index + 1] === undefined) {\n return;\n }\n params[obj.name] = matches[index + 1];\n });\n params.actionName = _.get(defaults, [type, path, request.method.toLowerCase()]);\n }\n\n if (Object.keys(params).length === 0) {\n return false;\n }\n\n if (params.resourceName) {\n const [resourceName, actionName] = params.resourceName.split(':');\n if (actionName) {\n params.resourceName = resourceName;\n params.actionName = actionName;\n }\n }\n\n return params;\n}\n\nexport function requireModule(module: any) {\n if (typeof module === 'string') {\n module = require(module);\n }\n if (typeof module !== 'object') {\n return module;\n }\n return module.__esModule ? module.default : module;\n}\n\nexport function parseQuery(input: string): any {\n // 自带 query 处理的不太给力,需要用 qs 转一下\n const query = qs.parse(input, {\n // 原始 query string 中如果一个键连等号“=”都没有可以被认为是 null 类型\n strictNullHandling: true,\n // 逗号分隔转换为数组\n comma: true\n });\n // filter 支持 json string\n if (typeof query.filter === 'string') {\n query.filter = JSON.parse(query.filter);\n }\n\n return query;\n}\n\nexport function parseFields(fields: any) {\n if (!fields) {\n return {}\n }\n if (typeof fields === 'string') {\n fields = fields.split(',').map(field => field.trim());\n }\n if (Array.isArray(fields)) {\n const onlyFields = [];\n const output: any = {};\n fields.forEach(item => {\n if (typeof item === 'string') {\n onlyFields.push(item);\n } else if (typeof item === 'object') {\n if (item.only) {\n onlyFields.push(...item.only.toString().split(','));\n }\n Object.assign(output, parseFields(item));\n }\n });\n if (onlyFields.length) {\n output.only = onlyFields;\n }\n return output;\n }\n if (fields.only && typeof fields.only === 'string') {\n fields.only = fields.only.split(',').map(field => field.trim());\n }\n if (fields.except && typeof fields.except === 'string') {\n fields.except = fields.except.split(',').map(field => field.trim());\n }\n if (fields.appends && typeof fields.appends === 'string') {\n fields.appends = fields.appends.split(',').map(field => field.trim());\n }\n return fields;\n}\n\nexport function mergeFields(defaults: any, inputs: any) {\n let fields: any = {};\n defaults = parseFields(defaults);\n inputs = parseFields(inputs);\n if (inputs.only) {\n // 前端提供 only,后端提供 only\n if (defaults.only) {\n fields.only = defaults.only.filter(field => inputs.only.includes(field))\n }\n // 前端提供 only,后端提供 except,输出 only 排除 except\n else if (defaults.except) {\n fields.only = inputs.only.filter(field => !defaults.except.includes(field))\n }\n // 前端提供 only,后端没有提供 only 或 except\n else {\n fields.only = inputs.only;\n }\n } else if (inputs.except) {\n // 前端提供 except,后端提供 only,只输出 only 里排除 except 的字段\n if (defaults.only) {\n fields.only = defaults.only.filter(field => !inputs.except.includes(field))\n }\n // 前端提供 except,后端提供 except 或不提供,合并 except\n else {\n fields.except = _.uniq([...inputs.except, ...(defaults.except || [])]);\n }\n }\n // 前端没提供 only 或 except\n else {\n fields = defaults;\n }\n // 如果前端提供了 appends\n if (!_.isEmpty(inputs.appends)) {\n fields.appends = _.uniq([...inputs.appends, ...(defaults.appends || [])]);\n }\n if (!fields.appends) {\n fields.appends = [];\n }\n return fields;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nocobase/resourcer",
3
- "version": "0.5.0-alpha.32",
3
+ "version": "0.5.0-alpha.36",
4
4
  "description": "",
5
5
  "main": "./lib/index.js",
6
6
  "types": "./lib/index.d.ts",
@@ -18,5 +18,5 @@
18
18
  "url": "git+https://github.com/nocobase/nocobase.git",
19
19
  "directory": "packages/resourcer"
20
20
  },
21
- "gitHead": "7be6327458cb376e7281cff42a43a282105b65f8"
21
+ "gitHead": "9998cd903bf87bf9a5d8a7616055f0cd1a007a72"
22
22
  }