Skip to content

feat(schemas): separate public from internal schema#29041

Open
caugner wants to merge 81 commits intomainfrom
public-schema
Open

feat(schemas): separate public from internal schema#29041
caugner wants to merge 81 commits intomainfrom
public-schema

Conversation

@caugner
Copy link
Contributor

@caugner caugner commented Feb 13, 2026

Summary

Adds a public schema for data.json, separate from the internal browser/compat file schemas.

Also refines the schema descriptions based on Daniel's feedback.

Test results and supporting details

There are two changes that are strictly speaking breaking:

  1. The CompatStatement.source_file property is now required.
  2. The BrowserStatement.upstream property is narrowed down to UpstreamBrowserName, a subset of BrowserName.
Before
/* This file is a part of @mdn/browser-compat-data
 * See LICENSE file for more information. */

/**
* This file was automatically generated by json-schema-to-typescript.
* DO NOT MODIFY IT BY HAND. Instead, modify the source schema files in
* schemas/*, and run "npm run gentypes" to regenerate this file.
*/

/**
 * The names of the known browsers.
 */
export type BrowserName = "bun" | "chrome" | "chrome_android" | "deno" | "edge" | "firefox" | "firefox_android" | "ie" | "nodejs" | "oculus" | "opera" | "opera_android" | "safari" | "safari_ios" | "samsunginternet_android" | "webview_android" | "webview_ios";

export type VersionValue = string | false;

/**
 * This interface was referenced by `BrowserDataFile`'s JSON-Schema
 * via the `definition` "browsers".
 */
export type Browsers = Record<BrowserName, BrowserStatement>;
/**
 * This interface was referenced by `BrowserDataFile`'s JSON-Schema
 * via the `definition` "browser_type".
 */
export type BrowserType = "desktop" | "mobile" | "xr" | "server";
/**
 * This interface was referenced by `BrowserDataFile`'s JSON-Schema
 * via the `definition` "browser_engine".
 */
export type BrowserEngine = "Blink" | "EdgeHTML" | "Gecko" | "Presto" | "Trident" | "WebKit" | "V8";
/**
 * This interface was referenced by `BrowserDataFile`'s JSON-Schema
 * via the `definition` "browser_status".
 */
export type BrowserStatus = "retired" | "current" | "beta" | "nightly" | "esr" | "planned";


/**
 * This interface was referenced by `BrowserDataFile`'s JSON-Schema
 * via the `definition` "browser_statement".
 */
export interface BrowserStatement {
  /**
   * The browser brand name (e.g. Firefox, Firefox Android, Chrome, etc.).
   */
  name: string;
  /**
   * The platform the browser runs on (e.g. desktop, mobile, XR, or server engine).
   */
  type: BrowserType;
  /**
   * The upstream browser this browser derives from (e.g. Firefox Android is derived from Firefox, Edge is derived from Chrome).
   */
  upstream?: BrowserName;
  /**
   * The name of the browser's preview channel (e.g. 'Nightly' for Firefox or 'TP' for Safari).
   */
  preview_name?: string;
  /**
   * URL of the page where feature flags can be changed (e.g. 'about:config' for Firefox or 'chrome://flags' for Chrome).
   */
  pref_url?: string;
  /**
   * Whether the browser supports user-toggleable flags that enable or disable features.
   */
  accepts_flags: boolean;
  /**
   * Whether the browser supports extensions.
   */
  accepts_webextensions: boolean;
  /**
   * The known versions of this browser.
   */
  releases: {[version: string]: ReleaseStatement};
}
/**
 * This interface was referenced by `BrowserDataFile`'s JSON-Schema
 * via the `definition` "release_statement".
 */
export interface ReleaseStatement {
  /**
   * The date on which this version was released, formatted as `YYYY-MM-DD`.
   */
  release_date?: string;
  /**
   * A link to the release notes or changelog for a given release.
   */
  release_notes?: string;
  /**
   * A property indicating where in the lifetime cycle this release is in (e.g. current, retired, beta, nightly).
   */
  status: BrowserStatus;
  /**
   * Name of the browser's underlying engine.
   */
  engine?: BrowserEngine;
  /**
   * Version of the engine corresponding to the browser version.
   */
  engine_version?: string;
}


