diff --git a/packages/lit-dev-content/site/_includes/docs-nav-collapsing.html b/packages/lit-dev-content/site/_includes/docs-nav-collapsing.html index c1c5c6a65..95c790791 100644 --- a/packages/lit-dev-content/site/_includes/docs-nav-collapsing.html +++ b/packages/lit-dev-content/site/_includes/docs-nav-collapsing.html @@ -28,7 +28,7 @@ {{ child.title }} - {% if child.labs == true %} + {% if child.labs == true or child.labs == "true" %} labs {% endif %} diff --git a/packages/lit-dev-content/site/_includes/docs-nav.html b/packages/lit-dev-content/site/_includes/docs-nav.html index e0b282172..a2923ecf7 100644 --- a/packages/lit-dev-content/site/_includes/docs-nav.html +++ b/packages/lit-dev-content/site/_includes/docs-nav.html @@ -39,7 +39,7 @@ {{ child.title }} - {% if child.labs == true %} + {% if child.labs == true or child.labs == "true" %} labs {% endif %} diff --git a/packages/lit-dev-content/site/docs/api/api.html b/packages/lit-dev-content/site/docs/api/api.html index 11299de03..3f1b1747d 100644 --- a/packages/lit-dev-content/site/docs/api/api.html +++ b/packages/lit-dev-content/site/docs/api/api.html @@ -13,6 +13,7 @@ title: "{{ data.title }}" eleventyNavigation: key: "{{ data.title }}" + labs: "{{ data.labs }}" parent: API apiPath: /docs/api --- diff --git a/packages/lit-dev-tools-cjs/src/api-docs/configs/lit-2.ts b/packages/lit-dev-tools-cjs/src/api-docs/configs/lit-2.ts index ba8366961..8b7e6444f 100644 --- a/packages/lit-dev-tools-cjs/src/api-docs/configs/lit-2.ts +++ b/packages/lit-dev-tools-cjs/src/api-docs/configs/lit-2.ts @@ -16,6 +16,9 @@ const gitDir = pathlib.join(workDir, 'repo'); const litDir = pathlib.join(gitDir, 'packages', 'lit'); const srcDir = pathlib.join(litDir, 'src'); +const contextDir = pathlib.join(gitDir, 'packages', 'labs', 'context'); +const contextSrcDir = pathlib.join(contextDir, 'src'); + /** * lit.dev API docs configuration for Lit 2.x */ @@ -24,7 +27,6 @@ export const lit2Config: ApiDocsConfig = { commit: 'c134604f178e36444261d83eabe9e578c1ed90c4', workDir, gitDir, - tsConfigPath: pathlib.join(litDir, 'tsconfig.json'), pagesOutPath: pathlib.resolve(workDir, 'pages.json'), symbolsOutPath: pathlib.resolve(workDir, 'symbols.json'), typedocRoot: pathlib.join(root, 'packages'), @@ -36,21 +38,41 @@ export const lit2Config: ApiDocsConfig = { }, ], - entrypointModules: [ - pathlib.join(srcDir, 'async-directive.ts'), - pathlib.join(srcDir, 'decorators.ts'), - pathlib.join(srcDir, 'directives/'), // Entire directory - pathlib.join(srcDir, 'directive.ts'), - pathlib.join(srcDir, 'directive-helpers.ts'), - // Don't include html.ts because it is already re-exported by index.ts. - // pathlib.join(srcDir, 'html.ts'), - // Don't include hydration because it's not ready yet. - // pathlib.join(srcDir, 'hydrate.ts'), - // pathlib.join(srcDir, 'hydrate-support.ts'), - pathlib.join(srcDir, 'index.ts'), - // Don't include polyfill-support.ts because it doesn't export anything. - // pathlib.join(srcDir, 'polyfill-support.ts'), - pathlib.join(srcDir, 'static-html.ts'), + packages: [ + // 'lit' module documentation + { + tsConfigPath: pathlib.join(litDir, 'tsconfig.json'), + + entrypointModules: [ + pathlib.join(srcDir, 'async-directive.ts'), + pathlib.join(srcDir, 'decorators.ts'), + pathlib.join(srcDir, 'directives/*'), // Entire directory + pathlib.join(srcDir, 'directive.ts'), + pathlib.join(srcDir, 'directive-helpers.ts'), + // Don't include html.ts because it is already re-exported by index.ts. + // pathlib.join(srcDir, 'html.ts'), + // Don't include hydration because it's not ready yet. + // pathlib.join(srcDir, 'hydrate.ts'), + // pathlib.join(srcDir, 'hydrate-support.ts'), + pathlib.join(srcDir, 'index.ts'), + // Don't include polyfill-support.ts because it doesn't export anything. + // pathlib.join(srcDir, 'polyfill-support.ts'), + pathlib.join(srcDir, 'static-html.ts'), + ], + }, + // @lit-labs/context documentation + { + tsConfigPath: pathlib.join(contextDir, 'tsconfig.json'), + entrypointModules: [ + pathlib.join(contextSrcDir, 'index.ts'), + pathlib.join(contextSrcDir, 'lib/context-request-event.ts'), + pathlib.join(contextSrcDir, 'lib/create-context.ts'), + pathlib.join(contextSrcDir, 'lib/controllers/context-consumer.ts'), + pathlib.join(contextSrcDir, 'lib/controllers/context-provider.ts'), + pathlib.join(contextSrcDir, 'lib/decorators/provide.ts'), + pathlib.join(contextSrcDir, 'lib/decorators/consume.ts'), + ], + }, ], symbolOrder: ['LitElement', 'ReactiveElement'], @@ -127,6 +149,12 @@ export const lit2Config: ApiDocsConfig = { v1: 'api/lit-element/LitElement/', }, }, + // Add @lit-labs/context page. + { + slug: 'context', + title: 'Context', + labs: true, + }, ], pageForSymbol(node): string { @@ -139,6 +167,10 @@ export const lit2Config: ApiDocsConfig = { return 'decorators'; } + if (entrypoint.includes('/context/')) { + return 'context'; + } + if ( entrypoint.endsWith('/directive.ts') || entrypoint.endsWith('/directive-helpers.ts') || @@ -225,6 +257,13 @@ export const lit2Config: ApiDocsConfig = { // fine in practice, but when we add e.g. @lit/localize we'll need to be // smarter here. let [_, pkg, pathMinusExtension] = match; + + if (pkg === "labs/context") { + // There are no @lit-labs/context path extensions because everything is + // re-exported from root. + return "@lit-labs/context" + } + // TODO(aomarks) This wrongly assumes index.ts is always the package main. return pathMinusExtension === 'index' ? pkg diff --git a/packages/lit-dev-tools-cjs/src/api-docs/generate.ts b/packages/lit-dev-tools-cjs/src/api-docs/generate.ts index b99f4892e..99be88034 100644 --- a/packages/lit-dev-tools-cjs/src/api-docs/generate.ts +++ b/packages/lit-dev-tools-cjs/src/api-docs/generate.ts @@ -9,7 +9,7 @@ import * as fs from 'fs/promises'; import * as pathlib from 'path'; import {execFile} from 'child_process'; import {promisify} from 'util'; -import {ApiDocsTransformer} from './transformer.js'; +import {ApiDocsTransformer, Pages, SymbolMap} from './transformer.js'; import {lit2Config} from './configs/lit-2.js'; import type {ApiDocsConfig} from './types.js'; @@ -89,29 +89,34 @@ const analyze = async (config: ApiDocsConfig) => { } console.log(`Analyzing ${config.gitDir}`); - const app = new typedoc.Application(); - app.options.addReader(new typedoc.TSConfigReader()); - app.bootstrap({ - tsconfig: config.tsConfigPath, - entryPoints: config.entrypointModules, - entryPointStrategy: typedoc.EntryPointStrategy.Expand, - }); - const root = app.convert(); - if (!root) { - throw new Error('TypeDoc.Application.convert() returned undefined'); - } + const allPages: Pages = []; + const allSymbols: SymbolMap = {}; + for (const pkg of config.packages) { + const app = new typedoc.Application(); + app.options.addReader(new typedoc.TSConfigReader()); + app.bootstrap({ + tsconfig: pkg.tsConfigPath, + entryPoints: pkg.entrypointModules, + }); + const root = app.convert(); + if (!root) { + throw new Error('TypeDoc.Application.convert() returned undefined'); + } - const json = await app.serializer.projectToObject( - root, - pathlib.resolve(config.tsConfigPath, '..') - ); - const transformer = new ApiDocsTransformer(json, config); - const {pages, symbolMap} = await transformer.transform(); + const json = app.serializer.projectToObject( + root, + pathlib.resolve(pkg.tsConfigPath, '..') + ); + const transformer = new ApiDocsTransformer(json, config); + const {pages, symbolMap} = await transformer.transform(); + allPages.push(...pages); + Object.assign(allSymbols, symbolMap); + } await fs.mkdir(pathlib.dirname(config.pagesOutPath), {recursive: true}); await fs.writeFile( config.pagesOutPath, - JSON.stringify(pages, null, 2), + JSON.stringify(allPages, null, 2), 'utf8' ); console.log(`Wrote ${config.pagesOutPath}`); @@ -119,7 +124,7 @@ const analyze = async (config: ApiDocsConfig) => { await fs.mkdir(pathlib.dirname(config.symbolsOutPath), {recursive: true}); await fs.writeFile( config.symbolsOutPath, - JSON.stringify(symbolMap, null, 2), + JSON.stringify(allSymbols, null, 2), 'utf8' ); console.log(`Wrote ${config.symbolsOutPath}`); diff --git a/packages/lit-dev-tools-cjs/src/api-docs/transformer.ts b/packages/lit-dev-tools-cjs/src/api-docs/transformer.ts index dd096f9a7..efce259d9 100644 --- a/packages/lit-dev-tools-cjs/src/api-docs/transformer.ts +++ b/packages/lit-dev-tools-cjs/src/api-docs/transformer.ts @@ -66,7 +66,7 @@ const symbolToExternalLink = new Map([ * Data consumed by lit.dev API docs Eleventy template. Each item is a separate * page. */ -type Pages = Array<{ +export type Pages = Array<{ slug: string; title: string; items: Array; @@ -76,7 +76,7 @@ type Pages = Array<{ * Map from $symbol to the location it appears in our docs. If there is more * than one item, then the symbol is ambiguous. */ -type SymbolMap = { +export type SymbolMap = { [symbol: string]: Array; }; diff --git a/packages/lit-dev-tools-cjs/src/api-docs/types.ts b/packages/lit-dev-tools-cjs/src/api-docs/types.ts index 1f4d0afcc..031b3b53b 100644 --- a/packages/lit-dev-tools-cjs/src/api-docs/types.ts +++ b/packages/lit-dev-tools-cjs/src/api-docs/types.ts @@ -57,6 +57,30 @@ export interface Location { excludeFromTOC?: boolean; } +/** + * A package, such as `lit` or `@lit-labs/context`. + */ +export interface Package { + /** + * Path to the tsconfig.json that owns the entrypoint modules. + */ + tsConfigPath: string; + + /** + * Entrypoint TypeScript modules for TypeDoc to analyze. + * + * The modules listed here should be the preferred modules that users should + * import from, because import statements will be generated using these + * entrypoints as the module specifier (e.g. `import {LitElement} from + * 'lit'`). GitHub source links will be generated pointing at the ultimate + * location where the symbol is concretely defined (e.g. + * `packages/lit-element/src/lit-element.ts`). + * + * If a directory, all .ts files within it are included. + */ + entrypointModules: Array; +} + export interface ApiDocsConfig { /** * Git repo remote URL. @@ -78,37 +102,20 @@ export interface ApiDocsConfig { */ gitDir: string; - /** - * Path to the tsconfig.json that owns the entrypoint modules. - */ - tsConfigPath: string; - /** * The directory that TypeDoc chooses as the root of this package. Unclear why * this is unpredictable. */ typedocRoot: string; + packages: Package[]; + /** * Extra setup/build commands to run after NPM install and before running * TypeDoc. */ extraSetupCommands?: Array<{cmd: string; args: string[]}>; - /** - * Entrypoint TypeScript modules for TypeDoc to analyze. - * - * The modules listed here should be the preferred modules that users should - * import from, because import statements will be generated using these - * entrypoints as the module specifier (e.g. `import {LitElement} from - * 'lit'`). GitHub source links will be generated pointing at the ultimate - * location where the symbol is concretely defined (e.g. - * `packages/lit-element/src/lit-element.ts`). - * - * If a directory, all .ts files within it are included. - */ - entrypointModules: string[]; - /** * Where to write the API data that is consumed by our Eleventy template. */ @@ -133,7 +140,8 @@ export interface ApiDocsConfig { slug: string; title: string; tocFilter?: (node: DeclarationReflection) => boolean; - versionLinks?: {[version: string]: string}; + versionLinks?: { [version: string]: string }; + labs?: true; }>; /**