From 149845fc5326623cfc63aa109a62182450e4c9b5 Mon Sep 17 00:00:00 2001 From: Evan Hahn Date: Thu, 12 Sep 2024 13:30:58 -0500 Subject: [PATCH] chore: work around Ajv module bug in generated code (#256) JavaScript module inconsistency strikes again. In some cases, Ajv will inject `require` calls into generated code even if you ask it to generate ESM. [This is a bug][0]. For example, here's something it adds if you use [the string `minLength` or `maxLength` properties][1]: // ... const func2 = require("ajv/dist/runtime/ucs2length").default; // ... That won't work in an ESM environment. As a workaround, I inject the following into our generated code: import { createRequire } from 'node:module'; const require = createRequire(import.meta.url); This, along with moving `ajv` to production dependencies, should work around this issue until the bug is fixed. [0]: https://github.com/ajv-validator/ajv/issues/2209 [1]: https://json-schema.org/understanding-json-schema/reference/string#length --- package-lock.json | 13 ++++--------- package.json | 2 +- scripts/lib/generate-validations.js | 10 +++++++++- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/package-lock.json b/package-lock.json index 52958165..a2a6ebdc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "3.0.0-next.26", "license": "MIT", "dependencies": { + "ajv": "^8.12.0", "compact-encoding": "^2.12.0", "protobufjs": "^7.2.5", "type-fest": "^4.26.0" @@ -18,7 +19,6 @@ "@json-schema-tools/dereferencer": "^1.6.3", "@types/compact-encoding": "^2.15.0", "@types/json-schema": "^7.0.12", - "ajv": "^8.12.0", "c8": "^8.0.1", "cpy-cli": "^5.0.0", "eslint": "^8.46.0", @@ -833,7 +833,7 @@ "version": "8.12.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", - "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -1819,8 +1819,7 @@ "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "node_modules/fast-fifo": { "version": "1.1.0", @@ -2885,8 +2884,7 @@ "node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -3944,7 +3942,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true, "engines": { "node": ">=6" } @@ -4332,7 +4329,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -5129,7 +5125,6 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, "dependencies": { "punycode": "^2.1.0" } diff --git a/package.json b/package.json index 8abf8b6e..707b4440 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,6 @@ "@json-schema-tools/dereferencer": "^1.6.3", "@types/compact-encoding": "^2.15.0", "@types/json-schema": "^7.0.12", - "ajv": "^8.12.0", "c8": "^8.0.1", "cpy-cli": "^5.0.0", "eslint": "^8.46.0", @@ -61,6 +60,7 @@ "typescript": "^5.5.4" }, "dependencies": { + "ajv": "^8.12.0", "compact-encoding": "^2.12.0", "protobufjs": "^7.2.5", "type-fest": "^4.26.0" diff --git a/scripts/lib/generate-validations.js b/scripts/lib/generate-validations.js index 09bef59c..f8cf93bb 100644 --- a/scripts/lib/generate-validations.js +++ b/scripts/lib/generate-validations.js @@ -26,5 +26,13 @@ export function generateValidations(config, jsonSchemas) { ajv.addKeyword('meta:enum') // generate validation code - return '// @ts-nocheck\n' + standaloneCode(ajv, schemaExports) + return [ + '// @ts-nocheck', + // AJV has [a bug when generating ESM code][0]: it includes `require` in the + // output. We should be able to remove this once the bug is fixed. + // [0]: https://github.com/ajv-validator/ajv/issues/2209 + "import { createRequire } from 'node:module';", + 'const require = createRequire(import.meta.url);', + standaloneCode(ajv, schemaExports), + ].join('\n') }