@lowdefy/ajv 5.3.0 → 5.4.0

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.
@@ -0,0 +1,60 @@
1
+ /*
2
+ Copyright 2020-2026 Lowdefy, Inc
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */ import Ajv from 'ajv';
16
+ import addFormats from 'ajv-formats';
17
+ import addKeywords from 'ajv-keywords';
18
+ import ajvErrors from 'ajv-errors';
19
+ // Hard cap on errors collected per generated validator function.
20
+ // `allErrors: true` is required for ajv-errors (errorMessage:), but without a
21
+ // cap an attacker can make Ajv allocate an unbounded number of error objects
22
+ // (CodeQL js/resource-exhaustion-from-deep-object-traversal). The code.process
23
+ // hook below rewrites every `errors++;` site to early-exit at this threshold,
24
+ // bounding memory at ~MAX_VALIDATION_ERRORS * ~500 bytes per validate() call.
25
+ const MAX_VALIDATION_ERRORS = 20;
26
+ // Ajv 8 emits the exact pattern `errors++;` after every error push (see
27
+ // ajv/lib/compile/errors.ts addError), and ends each generated validator with
28
+ // `<validateName>.errors = vErrors; return errors === 0;`. We inject a
29
+ // `<validateName>.errors = vErrors; return false;` guard immediately after
30
+ // each `errors++;` so the validator stops walking the input once the cap is
31
+ // reached *and* the caller still sees the (capped) errors array on the
32
+ // function's `.errors` property — which is how `ajv.errors` is populated.
33
+ function capErrors(code) {
34
+ const fnMatch = code.match(/return\s+function\s+(\w+)\s*\(/);
35
+ if (!fnMatch) return code;
36
+ const fnName = fnMatch[1];
37
+ return code.replace(/errors\+\+;/g, `errors++;if(errors>=${MAX_VALIDATION_ERRORS}){${fnName}.errors=vErrors;return false;}`);
38
+ }
39
+ const ajv = new Ajv({
40
+ // codeql[js/resource-exhaustion-from-deep-object-traversal] -- bounded by capErrors() above
41
+ allErrors: true,
42
+ strict: false,
43
+ code: {
44
+ process: capErrors
45
+ }
46
+ });
47
+ // Order matters: format and keyword definitions must be registered before
48
+ // ajv-errors so the errorMessage keyword can attach to them.
49
+ addFormats(ajv);
50
+ // `instanceof` — match JS class instances (e.g. `instanceof: 'Date'`).
51
+ // `transform` — normalise string values mid-validation (`transform: [trim, toUpperCase]`).
52
+ // `regexp` — `pattern:` with regex flags (`regexp: '/^l[0-9]+$/i'`).
53
+ addKeywords(ajv, [
54
+ 'instanceof',
55
+ 'transform',
56
+ 'regexp'
57
+ ]);
58
+ ajvErrors(ajv);
59
+ export { MAX_VALIDATION_ERRORS };
60
+ export default ajv;
@@ -0,0 +1,26 @@
1
+ /*
2
+ Copyright 2020-2026 Lowdefy, Inc
3
+
4
+ Licensed under the Apache License, Version 2.0 (the "License");
5
+ you may not use this file except in compliance with the License.
6
+ You may obtain a copy of the License at
7
+
8
+ http://www.apache.org/licenses/LICENSE-2.0
9
+
10
+ Unless required by applicable law or agreed to in writing, software
11
+ distributed under the License is distributed on an "AS IS" BASIS,
12
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ See the License for the specific language governing permissions and
14
+ limitations under the License.
15
+ */ import ajv from './ajvInstance.js';
16
+ function compile({ schema }) {
17
+ const validator = ajv.compile(schema);
18
+ return (data)=>{
19
+ const valid = validator(data);
20
+ return {
21
+ valid,
22
+ errors: valid ? [] : validator.errors || []
23
+ };
24
+ };
25
+ }
26
+ export default compile;
package/dist/index.js CHANGED
@@ -13,4 +13,5 @@
13
13
  See the License for the specific language governing permissions and
14
14
  limitations under the License.
15
15
  */ import validate from './validate.js';
16
- export { validate };
16
+ import compile from './compile.js';
17
+ export { validate, compile };
package/dist/validate.js CHANGED
@@ -12,14 +12,8 @@
12
12
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
13
  See the License for the specific language governing permissions and
14
14
  limitations under the License.
15
- */ import Ajv from 'ajv';
16
- import ajvErrors from 'ajv-errors';
15
+ */ import ajv from './ajvInstance.js';
17
16
  import createErrorMessage from './createErrorMessage.js';
18
- const ajv = new Ajv({
19
- allErrors: true,
20
- strict: false
21
- });
22
- ajvErrors(ajv);
23
17
  function validate({ schema, data, returnErrors = false }) {
24
18
  const valid = ajv.validate(schema, data);
25
19
  if (!valid) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lowdefy/ajv",
3
- "version": "5.3.0",
3
+ "version": "5.4.0",
4
4
  "license": "Apache-2.0",
5
5
  "description": "",
6
6
  "homepage": "https://lowdefy.com",
@@ -33,9 +33,11 @@
33
33
  "dist/*"
34
34
  ],
35
35
  "dependencies": {
36
- "@lowdefy/nunjucks": "5.3.0",
36
+ "@lowdefy/nunjucks": "5.4.0",
37
37
  "ajv": "8.12.0",
38
- "ajv-errors": "3.0.0"
38
+ "ajv-errors": "3.0.0",
39
+ "ajv-formats": "2.1.1",
40
+ "ajv-keywords": "5.1.0"
39
41
  },
40
42
  "devDependencies": {
41
43
  "@swc/cli": "0.8.0",