From af1d35c372f78c14f364b63e819fd69548508f55 Mon Sep 17 00:00:00 2001 From: Evan Wallace Date: Thu, 13 Jul 2023 10:57:43 -0400 Subject: [PATCH] add "mdn" as a compat table data source --- compat-table/package-lock.json | 11 ++++++ compat-table/package.json | 1 + compat-table/src/index.ts | 61 ++++++---------------------------- compat-table/src/mdn.ts | 60 +++++++++++++++++++++++++++++++++ internal/compat/js_table.go | 14 +++++++- 5 files changed, 96 insertions(+), 51 deletions(-) create mode 100644 compat-table/src/mdn.ts diff --git a/compat-table/package-lock.json b/compat-table/package-lock.json index bbdfceca8ab..79267d57163 100644 --- a/compat-table/package-lock.json +++ b/compat-table/package-lock.json @@ -5,11 +5,17 @@ "packages": { "": { "dependencies": { + "@mdn/browser-compat-data": "5.3.2", "@types/caniuse-lite": "1.0.1", "@types/node": "20.3.2", "caniuse-lite": "1.0.30001508" } }, + "node_modules/@mdn/browser-compat-data": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-5.3.2.tgz", + "integrity": "sha512-c2dxwcqbClWUUSZqM6hMzM8dAUCEaPBBciBW8iyT+62OPmfb61VVZKu4vtCyAPzE/fBYY1F2bhuTsOTBRtt7WA==" + }, "node_modules/@types/caniuse-lite": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@types/caniuse-lite/-/caniuse-lite-1.0.1.tgz", @@ -41,6 +47,11 @@ } }, "dependencies": { + "@mdn/browser-compat-data": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-5.3.2.tgz", + "integrity": "sha512-c2dxwcqbClWUUSZqM6hMzM8dAUCEaPBBciBW8iyT+62OPmfb61VVZKu4vtCyAPzE/fBYY1F2bhuTsOTBRtt7WA==" + }, "@types/caniuse-lite": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@types/caniuse-lite/-/caniuse-lite-1.0.1.tgz", diff --git a/compat-table/package.json b/compat-table/package.json index 8b91d4bf051..e8a42a25307 100644 --- a/compat-table/package.json +++ b/compat-table/package.json @@ -4,6 +4,7 @@ "williamkapke/node-compat-table": "b11fbdb3e6c6d5fffbf4688d830c7453eb64cff7" }, "dependencies": { + "@mdn/browser-compat-data": "5.3.2", "@types/caniuse-lite": "1.0.1", "@types/node": "20.3.2", "caniuse-lite": "1.0.30001508" diff --git a/compat-table/src/index.ts b/compat-table/src/index.ts index 8ccc8a48bd6..7e0ef9ed7d6 100644 --- a/compat-table/src/index.ts +++ b/compat-table/src/index.ts @@ -5,6 +5,7 @@ import fs = require('fs') import path = require('path') import { generateTableForJS } from './js_table' import * as caniuse from './caniuse' +import * as mdn from './mdn' export type Engine = keyof typeof engines export const engines = { @@ -242,6 +243,9 @@ import('./kangax').then(({ js }) => { // Merge data from https://caniuse.com into the JavaScript support map mergeSupportMaps(js, caniuse.js) + // Merge data from the Mozilla Developer Network into the JavaScript support map + mergeSupportMaps(js, mdn.js) + // ES5 features js.ObjectAccessors.ES = { 5: { force: true } } js.ObjectAccessors.Node = { '0.4': { force: true } } // "node-compat-table" doesn't appear to cover ES5 features... @@ -284,6 +288,7 @@ import('./kangax').then(({ js }) => { // ES2020 features js.Bigint.ES = { 2020: { force: true } } + js.ExportStarAs.ES = { 2020: { force: true } } js.ImportMeta.ES = { 2020: { force: true } } js.NullishCoalescing.ES = { 2020: { force: true } } js.OptionalChain.ES = { 2020: { force: true } } @@ -307,37 +312,6 @@ import('./kangax').then(({ js }) => { js.ArbitraryModuleNamespaceNames.ES = { 2022: { force: true } } js.RegexpMatchIndices.ES = { 2022: { force: true } } - // Manually copied from https://caniuse.com/?search=export%20*%20as - { - js.ExportStarAs.Chrome = { 72: { force: true } } - js.ExportStarAs.Edge = { 79: { force: true } } - js.ExportStarAs.ES = { 2020: { force: true } } - js.ExportStarAs.Firefox = { 80: { force: true } } - js.ExportStarAs.Node = { 12: { force: true } } // From https://developer.mozilla.org/en-US/docs/web/javascript/reference/statements/export - js.ExportStarAs.Opera = { 60: { force: true } } - - // This feature has been implemented in Safari but I have no idea what version - // this bug corresponds to: https://bugs.webkit.org/show_bug.cgi?id=214379 - } - - // Manually copied from https://caniuse.com/#search=import.meta - js.ImportMeta.Chrome = { 64: { force: true } } - js.ImportMeta.Edge = { 79: { force: true } } - js.ImportMeta.Firefox = { 62: { force: true } } - js.ImportMeta.IOS = { 12: { force: true } } - js.ImportMeta.Node = { '10.4': { force: true } } // From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import.meta - js.ImportMeta.Opera = { 51: { force: true } } - js.ImportMeta.Safari = { '11.1': { force: true } } - - // Manually copied from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await - js.TopLevelAwait.Chrome = { 89: { force: true } } - js.TopLevelAwait.Edge = { 89: { force: true } } - js.TopLevelAwait.Firefox = { 89: { force: true } } - js.TopLevelAwait.IOS = { 15: { force: true } } - js.TopLevelAwait.Node = { '14.8': { force: true } } - js.TopLevelAwait.Opera = { 75: { force: true } } - js.TopLevelAwait.Safari = { 15: { force: true } } - // This is a problem specific to Internet Explorer. See https://github.com/tc39/ecma262/issues/1440 for (const engine in engines) { if (engine as Engine !== 'ES' && engine as Engine !== 'IE') { @@ -420,31 +394,18 @@ import('./kangax').then(({ js }) => { // this bug corresponds to: https://bugs.webkit.org/show_bug.cgi?id=217576 } - // Import assertions + // Import assertions (note: these were removed from the JavaScript specification and never standardized) { - // From https://www.chromestatus.com/feature/5765269513306112 - js.ImportAssertions.Chrome = { 91: { force: true } } - // From https://github.com/nodejs/node/blob/master/doc/changelogs/CHANGELOG_V16.md#16.14.0 js.ImportAssertions.Node = { '16.14': { force: true } } - // Not yet in Firefox: https://bugzilla.mozilla.org/show_bug.cgi?id=1736059 + // MDN data is wrong here: https://bugs.webkit.org/show_bug.cgi?id=251600 + delete js.ImportAssertions.IOS + delete js.ImportAssertions.Safari } - // Manually copied from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Class_static_initialization_blocks - js.ClassStaticBlocks.Chrome = { 91: { force: true } } // From https://www.chromestatus.com/feature/6482797915013120 - js.ClassStaticBlocks.Edge = { 94: { force: true } } - js.ClassStaticBlocks.Firefox = { 93: { force: true } } - js.ClassStaticBlocks.Node = { '16.11': { force: true } } - js.ClassStaticBlocks.Opera = { 80: { force: true } } - - // Manually copied from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/hasIndices - js.RegexpMatchIndices.Chrome = { 90: { force: true } } - js.RegexpMatchIndices.Edge = { 90: { force: true } } - js.RegexpMatchIndices.Firefox = { 88: { force: true } } - js.RegexpMatchIndices.IOS = { 15: { force: true } } - js.RegexpMatchIndices.Opera = { 76: { force: true } } - js.RegexpMatchIndices.Safari = { 15: { force: true } } + // MDN data is wrong here: https://www.chromestatus.com/feature/6482797915013120 + js.ClassStaticBlocks.Chrome = { 91: { force: true } } const jsVersionRanges = supportMapToVersionRanges(js) generateTableForJS(jsVersionRanges) diff --git a/compat-table/src/mdn.ts b/compat-table/src/mdn.ts new file mode 100644 index 00000000000..96c39cb9b58 --- /dev/null +++ b/compat-table/src/mdn.ts @@ -0,0 +1,60 @@ +// This file processes data from https://developer.mozilla.org/en-US/docs/Web + +import bcd from '@mdn/browser-compat-data' +import { Engine, JSFeature, Support, SupportMap } from './index' + +const supportedEnvironments: Record = { + chrome: 'Chrome', + deno: 'Deno', + edge: 'Edge', + firefox: 'Firefox', + ie: 'IE', + nodejs: 'Node', + opera: 'Opera', + safari: 'Safari', + safari_ios: 'IOS', +} + +const jsFeatures: Record = { + 'javascript.builtins.RegExp.hasIndices': 'RegexpMatchIndices', + 'javascript.classes.static_initialization_blocks': 'ClassStaticBlocks', + 'javascript.operators.await.top_level': 'TopLevelAwait', + 'javascript.operators.import_meta': 'ImportMeta', + 'javascript.statements.export.namespace': 'ExportStarAs', + 'javascript.statements.import.import_assertions': 'ImportAssertions', +} + +export const js: SupportMap = {} as SupportMap + +for (const feature in jsFeatures) { + const jsFeature = jsFeatures[feature] + const engines: Partial>> = {} + let object: any = bcd + + // Traverse the JSON object to find the data + for (const key of feature.split('.')) { + object = object[key] + } + + const support = object.__compat.support + + for (const env in support) { + const engine = supportedEnvironments[env] + + if (engine) { + const entries = support[env] + + for (const { flags, version_added, version_removed } of Array.isArray(entries) ? entries : [entries]) { + if (flags && flags.length > 0) { + // The feature isn't considered to be supported if it requires a flag + continue + } + if (version_added && !version_removed && /^\d+(?:\.\d+(?:\.\d+)?)?$/.test(version_added)) { + engines[engine] = { [version_added]: { force: true } } + } + } + } + } + + js[jsFeature] = engines +} diff --git a/internal/compat/js_table.go b/internal/compat/js_table.go index 3a6be3dbdcc..87407487c8e 100644 --- a/internal/compat/js_table.go +++ b/internal/compat/js_table.go @@ -351,11 +351,14 @@ var jsTable = map[JSFeature]map[Engine][]versionRange{ }, ClassStaticBlocks: { Chrome: {{start: v{91, 0, 0}}}, + Deno: {{start: v{1, 14, 0}}}, Edge: {{start: v{94, 0, 0}}}, ES: {{start: v{2022, 0, 0}}}, Firefox: {{start: v{93, 0, 0}}}, + IOS: {{start: v{16, 4, 0}}}, Node: {{start: v{16, 11, 0}}}, Opera: {{start: v{80, 0, 0}}}, + Safari: {{start: v{16, 4, 0}}}, }, ClassStaticField: { Chrome: {{start: v{73, 0, 0}}}, @@ -427,11 +430,14 @@ var jsTable = map[JSFeature]map[Engine][]versionRange{ }, ExportStarAs: { Chrome: {{start: v{72, 0, 0}}}, + Deno: {{start: v{1, 0, 0}}}, Edge: {{start: v{79, 0, 0}}}, ES: {{start: v{2020, 0, 0}}}, Firefox: {{start: v{80, 0, 0}}}, - Node: {{start: v{12, 0, 0}}}, + IOS: {{start: v{14, 5, 0}}}, + Node: {{start: v{13, 2, 0}}}, Opera: {{start: v{60, 0, 0}}}, + Safari: {{start: v{14, 1, 0}}}, }, ForAwait: { Chrome: {{start: v{63, 0, 0}}}, @@ -494,10 +500,13 @@ var jsTable = map[JSFeature]map[Engine][]versionRange{ }, ImportAssertions: { Chrome: {{start: v{91, 0, 0}}}, + Deno: {{start: v{1, 17, 0}}}, + Edge: {{start: v{91, 0, 0}}}, Node: {{start: v{16, 14, 0}}}, }, ImportMeta: { Chrome: {{start: v{64, 0, 0}}}, + Deno: {{start: v{1, 0, 0}}}, Edge: {{start: v{79, 0, 0}}}, ES: {{start: v{2020, 0, 0}}}, Firefox: {{start: v{62, 0, 0}}}, @@ -649,10 +658,12 @@ var jsTable = map[JSFeature]map[Engine][]versionRange{ }, RegexpMatchIndices: { Chrome: {{start: v{90, 0, 0}}}, + Deno: {{start: v{1, 8, 0}}}, Edge: {{start: v{90, 0, 0}}}, ES: {{start: v{2022, 0, 0}}}, Firefox: {{start: v{88, 0, 0}}}, IOS: {{start: v{15, 0, 0}}}, + Node: {{start: v{16, 0, 0}}}, Opera: {{start: v{76, 0, 0}}}, Safari: {{start: v{15, 0, 0}}}, }, @@ -715,6 +726,7 @@ var jsTable = map[JSFeature]map[Engine][]versionRange{ }, TopLevelAwait: { Chrome: {{start: v{89, 0, 0}}}, + Deno: {{start: v{1, 0, 0}}}, Edge: {{start: v{89, 0, 0}}}, ES: {{start: v{2022, 0, 0}}}, Firefox: {{start: v{89, 0, 0}}},