diff --git a/.github/workflows/www.yaml b/.github/workflows/www.yaml index d271d759a..96d2490c8 100644 --- a/.github/workflows/www.yaml +++ b/.github/workflows/www.yaml @@ -26,7 +26,7 @@ jobs: - name: Setup Deno uses: denoland/setup-deno@v2 with: - deno-version: v2.6.1 + deno-version: v2.9.1 - name: Serve Website run: | diff --git a/www/components/api/api-page.tsx b/www/components/api/api-page.tsx index f262aef86..f7ead5529 100644 --- a/www/components/api/api-page.tsx +++ b/www/components/api/api-page.tsx @@ -35,7 +35,7 @@ export function* ApiPage({ method, ) { const target = pages && - pages.find((page) => page.name === symbol && page.kind !== "import"); + pages.find((page) => page.name === symbol); if (target) { return `[${ @@ -123,14 +123,17 @@ export function* ApiBody({

- {yield* Type({ node: section.node })} + {yield* Type({ + declaration: section.declaration, + symbol: { name: page.name }, + })}

diff --git a/www/components/package/exports.tsx b/www/components/package/exports.tsx index d2c3a53db..036e49f70 100644 --- a/www/components/package/exports.tsx +++ b/www/components/package/exports.tsx @@ -20,7 +20,7 @@ export function* PackageExports({ let elements: JSXElement[] = []; for (let [exportName, docPages] of Object.entries(docs)) { - if (docPages.filter((page) => page.kind !== "import").length > 0) { + if (docPages.length > 0) { elements.push( yield* PackageExport({ linkResolver, @@ -51,8 +51,7 @@ function* PackageExport({ let exports: JSXChild[] = []; for ( - let page of docPages - .flatMap((page) => (page.kind === "import" ? [] : [page])) + let page of [...docPages] .sort((a, b) => a.name.localeCompare(b.name)) ) { exports.push( diff --git a/www/components/type/jsx.tsx b/www/components/type/jsx.tsx index fb4bcd773..59f4887ab 100644 --- a/www/components/type/jsx.tsx +++ b/www/components/type/jsx.tsx @@ -1,13 +1,14 @@ import { JSXElement } from "revolution/jsx-runtime"; import { type Operation } from "effection"; import type { - DocNode, + Declaration, ParamDef, TsTypeDef, TsTypeParamDef, TsTypeRefDef, VariableDef, } from "@deno/doc"; +import type { SymbolInfo } from "../../hooks/use-deno-doc.tsx"; import { Builtin, ClassName, @@ -18,51 +19,53 @@ import { } from "./tokens.tsx"; interface TypeProps { - node: DocNode; + declaration: Declaration; + symbol: SymbolInfo; } export function* Type(props: TypeProps): Operation { - let { node } = props; + // `node` aliases the declaration; `symbol` supplies the name. + let { declaration: node, symbol } = props; switch (node.kind) { - case "function": + case "function": { + let typeParams = node.def.typeParams ?? []; return ( - {node.functionDef.isAsync - ? {"async "} - : <>} + {node.def.isAsync ? {"async "} : <>} {node.kind} - {node.functionDef.isGenerator ? * : <>} - {" "} - {node.name} - {node.functionDef.typeParams.length > 0 - ? + {node.def.isGenerator ? * : <>}{" "} + {symbol.name} + {typeParams.length > 0 + ? : <>} ( - - ): {node.functionDef.returnType - ? + + ): {node.def.returnType + ? : <>} ); - case "class": + } + case "class": { + let impl /* implements */ = node.def.implements ?? []; return ( - {node.kind} {node.name} - {node.classDef.extends + {node.kind} {symbol.name} + {node.def.extends ? ( <> {" extends "} - {node.classDef.extends} + {node.def.extends} ) : <>} - {node.classDef.implements + {impl.length > 0 ? ( <> {" implements "} <> - {node.classDef.implements + {impl .flatMap((typeDef) => [, ", "]) .slice(0, -1)} @@ -71,19 +74,22 @@ export function* Type(props: TypeProps): Operation { : <>} ); - case "interface": + } + case "interface": { + let typeParams = node.def.typeParams ?? []; + let ext = node.def.extends ?? []; return ( - {node.kind} {node.name} - {node.interfaceDef.typeParams.length > 0 - ? + {node.kind} {symbol.name} + {typeParams.length > 0 + ? : <>} - {node.interfaceDef.extends.length > 0 + {ext.length > 0 ? ( <> {" extends "} <> - {node.interfaceDef.extends + {ext .flatMap((typeDef) => [, ", "]) .slice(0, -1)} @@ -92,30 +98,29 @@ export function* Type(props: TypeProps): Operation { : <>} ); + } case "variable": return ( - + ); case "typeAlias": return ( {"type "} - {node.name} + {symbol.name} {" = "} - + ); case "enum": - case "import": - case "moduleDoc": case "namespace": default: console.log(" unimplemented", node.kind); return ( - {node.kind} {node.name} + {node.kind} {symbol.name} ); } @@ -187,51 +192,51 @@ function TSParam({ param }: { param: ParamDef }) { export function TypeDef({ typeDef }: { typeDef: TsTypeDef }) { switch (typeDef.kind) { case "literal": - switch (typeDef.literal.kind) { + switch (typeDef.value.kind) { case "string": - return "{typeDef.repr}"; + return "{typeDef.repr ?? ""}"; case "number": - return {typeDef.repr}; + return {typeDef.repr ?? ""}; case "boolean": - return {typeDef.repr}; + return {typeDef.repr ?? ""}; case "bigInt": - return {typeDef.repr}; + return {typeDef.repr ?? ""}; default: // TODO(taras): implement template return <>; } case "keyword": - if (["number", "string", "boolean", "bigint"].includes(typeDef.keyword)) { - return {typeDef.keyword}; + if (["number", "string", "boolean", "bigint"].includes(typeDef.value)) { + return {typeDef.value}; } else { - return {typeDef.keyword}; + return {typeDef.value}; } case "typeRef": - return ; + return ; case "union": - return ; + return ; case "fnOrConstructor": - if (typeDef.fnOrConstructor.constructor) { - console.log(` unimplemeneted`, typeDef.fnOrConstructor); + if (typeDef.value.constructor) { + console.log(` unimplemeneted`, typeDef.value); // TODO(taras): implement return <>; } else { return ( <> ( - + ) {" => "} - + ); } case "indexedAccess": return ( <> - + [ - + ] ); @@ -240,7 +245,7 @@ export function TypeDef({ typeDef }: { typeDef: TsTypeDef }) { <> [ <> - {typeDef.tuple + {typeDef.value .flatMap((tp) => [, ", "]) .slice(0, -1)} @@ -250,22 +255,22 @@ export function TypeDef({ typeDef }: { typeDef: TsTypeDef }) { case "array": return ( <> - + [] ); case "typeOperator": return ( <> - {typeDef.typeOperator.operator}{" "} - + {typeDef.value.operator}{" "} + ); case "parenthesized": { return ( <> ( - + ) ); @@ -273,7 +278,7 @@ export function TypeDef({ typeDef }: { typeDef: TsTypeDef }) { case "intersection": { return ( <> - {typeDef.intersection + {typeDef.value .flatMap((tp) => [ , {" & "}, @@ -294,13 +299,13 @@ export function TypeDef({ typeDef }: { typeDef: TsTypeDef }) { case "conditional": { return ( <> - + {" extends "} - + {" ? "} - + {" : "} - + ); } @@ -308,7 +313,7 @@ export function TypeDef({ typeDef }: { typeDef: TsTypeDef }) { return ( <> {"infer "} - {typeDef.infer.typeParam.name} + {typeDef.value.typeParam.name} ); } @@ -316,15 +321,15 @@ export function TypeDef({ typeDef }: { typeDef: TsTypeDef }) { return ( <> [ - {typeDef.mappedType.typeParam.name} + {typeDef.value.typeParam.name} {` in `} - {typeDef.mappedType.typeParam.constraint - ? + {typeDef.value.typeParam.constraint + ? : <>} ] {" : "} - {typeDef.mappedType.tsType - ? + {typeDef.value.tsType + ? : <>} ); diff --git a/www/components/type/markdown.tsx b/www/components/type/markdown.tsx index 7ccdf85f0..087151336 100644 --- a/www/components/type/markdown.tsx +++ b/www/components/type/markdown.tsx @@ -1,13 +1,13 @@ import { Operation } from "effection"; import type { ClassMethodDef, - DocNode, + Declaration, ParamDef, TsTypeDef, TsTypeParamDef, } from "@deno/doc"; import { toHtml } from "hast-util-to-html"; -import { DocPage } from "../../hooks/use-deno-doc.tsx"; +import { DocPage, type SymbolInfo } from "../../hooks/use-deno-doc.tsx"; import { Icon } from "./icon.tsx"; const NEW = @@ -20,7 +20,8 @@ const READONLY = export const NO_DOCS_AVAILABLE = "*No documentation available.*"; export function* extract( - node: DocNode, + node: Declaration, + symbol: SymbolInfo, ): Operation<{ markdown: string; ignore: boolean; pages: DocPage[] }> { let lines = []; let pages: DocPage[] = []; @@ -61,11 +62,12 @@ export function* extract( } if (node.kind === "class") { - if (node.classDef.constructors.length > 0) { + let constructors = node.def.constructors ?? []; + if (constructors.length > 0) { lines.push(`### Constructors`, "
"); - for (let constructor of node.classDef.constructors) { + for (let constructor of constructors) { lines.push( - `
${NEW} **${node.name}**(${ + `
${NEW} **${symbol.name}**(${ constructor.params .map(Param) .join(", ") @@ -78,14 +80,15 @@ export function* extract( lines.push("
"); } - let nonStatic = node.classDef.methods.filter( + let methods = node.def.methods ?? []; + let nonStatic = methods.filter( (method) => !method.isStatic, ); if (nonStatic.length > 0) { lines.push("### Methods", `
`, ...methodList(nonStatic), "
"); } - let staticMethods = node.classDef.methods.filter( + let staticMethods = methods.filter( (method) => method.isStatic, ); if (staticMethods.length > 0) { @@ -99,25 +102,29 @@ export function* extract( } if (node.kind === "namespace") { - let variables = node.namespaceDef.elements.flatMap((node) => - node.kind === "variable" ? [node] : [] - ) ?? []; - if (variables.length > 0) { + // v2 namespace elements are member symbols; render each variable member, + // passing the member's own symbol for its name/identity. + let members = node.def.elements.flatMap((element) => + element.declarations + .filter((declaration) => declaration.kind === "variable") + .map((declaration) => ({ declaration, member: element })) + ); + if (members.length > 0) { lines.push("### Variables"); lines.push("
"); - for (let variable of variables) { - let name = `${node.name}.${variable.name}`; - let section = yield* extract(variable); - let description = variable.jsDoc?.doc || NO_DOCS_AVAILABLE; + for (let { declaration, member } of members) { + let name = `${symbol.name}.${member.name}`; + let section = yield* extract(declaration, member); + let description = declaration.jsDoc?.doc || NO_DOCS_AVAILABLE; pages.push({ name, - kind: variable.kind, + kind: declaration.kind, description, dependencies: [], sections: [ { - id: exportHash(variable, 0), - node: variable, + id: exportHash(declaration, member, 0), + declaration, markdown: section.markdown, ignore: section.ignore, }, @@ -125,7 +132,7 @@ export function* extract( }); lines.push( `
`, - toHtml(), + toHtml(), `[${name}](${name})`, `
`, ); @@ -136,13 +143,12 @@ export function* extract( } if (node.kind === "interface") { - if (node.name === "Completed") console.log(node); - - lines.push("\n", ...TypeParams(node.interfaceDef.typeParams, node)); + lines.push("\n", ...TypeParams(node.def.typeParams ?? [], node)); - if (node.interfaceDef.properties.length > 0) { + let properties = node.def.properties ?? []; + if (properties.length > 0) { lines.push("### Properties", "
"); - for (let property of node.interfaceDef.properties) { + for (let property of properties) { let typeDef = property.tsType ? TypeDef(property.tsType) : ""; let description = property.jsDoc?.doc || NO_DOCS_AVAILABLE; lines.push( @@ -157,10 +163,11 @@ export function* extract( lines.push("
"); } - if (node.interfaceDef.methods.length > 0) { + let methods = node.def.methods ?? []; + if (methods.length > 0) { lines.push("### Methods", "
"); - for (let method of node.interfaceDef.methods) { - let typeParams = method.typeParams.map(TypeParam).join(", "); + for (let method of methods) { + let typeParams = (method.typeParams ?? []).map(TypeParam).join(", "); let params = method.params.map(Param).join(", "); let returnType = method.returnType ? TypeDef(method.returnType) : ""; let description = method.jsDoc?.doc || NO_DOCS_AVAILABLE; @@ -178,13 +185,13 @@ export function* extract( } if (node.kind === "typeAlias") { - lines.push("\n", ...TypeParams(node.typeAliasDef.typeParams, node)); + lines.push("\n", ...TypeParams(node.def.typeParams ?? [], node)); } if (node.kind === "function") { - lines.push(...TypeParams(node.functionDef.typeParams, node)); + lines.push(...TypeParams(node.def.typeParams ?? [], node)); - let { params } = node.functionDef; + let { params } = node.def; if (params.length > 0) { lines.push("### Parameters"); let jsDocs = node.jsDoc?.tags?.flatMap((tag) => @@ -200,8 +207,8 @@ export function* extract( } } - if (node.functionDef.returnType) { - lines.push("### Return Type", "\n", TypeDef(node.functionDef.returnType)); + if (node.def.returnType) { + lines.push("### Return Type", "\n", TypeDef(node.def.returnType)); let jsDocs = node.jsDoc?.tags?.find((tag) => tag.kind === "return"); if (jsDocs && jsDocs.doc) { lines.push("\n", jsDocs.doc); @@ -209,8 +216,8 @@ export function* extract( } } - if (node.kind === "variable" && node.variableDef.tsType) { - lines.push("### Type", "\n", TypeDef(node.variableDef.tsType)); + if (node.kind === "variable" && node.def.tsType) { + lines.push("### Type", "\n", TypeDef(node.def.tsType)); } let see: string[] = []; @@ -240,11 +247,15 @@ export function* extract( }; } -export function exportHash(node: DocNode, index: number): string { - return [node.kind, node.name, index].filter(Boolean).join("_"); +export function exportHash( + declaration: Declaration, + symbol: SymbolInfo, + index: number, +): string { + return [declaration.kind, symbol.name, index].filter(Boolean).join("_"); } -export function TypeParams(typeParams: TsTypeParamDef[], node: DocNode) { +export function TypeParams(typeParams: TsTypeParamDef[], node: Declaration) { let lines = []; if (typeParams.length > 0) { lines.push("### Type Parameters"); @@ -267,76 +278,76 @@ export function TypeParams(typeParams: TsTypeParamDef[], node: DocNode) { export function TypeDef(typeDef: TsTypeDef): string { switch (typeDef.kind) { case "fnOrConstructor": { - let params = typeDef.fnOrConstructor.params.map(Param).join(", "); - let tparams = typeDef.fnOrConstructor.typeParams + let params = typeDef.value.params.map(Param).join(", "); + let tparams = (typeDef.value.typeParams ?? []) .map(TypeParam) .join(", "); return `${tparams.length > 0 ? `<${tparams}>` : ""}(${params}) => ${ TypeDef( - typeDef.fnOrConstructor.tsType, + typeDef.value.tsType, ) }`; } case "typeRef": { - let tparams = typeDef.typeRef.typeParams?.map(TypeDef).join(", "); - return `{@link ${typeDef.typeRef.typeName}}${ + let tparams = typeDef.value.typeParams?.map(TypeDef).join(", "); + return `{@link ${typeDef.value.typeName}}${ tparams && tparams?.length > 0 ? `<${tparams}>` : "" }`; } case "keyword": { - return typeDef.keyword; + return typeDef.value; } case "union": { - return typeDef.union.map(TypeDef).join(" | "); + return typeDef.value.map(TypeDef).join(" | "); } case "array": { - return `${TypeDef(typeDef.array)}[]`; + return `${TypeDef(typeDef.value)}[]`; } case "typeOperator": { - return `${typeDef.typeOperator.operator} ${ + return `${typeDef.value.operator} ${ TypeDef( - typeDef.typeOperator.tsType, + typeDef.value.tsType, ) }`; } case "tuple": { - return `[${typeDef.tuple.map(TypeDef).join(", ")}]`; + return `[${typeDef.value.map(TypeDef).join(", ")}]`; } case "parenthesized": { - return TypeDef(typeDef.parenthesized); + return TypeDef(typeDef.value); } case "intersection": { - return typeDef.intersection.map(TypeDef).join(" & "); + return typeDef.value.map(TypeDef).join(" & "); } case "typeLiteral": { // todo(taras): this is incomplete return `{}`; } case "mapped": { - return `[${TypeParam(typeDef.mappedType.typeParam)}]: ${ - typeDef.mappedType.tsType ? TypeDef(typeDef.mappedType.tsType) : "" + return `[${TypeParam(typeDef.value.typeParam)}]: ${ + typeDef.value.tsType ? TypeDef(typeDef.value.tsType) : "" }`; } case "conditional": { - return `${TypeDef(typeDef.conditionalType.checkType)} extends ${ + return `${TypeDef(typeDef.value.checkType)} extends ${ TypeDef( - typeDef.conditionalType.extendsType, + typeDef.value.extendsType, ) } ? ${ TypeDef( - typeDef.conditionalType.trueType, + typeDef.value.trueType, ) - } : ${TypeDef(typeDef.conditionalType.falseType)}`; + } : ${TypeDef(typeDef.value.falseType)}`; } case "indexedAccess": { - return `${TypeDef(typeDef.indexedAccess.objType)}[${ + return `${TypeDef(typeDef.value.objType)}[${ TypeDef( - typeDef.indexedAccess.indexType, + typeDef.value.indexType, ) }]`; } case "literal": { - return `*${typeDef.repr}*`; + return `*${typeDef.repr ?? ""}*`; } case "importType": case "infer": @@ -355,7 +366,7 @@ function TypeParam(paramDef: TsTypeParamDef) { if (paramDef.constraint) { if ( paramDef.constraint.kind === "typeOperator" && - paramDef.constraint.typeOperator.operator === "keyof" + paramDef.constraint.value.operator === "keyof" ) { parts.push(`in ${TypeDef(paramDef.constraint)}`); } else { @@ -390,10 +401,10 @@ function Param(paramDef: ParamDef): string { export function methodList(methods: ClassMethodDef[]) { let lines = []; for (let method of methods) { - let typeParams = method.functionDef.typeParams.map(TypeParam).join(", "); - let params = method.functionDef.params.map(Param).join(", "); - let returnType = method.functionDef.returnType - ? TypeDef(method.functionDef.returnType) + let typeParams = (method.def.typeParams ?? []).map(TypeParam).join(", "); + let params = method.def.params.map(Param).join(", "); + let returnType = method.def.returnType + ? TypeDef(method.def.returnType) : ""; let description = method.jsDoc?.doc || NO_DOCS_AVAILABLE; lines.push( diff --git a/www/deno.json b/www/deno.json index c3fdfc601..6363900ad 100644 --- a/www/deno.json +++ b/www/deno.json @@ -80,8 +80,8 @@ "@tailwindcss/typography": "npm:@tailwindcss/typography@^0.5.16", "tailwindcss": "npm:tailwindcss@^4.1.0", "semver": "npm:semver@7.6.3", - "@deno/doc": "jsr:@deno/doc@0.188.0", - "@deno/graph": "jsr:@deno/graph@0.89.0", + "@deno/doc": "jsr:@deno/doc@0.199.0", + "@deno/graph": "jsr:@deno/graph@0.100.1", "git-url-parse": "npm:git-url-parse@16.1.0", "@std/fs": "jsr:@std/fs@1", "@std/path": "jsr:@std/path@1", diff --git a/www/hooks/use-deno-doc.tsx b/www/hooks/use-deno-doc.tsx index e95cad3af..2b2c9cf42 100644 --- a/www/hooks/use-deno-doc.tsx +++ b/www/hooks/use-deno-doc.tsx @@ -1,10 +1,12 @@ import { CacheSetting, + type Declaration, doc, - type DocNode, type DocOptions, + type Document, LoadResponse, Location, + type Symbol as DocSymbol, } from "@deno/doc"; import { call, type Operation, until, useScope } from "effection"; import { createGraph } from "@deno/graph"; @@ -20,12 +22,21 @@ export const npmSpecifierPattern = regex( "^(?:(?@[^/]+)/)?(?[^/]+)(?/.*)?$", ); -export type { DocNode }; +/** + * A symbol's identity without its declarations. + * + * `@deno/doc` v2 groups a module's declarations under a `Symbol` ({ name, + * isDefault?, declarations }). Renderers only need the identity (name / + * isDefault), not the sibling declarations — which would duplicate the + * per-section `Declaration`s — so they take a `SymbolInfo`. A full `Symbol` is + * structurally assignable to it, so build-time code can pass the real Symbol. + */ +export type SymbolInfo = Omit; export function* useDenoDoc( specifiers: string[], docOptions?: DocOptions, -): Operation> { +): Operation> { let docs = yield* until(doc(specifiers, docOptions)); return docs; } @@ -40,14 +51,14 @@ export interface DocPage { name: string; sections: DocPageSection[]; description: string; - kind: DocNode["kind"]; + kind: Declaration["kind"]; dependencies: Dependency[]; } export interface DocPageSection { id: string; - node: DocNode; + declaration: Declaration; markdown?: string; @@ -125,46 +136,45 @@ export function* useDocPages( let entrypoints: Record = {}; - for (let [url, all] of Object.entries(docs)) { + for (let [url, document] of Object.entries(docs)) { let pages: DocPage[] = []; - for ( - let [symbol, nodes] of Object.entries( - Object.groupBy(all, (node) => node.name), - ) - ) { - if (nodes) { - let sections: DocPageSection[] = []; - for (let node of nodes) { - let { markdown, ignore, pages: _pages } = yield* extract(node); - sections.push({ - id: exportHash(node, sections.length), - node, - markdown, - ignore, - }); - pages.push( - ..._pages.map((page) => ({ - ...page, - dependencies: externalDependencies, - })), - ); - } + for (let symbol of document.symbols) { + // v2 groups declarations under a symbol; render each declaration as a + // section, passing the owning symbol for its name/identity. + let sections: DocPageSection[] = []; + for (let declaration of symbol.declarations) { + let { markdown, ignore, pages: _pages } = yield* extract( + declaration, + symbol, + ); + sections.push({ + id: exportHash(declaration, symbol, sections.length), + declaration, + markdown, + ignore, + }); + pages.push( + ..._pages.map((page) => ({ + ...page, + dependencies: externalDependencies, + })), + ); + } - let markdown = sections - .map((s) => s.markdown) - .filter((m) => m) - .join(""); + let markdown = sections + .map((s) => s.markdown) + .filter((m) => m) + .join(""); - let description = yield* useDescription(markdown); + let description = yield* useDescription(markdown); - pages.push({ - name: symbol, - kind: nodes?.at(0)?.kind!, - description, - sections, - dependencies: externalDependencies, - }); - } + pages.push({ + name: symbol.name, + kind: symbol.declarations.at(0)?.kind!, + description, + sections, + dependencies: externalDependencies, + }); } entrypoints[url] = pages; @@ -266,8 +276,8 @@ function isDocPageSection(value: unknown): value is DocPageSection { return ( typeof section.id === "string" && - typeof section.node === "object" && - section.node !== null && // You might need a guard for DocNode if it's complex + typeof section.declaration === "object" && + section.declaration !== null && (typeof section.markdown === "undefined" || typeof section.markdown === "string") && typeof section.ignore === "boolean" @@ -303,19 +313,19 @@ function* extractImports( } /** - * LocalDocsPages are DocNodes that are stored locally + * LocalDocsPages are declarations that are stored locally * but they represent symbols hosted on GitHub. They - * have LocalDocNode locations that include URLs to GitHub. + * have LocalDeclaration locations that include URLs to GitHub. */ export type LocalDocsPages = Record; export type LocalDocPage = DocPage & { sections: LocalDocPageSection[] }; export type LocalDocPageSection = DocPageSection & { - node: LocalDocNode; + declaration: LocalDeclaration; }; -export type LocalDocNode = DocNode & { +export type LocalDeclaration = Declaration & { location: LocalLocation; }; diff --git a/www/lib/package.ts b/www/lib/package.ts index 6639c1b54..db64507e8 100644 --- a/www/lib/package.ts +++ b/www/lib/package.ts @@ -168,17 +168,17 @@ function* initPackage( ...page, sections: page.sections.map((section) => ({ ...section, - node: { - ...section.node, + declaration: { + ...section.declaration, location: { - ...section.node.location, + ...section.declaration.location, url: new URL( `${ relative( path, - fileURLToPath(section.node.location.filename), + fileURLToPath(section.declaration.location.filename), ) - }#L${section.node.location.line}`, + }#L${section.declaration.location.line + 1}`, `${ref.url}/`, ), }, diff --git a/www/lib/package/node.ts b/www/lib/package/node.ts index 8704867e4..ae48a28af 100644 --- a/www/lib/package/node.ts +++ b/www/lib/package/node.ts @@ -258,17 +258,17 @@ export function createNodePackage( ...page, sections: page.sections.map((section) => ({ ...section, - node: { - ...section.node, + declaration: { + ...section.declaration, location: { - ...section.node.location, + ...section.declaration.location, url: new URL( `${ relative( path, - fileURLToPath(section.node.location.filename), + fileURLToPath(section.declaration.location.filename), ) - }#L${section.node.location.line}`, + }#L${section.declaration.location.line + 1}`, `${ref.url}/`, ), }, diff --git a/www/routes/blog-image-route.ts b/www/routes/blog-image-route.ts index f1a355e0d..186df10dd 100644 --- a/www/routes/blog-image-route.ts +++ b/www/routes/blog-image-route.ts @@ -61,7 +61,9 @@ export function blogImageRoute(): { } function pngResponse(png: Uint8Array): Response { - return new Response(png, { + // `Uint8Array` (deno's newer lib types) is a valid + // `BodyInit` at runtime; cast to satisfy the narrower DOM signature. + return new Response(png as unknown as BodyInit, { headers: { "Content-Type": "image/png", "Cache-Control": "public, max-age=31536000, immutable", diff --git a/www/routes/x-package-route.tsx b/www/routes/x-package-route.tsx index 9387dddf1..551a0e219 100644 --- a/www/routes/x-package-route.tsx +++ b/www/routes/x-package-route.tsx @@ -94,7 +94,7 @@ export function xPackageRoute({ return internal; } let page = docs["."].find( - (page) => page.name === symbol && page.kind !== "import", + (page) => page.name === symbol, ); if (page) {