Skip to content

API Descriptions Update #1940

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

Merged
merged 97 commits into from
Apr 17, 2025
Merged
Show file tree
Hide file tree
Changes from 96 commits
Commits
Show all changes
97 commits
Select commit Hold shift + click to select a range
6bdf491
chore: remove the old json file
Bashamega Mar 15, 2025
5d9b1b3
docs: update README to remove deprecatedMessage.json reference
Bashamega Mar 15, 2025
de0d117
feat: implement GitHub API integration to fetch index.md file descrip…
Bashamega Mar 15, 2025
39d5719
ci: add GITHUB_TOKEN to CI workflow environment
Bashamega Mar 15, 2025
df3631e
feat: add mdn-content submodule for documentation resources
Bashamega Mar 15, 2025
e9c9379
chore: revert
Bashamega Mar 15, 2025
8e74526
feat: add script to recursively retrieve folder paths for API documen…
Bashamega Mar 15, 2025
40e5317
feat: add generate script to build process for description generation
Bashamega Mar 15, 2025
d7c6297
feat: enhance description generation by adding index.md content retri…
Bashamega Mar 15, 2025
51bc9cb
refactor: simplify folder retrieval logic in generateDescriptions.ts
Bashamega Mar 15, 2025
af54369
feat: update output path for generated API descriptions JSON file
Bashamega Mar 15, 2025
1bb475e
-
Bashamega Mar 15, 2025
2695f20
feat: add summary extraction from index.md content for description ge…
Bashamega Mar 15, 2025
5a5cbdd
feat: generate the API descriptions
Bashamega Mar 15, 2025
66f5156
fix: json format
Bashamega Mar 15, 2025
61d4fde
refactor: improve code readability and formatting in generateDescript…
Bashamega Mar 15, 2025
c06f21b
chore: generate baseline
Bashamega Mar 15, 2025
c110920
chore: generate
Bashamega Mar 16, 2025
ed6f97f
feat: refactor generateDescriptions to export generateDescription fun…
Bashamega Mar 16, 2025
afbb9e1
refactor: enhance generateDescription function to improve Markdown pr…
Bashamega Mar 21, 2025
c854ebb
chore: build
Bashamega Mar 21, 2025
17ded6a
-
Bashamega Mar 27, 2025
4c87230
format
Bashamega Mar 27, 2025
47bd142
Merge branch 'microsoft:main' into 1937
Bashamega Mar 27, 2025
5933dd8
adds missing libs
Bashamega Mar 27, 2025
0ce76d5
Modify the regexes
Bashamega Mar 27, 2025
6ff87d9
fix: This string may still contain <script , which may cause an HTML …
Bashamega Mar 27, 2025
3b416ad
fix: regex in cleanText function to prevent exponential backtracking
Bashamega Mar 27, 2025
b8d9480
chore: don't delete the api descriptions, if the submodule doesn't exist
Bashamega Mar 28, 2025
ad92293
feat: unit tests
Bashamega Mar 28, 2025
5d58288
-
Bashamega Mar 28, 2025
c1ad6ea
get only the first paragraph
Bashamega Mar 29, 2025
8402152
fix: update API description generation to return data instead of savi…
Bashamega Mar 29, 2025
445fa89
chore: remove json file
Bashamega Mar 29, 2025
4a9adfa
chore: update .gitignore
Bashamega Mar 29, 2025
28bfccf
Re-add mdn submodule
Bashamega Mar 29, 2025
faca57f
remove old submodule
Bashamega Mar 29, 2025
ba429e0
chore: update dir
Bashamega Mar 29, 2025
ee545fc
refactor: simplify text cleaning logic in generateDescriptions.ts
Bashamega Mar 29, 2025
6232f92
Make it take the full sentence
Bashamega Mar 29, 2025
bfbfcbb
fix workflow
Bashamega Mar 29, 2025
8e5651c
chore: fetch submodules
Bashamega Mar 29, 2025
46ed6ae
fix
Bashamega Mar 29, 2025
4f02639
fix
Bashamega Mar 29, 2025
dea3437
chore: updates deploy
Bashamega Mar 29, 2025
afeef87
-
Bashamega Mar 29, 2025
8f1ca09
Restore
Bashamega Mar 30, 2025
499e76e
linter
Bashamega Mar 30, 2025
156c52d
feat: markdown libs
Bashamega Mar 30, 2025
4f48c8d
fix
Bashamega Mar 30, 2025
1d050d3
remove parser
Bashamega Mar 30, 2025
bff43b4
remove backstick
Bashamega Mar 30, 2025
b9d231b
remove extra steps
Bashamega Mar 30, 2025
fe739ba
adds back sticks
Bashamega Mar 30, 2025
6f7c6cf
-
Bashamega Mar 30, 2025
acc701a
remove extra chore
Bashamega Mar 30, 2025
c0b174b
-
Bashamega Mar 30, 2025
aeb2d85
fix: prevent sentence split before abbreviations like "i.e." and "e.g."
Bashamega Mar 30, 2025
65213fe
generate baselines
Bashamega Mar 30, 2025
26b2047
fix: improve title extraction by removing trailing 'extension'
Bashamega Mar 30, 2025
d899655
refactor: update fs import to use promises module
Bashamega Mar 30, 2025
4c51aa9
move and rename the generate descriptions file
Bashamega Mar 30, 2025
bb2d85a
urls
Bashamega Mar 30, 2025
1f4f5f1
removes fs
Bashamega Mar 30, 2025
e4a1eb4
removes redirect
Bashamega Mar 30, 2025
6166a1f
-
Bashamega Mar 30, 2025
3f18c23
chore: removes url and path
Bashamega Mar 31, 2025
7289d10
refactor: update directory handling to use URL objects
Bashamega Mar 31, 2025
2dbb91b
fix
Bashamega Mar 31, 2025
1693dbd
-
Bashamega Mar 31, 2025
f2ab8d1
refactor: update workflow to include submodule handling
Bashamega Mar 31, 2025
2a3ead7
update submodule
Bashamega Mar 31, 2025
5894b0d
-
Bashamega Mar 31, 2025
2710f19
-
Bashamega Mar 31, 2025
f18a444
-
Bashamega Apr 1, 2025
f9d9bf8
rename workflow
Bashamega Apr 1, 2025
5ec693d
-
Bashamega Apr 1, 2025
8868c1d
Update update-core-deps.yml
Bashamega Apr 1, 2025
b3cf7d6
Merge branch 'microsoft:main' into 1937
Bashamega Apr 1, 2025
4008574
Update update-core-deps.yml
Bashamega Apr 2, 2025
9ed120d
Update mdn-comments.ts
Bashamega Apr 2, 2025
6bd4822
Update README.md
Bashamega Apr 3, 2025
6ba9eea
Update submodule
Bashamega Apr 3, 2025
d2d7817
Update update-core-deps.yml
Bashamega Apr 10, 2025
0e5b7c8
Merge branch 'microsoft:main' into 1937
Bashamega Apr 15, 2025
9e1b9de
generate
Bashamega Apr 15, 2025
56935fe
-
Bashamega Apr 15, 2025
aa1d888
Update README.md
Bashamega Apr 15, 2025
434acbf
Update package-lock.json
Bashamega Apr 15, 2025
d960681
revert
Bashamega Apr 15, 2025
79d2845
-
Bashamega Apr 15, 2025
22cb393
Merge branch 'main' into 1937
Bashamega Apr 15, 2025
3365a61
-
Bashamega Apr 15, 2025
1ba1b36
-
Bashamega Apr 15, 2025
1a888c7
-
Bashamega Apr 15, 2025
a220c15
-
Bashamega Apr 15, 2025
eea3294
Update README.md
Bashamega Apr 16, 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: 4 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ jobs:

