From 2888cf5f5a5a35011acf99e9ae6f037fb6dd50c9 Mon Sep 17 00:00:00 2001 From: "Queen Vinyl Da.i'gyu-Kazotetsu" Date: Mon, 6 Jun 2022 22:16:45 -0700 Subject: [PATCH] Generate TypeScript definitions from schema (#16571) * Install json-schema-to-typescript * Auto-generate typedefs from JSON schema * Remove primary_identifier from schema * Remove webextensions_compat_statement * Reverse order of typedefs output * Add TS type overrides * Allow for top-level __compat should we ever want it * Ensure potentially-unreachable definitions are generated as well * Generate BrowserName type from BCD * Generate enum types for browser data * Add/update descriptions * Simplify schema for support statements * Don't mark "mirror" as potential option for support statement * Generate CompatData type * Enforce type on compat data file * Add custom names to file types in schema * Rename script * Fix types output * Apply transformations to TypeScript manually (until PR is merged) * Move test to ensure alt. name + prefix aren't both defined into linter * Add descriptions * Update types * Make browser type property required * Add keywords to AJV * Finish preparing auto-generated types * Replace types.d.ts with auto-generated file * Ignore types.d.ts in Prettier/ESLint --- .eslintignore | 1 + .gitignore | 1 + .prettierignore | 1 + package-lock.json | 663 ++++++++++++++++++++++++++++++++ package.json | 5 +- schemas/browsers.schema.json | 87 +++-- schemas/compat-data.schema.json | 161 ++++---- scripts/generate-types.js | 88 +++++ test/linter/test-prefix.js | 5 + test/linter/test-schema.js | 5 + types.d.ts | 406 ------------------- 11 files changed, 890 insertions(+), 533 deletions(-) create mode 100644 scripts/generate-types.js delete mode 100644 types.d.ts diff --git a/.eslintignore b/.eslintignore index 9598782dedca55..e0434ca013459c 100644 --- a/.eslintignore +++ b/.eslintignore @@ -10,3 +10,4 @@ LICENSE /CODE_OF_CONDUCT.md build/ coverage/ +types.d.ts diff --git a/.gitignore b/.gitignore index f8545075ef88a5..8b7d9a8ad55077 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ yarn.lock .nyc_output/ coverage.lcov coverage/ +types.d.ts diff --git a/.prettierignore b/.prettierignore index 9598782dedca55..e0434ca013459c 100644 --- a/.prettierignore +++ b/.prettierignore @@ -10,3 +10,4 @@ LICENSE /CODE_OF_CONDUCT.md build/ coverage/ +types.d.ts diff --git a/package-lock.json b/package-lock.json index f6d70226b7034c..3222d73726aeac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,6 +33,7 @@ "eslint-plugin-promise": "~6.0.0", "fast-json-stable-stringify": "~2.1.0", "fdir": "~5.2.0", + "json-schema-to-typescript": "~10.1.5", "mdn-confluence": "~2.2.2", "mocha": "~10.0.0", "open-cli": "~7.0.1", @@ -61,6 +62,18 @@ "node": ">=6.0.0" } }, + "node_modules/@apidevtools/json-schema-ref-parser": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-9.0.9.tgz", + "integrity": "sha512-GBD2Le9w2+lVFoc4vswGI/TjkNIZSVp7+9xPf+X3uidBfWnAeUWmquteSyt0+VCrhNMWj/FTABISQrD3Z/YA+w==", + "dev": true, + "dependencies": { + "@jsdevtools/ono": "^7.1.3", + "@types/json-schema": "^7.0.6", + "call-me-maybe": "^1.0.1", + "js-yaml": "^4.1.0" + } + }, "node_modules/@babel/code-frame": { "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", @@ -730,6 +743,12 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "node_modules/@jsdevtools/ono": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", + "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==", + "dev": true + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -795,18 +814,46 @@ "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", "dev": true }, + "node_modules/@types/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", + "dev": true, + "dependencies": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", "dev": true }, + "node_modules/@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "dev": true + }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, + "node_modules/@types/lodash": { + "version": "4.14.182", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.182.tgz", + "integrity": "sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q==", + "dev": true + }, + "node_modules/@types/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", + "dev": true + }, "node_modules/@types/minimist": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", @@ -825,6 +872,12 @@ "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", "dev": true }, + "node_modules/@types/prettier": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.6.3.tgz", + "integrity": "sha512-ymZk3LEC/fsut+/Q5qejp6R9O1rMxz3XaRHDV6kX8MrGAhOSPqVARbDi+EZvInBpw+BnCX3TD240byVkOfQsHg==", + "dev": true + }, "node_modules/@ungap/promise-all-settled": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", @@ -955,6 +1008,12 @@ "node": ">=4" } }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true + }, "node_modules/anymatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", @@ -1313,6 +1372,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/call-me-maybe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", + "integrity": "sha512-wCyFsDQkKPwwF8BDwOiWNx/9K45L/hvggQiDbve+viMNMQnWhrlYIuBk09offfwCRtCO9P6XwUttufzU11WCVw==", + "dev": true + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -1481,6 +1546,22 @@ "node": ">=6" } }, + "node_modules/cli-color": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-2.0.2.tgz", + "integrity": "sha512-g4JYjrTW9MGtCziFNjkqp3IMpGhnJyeB0lOtRPjQkYhXzKYr6tYnXKyEVnMzITxhpbahsEW9KsxOYIDKwcsIBw==", + "dev": true, + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.59", + "es6-iterator": "^2.0.3", + "memoizee": "^0.4.15", + "timers-ext": "^0.1.7" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/cli-cursor": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", @@ -1599,6 +1680,16 @@ "node": ">=8" } }, + "node_modules/d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "dev": true, + "dependencies": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -1857,6 +1948,54 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/es5-ext": { + "version": "0.10.61", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.61.tgz", + "integrity": "sha512-yFhIqQAzu2Ca2I4SE2Au3rxVfmohU9Y7wqGR+s7+H7krk26NXhIRAZDgqd6xqjCEFUomDEA3/Bo/7fKmIkW1kA==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "next-tick": "^1.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", + "dev": true, + "dependencies": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/es6-symbol": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", + "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "dev": true, + "dependencies": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, + "node_modules/es6-weak-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", + "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", + "dev": true, + "dependencies": { + "d": "1", + "es5-ext": "^0.10.46", + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.1" + } + }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -2554,6 +2693,31 @@ "node": ">=0.10.0" } }, + "node_modules/event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", + "dev": true, + "dependencies": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "node_modules/ext": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.6.0.tgz", + "integrity": "sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg==", + "dev": true, + "dependencies": { + "type": "^2.5.0" + } + }, + "node_modules/ext/node_modules/type": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/type/-/type-2.6.0.tgz", + "integrity": "sha512-eiDBDOmkih5pMbo9OqsqPRGMljLodLcwd5XD5JbtNB0o89xZAwynY9EdCDsJU7LtcVCClu9DvM7/0Ep1hYX3EQ==", + "dev": true + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -2859,6 +3023,21 @@ "node": ">= 6" } }, + "node_modules/glob-promise": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/glob-promise/-/glob-promise-3.4.0.tgz", + "integrity": "sha512-q08RJ6O+eJn+dVanerAndJwIcumgbDdYiUT7zFQl3Wm1xD6fBKtah7H8ZJChj4wP+8C+QfeVy8xautR7rdmKEw==", + "dev": true, + "dependencies": { + "@types/glob": "*" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "glob": "*" + } + }, "node_modules/glob/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -3330,6 +3509,12 @@ "node": ">=8" } }, + "node_modules/is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", + "dev": true + }, "node_modules/is-regex": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", @@ -3515,6 +3700,59 @@ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true }, + "node_modules/json-schema-ref-parser": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/json-schema-ref-parser/-/json-schema-ref-parser-9.0.9.tgz", + "integrity": "sha512-qcP2lmGy+JUoQJ4DOQeLaZDqH9qSkeGCK3suKWxJXS82dg728Mn3j97azDMaOUmJAN4uCq91LdPx4K7E8F1a7Q==", + "dev": true, + "dependencies": { + "@apidevtools/json-schema-ref-parser": "9.0.9" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/json-schema-to-typescript": { + "version": "10.1.5", + "resolved": "https://registry.npmjs.org/json-schema-to-typescript/-/json-schema-to-typescript-10.1.5.tgz", + "integrity": "sha512-X8bNNksfCQo6LhEuqNxmZr4eZpPjXZajmimciuk8eWXzZlif9Brq7WuMGD/SOhBKcRKP2SGVDNZbC28WQqx9Rg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.6", + "@types/lodash": "^4.14.168", + "@types/prettier": "^2.1.5", + "cli-color": "^2.0.0", + "get-stdin": "^8.0.0", + "glob": "^7.1.6", + "glob-promise": "^3.4.0", + "is-glob": "^4.0.1", + "json-schema-ref-parser": "^9.0.6", + "json-stringify-safe": "^5.0.1", + "lodash": "^4.17.20", + "minimist": "^1.2.5", + "mkdirp": "^1.0.4", + "mz": "^2.7.0", + "prettier": "^2.2.0" + }, + "bin": { + "json2ts": "dist/src/cli.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/json-schema-to-typescript/node_modules/get-stdin": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", + "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", @@ -3527,6 +3765,12 @@ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true + }, "node_modules/json5": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", @@ -3609,6 +3853,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -3692,6 +3942,15 @@ "node": ">=10" } }, + "node_modules/lru-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", + "integrity": "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==", + "dev": true, + "dependencies": { + "es5-ext": "~0.10.2" + } + }, "node_modules/make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -3772,6 +4031,22 @@ "node": ">=10" } }, + "node_modules/memoizee": { + "version": "0.4.15", + "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz", + "integrity": "sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==", + "dev": true, + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.53", + "es6-weak-map": "^2.0.3", + "event-emitter": "^0.3.5", + "is-promise": "^2.2.2", + "lru-queue": "^0.1.0", + "next-tick": "^1.1.0", + "timers-ext": "^0.1.7" + } + }, "node_modules/meow": { "version": "10.1.2", "resolved": "https://registry.npmjs.org/meow/-/meow-10.1.2.tgz", @@ -3909,6 +4184,18 @@ "node": ">=0.10.0" } }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/mocha": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.0.0.tgz", @@ -4001,6 +4288,17 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, "node_modules/nanoid": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", @@ -4019,6 +4317,12 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, + "node_modules/next-tick": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", + "dev": true + }, "node_modules/node-releases": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.4.tgz", @@ -4050,6 +4354,15 @@ "node": ">=0.10.0" } }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/object-inspect": { "version": "1.12.0", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", @@ -5073,6 +5386,37 @@ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=", + "dev": true, + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/timers-ext": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", + "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==", + "dev": true, + "dependencies": { + "es5-ext": "~0.10.46", + "next-tick": "1" + } + }, "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -5194,6 +5538,12 @@ "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", "dev": true }, + "node_modules/type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", + "dev": true + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -5534,6 +5884,18 @@ "@jridgewell/trace-mapping": "^0.3.9" } }, + "@apidevtools/json-schema-ref-parser": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-9.0.9.tgz", + "integrity": "sha512-GBD2Le9w2+lVFoc4vswGI/TjkNIZSVp7+9xPf+X3uidBfWnAeUWmquteSyt0+VCrhNMWj/FTABISQrD3Z/YA+w==", + "dev": true, + "requires": { + "@jsdevtools/ono": "^7.1.3", + "@types/json-schema": "^7.0.6", + "call-me-maybe": "^1.0.1", + "js-yaml": "^4.1.0" + } + }, "@babel/code-frame": { "version": "7.16.7", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", @@ -6062,6 +6424,12 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "@jsdevtools/ono": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", + "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==", + "dev": true + }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -6118,18 +6486,46 @@ "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", "dev": true }, + "@types/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", + "dev": true, + "requires": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, "@types/istanbul-lib-coverage": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", "dev": true }, + "@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "dev": true + }, "@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, + "@types/lodash": { + "version": "4.14.182", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.182.tgz", + "integrity": "sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q==", + "dev": true + }, + "@types/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", + "dev": true + }, "@types/minimist": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", @@ -6148,6 +6544,12 @@ "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", "dev": true }, + "@types/prettier": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.6.3.tgz", + "integrity": "sha512-ymZk3LEC/fsut+/Q5qejp6R9O1rMxz3XaRHDV6kX8MrGAhOSPqVARbDi+EZvInBpw+BnCX3TD240byVkOfQsHg==", + "dev": true + }, "@ungap/promise-all-settled": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", @@ -6240,6 +6642,12 @@ "color-convert": "^1.9.0" } }, + "any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "dev": true + }, "anymatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", @@ -6495,6 +6903,12 @@ "get-intrinsic": "^1.0.2" } }, + "call-me-maybe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", + "integrity": "sha512-wCyFsDQkKPwwF8BDwOiWNx/9K45L/hvggQiDbve+viMNMQnWhrlYIuBk09offfwCRtCO9P6XwUttufzU11WCVw==", + "dev": true + }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -6599,6 +7013,19 @@ "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", "dev": true }, + "cli-color": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-2.0.2.tgz", + "integrity": "sha512-g4JYjrTW9MGtCziFNjkqp3IMpGhnJyeB0lOtRPjQkYhXzKYr6tYnXKyEVnMzITxhpbahsEW9KsxOYIDKwcsIBw==", + "dev": true, + "requires": { + "d": "^1.0.1", + "es5-ext": "^0.10.59", + "es6-iterator": "^2.0.3", + "memoizee": "^0.4.15", + "timers-ext": "^0.1.7" + } + }, "cli-cursor": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", @@ -6698,6 +7125,16 @@ "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", "dev": true }, + "d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "dev": true, + "requires": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -6901,6 +7338,50 @@ "is-symbol": "^1.0.2" } }, + "es5-ext": { + "version": "0.10.61", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.61.tgz", + "integrity": "sha512-yFhIqQAzu2Ca2I4SE2Au3rxVfmohU9Y7wqGR+s7+H7krk26NXhIRAZDgqd6xqjCEFUomDEA3/Bo/7fKmIkW1kA==", + "dev": true, + "requires": { + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "next-tick": "^1.1.0" + } + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "es6-symbol": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", + "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "dev": true, + "requires": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, + "es6-weak-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", + "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "^0.10.46", + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.1" + } + }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -7401,6 +7882,33 @@ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, + "event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, + "ext": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.6.0.tgz", + "integrity": "sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg==", + "dev": true, + "requires": { + "type": "^2.5.0" + }, + "dependencies": { + "type": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/type/-/type-2.6.0.tgz", + "integrity": "sha512-eiDBDOmkih5pMbo9OqsqPRGMljLodLcwd5XD5JbtNB0o89xZAwynY9EdCDsJU7LtcVCClu9DvM7/0Ep1hYX3EQ==", + "dev": true + } + } + }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -7641,6 +8149,15 @@ "is-glob": "^4.0.1" } }, + "glob-promise": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/glob-promise/-/glob-promise-3.4.0.tgz", + "integrity": "sha512-q08RJ6O+eJn+dVanerAndJwIcumgbDdYiUT7zFQl3Wm1xD6fBKtah7H8ZJChj4wP+8C+QfeVy8xautR7rdmKEw==", + "dev": true, + "requires": { + "@types/glob": "*" + } + }, "globals": { "version": "13.15.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz", @@ -7941,6 +8458,12 @@ "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true }, + "is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", + "dev": true + }, "is-regex": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", @@ -8069,6 +8592,46 @@ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true }, + "json-schema-ref-parser": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/json-schema-ref-parser/-/json-schema-ref-parser-9.0.9.tgz", + "integrity": "sha512-qcP2lmGy+JUoQJ4DOQeLaZDqH9qSkeGCK3suKWxJXS82dg728Mn3j97azDMaOUmJAN4uCq91LdPx4K7E8F1a7Q==", + "dev": true, + "requires": { + "@apidevtools/json-schema-ref-parser": "9.0.9" + } + }, + "json-schema-to-typescript": { + "version": "10.1.5", + "resolved": "https://registry.npmjs.org/json-schema-to-typescript/-/json-schema-to-typescript-10.1.5.tgz", + "integrity": "sha512-X8bNNksfCQo6LhEuqNxmZr4eZpPjXZajmimciuk8eWXzZlif9Brq7WuMGD/SOhBKcRKP2SGVDNZbC28WQqx9Rg==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.6", + "@types/lodash": "^4.14.168", + "@types/prettier": "^2.1.5", + "cli-color": "^2.0.0", + "get-stdin": "^8.0.0", + "glob": "^7.1.6", + "glob-promise": "^3.4.0", + "is-glob": "^4.0.1", + "json-schema-ref-parser": "^9.0.6", + "json-stringify-safe": "^5.0.1", + "lodash": "^4.17.20", + "minimist": "^1.2.5", + "mkdirp": "^1.0.4", + "mz": "^2.7.0", + "prettier": "^2.2.0" + }, + "dependencies": { + "get-stdin": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", + "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", + "dev": true + } + } + }, "json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", @@ -8081,6 +8644,12 @@ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true + }, "json5": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", @@ -8142,6 +8711,12 @@ "p-locate": "^5.0.0" } }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, "lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -8203,6 +8778,15 @@ "yallist": "^4.0.0" } }, + "lru-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", + "integrity": "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==", + "dev": true, + "requires": { + "es5-ext": "~0.10.2" + } + }, "make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -8266,6 +8850,22 @@ } } }, + "memoizee": { + "version": "0.4.15", + "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz", + "integrity": "sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==", + "dev": true, + "requires": { + "d": "^1.0.1", + "es5-ext": "^0.10.53", + "es6-weak-map": "^2.0.3", + "event-emitter": "^0.3.5", + "is-promise": "^2.2.2", + "lru-queue": "^0.1.0", + "next-tick": "^1.1.0", + "timers-ext": "^0.1.7" + } + }, "meow": { "version": "10.1.2", "resolved": "https://registry.npmjs.org/meow/-/meow-10.1.2.tgz", @@ -8373,6 +8973,12 @@ } } }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + }, "mocha": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.0.0.tgz", @@ -8441,6 +9047,17 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, + "mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "requires": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, "nanoid": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz", @@ -8453,6 +9070,12 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, + "next-tick": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", + "dev": true + }, "node-releases": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.4.tgz", @@ -8478,6 +9101,12 @@ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true + }, "object-inspect": { "version": "1.12.0", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz", @@ -9158,6 +9787,34 @@ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, + "thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "requires": { + "any-promise": "^1.0.0" + } + }, + "thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=", + "dev": true, + "requires": { + "thenify": ">= 3.1.0 < 4" + } + }, + "timers-ext": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", + "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==", + "dev": true, + "requires": { + "es5-ext": "~0.10.46", + "next-tick": "1" + } + }, "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -9237,6 +9894,12 @@ "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==", "dev": true }, + "type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", + "dev": true + }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", diff --git a/package.json b/package.json index d6441ad8f7e1b5..c4f24a195b4132 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,7 @@ "eslint-plugin-promise": "~6.0.0", "fast-json-stable-stringify": "~2.1.0", "fdir": "~5.2.0", + "json-schema-to-typescript": "~10.1.5", "mdn-confluence": "~2.2.2", "mocha": "~10.0.0", "open-cli": "~7.0.1", @@ -63,6 +64,7 @@ "yargs": "~17.5.0" }, "scripts": { + "prepare": "npm run gentypes", "confluence": "node ./node_modules/mdn-confluence/main/generate.es6.js --output-dir=. --bcd-module=./index.js", "diff": "node scripts/diff.js", "unittest": "c8 mocha --recursive \"{,!(node_modules)/**}/*.test.js\"", @@ -72,7 +74,8 @@ "lint": "node test/lint", "fix": "npm run format:fix && node scripts/fix/index.js", "stats": "node scripts/statistics", - "build": "node scripts/release/build", + "build": "npm run gentypes && node scripts/release/build", + "gentypes": "node scripts/generate-types", "release-pulls": "node scripts/release/pulls", "release-notes": "node scripts/release/notes", "release-stats": "node scripts/release/stats", diff --git a/schemas/browsers.schema.json b/schemas/browsers.schema.json index cd88e33d47c2d1..ee65b676892072 100644 --- a/schemas/browsers.schema.json +++ b/schemas/browsers.schema.json @@ -2,6 +2,37 @@ "$schema": "http://json-schema.org/schema#", "definitions": { + "browser_type": { + "type": "string", + "enum": ["desktop", "mobile", "xr", "server"] + }, + + "browser_engine": { + "type": "string", + "enum": [ + "Blink", + "EdgeHTML", + "Gecko", + "Presto", + "Trident", + "WebKit", + "V8" + ] + }, + + "browser_status": { + "type": "string", + "enum": [ + "retired", + "current", + "exclusive", + "beta", + "nightly", + "esr", + "planned" + ] + }, + "browsers": { "type": "object", "additionalProperties": { @@ -12,7 +43,8 @@ "errorMessage": { "minProperties": "A browser must be described within the file.", "maxProperties": "Each browser JSON file may only describe one browser." - } + }, + "tsType": "Record" }, "browser_statement": { @@ -20,12 +52,12 @@ "properties": { "name": { "type": "string", - "description": "Browser name, avoid using unnecessary English (e.g. prefer 'Chrome Android' over 'Chrome for Android')." + "description": "The browser brand name (e.g. Firefox, Firefox Android, Chrome, etc.)." }, "type": { - "type": "string", - "enum": ["desktop", "mobile", "xr", "server"], - "description": "What type of browser this is (desktop, mobile, XR, or server engine)." + "$ref": "#/definitions/browser_type", + "description": "The platform the browser runs on (e.g. desktop, mobile, XR, or server engine).", + "tsType": "BrowserType" }, "upstream": { "type": "string", @@ -33,7 +65,7 @@ }, "accepts_flags": { "type": "boolean", - "description": "Whether the browser supports flags." + "description": "Whether the browser supports flags to enable or disablle features." }, "accepts_webextensions": { "type": "boolean", @@ -41,18 +73,20 @@ }, "pref_url": { "type": "string", - "description": "URL of the page where feature flags can be changed (e.g. 'about:config' or 'chrome://flags')." + "description": "URL of the page where feature flags can be changed (e.g. 'about:config' for Firefox or 'chrome://flags' for Chrome)." }, "preview_name": { "type": "string", - "description": "Preview name, avoid long-form names (use 'Nightly' instead of 'Firefox Nightly')." + "description": "The name of the browser's preview channel (e.g. 'Nightly' for Firefox or 'TP' for Safari)." }, "releases": { "type": "object", - "additionalProperties": { "$ref": "#/definitions/release_statement" } + "additionalProperties": { "$ref": "#/definitions/release_statement" }, + "description": "The known versions of this browser.", + "tsType": "{ [version: string]: ReleaseStatement };" } }, - "required": ["name", "releases"], + "required": ["name", "type", "releases"], "additionalProperties": false }, @@ -62,7 +96,7 @@ "release_date": { "type": "string", "format": "date", - "description": "Release date" + "description": "The date on which this version was released, formatted as `YYYY-MM-DD`." }, "release_notes": { "type": "string", @@ -71,34 +105,18 @@ "description": "A link to the release notes or changelog for a given release." }, "engine": { - "type": "string", - "enum": [ - "Blink", - "EdgeHTML", - "Gecko", - "Presto", - "Trident", - "WebKit", - "V8" - ], - "description": "Name of the browser's underlying engine." + "$ref": "#/definitions/browser_engine", + "description": "Name of the browser's underlying engine.", + "tsType": "BrowserEngine" }, "engine_version": { "type": "string", "description": "Version of the engine corresponding to the browser version." }, "status": { - "type": "string", - "enum": [ - "retired", - "current", - "exclusive", - "beta", - "nightly", - "esr", - "planned" - ], - "description": "The status of the given browser release (e.g. current, retired, beta, nightly)." + "$ref": "#/definitions/browser_status", + "description": "A property indicating where in the lifetime cycle this release is in (e.g. current, retired, beta, nightly).", + "tsType": "BrowserStatus" } }, "additionalProperties": false @@ -109,5 +127,6 @@ "properties": { "browsers": { "$ref": "#/definitions/browsers" } }, - "additionalProperties": false + "additionalProperties": false, + "tsName": "BrowserDataFile" } diff --git a/schemas/compat-data.schema.json b/schemas/compat-data.schema.json index b59ce805ff4fbd..b967957929480b 100644 --- a/schemas/compat-data.schema.json +++ b/schemas/compat-data.schema.json @@ -16,7 +16,8 @@ "type": "boolean", "nullable": true } - ] + ], + "tsType": "VersionValue" }, "version_removed": { "description": "A string, indicating which browser version removed this feature, or the value true, indicating that the feature was removed in an unknown version.", @@ -28,7 +29,8 @@ { "const": true } - ] + ], + "tsType": "VersionValue" }, "prefix": { "type": "string", @@ -43,25 +45,9 @@ "description": "An optional array of objects describing flags that must be configured for this browser to support this feature.", "minItems": 1, "items": { - "type": "object", - "properties": { - "type": { - "type": "string", - "description": "An enum that indicates the flag type.", - "enum": ["preference", "runtime_flag"] - }, - "name": { - "type": "string", - "description": "A string giving the name of the flag or preference that must be configured." - }, - "value_to_set": { - "type": "string", - "description": "A string giving the value which the specified flag must be set to for this feature to work." - } - }, - "additionalProperties": false, - "required": ["type", "name"] - } + "$ref": "#/definitions/flag_statement" + }, + "tsType": "FlagStatement[]" }, "impl_url": { "anyOf": [ @@ -77,6 +63,7 @@ } ], "description": "An optional changeset/commit URL for the revision which implemented the feature in the source code, or the URL to the bug tracking the implementation, for the associated browser.", + "tsType": "string | string[]", "errorMessage": { "pattern": "impl_url must be a link to a browser commit or bug URL. URLs must be in shortened form (ex. bugs.chromium.org -> crbug.com). Note: `npm run fix` may resolve these issues." } @@ -98,21 +85,11 @@ "type": "string" } } - ] + ], + "tsType": "string | string[]" } }, "required": ["version_added"], - "anyOf": [ - { - "not": { "required": ["prefix", "alternative_name"] } - }, - { - "oneOf": [ - { "required": ["prefix"] }, - { "required": ["alternative_name"] } - ] - } - ], "dependencies": { "partial_implementation": { "if": { @@ -124,20 +101,40 @@ "additionalProperties": false }, - "array_support_statement": { - "type": "array", - "minItems": 2, - "items": { - "$ref": "#/definitions/simple_support_statement" - } + "flag_statement": { + "type": "object", + "properties": { + "type": { + "type": "string", + "description": "An enum that indicates the flag type.", + "enum": ["preference", "runtime_flag"] + }, + "name": { + "type": "string", + "description": "A string giving the name of the flag or preference that must be configured." + }, + "value_to_set": { + "type": "string", + "description": "A string giving the value which the specified flag must be set to for this feature to work." + } + }, + "additionalProperties": false, + "required": ["type", "name"] }, "support_statement": { "anyOf": [ { "$ref": "#/definitions/simple_support_statement" }, - { "$ref": "#/definitions/array_support_statement" }, + { + "type": "array", + "minItems": 2, + "items": { + "$ref": "#/definitions/simple_support_statement" + } + }, { "const": "mirror" } - ] + ], + "tsType": "SimpleSupportStatement | SimpleSupportStatement[]" }, "status_block": { @@ -183,7 +180,8 @@ }, "additionalProperties": { "$ref": "#/definitions/support_statement" - } + }, + "tsType": "Partial>" }, "spec_url_value": { @@ -224,61 +222,34 @@ } } ], - "description": "An optional URL or array of URLs, each of which is for a specific part of a specification in which this feature is defined. Each URL must contain a fragment identifier." + "description": "An optional URL or array of URLs, each of which is for a specific part of a specification in which this feature is defined. Each URL must contain a fragment identifier.", + "tsType": "string | string[]" }, - "support": { "$ref": "#/definitions/support_block" }, - "status": { "$ref": "#/definitions/status_block" } - }, - "required": ["support", "status"], - "additionalProperties": false - }, - - "webextensions_compat_statement": { - "type": "object", - "properties": { - "description": { - "type": "string", - "description": "A string containing a human-readable description of the feature." - }, - "mdn_url": { - "type": "string", - "format": "uri", - "pattern": "^https://developer\\.mozilla\\.org/docs/", - "description": "A URL that points to an MDN reference page documenting the feature. The URL should be language-agnostic." + "support": { + "$ref": "#/definitions/support_block", + "description": "The data for the support of each browser, containing a `support_statement` object for each browser identifier with information about versions, prefixes, or alternate names, as well as notes.", + "tsType": "SupportBlock" }, - "support": { "$ref": "#/definitions/support_block" }, - "status": { "$ref": "#/definitions/status_block" } + "status": { + "$ref": "#/definitions/status_block", + "description": "An object containing information about the stability of the feature.", + "tsType": "StatusBlock" + } }, "required": ["support"], "additionalProperties": false }, - "primary_identifier": { - "allOf": [ - { "$ref": "#/definitions/identifier" }, - { - "type": "object", - "maxProperties": 1, - "minProperties": 1 - } - ] - }, - - "primary_webextensions_identifier": { - "allOf": [ - { "$ref": "#/definitions/webextensions_identifier" }, - { - "type": "object", - "maxProperties": 1, - "minProperties": 1 - } - ] - }, - "identifier": { "type": "object", "properties": { - "__compat": { "$ref": "#/definitions/compat_statement" } + "__compat": { + "type": "object", + "$ref": "#/definitions/compat_statement", + "required": ["status"], + "description": "A feature is described by an identifier containing the `__compat` property.\n\nIn other words, identifiers without `__compat` aren't necessarily features, but help to nest the features properly.\n\nWhen an identifier has a `__compat` block, it represents its basic support, indicating that a minimal implementation of a functionality is included.\n\nWhat it represents exactly depends of the evolution of the feature over time, both in terms of specifications and of browser support.", + "tsType": "CompatStatement" + } }, "patternProperties": { "^(?!__compat)[a-zA-Z_0-9-$@]*$": { "$ref": "#/definitions/identifier" } @@ -292,11 +263,12 @@ "webextensions_identifier": { "type": "object", "properties": { - "__compat": { "$ref": "#/definitions/webextensions_compat_statement" } + "__compat": { "$ref": "#/definitions/compat_statement" } }, "patternProperties": { "^(?!__compat)[a-zA-Z_0-9-$@]*$": { - "$ref": "#/definitions/webextensions_identifier" + "$ref": "#/definitions/webextensions_identifier", + "tsType": "Identifier" } }, "additionalProperties": false, @@ -309,10 +281,14 @@ "type": "object", "patternProperties": { "^(?!__compat)(?!webextensions)[a-zA-Z_0-9-$@]*$": { - "$ref": "#/definitions/primary_identifier" + "$ref": "#/definitions/identifier" }, "^webextensions*$": { - "$ref": "#/definitions/primary_webextensions_identifier" + "$ref": "#/definitions/webextensions_identifier", + "tsType": "Identifier" + }, + "^__compat$": { + "$ref": "#/definitions/compat_statement" } }, "additionalProperties": false, @@ -320,5 +296,6 @@ "additionalProperties": "Feature names can only contain alphanumerical characters or the following symbols: _-$@" }, "maxProperties": 1, - "minProperties": 1 + "minProperties": 1, + "tsName": "CompatDataFile" } diff --git a/scripts/generate-types.js b/scripts/generate-types.js new file mode 100644 index 00000000000000..1cb0609a841276 --- /dev/null +++ b/scripts/generate-types.js @@ -0,0 +1,88 @@ +/* This file is a part of @mdn/browser-compat-data + * See LICENSE file for more information. */ + +import fs from 'node:fs/promises'; + +import esMain from 'es-main'; +import { compileFromFile } from 'json-schema-to-typescript'; + +import bcd from '../index.js'; + +const opts = { + bannerComment: '', + unreachableDefinitions: true, +}; + +const header = + '/* This file is a part of @mdn/browser-compat-data\n * See LICENSE file for more information. */\n\n/**\n* This file was automatically generated by json-schema-to-typescript.\n* DO NOT MODIFY IT BY HAND. Instead, modify the source schema files in\n* schemas/*, and run "npm run gentypes" to regenerate this file.\n*/'; + +const compatDataTypes = { + api: 'Contains data for each [Web API](https://developer.mozilla.org/docs/Web/API) interface.', + browsers: 'Contains data for each known and tracked browser/engine.', + css: 'Contains data for [CSS](https://developer.mozilla.org/docs/Web/CSS) properties, selectors, and at-rules.', + html: 'Contains data for [HTML](https://developer.mozilla.org/docs/Web/HTML) elements, attributes, and global attributes.', + http: 'Contains data for [HTTP](https://developer.mozilla.org/docs/Web/HTTP) headers, statuses, and methods.', + javascript: + 'Contains data for [JavaScript](https://developer.mozilla.org/docs/Web/JavaScript) built-in Objects, statement, operators, and other ECMAScript language features.', + mathml: + 'Contains data for [MathML](https://developer.mozilla.org/docs/Web/MathML) elements, attributes, and global attributes.', + svg: 'Contains data for [SVG](https://developer.mozilla.org/docs/Web/SVG) elements, attributes, and global attributes.', + webdriver: + 'Contains data for [WebDriver](https://developer.mozilla.org/docs/Web/WebDriver) commands.', + webextensions: + 'Contains data for [WebExtensions](https://developer.mozilla.org/Add-ons/WebExtensions) JavaScript APIs and manifest keys.', +}; + +const generateBrowserNames = () => { + const browsers = Object.keys(bcd.browsers); + return `/**\n * The names of the known browsers.\n */\nexport type BrowserName = ${browsers + .map((b) => `"${b}"`) + .join(' | ')};`; +}; + +const generateCompatDataTypes = () => { + const props = Object.entries(compatDataTypes).map( + (t) => + ` /**\n * ${t[1]}\n */\n ${t[0]}: ${ + t[0] === 'browsers' ? 'Browsers' : 'Identifier' + };`, + ); + return `export interface CompatData {\n${props.join('\n\n')}\n}\n`; +}; + +const transformTS = (browserTS, compatTS) => { + // XXX Temporary until the following PR is merged and released: + // https://github.com/bcherny/json-schema-to-typescript/pull/456 + let ts = browserTS + '\n\n' + compatTS; + + ts = ts + .replace('export type Browsers1', 'export type Browsers') + .replace( + 'export interface Browsers {\n browsers?: Browsers1;\n}', + 'export interface BrowserDataFile {\n browsers?: Browsers;\n}', + ) + .replace('export interface CompatData {}', ''); + + return ts; +}; + +const compile = async () => { + const browserTS = await compileFromFile('schemas/browsers.schema.json', opts); + const compatTS = await compileFromFile( + 'schemas/compat-data.schema.json', + opts, + ); + + const ts = [ + header, + generateBrowserNames(), + 'export type VersionValue = string | boolean | null;', + transformTS(browserTS, compatTS), + generateCompatDataTypes(), + ].join('\n\n'); + await fs.writeFile(new URL('../types.d.ts', import.meta.url), ts); +}; + +if (esMain(import.meta)) { + await compile(); +} diff --git a/test/linter/test-prefix.js b/test/linter/test-prefix.js index 187d294546d70c..956de06d08b3fb 100644 --- a/test/linter/test-prefix.js +++ b/test/linter/test-prefix.js @@ -47,6 +47,11 @@ function processData(data, category, logger) { const supportStatements = Array.isArray(support) ? support : [support]; for (const statement of supportStatements) { + if (statement.prefix && statement.alternative_name) { + logger.error( + chalk`Both prefix and alternative name are defined, which is not allowed.`, + ); + } if ( statement.prefix && !prefixes.some((p) => statement.prefix.startsWith(p)) diff --git a/test/linter/test-schema.js b/test/linter/test-schema.js index c4ac95a8dcd82c..b09a21d1d11734 100644 --- a/test/linter/test-schema.js +++ b/test/linter/test-schema.js @@ -20,6 +20,11 @@ ajvFormats(ajv, { mode: 'fast' }); // Allow for custom error messages to provide better directions for contributors ajvErrors(ajv); +// Define keywords for schema->TS converter +ajv.addKeyword('tsEnumNames'); +ajv.addKeyword('tsName'); +ajv.addKeyword('tsType'); + export default { name: 'JSON Schema', description: 'Test a file to ensure that it follows the defined schema', diff --git a/types.d.ts b/types.d.ts deleted file mode 100644 index 35470a569648a6..00000000000000 --- a/types.d.ts +++ /dev/null @@ -1,406 +0,0 @@ -/* This file is a part of @mdn/browser-compat-data - * See LICENSE file for more information. */ - -/** - * The names of the known browsers. - */ -export type BrowserNames = - | 'chrome' - | 'chrome_android' - | 'deno' - | 'edge' - | 'firefox' - | 'firefox_android' - | 'ie' - | 'nodejs' - | 'oculus' - | 'opera' - | 'opera_android' - | 'safari' - | 'safari_ios' - | 'samsunginternet_android' - | 'webview_android'; - -export type BrowserEngines = - | 'Blink' - | 'EdgeHTML' - | 'Gecko' - | 'Presto' - | 'Trident' - | 'WebKit' - | 'V8'; - -export type BrowserTypes = 'desktop' | 'mobile' | 'xr' | 'server'; - -/** - * The browser namespace. - */ -export interface Browsers - extends Record, - Record {} - -/** - * A browser statement. - */ -export interface BrowserStatement { - /** - * The browser brand name, for example: - * `"Firefox"`, `"Firefox Android"`, `"Safari"`, `"iOS Safari"`, etc. - */ - name: string; - - /** - * The platform the browser runs on, for example: - * `"desktop"`, `"mobile"`, `"server"`, etc. - */ - type: BrowserTypes; - - /** - * The upstream browser - */ - upstream?: string; - - /** - * Whether the browser supports flags to enable or disable features. - */ - accepts_flags?: boolean; - - /** - * Whether the browser supports extensions. - */ - accepts_webextensions?: boolean; - - /** - * An optional string containing the URL of the page where feature flags can be changed - * (e.g. `"about:config"` for Firefox or `"chrome://flags"` for Chrome). - */ - pref_url?: string; - - /** - * The preview browser's name, for example: - * `"Nightly"`, `"Canary"`, `"TP"`, etc. - */ - preview_name?: string; - - /** - * The known versions of this browser. - */ - releases: { - [version: string]: ReleaseStatement; - }; -} - -/** - * The data about this version. - */ -export interface ReleaseStatement { - /** - * The date on which this version was released. - * - * Formatted as `YYYY-MM-DD`. - */ - release_date?: string; - - /** - * The URL of the release notes. - */ - release_notes?: string; - - /** - * Name of the browser's underlying engine. - */ - engine?: BrowserEngines; - - /** - * Version of the engine corresponding to the browser version. - */ - engine_version?: string; - - /** - * A property indicating where in the lifetime cycle this release is in. - * - * It's an enum accepting these values: - * - `retired`: This release is no longer supported (EOL). - * - `current`: This release is the official latest release. - * - `exclusive`: This is an exclusive release (for example on a flagship device), - * not generally available. - * - `beta`: This release will the next official release. - * - `nightly`: This release is the current alpha / experimental release - * (like Firefox Nightly, Chrome Canary). - * - `esr`: This release is an Extended Support Release. - * - `planned`: This release is planned in the future. - */ - status: - | 'retired' - | 'current' - | 'limited' - | 'beta' - | 'nightly' - | 'esr' - | 'planned'; -} - -/** - * The `support_statement` object describes the support provided - * by a single browser type for the given sub-feature. - * - * It is an array of `simple_support_statement` objects, but if there - * is only one of them, the array must be omitted. - */ -export type SupportStatement = - | SimpleSupportStatement - | SimpleSupportStatement[]; - -export type VersionValue = string | boolean | null; - -/** - * The `simple_support_statement` object is the core object containing the compatibility information for a browser. - */ -export interface SimpleSupportStatement { - /** The version indicating when a sub-feature has been added (and is therefore supported). - * - * The `boolean` values indicate that a sub-feature is supported - * (`true`, with the additional meaning that it is unknown in which version support was added) - * or not supported (`false`). - * - * A value of `null` indicates that support information is entirely unknown. - */ - version_added: VersionValue; - - /** - * Contains a string with the version number the sub-feature was - * removed in. It may also be a `boolean` value of (`true` or `false`), - * or the `null` value. - * - * Default values: - * - If `version_added` is set to `true`, `false`, or a string, - * `version_removed` defaults to `false`. - * - if `version_added` is set to `null`, the default value - * of `version_removed` is also `null`. - */ - version_removed?: VersionValue; - - /** - * A prefix to add to the sub-feature name (defaults to empty string). - * - * Only non-standard vendor prefixes are permitted. - * - * Note that leading and trailing `-` must be included. - */ - prefix?: string; - - /** - * In some cases features are named entirely differently and not just prefixed, - * or the prefix is an official non-vendor prefix. - * - * (eg. the official `grid-` prefixed aliases for the CSS `*-gap` properties). - */ - alternative_name?: string; - - /** - * An optional array of objects indicating what kind of flags must be set for this feature to work. - * Usually this array will have one item, but there are cases where two or more flags can be required to activate a feature. - */ - flags?: { - /** - * An enum that indicates the flag type: - * - `preference` a flag the user can set (like in `about:config` in Firefox). - * - `runtime_flag` a flag to be set before starting the browser. - */ - type: 'preference' | 'runtime_flag'; - - /** - * A `string` representing the flag or preference to modify. - */ - name: string; - - /** - * Property representing the actual value to set the flag to. - * - * It is a string, that may be converted to the right type - * (that is `true` or `false` for a `boolean` value, or `4` for a `number` value). - * - * It doesn't need to be enclosed in `` tags. - */ - value_to_set?: string; - }[]; - - /** - * An optional changeset/commit URL for the revision which implemented the feature in the source code, or the URL to the bug tracking the implementation, for the associated browser; e.g. a https://trac.webkit.org/changeset/ - * https://hg.mozilla.org/mozilla-central/rev/, or https://crrev.com/ URL. - */ - impl_url?: string; - - /** - * A `boolean` value indicating whether or not the implementation of the sub-feature follows - * the current specification closely enough to not create major interoperability problems. - * - * It defaults to `false` (no interoperability problem expected). - * - * If set to `true`, it is recommended to add a note indicating how it diverges from - * the standard (implements an old version of the standard, for example). - */ - partial_implementation?: boolean; - - /** - * An `array` of zero or more strings containing - * additional information. If there is only one entry in the array, - * the array must be omitted. - * - * The `` and `` HTML elements can be used. - */ - notes?: string | string[]; -} - -export interface Identifier { - /** - * A feature is described by an identifier containing the `__compat` property. - * - * In other words, identifiers without `__compat` aren't necessarily features, - * but help to nest the features properly. - * - * When an identifier has a `__compat` block, it represents its basic support, - * indicating that a minimal implementation of a functionality is included. - * - * What it represents exactly depends of the evolution of the feature over time, - * both in terms of specifications and of browser support. - */ - __compat?: CompatStatement; - - [k: string]: Identifier; -} - -export interface CompatStatement { - /** - * A string containing a human-readable description of the feature. - * - * It is intended to be used as a caption or title and should be kept short. - * - * The `` and `` HTML elements can be used. - */ - description?: string; - - /** - * URL which points to a MDN reference page documenting the feature. - * - * It needs to be a valid URL, and should be the language-⁠neutral URL - * (e.g. use `https⁠://developer.mozilla.org/docs/Web/CSS/text-⁠align` - * instead of `https⁠://developer.mozilla.org/en-⁠US/docs/Web/CSS/text-⁠align`). - */ - mdn_url?: string; - - /** - * An optional URL or array of URLs, each of which is for a specific part of a specification in which this feature is defined. Each URL must contain a fragment identifier. - */ - spec_url?: string | string[]; - - /** - * Each `__compat` object contains support information. - * - * For each browser identifier, it contains a `support_statement` object with - * information about versions, prefixes, or alternate names, as well as notes. - */ - support: SupportBlock; - - /** - * An object containing information about the stability of the feature: - * - * Is it a functionality that is standard? Is it stable? - * Has it been deprecated and shouldn't be used anymore? - */ - status?: StatusBlock; -} - -export interface SupportBlock - extends Partial>, - Partial> {} - -/** - * The status property contains information about stability of the feature. - */ -export interface StatusBlock { - /** - * `boolean` value that indicates this functionality is - * intended to be an addition to the Web platform. Some features are added to - * conduct tests. - * - * Set to `false`, it means the functionality is mature, and no - * significant incompatible changes are expected in the future. - */ - experimental: boolean; - - /** - * `boolean` value indicating if the feature is part - * of an active specification or specification process. - */ - standard_track: boolean; - - /** - * `boolean` value that indicates if the feature is no longer recommended. - * - * It might be removed in the future or might only be kept for compatibility purposes. - * Avoid using this functionality. - */ - deprecated: boolean; -} - -export interface CompatData { - /** - * Contains data for each [Web API](https://developer.mozilla.org/docs/Web/API) - * interface. - */ - api: Identifier; - - /** - * Contains data for each known and tracked browser/engine. - */ - browsers: Browsers; - - /** - * Contains data for [CSS](https://developer.mozilla.org/docs/Web/CSS) - * properties, selectors, and at-rules. - */ - css: Identifier; - - /** - * Contains data for [HTML](https://developer.mozilla.org/docs/Web/HTML) - * elements, attributes, and global attributes. - */ - html: Identifier; - - /** - * Contains data for [HTTP](https://developer.mozilla.org/docs/Web/HTTP) - * headers, statuses, and methods. - */ - http: Identifier; - - /** - * Contains data for [JavaScript](https://developer.mozilla.org/docs/Web/JavaScript) - * built-in Objects, statement, operators, and other ECMAScript language features. - */ - javascript: Identifier; - - /** - * Contains data for [MathML](https://developer.mozilla.org/docs/Web/MathML) - * elements, attributes, and global attributes. - */ - mathml: Identifier; - - /** - * Contains data for [SVG](https://developer.mozilla.org/docs/Web/SVG) - * elements, attributes, and global attributes. - */ - svg: Identifier; - - /** - * Contains data for [WebDriver](https://developer.mozilla.org/docs/Web/WebDriver) - * commands. - */ - webdriver: Identifier; - - /** - * Contains data for [WebExtensions](https://developer.mozilla.org/Add-ons/WebExtensions) - * JavaScript APIs and manifest keys. - */ - webextensions: Identifier; -}