Skip to content

Add move and split redirects to the schema #3000

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 24 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
9846b90
Demonstrate JSON Schema as source of truth
ddbeck May 20, 2025
1012068
Replace types with newly generated types
ddbeck May 26, 2025
77bf8f9
Add new types to web-features package build
ddbeck May 26, 2025
7742c64
Format types.ts
ddbeck May 27, 2025
7f7aa98
Fix schema key sort order
ddbeck May 26, 2025
459ac43
Add redirect feature schema types
ddbeck May 27, 2025
758e77a
Update scripts to use redirects
ddbeck May 27, 2025
2294698
Split webcodecs
ddbeck May 27, 2025
eaf208d
Rename `numeric-seperators`
ddbeck May 27, 2025
dc4974b
Prevent double and circular redirects
ddbeck May 27, 2025
95bf898
Merge branch 'main' into 91-jsonschema-source-of-truth
ddbeck Jun 10, 2025
b2b6762
Add unintentionally missing required fields
ddbeck Jun 10, 2025
dd23730
Add more property constraints to reduce any in TS
ddbeck Jun 10, 2025
a8b6ba1
Merge branch 'main' into 91-jsonschema-source-of-truth
ddbeck Jun 30, 2025
6e383ff
Drop tsup and export our types directly
ddbeck Jun 30, 2025
036bdaf
Merge branch '91-jsonschema-source-of-truth' into 91-redirects
ddbeck Jun 30, 2025
cf6fad8
Merge branch 'main' into 91-jsonschema-source-of-truth
ddbeck Jul 16, 2025
0d54e06
Fix bad Quicktype command parsing
ddbeck Jul 16, 2025
c01bba1
Merge branch '91-jsonschema-source-of-truth' into 91-redirects
ddbeck Jul 16, 2025
7f7c96f
Provide discriminator property on feature data
ddbeck Jul 22, 2025
9b276f0
Use single-color-gradients as split demonstrator feature
ddbeck Jul 22, 2025
66adbd4
fixup! Use single-color-gradients as split demonstrator feature
ddbeck Jul 22, 2025
6ad4e80
Set `kind: feature` at runtime, for author convenience
ddbeck Jul 22, 2025
7845c1a
Fix switch statement exhaustiveness check
ddbeck Jul 22, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ packages/web-features/index.d.ts
packages/**/LICENSE.txt
packages/web-features/data.json
packages/web-features/data.schema.json
packages/web-features/types.ts
packages/web-features/types*
packages/web-features/index.js
data.extended.json
index.js

# Ignore files created & used by pages & 11ty
/_site/**
3 changes: 0 additions & 3 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
/**/*.dist
/**/dist