steps:
- uses: actions/checkout@v4
with:
submodules: true # Ensures submodules are cloned


- uses: actions/setup-node@v4
with:
node-version: "lts/*"
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ jobs:

steps:
- uses: actions/checkout@v4
with:
submodules: true # Ensures submodules are cloned

- uses: actions/setup-node@v4
with:
node-version: "lts/*"
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/test_typescript.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ jobs:

steps:
- uses: actions/checkout@v4
with:
submodules: true # Ensures submodules are cloned


- uses: actions/setup-node@v4
with:
node-version: "lts/*"
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/update-core-deps.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: true # Ensure submodules are checked out

- name: Update submodules
run: git submodule update --init --remote
- uses: actions/setup-node@v4
with:
node-version: "lts/*"
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "inputfiles/mdn"]
path = inputfiles/mdn
url = https://github.com/mdn/content.git
138 changes: 104 additions & 34 deletions baselines/audioworklet.generated.d.ts

Large diffs are not rendered by default.

2,198 changes: 1,579 additions & 619 deletions baselines/dom.generated.d.ts

Large diffs are not rendered by default.

800 changes: 604 additions & 196 deletions baselines/serviceworker.generated.d.ts

Large diffs are not rendered by default.

797 changes: 606 additions & 191 deletions baselines/sharedworker.generated.d.ts