/**
 * This interface was referenced by `CompatDataFile`'s JSON-Schema definition
 * via the `patternProperty` "^(?!__compat)(?!webextensions)[a-zA-Z_0-9-$@]*$".
 *
 * This interface was referenced by `CompatDataFile`'s JSON-Schema
 * via the `definition` "identifier".
 */
export type Identifier = {[key: string]: Identifier} & {__compat?: CompatStatement};
/**
 * 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.
 */
export type SupportBlock = Partial<Record<BrowserName, SupportStatement>>;
/**
 * This interface was referenced by `CompatDataFile`'s JSON-Schema
 * via the `definition` "support_statement".
 */
export type SupportStatement =
  | SimpleSupportStatement
  | [SimpleSupportStatement, SimpleSupportStatement, ...SimpleSupportStatement[]];


/**
 * This interface was referenced by `CompatDataFile`'s JSON-Schema definition
 * via the `patternProperty` "^__compat$".
 *
 * This interface was referenced by `CompatDataFile`'s JSON-Schema
 * via the `definition` "compat_statement".
 */
export interface CompatStatement {
  /**
   * A string containing a human-readable description of the feature.
   */
  description?: string;
  /**
   * A URL that points to an MDN reference page documenting the feature. The URL should be language-agnostic.
   */
  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, string, ...string[]];
  /**
   * An optional array of strings allowing to assign tags to the feature.
   *
   * @minItems 1
   */
  tags?: [string, ...string[]];
  /**
   * The path to the file that defines this feature in browser-compat-data, relative to the repository root. Useful for guiding potential contributors towards the correct file to edit. This is automatically generated at build time and should never manually be specified.
   */
  source_file?: string;
  support: SupportBlock;
  status?: StatusBlock;
}
/**
 * An object containing information about the stability of the feature.
 */
export interface StatusBlock {
  /**
   * @deprecated
   * (This property is deprecated. Prefer using more well-defined stability calculations, such as Baseline, instead.) A boolean value. Usually, this value is true for single-implementer features and false for multiple-implementer features or single-implementer features that are not expected to change.
   */
  experimental: boolean;
  /**
   * A boolean value indicating whether the feature is part of an active specification or specification process.
   */
  standard_track: boolean;
  /**
   * A boolean value that indicates whether 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;
}
/**
 * This interface was referenced by `CompatDataFile`'s JSON-Schema
 * via the `definition` "simple_support_statement".
 */
export interface SimpleSupportStatement {
  /**
   * A string (indicating which browser version added this feature), or the value false (indicating the feature is not supported).
   */
  version_added: VersionValue;
  /**
   * A string, indicating which browser version removed this feature.
   */
  version_removed?: string;
  /**
   * A string, indicating the last browser version that supported this feature. This is automatically generated.
   */
  version_last?: string;
  /**
   * A prefix to add to the sub-feature name (defaults to empty string). If applicable, leading and trailing '-' must be included.
   */
  prefix?: string;
  /**
   * An alternative name for the feature, for cases where a feature is implemented under an entirely different name and not just prefixed.
   */
  alternative_name?: string;
  /**
   * An optional array of objects describing flags that must be configured for this browser to support this feature.
   *
   * @minItems 1
   */
  flags?: [FlagStatement, ...FlagStatement[]];
  /**
   * 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.
   */
  impl_url?: string | [string, string, ...string[]];
  /**
   * A boolean value indicating whether or not the implementation of the sub-feature deviates from the specification in a way that may cause compatibility problems. It defaults to false (no interoperability problems expected). If set to true, it is recommended that you add a note explaining how it diverges from the standard (such as that it implements an old version of the standard, for example).
   */
  partial_implementation?: true;
  /**
   * A string or array of strings containing additional information.
   */
  notes?: string | [string, string, ...string[]];
}
/**
 * This interface was referenced by `CompatDataFile`'s JSON-Schema
 * via the `definition` "flag_statement".
 */
export interface FlagStatement {
  /**
   * An enum that indicates the flag type.
   */
  type: "preference" | "runtime_flag";
  /**
   * A string giving the name of the flag or preference that must be configured.
   */
  name: string;
  /**
   * A string giving the value which the specified flag must be set to for this feature to work.
   */
  value_to_set?: string;
}


export interface MetaBlock {
  version: string;
  timestamp: string;
}

export interface CompatData {
  /**
   * Contains metadata for the current BCD information, such as the BCD version.
   */
  __meta: MetaBlock;

