Skip to content

Commit

Permalink
fix: named action execution
Browse files Browse the repository at this point in the history
  • Loading branch information
loopingz committed Dec 5, 2023
1 parent 7a8a90e commit 931f4b2
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 17 deletions.
17 changes: 10 additions & 7 deletions packages/core/src/models/coremodel.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ class TestMask extends CoreModel {
return super.attributePermission(key, value, mode, context);
}

@Action()
static globalAction() {}
@Action({ name: "globalAction" })
static globalActionMethod() {}

@Action()
localAction() {}
Expand All @@ -57,6 +57,9 @@ class TestMask extends CoreModel {
class SubTestMask extends TestMask {
@Action()
secondAction() {}

@Action({ name: "localAction" })
localActionMethod(): void {}
}
@suite
class CoreModelTest extends WebdaTest {
Expand All @@ -80,13 +83,13 @@ class CoreModelTest extends WebdaTest {
actionAnnotation() {
assert.deepStrictEqual(CoreModel.getActions(), {});
assert.deepStrictEqual(TestMask.getActions(), {
localAction: { global: false },
globalAction: { global: true }
localAction: { global: false, method: "localAction" },
globalAction: { global: true, method: "globalActionMethod", name: "globalAction" }
});
assert.deepStrictEqual(SubTestMask.getActions(), {
secondAction: { global: false },
localAction: { global: false },
globalAction: { global: true }
secondAction: { global: false, method: "secondAction" },
localAction: { global: false, method: "localActionMethod", name: "localAction" },
globalAction: { global: true, method: "globalActionMethod", name: "globalAction" }
});
}

Expand Down
9 changes: 7 additions & 2 deletions packages/core/src/models/coremodel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,10 @@ export interface ModelAction {
* Additional openapi info
*/
openapi?: any;
/**
* Method of the action
*/
method?: string;
}

/**
Expand Down Expand Up @@ -356,7 +360,8 @@ export function Action(options: { methods?: HttpMethodType[]; openapi?: any; nam
const actions = ActionsAnnotated.get(custom);
actions[options.name || propertyKey] = {
...options,
global
global,
method: propertyKey
};
};
}
Expand Down Expand Up @@ -1017,7 +1022,7 @@ class CoreModel {
}
clazz = Object.getPrototypeOf(clazz);
}
// Reduce right to give priority to the last class:
// Reduce right to give priority to the last class:
return actions.reduceRight((v, c) => ({ ...v, ...c }), {});
}

Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/services/domainservice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -708,7 +708,7 @@ export class RESTDomainService<
return model.store().httpGlobalAction(ctx, model);
} else {
ctx.getParameters().uuid = model.completeUid(ctx.getParameters().uuid);
return model.store().httpAction(ctx);
return model.store().httpAction(ctx, action.method);
}
},
openapi
Expand Down
16 changes: 9 additions & 7 deletions packages/core/src/stores/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -799,23 +799,24 @@ abstract class Store<
let actions = this._model.getActions();
Object.keys(actions).forEach(name => {
let action: ModelAction = actions[name];
action.method ??= name;
if (!action.methods) {
action.methods = ["PUT"];
}
let executer;
if (action.global) {
// By default will grab the object and then call the action
if (!this._model[name]) {
throw Error("Action static method " + name + " does not exist");
if (!this._model[action.method]) {
throw Error("Action static method " + action.method + " does not exist");
}
executer = this.httpGlobalAction;
this.addRoute(`./${name}`, action.methods, executer, action.openapi);
} else {
// By default will grab the object and then call the action
if (!this._model.prototype[name]) {
throw Error("Action method " + name + " does not exist");
if (!this._model.prototype[action.method]) {
throw Error("Action method " + action.method + " does not exist");
}
executer = this.httpAction;
executer = ctx => this.httpAction(ctx, action.method);

this.addRoute(`./{uuid}/${name}`, action.methods, executer, action.openapi);
}
Expand Down Expand Up @@ -2096,8 +2097,9 @@ abstract class Store<
* Handle obect action
* @param ctx
*/
async httpAction(ctx: WebContext) {
async httpAction(ctx: WebContext, actionMethod?: string) {
let action = ctx.getHttpContext().getUrl().split("/").pop();
actionMethod ??= action;
let object = await this.get(ctx.parameter("uuid"), ctx);
if (object === undefined || object.__deleted) {
throw new WebdaError.NotFound("Object not found or is deleted");
Expand All @@ -2121,7 +2123,7 @@ abstract class Store<
context: ctx
};
await Promise.all([this.emitSync("Store.Action", evt), object.__class.emitSync("Store.Action", evt)]);
const res = await object[action](ctx);
const res = await object[actionMethod](ctx);
if (res) {
ctx.write(res);
}
Expand Down

0 comments on commit 931f4b2

Please sign in to comment.