Skip to content

Commit

Permalink
feat: precompile cloudevent schema (#471)
Browse files Browse the repository at this point in the history
* feat: precompile cloudevent schema

This commit modifies the build pipleline so that the cloudevent schema is
precompiled for runtime validation. This eliminates the need to compile the
schema at runtime, improving both performance and security.

Fixes: #423

Signed-off-by: Lance Ball <lball@redhat.com>
  • Loading branch information
lance authored Feb 15, 2022
1 parent 4d8f03f commit b13bde9
Show file tree
Hide file tree
Showing 11 changed files with 275 additions and 133 deletions.
1 change: 1 addition & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"plugins": [
"header"
],
"ignorePatterns": ["**/schema/*"],
"rules": {
"no-var": "error",
"standard/no-callback-literal": "off",
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ index.js
/bundles
/dist
/docs
src/schema/v1.js

# Runtime data
pids
Expand Down
137 changes: 117 additions & 20 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 7 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
"main": "dist/index.js",
"scripts": {
"watch": "tsc --project tsconfig.json --watch",
"build": "tsc --project tsconfig.json && tsc --project tsconfig.browser.json && webpack",
"build:src": "tsc --project tsconfig.json",
"build:browser": "tsc --project tsconfig.browser.json && webpack",
"build:schema": "ajv compile -c ./src/schema/formats.js -s src/schema/cloudevent.json --strict-types false -o src/schema/v1.js",
"build": "npm run build:schema && npm run build:src && npm run build:browser",
"lint": "npm run lint:md && npm run lint:js",
"lint:js": "eslint 'src/**/*.{js,ts}' 'test/**/*.{js,ts}' cucumber.js",
"lint:md": "remark .",
Expand Down Expand Up @@ -106,13 +109,12 @@
},
"homepage": "https://github.com/cloudevents/sdk-javascript#readme",
"dependencies": {
"ajv": "~6.12.3",
"ajv": "^8.6.3",
"util": "^0.12.4",
"uuid": "~8.3.0"
},
"devDependencies": {
"@cucumber/cucumber": "^8.0.0-rc.1",
"@types/ajv": "^1.0.0",
"@types/chai": "^4.2.11",
"@types/cucumber": "^6.0.1",
"@types/got": "^9.6.11",
Expand All @@ -122,6 +124,8 @@
"@types/uuid": "^8.0.0",
"@typescript-eslint/eslint-plugin": "^4.29.0",
"@typescript-eslint/parser": "^4.29.0",
"ajv-cli": "^5.0.0",
"ajv-formats": "^2.1.1",
"axios": "^0.21.3",
"chai": "~4.2.0",
"eslint": "^7.32.0",
Expand Down
86 changes: 0 additions & 86 deletions src/event/schemas.ts

This file was deleted.

17 changes: 3 additions & 14 deletions src/event/spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,17 @@
SPDX-License-Identifier: Apache-2.0
*/

import Ajv, { Options } from "ajv";
import { ValidationError } from "./validation";

import { CloudEventV1 } from "./interfaces";
import { schemaV1 } from "./schemas";
import { Version } from "./cloudevent";
import validate from "../schema/v1";

const ajv = new Ajv({ extendRefs: true } as Options);

// handle date-time format specially because a user could pass
// Date().toString(), which is not spec compliant date-time format
ajv.addFormat("js-date-time", function (dateTimeString) {
const date = new Date(Date.parse(dateTimeString));
return date.toString() !== "Invalid Date";
});

const isValidAgainstSchemaV1 = ajv.compile(schemaV1);

export function validateCloudEvent<T>(event: CloudEventV1<T>): boolean {
if (event.specversion === Version.V1) {
if (!isValidAgainstSchemaV1(event)) {
throw new ValidationError("invalid payload", isValidAgainstSchemaV1.errors);
if (!validate(event)) {
throw new ValidationError("invalid payload", (validate as any).errors);
}
} else {
return false;
Expand Down
Loading

0 comments on commit b13bde9

Please sign in to comment.