  /**
   * 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 various manifests, such as the [Web Application Manifest](https://developer.mozilla.org/docs/Web/Progressive_web_apps/manifest).
   */
  manifests: Identifier;

  /**
   * Contains data for [MathML](https://developer.mozilla.org/docs/Web/MathML) elements, attributes, and global attributes.
   */
  mathml: Identifier;

  /**
   * Contains data for [Media types](https://developer.mozilla.org/docs/Web/HTTP/Guides/MIME_types).
   */
  mediatypes: Identifier;

  /**
   * Contains data for [SVG](https://developer.mozilla.org/docs/Web/SVG) elements, attributes, and global attributes.
   */
  svg: Identifier;

  /**
   * Contains data for [WebAssembly](https://developer.mozilla.org/docs/WebAssembly) features.
   */
  webassembly: 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;
}
After
/* This file is a part of @mdn/browser-compat-data
 * See LICENSE file for more information. */

/**
 * This file was automatically generated by json-schema-to-typescript.
 * DO NOT MODIFY IT BY HAND. Instead, modify the source schema files in
 * schemas/*, and run "npm run gentypes" to regenerate this file.
 */

export type Identifier = {__compat?: CompatStatement} & {[key: string]: Identifier};
/**
 * Data for each known and tracked browser/runtime.
 */
export type Browsers = Record<BrowserName, BrowserStatement>;
/**
 * Platform the browser runs on (e.g. desktop, mobile, XR, or server engine).
 */
export type BrowserType = "desktop" | "mobile" | "xr" | "server";
/**
 * Browser engine.
 */
export type BrowserEngine = "Blink" | "EdgeHTML" | "Gecko" | "Presto" | "Trident" | "WebKit" | "V8";
/**
 * Browser key (e.g. 'firefox', 'chrome_android', or 'webview_ios').
 */
export type BrowserName =
  | "bun"
  | "chrome"
  | "chrome_android"
  | "deno"
  | "edge"
  | "firefox"
  | "firefox_android"
  | "ie"
  | "nodejs"
  | "oculus"
  | "opera"
  | "opera_android"
  | "safari"
  | "safari_ios"
  | "samsunginternet_android"
  | "webview_android"
  | "webview_ios";
/**
 * Upstream browser key (e.g. 'firefox' or 'chrome_android').
 */
export type UpstreamBrowserName = "chrome" | "chrome_android" | "firefox" | "safari" | "safari_ios";
/**
 * Lifetime cycle status of a browser release (e.g. 'current', 'retired', 'beta', 'nightly').
 */
export type BrowserStatus = "retired" | "current" | "beta" | "nightly" | "esr" | "planned";
/**
 * A string (indicating which browser version added this feature), or the value false (indicating the feature is not supported).
 */
export type VersionValue = string | false;
export type SupportStatement =
  | SimpleSupportStatement
  | [SimpleSupportStatement, SimpleSupportStatement, ...SimpleSupportStatement[]];
/**
 * 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.
 */
export type SupportBlock = Partial<Record<BrowserName, SupportStatement>>;

/**
 * Shape of the `data.json` file in published BCD releases
 */
export interface CompatData {
  __meta: MetaBlock;
  api: Identifier;
  browsers: Browsers;
  css: Identifier;
  html: Identifier;
  http: Identifier;
  javascript: Identifier;
  manifests: Identifier;
  mathml: Identifier;
  mediatypes: Identifier;
  svg: Identifier;
  webassembly: Identifier;
  webdriver: Identifier;
  webextensions: Identifier;
}
/**
 * Metadata of the present BCD data.
 */
export interface MetaBlock {
  version: string;
  timestamp: string;
}
export interface BrowserStatement {
  /**
   * Name of the browser (e.g. 'Firefox', 'Firefox Android', 'Chrome', etc.).
   */
  name: string;
  type: BrowserType;
  upstream?: UpstreamBrowserName;
  /**
   * Name of the browser's preview channel (e.g. 'Nightly' for Firefox or 'TP' for Safari).
   */
  preview_name?: string;
  /**
   * URL of the page where feature flags can be changed (e.g. 'about:config' for Firefox or 'chrome://flags' for Chrome).
   */
  pref_url?: string;
  /**
   * Whether the browser supports user-toggleable flags that enable or disable features.
   */
  accepts_flags: boolean;
  /**
   * Whether the browser supports extensions.
   */
  accepts_webextensions: boolean;
  /**
   * The known versions of this browser.
   */
  releases: Record<string, ReleaseStatement>;
}
export interface ReleaseStatement {
  /**
   * The date on which this version was released, formatted as `YYYY-MM-DD`.
   */
  release_date?: string;
  /**
   * A link to the release notes or changelog for a given release.
   */
  release_notes?: string;
  status: BrowserStatus;
  engine?: BrowserEngine;
  /**
   * Version of the engine corresponding to the browser version.
   */
  engine_version?: string;
}
export interface SimpleSupportStatement {
  version_added: VersionValue;
  /**
   * A string, indicating which browser version removed this feature.
   */
  version_removed?: string;
  /**
   * A string, indicating the last browser version that supported this feature. This is automatically generated.
   */
  version_last?: string;
  /**
   * A prefix to add to the sub-feature name (defaults to empty string). If applicable, leading and trailing '-' must be included.
   */
  prefix?: string;
  /**
   * An alternative name for the feature, for cases where a feature is implemented under an entirely different name and not just prefixed.
   */
  alternative_name?: string;
  /**
   * An optional array of objects describing flags that must be configured for this browser to support this feature.
   *
   * @minItems 1
   */
  flags?: [FlagStatement, ...FlagStatement[]];
  /**
   * 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.
   */
  impl_url?: string | [string, string, ...string[]];
  /**
   * A boolean value indicating whether or not the implementation of the sub-feature deviates from the specification in a way that may cause compatibility problems. It defaults to false (no interoperability problems expected). If set to true, it is recommended that you add a note explaining how it diverges from the standard (such as that it implements an old version of the standard, for example).
   */
  partial_implementation?: true;
  /**
   * A string or array of strings containing additional information.
   */
  notes?: string | [string, string, ...string[]];
}
export interface FlagStatement {
  /**
   * An enum that indicates the flag type.
   */
  type: "preference" | "runtime_flag";
  /**
   * A string giving the name of the flag or preference that must be configured.
   */
  name: string;
  /**
   * A string giving the value which the specified flag must be set to for this feature to work.
   */
  value_to_set?: string;
}
/**
 * An object containing information about the stability of the feature.
 */
export interface StatusBlock {
  /**
   * @deprecated
   * (This property is deprecated. Prefer using more well-defined stability calculations, such as Baseline, instead.) A boolean value. Usually, this value is true for single-implementer features and false for multiple-implementer features or single-implementer features that are not expected to change.
   */
  experimental: boolean;
  /**
   * A boolean value indicating whether the feature is part of an active specification or specification process.
   */
  standard_track: boolean;
  /**
   * A boolean value that indicates whether 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;
}
/**
 * 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.
 */
export interface CompatStatement {
  /**
   * Human-readable description of the feature.
   */
  description?: string;
  /**
   * Link to the MDN reference page documenting the feature.
   */
  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, string, ...string[]];
  /**
   * An optional array of strings allowing to assign tags to the feature.
   *
   * @minItems 1
   */
  tags?: [string, ...string[]];
  /**
   * The path to the file that defines this feature in browser-compat-data, relative to the repository root. Useful for guiding potential contributors towards the correct file to edit. This is automatically generated at build time and should never manually be specified.
   */
  source_file: string;
  support: SupportBlock;
  status?: StatusBlock;
}
diff
diff --git a/before.d.ts b/after.d.ts
index fd09440..6c45e5b 100644
--- a/before.d.ts
+++ b/after.d.ts
@@ -8,8 +8,7 @@
  */
 