# Exclude the website includes since these are typically fragments, or include
# things that makes Prettier unhappy.
/gh-pages/src/_includes/**
Expand All @@ -11,14 +10,12 @@
# TODO: Format all these files
README.md
index.ts
types.ts
2022-backgrounder.md
towards-features.md
/.github/**
/docs
!/docs/publishing.md
/features/draft
/schemas
/scripts/caniuse.ts
/scripts/schema.ts
/scripts/specs.ts
1 change: 1 addition & 0 deletions features/conic-gradients.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ status:
compat_features:
- css.types.gradient.conic-gradient
- css.types.gradient.conic-gradient.doubleposition
- css.types.gradient.conic-gradient.single_color_stop
- css.types.gradient.repeating-conic-gradient
12 changes: 12 additions & 0 deletions features/conic-gradients.yml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,15 @@ compat_features:
# safari: "12.1"
# safari_ios: "12.2"
- css.types.gradient.conic-gradient.doubleposition

# baseline: low
# baseline_low_date: 2025-04-04
# support:
# chrome: "135"
# chrome_android: "135"
# edge: "135"
# firefox: "136"
# firefox_android: "136"
# safari: "18.4"
# safari_ios: "18.4"
- css.types.gradient.conic-gradient.single_color_stop
4 changes: 4 additions & 0 deletions features/gradients.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,22 @@ compat_features:
- css.types.gradient.linear-gradient.interpolation_hints
- css.types.gradient.linear-gradient.premultiplied_gradients
- css.types.gradient.linear-gradient.to
- css.types.gradient.linear-gradient.single_color_stop
- css.types.gradient.linear-gradient.unitless_0_angle
- css.types.gradient.repeating-linear-gradient
- css.types.gradient.repeating-linear-gradient.doubleposition
- css.types.gradient.repeating-linear-gradient.interpolation_hints
- css.types.gradient.repeating-linear-gradient.to
- css.types.gradient.repeating-linear-gradient.single_color_stop
- css.types.gradient.repeating-linear-gradient.unitless_0_angle
- css.types.gradient.radial-gradient
- css.types.gradient.radial-gradient.at
- css.types.gradient.radial-gradient.doubleposition
- css.types.gradient.radial-gradient.interpolation_hints
- css.types.gradient.radial-gradient.premultiplied_gradients
- css.types.gradient.radial-gradient.single_color_stop
- css.types.gradient.repeating-radial-gradient
- css.types.gradient.repeating-radial-gradient.at
- css.types.gradient.repeating-radial-gradient.doubleposition
- css.types.gradient.repeating-radial-gradient.interpolation_hints
- css.types.gradient.repeating-radial-gradient.single_color_stop
15 changes: 15 additions & 0 deletions features/gradients.yml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -145,3 +145,18 @@ compat_features:
# safari_ios: "15"
- css.types.gradient.linear-gradient.premultiplied_gradients
- css.types.gradient.radial-gradient.premultiplied_gradients

# baseline: low
# baseline_low_date: 2025-04-04
# support:
# chrome: "135"
# chrome_android: "135"
# edge: "135"
# firefox: "136"
# firefox_android: "136"
# safari: "18.4"
# safari_ios: "18.4"
- css.types.gradient.linear-gradient.single_color_stop
- css.types.gradient.radial-gradient.single_color_stop
- css.types.gradient.repeating-linear-gradient.single_color_stop
- css.types.gradient.repeating-radial-gradient.single_color_stop
6 changes: 6 additions & 0 deletions features/numeric-separators.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
name: Numeric separators
description: To improve readability for numeric literals, underscores (`_`) can be used as separators. For example, `1_050.95` is equivalent to `1050.95`.
spec: https://tc39.es/ecma262/multipage/ecmascript-language-lexical-grammar.html#prod-NumericLiteralSeparator
group: javascript
compat_features:
- javascript.grammar.numeric_separators
17 changes: 17 additions & 0 deletions features/numeric-separators.yml.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Generated from: numeric-separators.yml
# Do not edit this file by hand. Edit the source file instead!

status:
baseline: high
baseline_low_date: 2020-07-28
baseline_high_date: 2023-01-28
support:
chrome: "75"
chrome_android: "75"
edge: "79"
firefox: "70"
firefox_android: "79"
safari: "13"
safari_ios: "13"
compat_features:
- javascript.grammar.numeric_separators
8 changes: 2 additions & 6 deletions features/numeric-seperators.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,2 @@
name: Numeric separators
description: To improve readability for numeric literals, underscores (`_`) can be used as separators. For example, `1_050.95` is equivalent to `1050.95`.
spec: https://tc39.es/ecma262/multipage/ecmascript-language-lexical-grammar.html#prod-NumericLiteralSeparator
group: javascript
compat_features:
- javascript.grammar.numeric_separators
kind: moved
redirect_target: numeric-separators
19 changes: 4 additions & 15 deletions features/numeric-seperators.yml.dist
Original file line number Diff line number Diff line change
@@ -1,17 +1,6 @@
# Generated from: numeric-seperators.yml
# Do not edit this file by hand. Edit the source file instead!
# This file intentionally left blank.
# Do not edit this file.
# The data for this feature has moved to numeric-separators.yml

status:
baseline: high
baseline_low_date: 2020-07-28
baseline_high_date: 2023-01-28
support:
chrome: "75"
chrome_android: "75"
edge: "79"
firefox: "70"
firefox_android: "79"
safari: "13"
safari_ios: "13"
compat_features:
- javascript.grammar.numeric_separators
{}
15 changes: 4 additions & 11 deletions features/single-color-gradients.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
name: Single color stop gradients
description: A single color stop can be provided to the `linear-gradient()`, `radial-gradient()`, and `conic-gradient()` CSS functions, and their repeating counterparts, to create a solid color background.
spec: https://drafts.csswg.org/css-images-4/#color-stop-syntax
group: gradients
compat_features:
- css.types.gradient.conic-gradient.single_color_stop
- css.types.gradient.linear-gradient.single_color_stop
- css.types.gradient.radial-gradient.single_color_stop
- css.types.gradient.repeating-conic-gradient.single_color_stop
- css.types.gradient.repeating-linear-gradient.single_color_stop
- css.types.gradient.repeating-radial-gradient.single_color_stop
kind: split
redirect_targets:
- gradients
- conic-gradients
25 changes: 6 additions & 19 deletions features/single-color-gradients.yml.dist
Original file line number Diff line number Diff line change
@@ -1,21 +1,8 @@
# Generated from: single-color-gradients.yml
# Do not edit this file by hand. Edit the source file instead!
# This file intentionally left blank.
# Do not edit this file.
# The data for this feature has moved to:
# - gradients.yml
# - conic-gradients.yml

status:
baseline: low
baseline_low_date: 2025-04-04
support:
chrome: "135"
chrome_android: "135"
edge: "135"
firefox: "136"
firefox_android: "136"
safari: "18.4"
safari_ios: "18.4"
compat_features:
- css.types.gradient.conic-gradient.single_color_stop
- css.types.gradient.linear-gradient.single_color_stop
- css.types.gradient.radial-gradient.single_color_stop
- css.types.gradient.repeating-conic-gradient.single_color_stop
- css.types.gradient.repeating-linear-gradient.single_color_stop
- css.types.gradient.repeating-radial-gradient.single_color_stop
{}
45 changes: 38 additions & 7 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import path from 'path';
import { Temporal } from '@js-temporal/polyfill';
import { fdir } from 'fdir';
import YAML from 'yaml';
import { FeatureData, GroupData, SnapshotData, WebFeaturesData } from './types';
import { GroupData, SnapshotData, WebFeaturesData } from './types';

import { toString as hastTreeToString } from 'hast-util-to-string';
import rehypeStringify from 'rehype-stringify';
Expand All @@ -14,6 +14,7 @@ import { unified } from 'unified';

import { BASELINE_LOW_TO_HIGH_DURATION, coreBrowserSet, parseRangedDateString } from 'compute-baseline';
import { Compat } from 'compute-baseline/browser-compat-data';
import { isMoved, isSplit } from './type-guards';

// The longest name allowed, to allow for compact display.
const nameMaxLength = 80;
Expand Down Expand Up @@ -118,7 +119,7 @@ function convertMarkdown(markdown: string) {
// Map from BCD keys/paths to web-features identifiers.
const bcdToFeatureId: Map<string, string> = new Map();

const features: { [key: string]: FeatureData } = {};
const features: WebFeaturesData["features"] = {};
for (const [key, data] of yamlEntries('features')) {
// Draft features reserve an identifier but aren't complete yet. Skip them.
if (data[draft]) {
Expand All @@ -128,6 +129,11 @@ for (const [key, data] of yamlEntries('features')) {
continue;
}

// Attach `kind: feature` to ordinary features
if (!isMoved(data) && !isSplit(data)) {
data.kind = "feature";
}

// Convert markdown to text+HTML.
if (data.description) {
const { text, html } = convertMarkdown(data.description);
Expand Down Expand Up @@ -183,12 +189,37 @@ for (const [key, data] of yamlEntries('features')) {
features[key] = data;
}

// Assert that discouraged feature's alternatives are valid
for (const [id, feature] of Object.entries(features)) {
for (const alternative of feature.discouraged?.alternatives ?? []) {
if (!(alternative in features)) {
throw new Error(`${id}'s alternative "${alternative}" is not a valid feature ID`);
// Assert that feature references are valid

function assertValidReference(sourceID: string, targetID: string): void {
if (targetID in features) {
if (isMoved(features[targetID]) || isSplit(features[targetID])) {
throw new Error(`${sourceID} references a redirect "${targetID}" instead of an ordinary feature ID`);
}
return;
}
throw new Error(`${sourceID}'s reference to "${targetID}" is not a valid feature ID`);
}

for (const [id, feature] of Object.entries(features)) {
const { kind } = feature;
switch (kind) {
case "feature":
for (const alternative of feature.discouraged?.alternatives ?? []) {
assertValidReference(id, alternative);
}
break;
case "moved":
assertValidReference(id, feature.redirect_target);
break;
case "split":
for (const target of feature.redirect_targets) {
assertValidReference(id, target);
}
break;
default:
kind satisfies never;
throw new Error(`Unhandled feature kind ${kind}}`);
}
}

Expand Down
Loading