Skip to content
Sam Thorogood edited this page Oct 31, 2021 · 8 revisions

This wiki describes the design that parses Chrome's internal extension definitions and emits ".d.ts" files (one for MV3+ extensions only, and one for all APIs including deprecated Platform Apps APIs.)

Escalations

This repository understands Chrome's extensions format and was built around ~Chrome 95's release (Oct 2021). If its GitHub Actions fails to run, this is likely because there's been a change to the format by the Extensions team.

If you're a Googler, escalate to that team via go/crx-team. They're not specifically responsible for this code, but it's possible to bisect their changes to Chromium to see what's changed.

Background

Chromium has a file explaining their internal extension definitions. There's also a file explaining the feature files, which define under what conditions an API is made available (e.g., MV3+, whether whitelisted, extension vs Platform Apps).

This repo parses extension definitions from three locations: extensions/common/api, chrome/common/extensions/common/api and chrome/common/apps/platform_apps/api.

Chrome has a confusing matrix of target channels and releases. APIs can be marked as available in "stable", "beta", "dev" channels and so on. But this may happen in pending/trunk code before that code is actually released to that channel. This repo ignores all but "stable" APIs for history generation, and if that "stable" API is not actually yet released in a published major Chrome version, it's annotated with the key @since Pending to mean—"will be released soon".

Tools

The "tools/run-release.js" performs the entire task of processing Chrome's types, including at historic versions to determine API availabilty, and preparing a release bundle inside the "dist/" folder. This release will include an updated "package.json" file if a change is detected. GitHub Actions will use this to publish a new version, or skip publishing if nothing has changed (the version is the same).

You can run this command without any special permissions. Check out the repo, run npm ci, and then npm run build.

It runs tsc on the generated TypeScript Definitions files, which can fail if the generated types are invalid.

The release script internally is using the following scripts (which you can also run directly).

Bundle

The "tools/prepare.js" script generates a JSON bundle (defined in as ProcessedAPIData in "types/chrome.d.ts") which represents Chrome's APIs at a given revision of Chrome.

By default this will find Chrome's HEAD revision (so running this over time will generate different results), but you can specify a numbered stable release, e.g. "tools/prepare.js 95" to generate the bundle for Chrome 95. This uses git directly to find the latest named tag for that release in Chrome's repositories and checks that revision out. This has been tested back to Chrome 42, but may work even earlier.

As mentioned in Chrome's documentation, extension definitions are either in IDL or JSON. This prepare script runs Chrome's internal converter with Python (found in tools/json_schema_compiler and some related paths) to convert all files to JSON before emitting the bundle. (This gives the repo its Python requirement).

Render .d.ts

You can pass the bundle above into "tools/render-dts.js", which will generate a TypeScript Definitions file for that bundle. Specify -a if you want to include all types, not just Platform Apps APIs.

For more information, see Rendering.

History Generation

To find when symbols were first made available in Chrome's stable release, the "tools/prepare-history.js" script can be run, which itself generates bundles for historic Chrome releases and renders symbols based on those releases. This uses the "tools/prepare.js" and "tools/render-symbols.js" scripts, respectively.

The "tools/render-symbols.js" script piggybacks on the Rendering code and generates a simple dictionary of symbols found at the given version (e.g., "api:alarms.AlarmCreateInfo", or "api:hid.DeviceFilter.productId"), including whether the API is deprecated at that version. We run this for releases over time to generate history data.

Cached Release Data / GitHub Actions

The "run-release.js" script directly and indirectly writes many files to ".cache", which is kept and restored by GitHub over time. The release takes about ~5 minutes without this, but with cached files (IDL => JSON, history data) it brings it down to <1min.

Clone this wiki locally