 /**
- * This interface was referenced by `BrowserDataFile`'s JSON-Schema
- * via the `definition` "browser_engine".
+ * Browser engine.
  */
 export type BrowserEngine =
   | "Blink"
@@ -20,7 +19,7 @@ export type BrowserEngine =
   | "WebKit"
   | "V8";
 /**
- * The names of the known browsers.
+ * Browser key (e.g. 'firefox', 'chrome_android', or 'webview_ios').
  */
 export type BrowserName =
   | "bun"
@@ -41,30 +40,19 @@ export type BrowserName =
   | "webview_android"
   | "webview_ios";
 /**
- * This interface was referenced by `BrowserDataFile`'s JSON-Schema
- * via the `definition` "browsers".
+ * Data for each known and tracked browser/runtime.
  */
 export type Browsers = Record<BrowserName, BrowserStatement>;
 
-/**
- * This interface was referenced by `BrowserDataFile`'s JSON-Schema
- * via the `definition` "browser_statement".
- */
 export interface BrowserStatement {
   /**
-   * The browser brand name (e.g. Firefox, Firefox Android, Chrome, etc.).
+   * Name of the browser (e.g. 'Firefox', 'Firefox Android', 'Chrome', etc.).
    */
   name: string;
-  /**
-   * The platform the browser runs on (e.g. desktop, mobile, XR, or server engine).
-   */
   type: BrowserType;
+  upstream?: UpstreamBrowserName;
   /**
-   * The upstream browser this browser derives from (e.g. Firefox Android is derived from Firefox, Edge is derived from Chrome).
-   */
-  upstream?: BrowserName;
-  /**
-   * The name of the browser's preview channel (e.g. 'Nightly' for Firefox or 'TP' for Safari).
+   * Name of the browser's preview channel (e.g. 'Nightly' for Firefox or 'TP' for Safari).
    */
   preview_name?: string;
   /**
@@ -82,11 +70,10 @@ export interface BrowserStatement {
   /**
    * The known versions of this browser.
    */
-  releases: { [version: string]: ReleaseStatement };
+  releases: Record<string, ReleaseStatement>;
 }
 /**
- * This interface was referenced by `BrowserDataFile`'s JSON-Schema
- * via the `definition` "browser_status".
+ * Lifetime cycle status of a browser release (e.g. 'current', 'retired', 'beta', 'nightly').
  */
 export type BrowserStatus =
   | "retired"
@@ -96,96 +83,45 @@ export type BrowserStatus =
   | "esr"
   | "planned";
 /**
- * This interface was referenced by `BrowserDataFile`'s JSON-Schema
- * via the `definition` "browser_type".
+ * Platform the browser runs on (e.g. desktop, mobile, XR, or server engine).
  */
 export type BrowserType = "desktop" | "mobile" | "xr" | "server";
 
+/**
+ * Shape of the `data.json` file in published BCD releases
+ */
 export interface CompatData {
-  /**
-   * Contains metadata for the current BCD information, such as the BCD version.
-   */
   __meta: MetaBlock;
-
-  /**
-   * 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 various manifests, such as the [Web Application Manifest](https://developer.mozilla.org/docs/Web/Progressive_web_apps/manifest).
-   */
   manifests: Identifier;
-
-  /**
-   * Contains data for [MathML](https://developer.mozilla.org/docs/Web/MathML) elements, attributes, and global attributes.
-   */
   mathml: Identifier;
-
-  /**
-   * Contains data for [Media types](https://developer.mozilla.org/docs/Web/HTTP/Guides/MIME_types).
-   */
   mediatypes: Identifier;
-
-  /**
-   * Contains data for [SVG](https://developer.mozilla.org/docs/Web/SVG) elements, attributes, and global attributes.
-   */
   svg: Identifier;
-
-  /**
-   * Contains data for [WebAssembly](https://developer.mozilla.org/docs/WebAssembly) features.
-   */
   webassembly: 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;
 }
 /**
- * This interface was referenced by `CompatDataFile`'s JSON-Schema definition
- * via the `patternProperty` "^__compat$".
+ * 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.
  *
- * This interface was referenced by `CompatDataFile`'s JSON-Schema
- * via the `definition` "compat_statement".
+ * 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.
  */
 export interface CompatStatement {
   /**
-   * A string containing a human-readable description of the feature.
+   * Human-readable description of the feature.
    */
   description?: string;
   /**
-   * A URL that points to an MDN reference page documenting the feature. The URL should be language-agnostic.
+   * Link to the MDN reference page documenting the feature.
    */
   mdn_url?: string;
   /**
@@ -201,14 +137,10 @@ export interface CompatStatement {
   /**
    * The path to the file that defines this feature in browser-compat-data, relative to the repository root. Useful for guiding potential contributors towards the correct file to edit. This is automatically generated at build time and should never manually be specified.
    */
-  source_file?: string;
+  source_file: string;
   support: SupportBlock;
   status?: StatusBlock;
 }
-/**
- * This interface was referenced by `CompatDataFile`'s JSON-Schema
- * via the `definition` "flag_statement".
- */
 export interface FlagStatement {
   /**
    * An enum that indicates the flag type.
@@ -223,25 +155,18 @@ export interface FlagStatement {
    */
   value_to_set?: string;
 }
-/**
- * This interface was referenced by `CompatDataFile`'s JSON-Schema definition
- * via the `patternProperty` "^(?!__compat)(?!webextensions)[a-zA-Z_0-9-$@]*$".
- *
- * This interface was referenced by `CompatDataFile`'s JSON-Schema
- * via the `definition` "identifier".
- */
-export type Identifier = { [key: string]: Identifier } & {
-  __compat?: CompatStatement;
+
+export type Identifier = { __compat?: CompatStatement } & {
+  [key: string]: Identifier;
 };
 
+/**
+ * Metadata of the present BCD data.
+ */
 export interface MetaBlock {
   version: string;
   timestamp: string;
 }
-/**
- * This interface was referenced by `BrowserDataFile`'s JSON-Schema
- * via the `definition` "release_statement".
- */
 export interface ReleaseStatement {
   /**
    * The date on which this version was released, formatted as `YYYY-MM-DD`.
@@ -251,27 +176,14 @@ export interface ReleaseStatement {
    * A link to the release notes or changelog for a given release.
    */
   release_notes?: string;
-  /**
-   * A property indicating where in the lifetime cycle this release is in (e.g. current, retired, beta, nightly).
-   */
   status: BrowserStatus;
-  /**
-   * Name of the browser's underlying engine.
-   */
   engine?: BrowserEngine;
   /**
    * Version of the engine corresponding to the browser version.
    */
   engine_version?: string;
 }
-/**
- * This interface was referenced by `CompatDataFile`'s JSON-Schema
- * via the `definition` "simple_support_statement".
- */
 export interface SimpleSupportStatement {
-  /**
-   * A string (indicating which browser version added this feature), or the value false (indicating the feature is not supported).
-   */
   version_added: VersionValue;
   /**
    * A string, indicating which browser version removed this feature.
@@ -330,10 +242,6 @@ export interface StatusBlock {
  * 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.
  */
 export type SupportBlock = Partial<Record<BrowserName, SupportStatement>>;
-/**
- * This interface was referenced by `CompatDataFile`'s JSON-Schema
- * via the `definition` "support_statement".
- */
 export type SupportStatement =
   | SimpleSupportStatement
   | [
@@ -341,5 +249,16 @@ export type SupportStatement =
       SimpleSupportStatement,
       ...SimpleSupportStatement[],
     ];
-
+/**
+ * Upstream browser key (e.g. 'firefox' or 'chrome_android').
+ */
+export type UpstreamBrowserName =
+  | "chrome"
+  | "chrome_android"
+  | "firefox"
+  | "safari"
+  | "safari_ios";
+/**
+ * A string (indicating which browser version added this feature), or the value false (indicating the feature is not supported).
+ */
 export type VersionValue = string | false;

Related issues

Fixes #29059.

@github-actions github-actions bot added schema Isses or pull requests regarding the JSON schema files used in this project. infra Infrastructure issues (npm, GitHub Actions, releases) of this project scripts Issues or pull requests regarding the scripts in scripts/. size:l [PR only] 101-1000 LoC changed labels Feb 13, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Feb 13, 2026

Tip: Review these changes grouped by change (recommended for most PRs), or grouped by feature (for large PRs).

@github-actions github-actions bot added linter Issues or pull requests regarding the tests / linter of the JSON files. bulk_update An update to a mass amount of data, or scripts/linters related to such changes size:xl [PR only] >1000 LoC changed and removed size:l [PR only] 101-1000 LoC changed labels Feb 13, 2026
@caugner
Copy link
Contributor Author

caugner commented Mar 17, 2026

Overall my biggest concern/confusion is over generating the internal types dynamically, and modifying the manually-defined internal types.

I understand wanting to generates the internal types from the internal schema - though I think things may be simpler just duplicating the data here, and having hand crafted internal types. After all, a change to the internal schema, could require changing the external schema too, and then I'm not sure how much overhead changing the internal types are. Linting/type checking should also catch any issues.

What I don't understand is defining some internal types, then removing elements from them to define the "true" internal types. Shouldn't they just be defined properly in the first place?

To summarize my comments on the review threads: This is the pre-existing behavior of the (internal) type generation, and it wasn't necessary to fix this to separate the public schema. But let me see if I can fix it anyhow.

@caugner
Copy link
Contributor Author

caugner commented Mar 17, 2026

But let me see if I can fix it anyhow.

@LeoMcA Resolved via 9193ced and 6ed2a4b. (It was easier than I thought, given that I had already aligned the JSON schemas following Daniel's review.)

@caugner caugner requested a review from LeoMcA March 17, 2026 14:58
@github-actions github-actions bot added the merge conflicts 🚧 This PR needs to merge latest "main" branch to resolve a merge conflict or other issue. label Mar 19, 2026
@github-actions
Copy link
Contributor

This pull request has merge conflicts that must be resolved before it can be merged.

@LeoMcA
Copy link
Member

LeoMcA commented Mar 19, 2026

This is still a bit confused/confusing:

  • Identifier in types/public.d.ts is a circular reference so resolves to any
    • for some reason the error is swallowed there, but surfaced in build/types.d.ts
    • having two files which are identical is a bit confusing: AIUI types/public.d.ts exists to use the public types internally in the build scripts, build/types.d.ts is the one we ship in the package. Maybe we could/should just bundle types/public.d.ts in the package? Or document this distinction?
  • InternalIdentifier is circular in types/internal.d.ts so silently resolves to any
  • the types referenced in types/index.d.ts are never imported, so silently resolve to any
  • build/import.d.mts and build/require.d.ts still reference InternalCompatData, which doesn't exist in build/types.d.ts, and this fails silently
  • none of the above should be failing silently, so there's some bug in the typescript config

@github-actions github-actions bot removed the merge conflicts 🚧 This PR needs to merge latest "main" branch to resolve a merge conflict or other issue. label Mar 19, 2026
@caugner
Copy link
Contributor Author

caugner commented Mar 19, 2026

  • Identifier in types/public.d.ts is a circular reference so resolves to any
  • InternalIdentifier is circular in types/internal.d.ts so silently resolves to any

This is a dilemma, but the resolution to any is probably less acceptable than the status quo, so I'm reverting to the previous type, in which __support is never, the union of Identifier (from {[key: string]: Identifier}) and CompatStatement (from {__compat?: CompatStatement}).

  • having two files which are identical is a bit confusing: AIUI types/public.d.ts exists to use the public types internally in the build scripts, build/types.d.ts is the one we ship in the package. Maybe we could/should just bundle types/public.d.ts in the package? Or document this distinction?

This is pre-existing, and I don't think it has actually caused any confusion. The build/ directory is essentially dist/ and shows the package contents as it would get published. Merging build/types.d.ts and types/public.d.ts would mean that either build/ no longer reflects the published package, or we would reference build/ from scripts, which is differently confusing.

  • the types referenced in types/index.d.ts are never imported, so silently resolve to any
  • build/import.d.mts and build/require.d.ts still reference InternalCompatData, which doesn't exist in build/types.d.ts, and this fails silently

These are now fixed.

  • none of the above should be failing silently, so there's some bug in the typescript config

It seems that the TypeScript errors in build/types.d.ts paradoxically disappear if we stop excluding build in tsconfig.json. Also, we cannot currently disable skipLibCheck due to web-platform-dx/web-features#3878.

Copy link
Member

@LeoMcA LeoMcA left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, nice! I built locally and installed in fred and typescript was happy.

So we don't rely on the web-features type fixes PR being merged, and so we can ensure type breakages aren't introduced in the future, it would be nice to drop a tsconfig.json like this into types/ and build/:

{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "skipLibCheck": false,
  }
}

I tested locally, with deliberate changes to break those files, and it surfaced them when running with cd types && npx tsc && cd ../build && npx tsc.

@caugner
Copy link
Contributor Author

caugner commented Mar 20, 2026

@LeoMcA

So we don't rely on the web-features type fixes PR being merged, and so we can ensure type breakages aren't introduced in the future, it would be nice to drop a tsconfig.json like this into types/ and build/:

I added it to types/, but I'm not in favor of adding it to build/. That would either mean it ends up in the published package (where it would be invalid, as it extends ../), or we would also have to add .npmignore that excludes it from the package.

I hope the web-features PR gets accepted, and then we can disable skipLibCheck globally.

@LeoMcA
Copy link
Member

LeoMcA commented Mar 20, 2026

I'm not in favor of adding it to build/. That would either mean it ends up in the published package (where it would be invalid, as it extends ../), or we would also have to add .npmignore that excludes it from the package.

I think it most needs to be there: those are the types we ship to consumers, and those are the types it's most essential to ensure are correct, and the ones least likely to be noticed are broken while working on bcd.

Is using .npmignore so bad?

@github-actions github-actions bot added the merge conflicts 🚧 This PR needs to merge latest "main" branch to resolve a merge conflict or other issue. label Mar 25, 2026
@github-actions
Copy link
Contributor

This pull request has merge conflicts that must be resolved before it can be merged.

@github-actions github-actions bot removed the merge conflicts 🚧 This PR needs to merge latest "main" branch to resolve a merge conflict or other issue. label Mar 25, 2026
@caugner
Copy link
Contributor Author

caugner commented Mar 25, 2026

I think it most needs to be there: those are the types we ship to consumers, and those are the types it's most essential to ensure are correct, and the ones least likely to be noticed are broken while working on bcd.

Is using .npmignore so bad?

You made good points, and convinced me.

Resolved via 77e9d15 c433281.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bulk_update An update to a mass amount of data, or scripts/linters related to such changes docs Issues or pull requests regarding the documentation of this project. infra Infrastructure issues (npm, GitHub Actions, releases) of this project linter Issues or pull requests regarding the tests / linter of the JSON files. schema Isses or pull requests regarding the JSON schema files used in this project. scripts Issues or pull requests regarding the scripts in scripts/. semver-major-bump A change that is potentially breaking for consumers size:xl [PR only] >1000 LoC changed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Separate public and internal schema

4 participants