Large diffs are not rendered by default.

138 changes: 104 additions & 34 deletions baselines/ts5.5/audioworklet.generated.d.ts

Large diffs are not rendered by default.

2,198 changes: 1,579 additions & 619 deletions baselines/ts5.5/dom.generated.d.ts

Large diffs are not rendered by default.

800 changes: 604 additions & 196 deletions baselines/ts5.5/serviceworker.generated.d.ts

Large diffs are not rendered by default.

797 changes: 606 additions & 191 deletions baselines/ts5.5/sharedworker.generated.d.ts

Large diffs are not rendered by default.

916 changes: 699 additions & 217 deletions baselines/ts5.5/webworker.generated.d.ts

Large diffs are not rendered by default.

916 changes: 699 additions & 217 deletions baselines/webworker.generated.d.ts

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions inputfiles/mdn
Submodule mdn added at 181082
445 changes: 0 additions & 445 deletions inputfiles/mdn/apiDescriptions.json

This file was deleted.

45 changes: 5 additions & 40 deletions src/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { getInterfaceElementMergeData } from "./build/webref/elements.js";
import { getInterfaceToEventMap } from "./build/webref/events.js";
import { getWebidls } from "./build/webref/idl.js";
import jsonc from "jsonc-parser";
import { generateDescription } from "./build/mdn-comments.js";

