baseline-browser-mapping 0.3.1 → 1.0.0-beta.1

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.
@@ -2,8 +2,8 @@ type BrowserVersion = {
2
2
  browser: string;
3
3
  version: string;
4
4
  release_date: string;
5
- engine: string | null;
6
- engine_version: string | null;
5
+ engine?: string;
6
+ engine_version?: string;
7
7
  };
8
8
  export declare function getMinimumWidelyAvailable(includeDownstream?: boolean): BrowserVersion[];
9
9
  export declare function getAllWidelyAvailable(includeDownstream?: boolean): BrowserVersion[];
@@ -2,6 +2,7 @@ import { createRequire } from "node:module";
2
2
  const require = createRequire(import.meta.url);
3
3
  const bcdBrowsers = require("@mdn/browser-compat-data");
4
4
  const otherBrowsers = require("../data/downstream-browsers.json");
5
+ import { features } from "web-features";
5
6
  const bcdCoreBrowserNames = [
6
7
  "chrome",
7
8
  "chrome_android",
@@ -23,6 +24,15 @@ const downstreamBrowserData = [
23
24
  ...Object.entries(otherBrowsers.browsers),
24
25
  ];
25
26
  const acceptableStatuses = ["current", "esr", "retired", "unknown"];
27
+ const stripLTEPrefix = (str) => {
28
+ if (!str) {
29
+ return str;
30
+ }
31
+ if (!str.startsWith("≤")) {
32
+ return str;
33
+ }
34
+ return str.slice(1);
35
+ };
26
36
  const compareVersions = (incomingVersionString, previousVersionString) => {
27
37
  let [incomingVersionStringMajor, incomingVersionStringMinor] = incomingVersionString.split(".");
28
38
  let [previousVersionStringMajor, previousVersionStringMinor] = previousVersionString.split(".");
@@ -33,8 +43,11 @@ const compareVersions = (incomingVersionString, previousVersionString) => {
33
43
  previousVersionString +
34
44
  "");
35
45
  }
46
+ if (parseInt(incomingVersionStringMajor) > parseInt(previousVersionStringMajor)) {
47
+ return 1;
48
+ }
36
49
  if (incomingVersionStringMinor) {
37
- if (parseInt(incomingVersionStringMajor) >=
50
+ if (parseInt(incomingVersionStringMajor) ==
38
51
  parseInt(previousVersionStringMajor) &&
39
52
  (!previousVersionStringMinor ||
40
53
  parseInt(incomingVersionStringMinor) >
@@ -42,59 +55,108 @@ const compareVersions = (incomingVersionString, previousVersionString) => {
42
55
  return 1;
43
56
  }
44
57
  }
45
- else {
46
- if (incomingVersionStringMajor > previousVersionStringMajor) {
47
- return 1;
48
- }
49
- }
50
58
  return 0;
51
59
  };
60
+ const getCompatibleFeaturesByDate = (date) => {
61
+ const compatibleFeatures = new Array();
62
+ Object.entries(features).forEach(([feature_id, feature]) => {
63
+ if (feature.status.baseline_low_date &&
64
+ new Date(feature.status.baseline_low_date) <= date) {
65
+ compatibleFeatures.push({
66
+ id: feature_id,
67
+ name: feature.name,
68
+ baseline_low_date: feature.status.baseline_low_date,
69
+ support: feature.status.support,
70
+ });
71
+ }
72
+ });
73
+ return compatibleFeatures;
74
+ };
75
+ const getMinimumVersionsFromFeatures = (features) => {
76
+ let minimumVersions = {};
77
+ Object.entries(coreBrowserData).forEach(([, browserData]) => {
78
+ minimumVersions[browserData[0]] = {
79
+ browser: browserData[0],
80
+ version: "0",
81
+ release_date: "",
82
+ };
83
+ });
84
+ features.forEach((feature) => {
85
+ Object.entries(feature.support).forEach((browser) => {
86
+ const browserName = browser[0];
87
+ const version = stripLTEPrefix(browser[1]);
88
+ if (minimumVersions[browserName] &&
89
+ compareVersions(version, stripLTEPrefix(minimumVersions[browserName].version)) === 1) {
90
+ minimumVersions[browserName] = {
91
+ browser: browserName,
92
+ version: version,
93
+ release_date: feature.baseline_low_date,
94
+ };
95
+ }
96
+ });
97
+ });
98
+ return Object.values(minimumVersions);
99
+ };
100
+ const getSubsequentVersions = (minimumVersions) => {
101
+ let subsequentVersions = [];
102
+ minimumVersions.forEach((minimumVersion) => {
103
+ let bcdBrowser = coreBrowserData.find((bcdBrowser) => bcdBrowser[0] === minimumVersion.browser);
104
+ if (bcdBrowser) {
105
+ let sortedVersions = Object.entries(bcdBrowser[1].releases)
106
+ .filter(([, versionData]) => {
107
+ if (!acceptableStatuses.includes(versionData.status)) {
108
+ return false;
109
+ }
110
+ return true;
111
+ })
112
+ .sort((a, b) => {
113
+ return compareVersions(a[0], b[0]);
114
+ });
115
+ sortedVersions.forEach(([version, versionData]) => {
116
+ if (!acceptableStatuses.includes(versionData.status)) {
117
+ return false;
118
+ }
119
+ if (compareVersions(version, minimumVersion.version) === 1) {
120
+ subsequentVersions.push({
121
+ browser: minimumVersion.browser,
122
+ version: version,
123
+ release_date: versionData.release_date
124
+ ? versionData.release_date
125
+ : "unknown",
126
+ });
127
+ return true;
128
+ }
129
+ return false;
130
+ });
131
+ }
132
+ });
133
+ return subsequentVersions;
134
+ };
52
135
  const getCoreVersionsByDate = (date, minOnly = true) => {
53
136
  if (date.getFullYear() < 2015) {
54
137
  throw new Error("There are no browser versions compatible with Baseline before 2015");
55
138
  }
56
- if (date.getFullYear() >= new Date().getFullYear()) {
139
+ if (date.getFullYear() > new Date().getFullYear()) {
57
140
  throw new Error("There are no browser versions compatible with Baseline in the future");
58
141
  }
59
- let versions = new Array();
60
- coreBrowserData.forEach(([browserName, browserData]) => {
61
- let sortedVersions = Object.entries(browserData.releases)
62
- .filter(([, versionData]) => {
63
- if (!acceptableStatuses.includes(versionData.status)) {
64
- return false;
142
+ const compatibleFeatures = getCompatibleFeaturesByDate(date);
143
+ const minimumVersions = getMinimumVersionsFromFeatures(compatibleFeatures);
144
+ if (minOnly) {
145
+ return minimumVersions;
146
+ }
147
+ else {
148
+ return [...minimumVersions, ...getSubsequentVersions(minimumVersions)].sort((a, b) => {
149
+ if (a.browser < b.browser) {
150
+ return -1;
65
151
  }
66
- return true;
67
- })
68
- .sort((a, b) => {
69
- return compareVersions(a[0], b[0]);
70
- });
71
- for (let i = 1; i < sortedVersions.length; i++) {
72
- const thisVersion = sortedVersions[i];
73
- if (thisVersion) {
74
- const versionData = thisVersion[1];
75
- const prevVersion = sortedVersions[i - 1];
76
- if (prevVersion) {
77
- const [prevVersionNumber, prevVersionData] = prevVersion;
78
- if (versionData.release_date &&
79
- new Date(versionData.release_date) > date) {
80
- versions.push({
81
- browser: browserName,
82
- version: prevVersionNumber,
83
- release_date: prevVersionData.release_date
84
- ? prevVersionData.release_date
85
- : "unknown",
86
- engine: null,
87
- engine_version: null,
88
- });
89
- if (minOnly) {
90
- break;
91
- }
92
- }
93
- }
152
+ else if (a.browser > b.browser) {
153
+ return 1;
94
154
  }
95
- }
96
- });
97
- return versions;
155
+ else {
156
+ return compareVersions(a.version, b.version);
157
+ }
158
+ });
159
+ }
98
160
  };
99
161
  const getDownstreamBrowsers = (inputArray = [], minOnly = true) => {
100
162
  let minimumChromeVersion = undefined;
@@ -133,13 +195,16 @@ const getDownstreamBrowsers = (inputArray = [], minOnly = true) => {
133
195
  const versionEntry = sortedAndFilteredVersions[i];
134
196
  if (versionEntry) {
135
197
  const [versionNumber, versionData] = versionEntry;
136
- downstreamArray.push({
198
+ let outputObject = {
137
199
  browser: browserName,
138
200
  version: versionNumber,
139
201
  release_date: versionData.release_date ?? "unknown",
140
- engine: versionData.engine ?? null,
141
- engine_version: versionData.engine_version ?? null,
142
- });
202
+ };
203
+ if (versionData.engine && versionData.engine_version) {
204
+ outputObject.engine = versionData.engine;
205
+ outputObject.engine_version = versionData.engine_version;
206
+ }
207
+ downstreamArray.push(outputObject);
143
208
  if (minOnly) {
144
209
  break;
145
210
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "baseline-browser-mapping",
3
- "version": "0.3.1",
3
+ "version": "1.0.0-beta.1",
4
4
  "description": "A library for obtaining browser versions with their maximum supported Baseline feature set and Widely Available status.",
5
5
  "exports": {
6
6
  ".": "./dist/index.js"
@@ -18,7 +18,8 @@
18
18
  },
19
19
  "license": "Apache-2.0",
20
20
  "dependencies": {
21
- "@mdn/browser-compat-data": "latest"
21
+ "@mdn/browser-compat-data": "latest",
22
+ "web-features": "latest"
22
23
  },
23
24
  "devDependencies": {
24
25
  "@types/node": "^22.13.5",