diff --git a/package-lock.json b/package-lock.json index 67e011e5e2e..21fe7a8da3e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3684,7 +3684,7 @@ } }, "packages/compute-baseline": { - "version": "0.1.1", + "version": "0.2.0", "license": "Apache-2.0", "dependencies": { "@js-temporal/polyfill": "^0.4.4", diff --git a/packages/compute-baseline/README.md b/packages/compute-baseline/README.md index 4e057a9218f..f4837d3d6c1 100644 --- a/packages/compute-baseline/README.md +++ b/packages/compute-baseline/README.md @@ -2,23 +2,21 @@ By the [W3C WebDX Community Group](https://www.w3.org/community/webdx/) and contributors. -`compute-baseline` computes preliminary [Baseline statuses](https://github.com/web-platform-dx/web-features/blob/main/docs/baseline.md) from `@mdn/browser-compat-data` feature keys. +`compute-baseline` computes [Baseline statuses](https://github.com/web-platform-dx/web-features/blob/main/docs/baseline.md) from `@mdn/browser-compat-data` feature keys. You can use `compute-baseline` to help you find interoperable web platform features, propose new [`web-features`](https://github.com/web-platform-dx/web-features/) features, or compare support between features. `compute-baseline` also provides utility classes for working with `@mdn/browser-compat-data` generally. ## Limitations -If you need authoritative Baseline statuses, check out the [`web-features`](https://github.com/web-platform-dx/web-features/tree/main/packages/web-features) package instead. +If you need authoritative Baseline statuses, check out the [`web-features`](https://github.com/web-platform-dx/web-features/tree/main/packages/web-features) package first. +Most of the time, the status information provided by `web-features` is the best representation of a feature overall. -Don't use `compute-baseline` to generate publishable Baseline statuses for arbitrary web platform features. -The results of `compute-baseline` invocations have _not_ received editorial review. -Strictly speaking, a Baseline status requires editorial review, so statuses generated by `compute-baseline` are tentative. -If you need authoritative Baseline statuses, check out the [`web-features`](https://github.com/web-platform-dx/web-features/tree/main/packages/web-features) package instead. - -You can use `compute-baseline` to explore possibilities or do error correction. -For example, you might use `compute-baseline` to hide a Baseline status, when showing a broader feature's status might be misleading. +If you need to know the Baseline status of a specific browser compatibility data entry within a `web-features` feature, then you can use the `getStatus` method. +The `web-features` package and the `getStatus` method are the **only** ways to get a status that have completed the full Baseline editorial review process. +All other invocations of `compute-baseline` have _not_ received editorial review. +Don't use `compute-baseline` to generate publishable Baseline statuses for arbitrary web platform features. If you're not sure whether your application fits with the definition of Baseline, please [file an issue](https://github.com/web-platform-dx/web-features/issues/new). ## Prerequisites @@ -40,8 +38,41 @@ Run: ## Usage +### Get a Baseline status for a portion of a feature + +To get a Baseline status for a specific browser compatibility data entry within a `web-features` feature, call `getStatus` with the web feature's ID and the BCD feature key as parameters, as shown below: + + + +```javascript +import { getStatus } from "compute-baseline"; + +getStatus("fetch", "api.Response.json"); +``` + +Returns: + +``` +{ + baseline: 'high', + baseline_low_date: '2017-03-27', + baseline_high_date: '2019-09-27', + support: { + chrome: '42', + chrome_android: '42', + edge: '14', + firefox: '39', + firefox_android: '39', + safari: '10.1', + safari_ios: '10.3' + } +} +``` + ### Check support for a group of compat keys +**Note**: This example returns support data that has not received an editorial review. Do not use for presenting a Baseline status. See [Limitations](#limitations). + ```javascript import { computeBaseline } from "compute-baseline"; @@ -73,6 +104,8 @@ Use the `toJSON()` method to get a `web-features`-like plain JSON representation ### Check support for a single support key +**Note**: This example returns support data that has not received an editorial review. Do not use for presenting a Baseline status. See [Limitations](#limitations). + Sometimes it can be helpful to know if parent features have less support than the specific feature you're checking (for example, the parent is behind a prefix or flag) when computing a status for a deeply-nested feature. This is typically most interesting when checking a single key. Use the `withAncestors` option: @@ -88,7 +121,9 @@ computeBaseline({ ### Bring your own compatibility data -If you don't want to import `@mdn/browser-compat-data` as your data source, you can bring your own schema-compatible compat data. +**Note**: This example returns support data that has not received an editorial review. Do not use for presenting a Baseline status. See [Limitations](#limitations). + +If you want to use some other source of data (such as pre-release browser-compat-data), you can bring your own schema-compatible compat data. ```javascript import data from "some-parsed-json-file"; diff --git a/packages/compute-baseline/package.json b/packages/compute-baseline/package.json index 676057815fb..b9ad0f0fa7b 100644 --- a/packages/compute-baseline/package.json +++ b/packages/compute-baseline/package.json @@ -1,6 +1,6 @@ { "name": "compute-baseline", - "version": "0.1.1", + "version": "0.2.0", "description": "A library for computing web-features statuses from browser compatibility data", "exports": { ".": "./dist/baseline/index.js", diff --git a/packages/compute-baseline/src/baseline/index.test.ts b/packages/compute-baseline/src/baseline/index.test.ts index db0e9431adb..5cbe64e6103 100644 --- a/packages/compute-baseline/src/baseline/index.test.ts +++ b/packages/compute-baseline/src/baseline/index.test.ts @@ -4,10 +4,26 @@ import { Temporal } from "@js-temporal/polyfill"; import * as chai from "chai"; import chaiJestSnapshot from "chai-jest-snapshot"; -import { computeBaseline, keystoneDateToStatus } from "./index.js"; +import { computeBaseline, getStatus, keystoneDateToStatus } from "./index.js"; chai.use(chaiJestSnapshot); +describe("getStatus", function () { + before(function () { + chaiJestSnapshot.resetSnapshotRegistry(); + }); + + beforeEach(function () { + chaiJestSnapshot.configureUsingMochaContext(this); + }); + + it("returns a status", function () { + const result = getStatus("fetch", "api.Response.json"); + assert.equal(result.baseline, "high"); + chai.expect(result).to.matchSnapshot(); + }); +}); + describe("computeBaseline", function () { before(function () { chaiJestSnapshot.resetSnapshotRegistry(); diff --git a/packages/compute-baseline/src/baseline/index.test.ts.snap b/packages/compute-baseline/src/baseline/index.test.ts.snap index c63dbe31747..9648f1ba518 100644 --- a/packages/compute-baseline/src/baseline/index.test.ts.snap +++ b/packages/compute-baseline/src/baseline/index.test.ts.snap @@ -130,3 +130,20 @@ Object { }", } `; + +exports[`getStatus returns a status 1`] = ` +Object { + "baseline": "high", + "baseline_high_date": "2019-09-27", + "baseline_low_date": "2017-03-27", + "support": Object { + "chrome": "42", + "chrome_android": "42", + "edge": "14", + "firefox": "39", + "firefox_android": "39", + "safari": "10.1", + "safari_ios": "10.3", + }, +} +`; diff --git a/packages/compute-baseline/src/baseline/index.ts b/packages/compute-baseline/src/baseline/index.ts index 8cc576a5aff..829dd9b3c39 100644 --- a/packages/compute-baseline/src/baseline/index.ts +++ b/packages/compute-baseline/src/baseline/index.ts @@ -34,7 +34,7 @@ export const BASELINE_LOW_TO_HIGH_DURATION = Temporal.Duration.from({ type BaselineStatus = "low" | "high" | false; type BaselineDate = string | null; -interface SupportStatus { +interface SupportDetails { compatKey?: string; baseline: BaselineStatus; baseline_low_date: BaselineDate; @@ -44,6 +44,41 @@ interface SupportStatus { toJSON: () => string; } +// TODO: Use a type from `web-features` directly, instead of approximating it here +interface SupportStatus { + baseline: "low" | "high" | false; + baseline_low_date: string; + baseline_high_date?: string; + support: Record; +} + +/** + * Calculate a Baseline status for specific browser compat data keys within a + * web-features feature, in the style of a web-feature's `status` key. Use this + * method to calculate fine-grained support statuses. This is the only method + * approved to compute Baseline statuses not otherwise published in the + * `web-features` package. + * + * For example, suppose you want to show a Baseline status for a specific method + * in a feature, which might've been supported earlier or later than the broader + * feature overall. Then you'd call `getStatus('example-feature', + * 'api.ExampleManager.doExample')`. + */ +export function getStatus( + featureId: string, + compatKey: string, + compat: Compat = defaultCompat, +): SupportStatus { + // TODO: actually check that featureId is a valid feature + // TODO: actually check that compatKey is tagged as featureId in BCD _or_ listed in web-features + return JSON.parse( + computeBaseline( + { compatKeys: [compatKey], checkAncestors: true }, + compat, + ).toJSON(), + ); +} + /** * Given a set of compat keys, compute the aggregate Baseline support ("high", * "low" or false, dates, and releases) for those keys. @@ -54,7 +89,7 @@ export function computeBaseline( checkAncestors?: boolean; }, compat: Compat = defaultCompat, -): SupportStatus { +): SupportDetails { const { compatKeys } = featureSelector; const keys = featureSelector.checkAncestors ? compatKeys.flatMap((key) => withAncestors(key, compat)) @@ -88,7 +123,7 @@ export function computeBaseline( * Compute the Baseline support ("high", "low" or false, dates, and releases) * for a single compat key. */ -function calculate(compatKey: string, compat: Compat): SupportStatus { +function calculate(compatKey: string, compat: Compat): SupportDetails { const f = feature(compatKey); const s = support(f, browsers(compat)); const keystoneDate = findKeystoneDate([...s.values()]); @@ -227,7 +262,7 @@ function findKeystoneDate( return latestDate; } -function jsonify(status: SupportStatus): string { +function jsonify(status: SupportDetails): string { const { baseline_low_date, baseline_high_date } = status; const support: Record = {};