function mergeNamesakes(filtered: Browser.WebIdl) {
const targets = [
Expand Down Expand Up @@ -90,33 +91,11 @@ async function emitDom() {
const inputFolder = new URL("../inputfiles/", import.meta.url);
const outputFolder = new URL("../generated/", import.meta.url);

// ${name} will be substituted with the name of an interface
const removeVerboseIntroductions: [RegExp, string][] = [
[
/^(The|A) ${name} interface of (the\s*)*((?:(?!API)[A-Za-z\d\s])+ API)/,
"This $3 interface ",
],
[
/^(The|A) ${name} (interface|event|object) (is|represents|describes|defines)?/,
"",
],
[
/^An object implementing the ${name} interface (is|represents|describes|defines)/,
"",
],
[/^The ${name} is an interface representing/, ""],
[/^This type (is|represents|describes|defines)?/, ""],
[
/^The (((?:(?!API)[A-Za-z\s])+ API)) ${name} (represents|is|describes|defines)/,
"The $1 ",
],
];

const overriddenItems = await readInputJSON("overridingTypes.jsonc");
const addedItems = await readInputJSON("addedTypes.jsonc");
const comments = await readInputJSON("comments.json");
const deprecatedInfo = await readInputJSON("deprecatedMessage.json");
const documentationFromMDN = await readInputJSON("mdn/apiDescriptions.json");
const documentationFromMDN = await generateDescription();
const removedItems = await readInputJSON("removedTypes.jsonc");

async function readInputJSON(filename: string) {
Expand Down Expand Up @@ -159,8 +138,8 @@ async function emitDom() {
);
for (const [key, value] of Object.entries(descriptions)) {
const target = idl.interfaces!.interface[key] || namespaces[key];
if (target && !value.startsWith("REDIRECT")) {
target.comment = transformVerbosity(key, value);
if (target) {
target.comment = value;
}
}
return idl;
Expand All @@ -178,26 +157,12 @@ async function emitDom() {
for (const [key, value] of Object.entries(descriptions)) {
const target = idl.interfaces!.interface[key] || namespaces[key];
if (target) {
target.deprecated = transformVerbosity(key, value);
target.deprecated = value;
}
}
return idl;
}

function transformVerbosity(name: string, description: string): string {
for (const regTemplate of removeVerboseIntroductions) {
const [{ source: template }, replace] = regTemplate;

const reg = new RegExp(template.replace(/\$\{name\}/g, name) + "\\s*");
const product = description.replace(reg, replace);
if (product !== description) {
return product.charAt(0).toUpperCase() + product.slice(1);
}
}

return description;
}

/// Load the input file
let webidl: Browser.WebIdl = {
events: await getInterfaceToEventMap(),
Expand Down
112 changes: 112 additions & 0 deletions src/build/mdn-comments.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import fs from "fs/promises";
import { basename } from "path";

const basePath = new URL(
"../../inputfiles/mdn/files/en-us/web/api/",
import.meta.url,
);

function extractSummary(markdown: string): string {
// Remove frontmatter (--- at the beginning)
markdown = markdown.replace(/^---[\s\S]+?---\n/, "");

// Normalize line breaks by collapsing consecutive newlines into a single space
const normalizedText = markdown
.split("\n")
.map((line) => line.trim())
.filter(
(line) =>
line &&
!line.startsWith("#") &&
!line.startsWith(">") &&
!line.startsWith("{{"),
)
.join(" ")
.replace(
/\{\{\s*(Glossary|HTMLElement|SVGAttr|SVGElement|cssxref|jsxref|HTTPHeader)\s*\(\s*["']((?:\\.|[^"\\])*?)["'].*?\)\s*\}\}/gi,
"$2",
) // Extract first argument from multiple templates, handling escaped quotes & spaces
.replace(
/\{\{\s*domxref\s*\(\s*["']((?:\\.|[^"\\])*?)["'][^}]*\)\s*\}\}/gi,
"$1",
) // Extract first argument from domxref, handling spaces
.replace(
/\{\{\s*(?:event|jsxref|cssref|specname)\s*\|\s*([^}]+)\s*\}\}/gi,
"$1",
) // Handle event, jsxref, cssref, etc.
.replace(/\{\{\s*([^}]+)\s*\}\}/g, (_, match) => `[MISSING: ${match}]`) // Catch any remaining unhandled templates
.replace(/\[(.*?)\]\(.*?\)/g, "$1") // Keep link text but remove URLs
.replace(/\s+/g, " ") // Normalize spaces
.replace(/\n\s*/g, "\n") // Ensure line breaks are preserved
.replace(/"/g, "'")
.trim();

// Extract the first sentence (ending in . ! or ?)
const sentenceMatch = normalizedText.match(/(.*?[.!?])(?=\s|$)/);
if (sentenceMatch) {
return sentenceMatch[0]; // Return the first full sentence
}

return normalizedText.split(" ")[0] || ""; // Fallback: first word if no sentence found
}

async function getDirectories(dirPath: URL): Promise<URL[]> {
try {
const entries = await fs.readdir(dirPath, {
withFileTypes: true,
});
return entries
.filter((entry) => entry.isDirectory())
.map((entry) => new URL(entry.name + "/", dirPath));
} catch (error) {
console.error("Error reading directories:", error);
return [];
}
}

async function getIndexMdContents(
folders: URL[],
): Promise<{ [key: string]: string }> {
const results: { [key: string]: string } = {};

for (const folder of folders) {
const indexPath = new URL("index.md", folder);

try {
const content = await fs.readFile(indexPath, "utf-8");

// Improved title extraction
const titleMatch = content.match(/title:\s*["']?([^"'\n]+)["']?/);
const filename = basename(folder.toString());
const title = titleMatch
? titleMatch[1].replace(/ extension$/, "")
: filename || "";

const summary = extractSummary(content);
results[title] = summary;
} catch (error) {
console.warn(`Skipping ${indexPath}: ${error}`);
}
}

return results;
}

export async function generateDescription(): Promise<Record<string, string>> {
const stats = await fs.stat(basePath);
if (!stats.isDirectory()) {
throw new Error(
"MDN submodule does not exist; try running `git submodule update --init`",
);
}
try {
const folders = await getDirectories(basePath);
if (folders.length > 0) {
return await getIndexMdContents(folders);
}
} catch (error) {
console.error("Error generating API descriptions:", error);
}

return {};
}