Skip to content

Commit

Permalink
feat(controllers): add a config to allow additional properties in act…
Browse files Browse the repository at this point in the history
…ions definitions
  • Loading branch information
fmauNeko committed Jan 7, 2025
1 parent ba37acb commit 8c3eabe
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 13 deletions.
13 changes: 13 additions & 0 deletions .kuzzlerc.sample.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -1117,5 +1117,18 @@
"sync": 7511
},
"syncTimeout": 5000
},
// [controllers]
// Controllers configuration
// * definition:
// Options to manage controllers definition behavior
// * allowAdditionalActionProperties:
// If set to true, Kuzzle will allow additional properties in
// actions definitions. If set to false, Kuzzle will throw an error
// if an action definition contains additional properties.
"controllers": {
"definition": {
"allowAdditionalActionProperties": false
}
}
}
6 changes: 6 additions & 0 deletions lib/config/default.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,12 @@ const defaultConfig: KuzzleConfiguration = {
},
/** @type {DocumentSpecification} */
validation: {},

controllers: {
definition: {
allowAdditionalActionProperties: false,
},
},
};

export default defaultConfig;
28 changes: 16 additions & 12 deletions lib/core/plugin/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -333,19 +333,23 @@ class Plugin {
for (const [action, actionDefinition] of Object.entries(
definition.actions,
)) {
const actionProperties = Object.keys(actionDefinition);

if (actionProperties.length > 2) {
actionProperties.splice(actionProperties.indexOf("handler"), 1);
actionProperties.splice(actionProperties.indexOf("http"), 1);

throw assertionError.get(
"invalid_controller_definition",
name,
`action "${action}" has invalid properties: ${actionProperties.join(
", ",
)}`,
if (
!global.app.config.content.controllers.definition
.allowAdditionalActionProperties
) {
const actionProperties = Object.keys(actionDefinition).filter(
(prop) => prop !== "handler" && prop !== "http",
);

if (actionProperties.length > 0) {
throw assertionError.get(
"invalid_controller_definition",
name,
`action "${action}" has invalid properties: ${actionProperties.join(
", ",
)}`,
);
}
}

if (typeof action !== "string") {
Expand Down
11 changes: 11 additions & 0 deletions lib/types/config/KuzzleConfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,17 @@ export interface IKuzzleConfiguration {
};

validation: Record<string, unknown>;

controllers: {
definition: {
/**
* Allow additional properties in action definitions.
*
* @default false
*/
allowAdditionalActionProperties: boolean;
};
};
}

export type KuzzleConfiguration = Partial<IKuzzleConfiguration>;
38 changes: 37 additions & 1 deletion test/core/backend/BackendController.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ describe("Backend", () => {

beforeEach(() => {
definition = getDefinition();
global.app.config.content.controllers.definition.allowAdditionalActionProperties = false;
});

it("should registers a new controller definition", () => {
Expand All @@ -89,9 +90,26 @@ describe("Backend", () => {
delete definition.actions;

should(() => {
application.controller.register(definition);
application.controller.register("greeting", definition);
}).throwError({ id: "plugin.assert.invalid_controller_definition" });
});

it("should reject additional properties", () => {
definition.actions.sayHello.foo = "bar";

should(() => {
application.controller.register("greeting", definition);
}).throwError({ id: "plugin.assert.invalid_controller_definition" });
});

it("should accept additional properties if config allows it", () => {
global.app.config.content.controllers.definition.allowAdditionalActionProperties = true;
definition.actions.sayHello.foo = "bar";

should(() => {
application.controller.register("greeting", definition);
}).not.throwError({ id: "plugin.assert.invalid_controller_definition" });
});
});

describe("ControllerManager#use", () => {
Expand All @@ -113,6 +131,7 @@ describe("Backend", () => {

beforeEach(() => {
controller = new GreetingController();
global.app.config.content.controllers.definition.allowAdditionalActionProperties = false;
});

it("should uses a new controller instance", () => {
Expand Down Expand Up @@ -155,5 +174,22 @@ describe("Backend", () => {
application.controller.use(controller);
}).throwError({ id: "plugin.assert.invalid_controller_definition" });
});

it("should reject additional properties", () => {
controller.definition.actions.sayHello.foo = "bar";

should(() => {
application.controller.use(controller);
}).throwError({ id: "plugin.assert.invalid_controller_definition" });
});

it("should accept additional properties if config allows it", () => {
global.app.config.content.controllers.definition.allowAdditionalActionProperties = true;
controller.definition.actions.sayHello.foo = "bar";

should(() => {
application.controller.use(controller);
}).not.throwError({ id: "plugin.assert.invalid_controller_definition" });
});
});
});

0 comments on commit 8c3eabe

Please sign in to comment.