@ascribed/astro 0.2.1-next.9 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/README.md +41 -9
  2. package/dist/cli.d.ts +2 -0
  3. package/dist/cli.js +62 -0
  4. package/dist/cli.js.map +1 -0
  5. package/dist/content.d.ts +30 -0
  6. package/dist/content.js +101 -2
  7. package/dist/content.js.map +1 -1
  8. package/dist/dev.d.ts +2 -1
  9. package/dist/dev.js +13 -3
  10. package/dist/dev.js.map +1 -1
  11. package/dist/files.d.ts +21 -4
  12. package/dist/files.js +46 -8
  13. package/dist/files.js.map +1 -1
  14. package/dist/head-check.d.ts +6 -0
  15. package/dist/head-check.js +28 -0
  16. package/dist/head-check.js.map +1 -0
  17. package/dist/head.d.ts +54 -0
  18. package/dist/head.js +114 -0
  19. package/dist/head.js.map +1 -0
  20. package/dist/headers.d.ts +50 -0
  21. package/dist/headers.js +155 -0
  22. package/dist/headers.js.map +1 -0
  23. package/dist/index.d.ts +40 -9
  24. package/dist/index.js +330 -95
  25. package/dist/index.js.map +1 -1
  26. package/dist/init.d.ts +41 -0
  27. package/dist/init.js +130 -0
  28. package/dist/init.js.map +1 -0
  29. package/dist/names.d.ts +5 -0
  30. package/dist/names.js +5 -0
  31. package/dist/names.js.map +1 -1
  32. package/dist/nav.d.ts +51 -0
  33. package/dist/nav.js +97 -0
  34. package/dist/nav.js.map +1 -0
  35. package/dist/permalinks.d.ts +78 -0
  36. package/dist/permalinks.js +114 -0
  37. package/dist/permalinks.js.map +1 -0
  38. package/dist/project.d.ts +37 -0
  39. package/dist/project.js +47 -2
  40. package/dist/project.js.map +1 -1
  41. package/dist/projects.d.ts +38 -0
  42. package/dist/projects.js +127 -0
  43. package/dist/projects.js.map +1 -0
  44. package/dist/records.d.ts +136 -0
  45. package/dist/records.js +182 -0
  46. package/dist/records.js.map +1 -0
  47. package/dist/review/devfile.d.ts +6 -1
  48. package/dist/review/devfile.js +12 -2
  49. package/dist/review/devfile.js.map +1 -1
  50. package/dist/review/diff.d.ts +13 -0
  51. package/dist/review/diff.js +34 -1
  52. package/dist/review/diff.js.map +1 -1
  53. package/dist/review/protocol.d.ts +6 -1
  54. package/dist/review/protocol.js.map +1 -1
  55. package/dist/review/routes.d.ts +3 -0
  56. package/dist/review/routes.js +49 -35
  57. package/dist/review/routes.js.map +1 -1
  58. package/dist/review/server.d.ts +15 -0
  59. package/dist/review/server.js +58 -7
  60. package/dist/review/server.js.map +1 -1
  61. package/dist/root-files.d.ts +68 -0
  62. package/dist/root-files.js +103 -0
  63. package/dist/root-files.js.map +1 -0
  64. package/dist/run.d.ts +7 -6
  65. package/dist/run.js +14 -6
  66. package/dist/run.js.map +1 -1
  67. package/dist/shapes.d.ts +8 -1
  68. package/dist/shapes.js.map +1 -1
  69. package/dist/toolbar/app.js +98 -0
  70. package/dist/toolbar/app.js.map +1 -1
  71. package/dist/toolbar/style.d.ts +1 -1
  72. package/dist/toolbar/style.js +31 -23
  73. package/dist/toolbar/style.js.map +1 -1
  74. package/package.json +32 -9
  75. package/src/Head.astro +58 -0
  76. package/src/MissingPermalink.astro +59 -0
  77. package/src/Permalink.astro +78 -0
  78. package/starter/src/content.config.ts +8 -0
  79. package/starter/src/layouts/Docs.astro +87 -0
  80. package/starter/src/nav.ts +13 -0
  81. package/starter/src/pages/[...slug].astro +20 -0
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["// @ascribed/astro: the Astro integration for Ascribe. Written against Astro\n// 7.3.5.\n//\n// // astro.config.mjs\n// import ascribe from \"@ascribed/astro\";\n// export default defineConfig({\n// base: \"/docs\", trailingSlash: \"never\", // as in ascribe.toml's [consumer]\n// integrations: [ascribe({ build: \"site\" })],\n// });\n//\n// // src/content.config.ts\n// import { defineCollection } from \"astro:content\";\n// import { ascribeCollection } from \"@ascribed/astro/content\";\n// // The generated schema. With the project outside the Astro root, import the\n// // copy inside it instead: \"../.astro/integrations/_ascribed_astro/schema.ts\".\n// import { schema } from \"../.ascribe/build/site/site/_ascribe/schema.ts\";\n// export const collections = { docs: defineCollection(ascribeCollection({ schema })) };\n//\n// // a layout\n// import Elements from \"@ascribed/astro/Elements.astro\"; // <Elements /> in <head>\n// import Availability from \"@ascribed/astro/Availability.astro\"; // the page's availability\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { AstroIntegration } from \"astro\";\nimport { findBinary } from \"./binary.js\";\nimport { codeTitles } from \"./code-titles.js\";\nimport { SeenFiles, watchDev } from \"./dev.js\";\nimport { copyPublishedFiles, filesMiddleware } from \"./files.js\";\nimport { consumerMismatches, readProject } from \"./project.js\";\nimport rehypeAscribeAttributes from \"./rehype.js\";\nimport { removeDevFile, siteUrl, writeDevFile } from \"./review/devfile.js\";\nimport { runDiff } from \"./review/diff.js\";\nimport { APP_ID } from \"./review/protocol.js\";\nimport { readRoutes } from \"./review/routes.js\";\nimport { channelProblem, ReviewServer, type ToolbarChannel } from \"./review/server.js\";\nimport { anchorsFor, hasWarnings, reviewFor, runBuild } from \"./run.js\";\nimport { satteriAscribeAttributes } from \"./satteri.js\";\nimport { copySchema } from \"./schema.js\";\n\nexport { default as rehypeAscribeAttributes } from \"./rehype.js\";\nexport { satteriAscribeAttributes } from \"./satteri.js\";\n\n/** The virtual module `content.ts` reads the resolved site output root from. */\nconst SITE_MODULE = \"virtual:ascribe/site\";\n\n/** Options of the integration. */\nexport interface AscribeOptions {\n /** The build whose site output is the collection (a name in `ascribe.toml`). */\n build: string;\n /** The directory holding `ascribe.toml`, relative to the Astro root. Default: the root. */\n project?: string;\n /**\n * The `ascribe` binary, relative to the Astro root. Default: `ASCRIBE_BIN`, then\n * the platform binary installed with `@ascribed/cli`.\n */\n binary?: string;\n /**\n * Mark each block of the site output with the source lines it came from\n * (source anchors), for review: `\"dev\"` in `astro dev` only, `true` always.\n * Default: `false`, though `review` has them in `astro dev`.\n */\n anchors?: boolean | \"dev\";\n /**\n * Review in the site preview: an **Ascribe review** app in `astro dev`'s\n * toolbar, which marks the page's changes and shows the pull request's\n * comments, with source anchors in `astro dev`. Default `true`; `false`\n * removes the app. `astro build` never has it.\n */\n review?: boolean;\n /**\n * Show a code block's title (`title=\"…\"` in its info string, as `@snippet`\n * writes it) above it, with a Shiki transformer that puts the block in a\n * `<figure class=\"code-title\">` with a `<figcaption>`. Default `true`.\n */\n codeTitles?: boolean;\n}\n\n/** The toolbar app's icon: a speech bubble over a page. */\nconst ICON =\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M6 3h8l4 4v6\"/><path d=\"M14 3v4h4\"/><path d=\"M6 3v15\"/><path d=\"M11 14h10v6h-6l-3 2v-2h-1z\"/></svg>';\n\n/** Runs `ascribe build`, checks the site's routing, adds the markdown plugin, and serves published files. */\nexport default function ascribe(options: AscribeOptions): AstroIntegration {\n let siteRoot = \"\";\n let devProject: ReturnType<typeof readProject> | undefined;\n let devConfig:\n | {\n base: string;\n trailingSlash: string;\n site: string | undefined;\n }\n | undefined;\n let rebuild: (() => Promise<void>) | undefined;\n /** The dev server's sources as its first build read them. */\n const seen = new SeenFiles();\n let binary: string | undefined;\n let reviewing = false;\n let devHttps = false;\n let review: ReviewServer | undefined;\n return {\n name: \"@ascribed/astro\",\n hooks: {\n \"astro:config:setup\": async ({\n config,\n command,\n logger,\n updateConfig,\n addDevToolbarApp,\n createCodegenDir,\n }) => {\n const root = fileURLToPath(config.root);\n const project = readProject(path.resolve(root, options.project ?? \".\"));\n // An unknown build is `ascribe build`'s to report: it knows the implicit `site` build.\n siteRoot = project.siteRoot(options.build);\n\n // `ascribe.toml`'s routing must be Astro's, or every link Ascribe writes is wrong.\n const problems = consumerMismatches(project, {\n base: config.base,\n trailingSlash: config.trailingSlash,\n site: config.site,\n });\n if (problems.length > 0) {\n throw new Error(\n `@ascribed/astro: ascribe.toml and astro.config disagree:\\n- ${problems.join(\"\\n- \")}`,\n );\n }\n\n // Where a markdown plugin goes depends on the processor Astro 7.3 runs.\n const processor = config.markdown.processor;\n const pluginLists = processor.options as {\n rehypePlugins?: unknown[];\n hastPlugins?: unknown[];\n };\n if (processor.name === \"satteri\" && pluginLists.hastPlugins !== undefined) {\n pluginLists.hastPlugins.push(satteriAscribeAttributes());\n } else if (processor.name === \"unified\" && pluginLists.rehypePlugins !== undefined) {\n pluginLists.rehypePlugins.push(rehypeAscribeAttributes);\n } else {\n throw new Error(\n `@ascribed/astro: the markdown processor \"${processor.name}\" is not one it can add its plugin to. ` +\n \"Use Astro's default (satteri) or unified(), or add `rehypeAscribeAttributes` to your own.\",\n );\n }\n\n devConfig = {\n base: config.base,\n trailingSlash: config.trailingSlash,\n site: config.site,\n };\n\n reviewing = reviewFor(options.review, command);\n if (reviewing) {\n addDevToolbarApp({\n id: APP_ID,\n name: \"Ascribe review\",\n icon: ICON,\n entrypoint: new URL(\"./toolbar/app.js\", import.meta.url),\n });\n }\n\n if (command !== \"preview\") {\n const found = findBinary({ binary: options.binary, root });\n binary = found;\n // The schema's copy inside the Astro root, for content.config.ts to import.\n const codegen = fileURLToPath(createCodegenDir());\n rebuild = async () => {\n logger.info(`running ${path.basename(found)} build for \"${options.build}\"`);\n const result = await runBuild({\n binary: found,\n configPath: project.configPath,\n build: options.build,\n cwd: project.dir,\n anchors: anchorsFor(options.anchors, command, reviewing),\n // While review is on, the JSON output says which page is at each route.\n outputs: review?.active ? [\"site\", \"json\"] : [\"site\"],\n });\n if (hasWarnings(result.diagnostics)) logger.warn(result.diagnostics);\n else if (result.diagnostics !== \"\") logger.info(result.diagnostics);\n if (result.summary !== \"\") logger.info(result.summary);\n copySchema(siteRoot, codegen);\n };\n // The sources as the first build reads them: the watcher may report their edits late.\n if (command === \"dev\") seen.prime([project.contentRoot, project.configPath]);\n await rebuild();\n if (command === \"dev\") devProject = project;\n }\n\n // Dev serving of `_ascribe/files/`; the build copies them in `astro:build:done`.\n updateConfig({\n ...(options.codeTitles === false\n ? {}\n : { markdown: { shikiConfig: { transformers: [codeTitles] } } }),\n vite: {\n // `Elements.astro` is Astro source, so Vite must compile it, not load it as a Node module.\n ssr: { noExternal: [\"@ascribed/astro\"] },\n plugins: [\n {\n name: \"@ascribed/astro:site\",\n resolveId: (id) => (id === SITE_MODULE ? `\\0${SITE_MODULE}` : undefined),\n load: (id) =>\n id === `\\0${SITE_MODULE}`\n ? `export const siteRoot = ${JSON.stringify(siteRoot)};`\n : undefined,\n },\n {\n name: \"@ascribed/astro:files\",\n configureServer(server) {\n server.middlewares.use(\n filesMiddleware(\n siteRoot,\n config.base.endsWith(\"/\") ? config.base : `${config.base}/`,\n ),\n );\n },\n },\n ],\n },\n });\n },\n \"astro:server:setup\": ({ server, refreshContent, logger, toolbar }) => {\n if (devProject && rebuild && devConfig) {\n if (!refreshContent)\n throw new Error(\"@ascribed/astro: this Astro version does not support refreshContent.\");\n const project = devProject;\n devHttps = Boolean(server.config.server.https);\n const builds = watchDev({\n server,\n seen,\n refreshContent: () => refreshContent({}),\n logger,\n project,\n astro: devConfig,\n build: options.build,\n rebuild,\n onBuilt: () => review?.rebuilt(),\n });\n if (reviewing && binary !== undefined) {\n const found = binary;\n const run = { binary: found, configPath: project.configPath, cwd: project.dir };\n const jsonRoot = path.join(path.dirname(siteRoot), \"json\");\n review = new ReviewServer({\n channel: toolbar as ToolbarChannel,\n logger,\n build: options.build,\n contentRoot: project.contentRoot,\n channelProblem: channelProblem(server.config),\n diff: (base) => runDiff({ ...run, build: options.build, base }),\n connect: async () => (await import(\"./review/github.js\")).connect(project.dir),\n writeRoutes: () =>\n builds.inTurn(async () => {\n await runBuild({ ...run, build: options.build, outputs: [\"json\"] });\n }),\n readRoutes: () => readRoutes(jsonRoot),\n });\n }\n }\n },\n \"astro:server:start\": ({ address, logger }) => {\n review?.listening(address.address);\n if (!devProject || !devConfig) return;\n const dir = devProject.dir;\n try {\n writeDevFile(dir, {\n url: siteUrl(address, { https: devHttps, base: devConfig.base }),\n build: options.build,\n pid: process.pid,\n });\n // Vite exits on a signal before `astro:server:done` runs.\n process.once(\"exit\", () => removeDevFile(dir, process.pid));\n } catch (error) {\n logger.warn(\n `couldn't write .ascribe/dev.json, which the editor's Open Site Preview reads: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n },\n \"astro:server:done\": () => {\n review?.dispose();\n review = undefined;\n if (devProject) removeDevFile(devProject.dir, process.pid);\n },\n \"astro:build:done\": async ({ dir, logger }) => {\n if (await copyPublishedFiles(siteRoot, dir)) logger.info(\"copied _ascribe/files/\");\n },\n },\n };\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["// @ascribed/astro: the Astro integration for Ascribe. Written against Astro\n// 7.3.5.\n//\n// // astro.config.mjs\n// import ascribe from \"@ascribed/astro\";\n// export default defineConfig({\n// // `site`, `base`, and `trailingSlash` come from ascribe.toml's\n// // [consumer] when they're left out here; set here, they must agree.\n// integrations: [ascribe({ build: \"site\" })],\n// });\n//\n// // src/content.config.ts\n// import { defineCollection } from \"astro:content\";\n// import { ascribeCollection } from \"@ascribed/astro/content\";\n// // The generated schema. With the project outside the Astro root, import the\n// // copy inside it instead: \"../.astro/integrations/_ascribed_astro/schema.ts\".\n// import { schema } from \"../.ascribe/build/site/site/_ascribe/schema.ts\";\n// export const collections = { docs: defineCollection(ascribeCollection({ schema })) };\n//\n// // a layout\n// import Elements from \"@ascribed/astro/Elements.astro\"; // <Elements /> in <head>\n// import Availability from \"@ascribed/astro/Availability.astro\"; // the page's availability\n// import Head from \"@ascribed/astro/Head.astro\"; // <Head entry={entry} /> in <head>\n//\n// // the sidebar: src/nav.ts's list, checked against the collection\n// import { sidebar } from \"@ascribed/astro/content\";\n// const groups = sidebar(nav, await getCollection(\"docs\"));\n//\n// // src/pages/404.astro\n// import MissingPermalink from \"@ascribed/astro/MissingPermalink.astro\"; // a permalink that isn't here\n//\n// Several projects in one site, each entry named, and each collection naming its entry:\n//\n// ascribe({\n// projects: [\n// { name: \"docs\", project: \"../docs\", build: \"site\" },\n// { name: \"home\", project: \"home\", build: \"site\" },\n// ],\n// review: \"docs\",\n// })\n// ascribeCollection({ schema, name: \"docs\" })\nimport { existsSync, mkdirSync, readFileSync } from \"node:fs\";\nimport { writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { AstroIntegration, IntegrationResolvedRoute } from \"astro\";\nimport { findBinary } from \"./binary.js\";\nimport { codeTitles } from \"./code-titles.js\";\nimport { SeenFiles, watchDev, type DevBuilds } from \"./dev.js\";\nimport {\n agentsMiddleware,\n copyAgentFiles,\n copyPublishedFiles,\n filesMiddleware,\n folderUnder,\n} from \"./files.js\";\nimport { WARN as HEAD_WARN } from \"./head-check.js\";\nimport { headersFor, headersOutcome, mergeRules, readHeaders } from \"./headers.js\";\nimport { forwardingRoutes, hasPermalinks, permalinkPattern, readPermalinks } from \"./permalinks.js\";\nimport {\n consumerMismatches,\n homeRoute,\n normalizeBase,\n readProject,\n supplyRouting,\n type AstroRouting,\n} from \"./project.js\";\nimport {\n basePathClashes,\n nameProblems,\n pagesUnderOtherPaths,\n permalinkProblems,\n type ProjectEntry,\n type ResolvedEntry,\n} from \"./projects.js\";\nimport {\n pageList,\n readRecords,\n routeAs,\n routeKey,\n sitemapRoute,\n type ProjectRobots,\n} from \"./records.js\";\nimport rehypeAscribeAttributes from \"./rehype.js\";\nimport { removeDevFile, siteUrl, writeDevFile } from \"./review/devfile.js\";\nimport { runDiff, runPrompt } from \"./review/diff.js\";\nimport { APP_ID } from \"./review/protocol.js\";\nimport { readRoutes } from \"./review/routes.js\";\nimport { channelProblem, ReviewServer, type ToolbarChannel } from \"./review/server.js\";\nimport {\n devRouted,\n devSitePages,\n rootFiles,\n rootFilesMiddleware,\n type RootFileSources,\n} from \"./root-files.js\";\nimport { anchorsFor, hasWarnings, reviewFor, runBuild } from \"./run.js\";\nimport { satteriAscribeAttributes } from \"./satteri.js\";\nimport { copySchema } from \"./schema.js\";\n\nexport { default as rehypeAscribeAttributes } from \"./rehype.js\";\nexport { satteriAscribeAttributes } from \"./satteri.js\";\nexport type { ProjectEntry } from \"./projects.js\";\n\n/** The virtual module `content.ts` reads the resolved site output roots from. */\nconst SITE_MODULE = \"virtual:ascribe/site\";\n\n/** Options every form of the integration takes. */\ninterface SharedOptions {\n /**\n * The `ascribe` binary, relative to the Astro root. Default: `ASCRIBE_BIN`, then\n * the platform binary installed with `@ascribed/cli`.\n */\n binary?: string;\n /**\n * Mark each block of the site output with the source lines it came from\n * (source anchors), for review: `\"dev\"` in `astro dev` only, `true` always.\n * Default: `false`, though `review` has them in `astro dev`.\n */\n anchors?: boolean | \"dev\";\n /**\n * Review in the site preview: an **Ascribe review** app in `astro dev`'s\n * toolbar, which marks the page's changes and shows the pull request's\n * comments, with source anchors in `astro dev`. Default `true`; `false`\n * removes the app. `astro build` never has it. With several projects, it\n * reviews one: the entry a name names, or the first for `true`.\n */\n review?: boolean | string;\n /**\n * Show a code block's title (`title=\"…\"` in its info string, as `@snippet`\n * writes it) above it, with a Shiki transformer that puts the block in a\n * `<figure class=\"code-title\">` with a `<figcaption>`. Default `true`.\n */\n codeTitles?: boolean;\n /**\n * The site's one sitemap, at `<base>sitemap.xml`, of every listed page of\n * every project and every page of the site's own. `exclude` lists routes,\n * from the host's root, of the site's own pages to leave out of it, such\n * as one that carries `noindex`.\n */\n sitemap?: { exclude?: string[] };\n}\n\n/** Options of the integration with one project. */\nexport interface OneProjectOptions extends SharedOptions {\n /** The build whose site output is the collection (a name in `ascribe.toml`). */\n build: string;\n /** The directory holding `ascribe.toml`, relative to the Astro root. Default: the root. */\n project?: string;\n projects?: never;\n}\n\n/** Options of the integration with several projects, each entry named. */\nexport interface ProjectsOptions extends SharedOptions {\n /** The projects, each a named build of a project; two entries may share a project. */\n projects: ProjectEntry[];\n build?: never;\n project?: never;\n}\n\n/** Options of the integration. */\nexport type AscribeOptions = OneProjectOptions | ProjectsOptions;\n\n/** The toolbar app's icon: a speech bubble over a page. */\nconst ICON =\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M6 3h8l4 4v6\"/><path d=\"M14 3v4h4\"/><path d=\"M6 3v15\"/><path d=\"M11 14h10v6h-6l-3 2v-2h-1z\"/></svg>';\n\n/** An entry as the hooks use it. */\ninterface Entry extends ResolvedEntry {\n siteRoot: string;\n /** The plain output's root, when the project publishes it for agents. */\n agentsRoot: string | undefined;\n /** Where the generated schema's copy goes, inside the Astro root. */\n schemaDir: string;\n}\n\n/** A project with the entries that build it, which a dev watcher follows together. */\ninterface DevGroup {\n project: ResolvedEntry[\"project\"];\n entries: Entry[];\n rebuild: () => Promise<void>;\n builds?: DevBuilds;\n}\n\nfunction fail(problems: string[], what: string): void {\n if (problems.length > 0) throw new Error(`@ascribed/astro: ${what}:\\n- ${problems.join(\"\\n- \")}`);\n}\n\n/**\n * Runs `ascribe build` for each project, checks the site's routing, adds the markdown plugin, adds a\n * page for each permalink's address, and serves published files, and, with `[consumer] agents = true`,\n * `llms.txt` and each page's Markdown, each at its project's base path; and writes the site's one\n * sitemap and `robots.txt` from every project's page records, and, with `[consumer] headers =\n * \"netlify\"`, its `_headers` from their headers lists.\n */\nexport default function ascribe(options: AscribeOptions): AstroIntegration {\n /** With `projects`; otherwise the one entry has no name a collection gives. */\n const named = options.projects !== undefined;\n let entries: Entry[] = [];\n let groups: DevGroup[] = [];\n let routing: AstroRouting | undefined;\n /** The dev server's sources as its first build read them. */\n const seen = new SeenFiles();\n let binary: string | undefined;\n let reviewed: Entry | undefined;\n let devCommand = false;\n let devHttps = false;\n let review: ReviewServer | undefined;\n /** The site's routes, as Astro resolved them, for what `astro dev` serves of the site's own. */\n let astroRoutes: IntegrationResolvedRoute[] = [];\n /** The site's `public/` folder, where its own `robots.txt` would be. */\n let publicDir = \"\";\n\n /** What the sitemap and `robots.txt` are drawn from, given the site's pages and its routes. */\n const rootSources = (\n sitePages: readonly string[],\n routed: (route: string) => boolean,\n ): RootFileSources => {\n const base = routing?.base ?? \"/\";\n const records = entries.map((entry) => readRecords(entry.siteRoot));\n // Entries of one project share its `ascribe.toml`, and so what it says to crawlers.\n const robots = new Map<string, ProjectRobots>();\n for (const [i, entry] of entries.entries()) {\n if (!robots.has(entry.project.dir))\n robots.set(entry.project.dir, {\n name: entry.name,\n robots: records[i]?.robots ?? { lines: [] },\n });\n }\n const root = normalizeBase(base);\n return {\n projects: records.map(pageList),\n routed,\n sitePages,\n excluded: [\n ...forwardingRoutes(entries.map((entry) => readPermalinks(entry.siteRoot))),\n `${root}404`,\n `${root}500`,\n ...(options.sitemap?.exclude ?? []),\n ],\n robots: [...robots.values()],\n site: routing?.site,\n base,\n ownRobots: existsSync(path.join(publicDir, \"robots.txt\")),\n ownSitemap: existsSync(path.join(publicDir, \"sitemap.xml\")),\n };\n };\n return {\n name: \"@ascribed/astro\",\n hooks: {\n \"astro:config:setup\": async ({\n config,\n command,\n logger,\n updateConfig,\n addDevToolbarApp,\n createCodegenDir,\n injectRoute,\n addMiddleware,\n }) => {\n const root = fileURLToPath(config.root);\n publicDir = fileURLToPath(config.publicDir);\n const list: ProjectEntry[] = options.projects ?? [\n {\n name: \"\",\n build: options.build,\n ...(options.project === undefined ? {} : { project: options.project }),\n },\n ];\n if (named) fail(nameProblems(list), \"the `projects` option is wrong\");\n const codegen = command === \"preview\" ? \"\" : fileURLToPath(createCodegenDir());\n entries = list.map((entry) => {\n const project = readProject(path.resolve(root, entry.project ?? \".\"));\n return {\n name: entry.name,\n build: entry.build,\n project,\n // An unknown build is `ascribe build`'s to report: it knows the implicit `site` build.\n siteRoot: project.siteRoot(entry.build),\n agentsRoot: project.consumer.agents ? project.plainRoot(entry.build) : undefined,\n schemaDir: named ? path.join(codegen, entry.name) : codegen,\n };\n });\n\n // What astro.config leaves unset comes from [consumer]: `site` and `trailingSlash` from the\n // first project that has them, and with one project, `base` from its base path. With\n // `projects`, `base` stays the site's, the root every base path is under.\n const { routing: astro, supplied } = supplyRouting(\n entries.map((entry) => entry.project),\n { base: config.base, trailingSlash: config.trailingSlash, site: config.site },\n !named,\n );\n // `ascribe.toml`'s routing must be Astro's, or every link Ascribe writes is wrong.\n for (const entry of entries) {\n fail(\n consumerMismatches(entry.project, astro),\n named\n ? `\"${entry.name}\"'s ascribe.toml and astro.config disagree`\n : \"ascribe.toml and astro.config disagree\",\n );\n }\n fail(basePathClashes(entries), \"two projects share a base path\");\n\n if (typeof options.review === \"string\" && !entries.some((e) => e.name === options.review)) {\n throw new Error(\n `@ascribed/astro: \\`review\\` names \"${options.review}\", and no entry of \\`projects\\` has that name.`,\n );\n }\n if (reviewFor(options.review, command)) {\n reviewed =\n typeof options.review === \"string\"\n ? entries.find((e) => e.name === options.review)\n : entries[0];\n }\n\n // Where a markdown plugin goes depends on the processor Astro 7.3 runs.\n const processor = config.markdown.processor;\n const pluginLists = processor.options as {\n rehypePlugins?: unknown[];\n hastPlugins?: unknown[];\n };\n if (processor.name === \"satteri\" && pluginLists.hastPlugins !== undefined) {\n pluginLists.hastPlugins.push(satteriAscribeAttributes());\n } else if (processor.name === \"unified\" && pluginLists.rehypePlugins !== undefined) {\n pluginLists.rehypePlugins.push(rehypeAscribeAttributes);\n } else {\n throw new Error(\n `@ascribed/astro: the markdown processor \"${processor.name}\" is not one it can add its plugin to. ` +\n \"Use Astro's default (satteri) or unified(), or add `rehypeAscribeAttributes` to your own.\",\n );\n }\n\n routing = astro;\n\n if (reviewed !== undefined) {\n addDevToolbarApp({\n id: APP_ID,\n name: \"Ascribe review\",\n icon: ICON,\n entrypoint: new URL(\"./toolbar/app.js\", import.meta.url),\n });\n }\n\n if (command !== \"preview\") {\n const found = findBinary({ binary: options.binary, root });\n binary = found;\n const buildEntry = async (entry: Entry) => {\n logger.info(\n `running ${path.basename(found)} build for \"${entry.build}\"${named ? ` (${entry.name})` : \"\"}`,\n );\n const result = await runBuild({\n binary: found,\n configPath: entry.project.configPath,\n build: entry.build,\n cwd: entry.project.dir,\n anchors: anchorsFor(options.anchors, command, entry === reviewed),\n outputs: [\n \"site\",\n // `llms.txt` and each page's Markdown, which agents read.\n ...(entry.agentsRoot === undefined ? [] : ([\"plain\"] as const)),\n // While review is on, the JSON output says which page is at each route.\n ...(entry === reviewed && review?.active ? ([\"json\"] as const) : []),\n ],\n });\n if (hasWarnings(result.diagnostics)) logger.warn(result.diagnostics);\n else if (result.diagnostics !== \"\") logger.info(result.diagnostics);\n if (result.summary !== \"\") logger.info(result.summary);\n // The schema's copy inside the Astro root, for content.config.ts to import.\n mkdirSync(entry.schemaDir, { recursive: true });\n copySchema(entry.siteRoot, entry.schemaDir);\n };\n // What the projects share, which no one project's build can see.\n const checkShared = () => {\n if (entries.length < 2) return;\n const current = entries.map((entry) => ({\n ...entry,\n project: readProject(entry.project.dir),\n }));\n fail(basePathClashes(current), \"two projects share a base path\");\n fail(pagesUnderOtherPaths(current), \"a page is under another project's base path\");\n fail(\n permalinkProblems(\n current,\n current.map((entry) => readPermalinks(entry.siteRoot)),\n ),\n \"the projects' permalinks can't share one route\",\n );\n };\n // One group for each project: a change rebuilds the project it's in.\n const byDir = new Map<string, Entry[]>();\n for (const entry of entries) {\n byDir.set(entry.project.dir, [...(byDir.get(entry.project.dir) ?? []), entry]);\n }\n groups = [...byDir.values()].map((group) => ({\n project: (group[0] as Entry).project,\n entries: group,\n rebuild: async () => {\n for (const entry of group) await buildEntry(entry);\n checkShared();\n },\n }));\n // The sources as the first build reads them: the watcher may report their edits late.\n if (command === \"dev\") {\n for (const group of groups)\n seen.prime([group.project.contentRoot, group.project.configPath]);\n }\n for (const entry of entries) await buildEntry(entry);\n checkShared();\n devCommand = command === \"dev\";\n if (devCommand) {\n // A tag of the head written twice, by Head.astro and the layout, is warned about.\n (globalThis as Record<symbol, unknown>)[HEAD_WARN] = (message: string) =>\n logger.warn(message);\n addMiddleware({\n entrypoint: new URL(\"./head-check.js\", import.meta.url),\n order: \"post\",\n });\n }\n\n // Each permalink's address, a page that forwards to its heading. One route serves every\n // list, at the path of the first that names anything.\n const lists = entries.flatMap((entry) => readPermalinks(entry.siteRoot) ?? []);\n const served = lists.find(hasPermalinks) ?? lists[0];\n if (served !== undefined) {\n injectRoute({\n pattern: permalinkPattern(served.path, astro.base),\n entrypoint: new URL(\"../src/Permalink.astro\", import.meta.url),\n prerender: true,\n });\n }\n }\n\n const projectHome = (entry: Entry) =>\n homeRoute(entry.project.consumer.basePath, astro.trailingSlash);\n // Dev serving of `_ascribe/files/`, and of the plain output for agents; the build copies them in `astro:build:done`.\n updateConfig({\n ...supplied,\n ...(options.codeTitles === false\n ? {}\n : { markdown: { shikiConfig: { transformers: [codeTitles] } } }),\n vite: {\n // `Elements.astro` is Astro source, so Vite must compile it, not load it as a Node module.\n ssr: { noExternal: [\"@ascribed/astro\"] },\n plugins: [\n {\n name: \"@ascribed/astro:site\",\n resolveId: (id) => (id === SITE_MODULE ? `\\0${SITE_MODULE}` : undefined),\n load: (id) =>\n id === `\\0${SITE_MODULE}`\n ? `export const siteRoot = ${JSON.stringify(entries[0]?.siteRoot ?? \"\")};\\n` +\n `export const astroRoot = ${JSON.stringify(root)};\\n` +\n `export const home = ${JSON.stringify(homeRoute(astro.base, astro.trailingSlash))};\\n` +\n `export const collections = ${JSON.stringify(\n named ? Object.fromEntries(entries.map((e) => [e.name, e.siteRoot])) : {},\n )};\\n` +\n `export const permalinks = ${JSON.stringify(\n entries.map((e) => ({ siteRoot: e.siteRoot, home: projectHome(e) })),\n )};\\n` +\n `export const routes = ${JSON.stringify(\n entries.map((e) => ({\n siteRoot: e.siteRoot,\n basePath: e.project.consumer.basePath,\n trailingSlash: e.project.consumer.trailingSlash,\n })),\n )};`\n : undefined,\n },\n {\n name: \"@ascribed/astro:files\",\n configureServer(server) {\n for (const entry of entries) {\n const base = entry.project.consumer.basePath;\n server.middlewares.use(filesMiddleware(entry.siteRoot, base));\n if (entry.agentsRoot !== undefined) {\n const siteRoot = entry.siteRoot;\n server.middlewares.use(\n agentsMiddleware(entry.agentsRoot, base, (pathname) =>\n headersFor(siteRoot, pathname),\n ),\n );\n }\n }\n // The sitemap and robots.txt, as the build would write them now.\n server.middlewares.use(\n rootFilesMiddleware(astro.base, () =>\n rootFiles(\n rootSources(\n devSitePages(astroRoutes, astro),\n devRouted(astroRoutes, astro),\n ),\n ),\n ),\n );\n },\n },\n ],\n },\n });\n },\n \"astro:routes:resolved\": ({ routes }) => {\n astroRoutes = routes;\n },\n \"astro:server:setup\": ({ server, refreshContent, logger, toolbar }) => {\n if (!devCommand || !routing) return;\n if (!refreshContent)\n throw new Error(\"@ascribed/astro: this Astro version does not support refreshContent.\");\n devHttps = Boolean(server.config.server.https);\n for (const group of groups) {\n group.builds = watchDev({\n server,\n seen,\n refreshContent: () => refreshContent({}),\n logger,\n project: group.project,\n astro: routing,\n builds: group.entries.map((entry) => entry.build),\n rebuild: group.rebuild,\n onBuilt: () => {\n if (reviewed !== undefined && group.entries.includes(reviewed)) review?.rebuilt();\n },\n });\n }\n const group = groups.find((g) => reviewed !== undefined && g.entries.includes(reviewed));\n if (reviewed !== undefined && group?.builds !== undefined && binary !== undefined) {\n const entry = reviewed;\n const builds = group.builds;\n const run = { binary, configPath: entry.project.configPath, cwd: entry.project.dir };\n const jsonRoot = path.join(path.dirname(entry.siteRoot), \"json\");\n review = new ReviewServer({\n channel: toolbar as ToolbarChannel,\n logger,\n build: entry.build,\n contentRoot: entry.project.contentRoot,\n channelProblem: channelProblem(server.config),\n diff: (base) => runDiff({ ...run, build: entry.build, base }),\n prompt: (page, base) => runPrompt({ ...run, build: entry.build, base, path: page }),\n projectDir: entry.project.dir,\n connect: async () => (await import(\"./review/github.js\")).connect(entry.project.dir),\n writeRoutes: () =>\n builds.inTurn(async () => {\n await runBuild({ ...run, build: entry.build, outputs: [\"json\"] });\n }),\n readRoutes: () => readRoutes(jsonRoot),\n });\n }\n },\n \"astro:server:start\": ({ address, logger }) => {\n review?.listening(address.address);\n if (!devCommand) return;\n // Each project's folder gets its own file, with its own address: its base path.\n for (const group of groups) {\n const entry = group.entries[0] as Entry;\n const dir = group.project.dir;\n try {\n writeDevFile(dir, {\n url: siteUrl(address, { https: devHttps, base: entry.project.consumer.basePath }),\n build: entry.build,\n pid: process.pid,\n });\n // Vite exits on a signal before `astro:server:done` runs.\n process.once(\"exit\", () => removeDevFile(dir, process.pid));\n } catch (error) {\n logger.warn(\n `couldn't write ${groups.length > 1 ? path.join(dir, \".ascribe\", \"dev.json\") : \".ascribe/dev.json\"}, which the editor's Open Site Preview reads: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n },\n \"astro:server:done\": () => {\n review?.dispose();\n review = undefined;\n if (devCommand) for (const group of groups) removeDevFile(group.project.dir, process.pid);\n },\n \"astro:build:done\": async ({ dir, pages, logger }) => {\n const base = routing?.base ?? \"/\";\n const trailingSlash = routing?.trailingSlash ?? \"ignore\";\n // Every page Astro built, by its route from the host's root. Astro lists\n // pages only, not endpoints such as a feed, so a dot in a page's last\n // segment, as in `/v1.2`, is still a page.\n const built = pages.map((page) =>\n routeAs(`${normalizeBase(base)}${page.pathname.replace(/^\\//, \"\")}`, trailingSlash),\n );\n const builtKeys = new Set(built.map(routeKey));\n const files = rootFiles(rootSources(built, (route) => builtKeys.has(routeKey(route))));\n fail(files.problems, \"the site's robots.txt\");\n for (const note of files.notes) logger[note.level](note.text);\n const out = fileURLToPath(dir);\n if (files.sitemap !== undefined) {\n await writeFile(path.join(out, \"sitemap.xml\"), files.sitemap);\n logger.info(`wrote ${sitemapRoute(base)}`);\n }\n if (files.robots !== undefined) {\n await writeFile(path.join(out, \"robots.txt\"), files.robots);\n logger.info(\"wrote /robots.txt\");\n }\n // The host's headers, from the projects that name its format.\n const ownHeaders = path.join(publicDir, \"_headers\");\n const headers = headersOutcome({\n rules: mergeRules(\n entries\n .filter((entry) => entry.project.consumer.headers === \"netlify\")\n .map((entry) => readHeaders(entry.siteRoot) ?? []),\n ),\n base,\n own: existsSync(ownHeaders) ? readFileSync(ownHeaders, \"utf8\") : undefined,\n });\n if (headers.kind === \"fail\") throw new Error(`@ascribed/astro: ${headers.text}`);\n if (headers.kind === \"note\") logger.info(headers.text);\n if (headers.kind === \"write\") {\n await writeFile(path.join(out, \"_headers\"), headers.text);\n logger.info(\"wrote /_headers\");\n }\n // Entries of one project publish at one base path: the first entry's copies go last, so they win.\n for (const entry of [...entries].reverse()) {\n const folder = folderUnder(entry.project.consumer.basePath, base);\n const where = folder === \"\" ? \"\" : ` to ${folder}`;\n if (await copyPublishedFiles(entry.siteRoot, dir, folder))\n logger.info(`copied _ascribe/files/${where}`);\n if (\n entry.agentsRoot !== undefined &&\n (await copyAgentFiles(entry.agentsRoot, dir, folder))\n )\n logger.info(`copied llms.txt and each page's Markdown${where}`);\n }\n },\n },\n };\n}\n"]}
package/dist/init.d.ts ADDED
@@ -0,0 +1,41 @@
1
+ import { type NavGroup } from "./nav.js";
2
+ import { type ProjectInfo } from "./project.js";
3
+ /** The files `init` writes, by path from the Astro root. */
4
+ export declare const STARTER_FILES: readonly ["src/content.config.ts", "src/pages/[...slug].astro", "src/layouts/Docs.astro", "src/nav.ts"];
5
+ /** What `init` is told. */
6
+ export interface InitOptions {
7
+ /** The Astro root, where the files go. */
8
+ root: string;
9
+ /** The directory holding `ascribe.toml`, relative to the root. Default: the root. */
10
+ project?: string | undefined;
11
+ /** The build whose site output is the collection. Default: the project's one build. */
12
+ build?: string | undefined;
13
+ }
14
+ /** What `init` did. */
15
+ export interface InitResult {
16
+ /** The build it listed the pages of, which the integration's `build` option names. */
17
+ build: string;
18
+ /** The files it wrote, by path from the root. */
19
+ written: string[];
20
+ }
21
+ /**
22
+ * Writes the starter's files into the Astro project at `root`, with the
23
+ * sidebar's list from a build of the project. Writes nothing, and throws, when
24
+ * any of them is there already, when the build can't be chosen, or when the
25
+ * build fails.
26
+ */
27
+ export declare function init(options: InitOptions): Promise<InitResult>;
28
+ /** The build `init` lists: the one asked for, or the project's only one. */
29
+ export declare function chooseBuild(project: ProjectInfo, asked: string | undefined): string;
30
+ /**
31
+ * The path `src/content.config.ts` imports the schema from: the generated file
32
+ * in the build's site output when the project is inside the Astro root, and
33
+ * the integration's copy inside the root when it's outside, where TypeScript
34
+ * can't find `astro/zod` from the original.
35
+ */
36
+ export declare function schemaImport(root: string, project: ProjectInfo, build: string): string;
37
+ /** The starter's files, by path from the Astro root, with the schema's path and the sidebar's list filled in. */
38
+ export declare function starterFiles(options: {
39
+ schema: string;
40
+ nav: readonly NavGroup[];
41
+ }): Map<string, string>;
package/dist/init.js ADDED
@@ -0,0 +1,130 @@
1
+ // The starter, `npx @ascribed/astro init`: writes into an Astro project, once,
2
+ // the files every site built with Ascribe writes again: the collection, the
3
+ // route, a layout that loads the elements, and the sidebar's list. From then
4
+ // on they're the site's own, as `ascribe templates eject` leaves a project's
5
+ // templates; `init` never writes over a file.
6
+ //
7
+ // The files are in `starter/`, as `examples/astro-site/src` has them; the
8
+ // example's are what `init` writes for its project, which a test holds. Two
9
+ // things differ from one project to the next: the schema's path, and the
10
+ // sidebar's pages, which `init` lists from a build.
11
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
12
+ import path from "node:path";
13
+ import { fileURLToPath } from "node:url";
14
+ import { findBinary } from "./binary.js";
15
+ import { navFor } from "./nav.js";
16
+ import { readProject } from "./project.js";
17
+ import { sitePages } from "./projects.js";
18
+ import { runBuild } from "./run.js";
19
+ /** The files `init` writes, by path from the Astro root. */
20
+ export const STARTER_FILES = [
21
+ "src/content.config.ts",
22
+ "src/pages/[...slug].astro",
23
+ "src/layouts/Docs.astro",
24
+ "src/nav.ts",
25
+ ];
26
+ /** The starter's files, in the package beside `src/` and `dist/`. */
27
+ const STARTER = fileURLToPath(new URL("../starter/", import.meta.url));
28
+ /** The import of the schema in the starter's `content.config.ts`, whose path `init` replaces. */
29
+ const SCHEMA_IMPORT = /^(import \{ schema \} from )"[^"]*";$/m;
30
+ /** The list in the starter's `nav.ts`, which `init` replaces. */
31
+ const NAV_LIST = /^export const nav: NavGroup\[\] = \[\n[\s\S]*?^\];$/m;
32
+ /**
33
+ * Writes the starter's files into the Astro project at `root`, with the
34
+ * sidebar's list from a build of the project. Writes nothing, and throws, when
35
+ * any of them is there already, when the build can't be chosen, or when the
36
+ * build fails.
37
+ */
38
+ export async function init(options) {
39
+ const root = path.resolve(options.root);
40
+ const project = readProject(path.resolve(root, options.project ?? "."));
41
+ const build = chooseBuild(project, options.build);
42
+ const there = STARTER_FILES.filter((file) => existsSync(path.join(root, file)));
43
+ if (there.length > 0) {
44
+ throw new Error(`@ascribed/astro init writes only files that aren't there, and ${there.join(", ")} ${there.length === 1 ? "is" : "are"}. It wrote nothing. Move ${there.length === 1 ? "it" : "them"} aside to start from the starter.`);
45
+ }
46
+ await runBuild({
47
+ binary: findBinary({ root }),
48
+ configPath: project.configPath,
49
+ build,
50
+ cwd: project.dir,
51
+ });
52
+ const files = starterFiles({
53
+ schema: schemaImport(root, project, build),
54
+ nav: navFor(sitePages(project, build)),
55
+ });
56
+ for (const [file, text] of files) {
57
+ mkdirSync(path.dirname(path.join(root, file)), { recursive: true });
58
+ writeFileSync(path.join(root, file), text);
59
+ }
60
+ return { build, written: [...files.keys()] };
61
+ }
62
+ /** The build `init` lists: the one asked for, or the project's only one. */
63
+ export function chooseBuild(project, asked) {
64
+ const builds = project.builds.length === 0 ? ["site"] : project.builds;
65
+ if (asked !== undefined) {
66
+ if (builds.includes(asked))
67
+ return asked;
68
+ throw new Error(`@ascribed/astro init: ${project.configPath} has no build "${asked}". Its builds are ${quoted(builds)}.`);
69
+ }
70
+ const [only] = builds;
71
+ if (builds.length === 1 && only !== undefined)
72
+ return only;
73
+ throw new Error(`@ascribed/astro init: ${project.configPath} has several builds, ${quoted(builds)}. Say which the site shows with --build.`);
74
+ }
75
+ /**
76
+ * The path `src/content.config.ts` imports the schema from: the generated file
77
+ * in the build's site output when the project is inside the Astro root, and
78
+ * the integration's copy inside the root when it's outside, where TypeScript
79
+ * can't find `astro/zod` from the original.
80
+ */
81
+ export function schemaImport(root, project, build) {
82
+ const schema = path.join(project.siteRoot(build), "_ascribe", "schema.ts");
83
+ const fromRoot = path.relative(root, schema);
84
+ const inside = !fromRoot.startsWith("..") && !path.isAbsolute(fromRoot);
85
+ const target = inside ? schema : path.join(root, ".astro/integrations/_ascribed_astro/schema.ts");
86
+ return path.relative(path.join(root, "src"), target).split(path.sep).join("/");
87
+ }
88
+ /** The starter's files, by path from the Astro root, with the schema's path and the sidebar's list filled in. */
89
+ export function starterFiles(options) {
90
+ const files = new Map();
91
+ for (const file of STARTER_FILES) {
92
+ let text = readFileSync(path.join(STARTER, file), "utf8");
93
+ if (file === "src/content.config.ts")
94
+ text = fill(text, SCHEMA_IMPORT, (_, start) => `${start}${JSON.stringify(options.schema)};`);
95
+ if (file === "src/nav.ts")
96
+ text = fill(text, NAV_LIST, () => navList(options.nav));
97
+ files.set(file, text);
98
+ }
99
+ return files;
100
+ }
101
+ /** `text` with the one match of `pattern` replaced. The starter's files are the package's own, so a miss is its bug. */
102
+ function fill(text, pattern, replacement) {
103
+ if (!pattern.test(text))
104
+ throw new Error(`@ascribed/astro init: the starter has no ${pattern.source}`);
105
+ return text.replace(pattern, replacement);
106
+ }
107
+ /** The sidebar's list as `nav.ts` declares it, laid out as Prettier would, at 100 columns. */
108
+ function navList(nav) {
109
+ const lines = ["export const nav: NavGroup[] = ["];
110
+ for (const group of nav) {
111
+ const pages = `[${group.pages.map((page) => JSON.stringify(page)).join(", ")}]`;
112
+ const line = ` { label: ${JSON.stringify(group.label)}, pages: ${pages} },`;
113
+ if (line.length <= 100) {
114
+ lines.push(line);
115
+ continue;
116
+ }
117
+ lines.push(" {", ` label: ${JSON.stringify(group.label)},`);
118
+ if (` pages: ${pages},`.length <= 100)
119
+ lines.push(` pages: ${pages},`);
120
+ else
121
+ lines.push(" pages: [", ...group.pages.map((page) => ` ${JSON.stringify(page)},`), " ],");
122
+ lines.push(" },");
123
+ }
124
+ lines.push("];");
125
+ return lines.join("\n");
126
+ }
127
+ function quoted(names) {
128
+ return names.map((name) => `"${name}"`).join(", ");
129
+ }
130
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"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","sourcesContent":["// The starter, `npx @ascribed/astro init`: writes into an Astro project, once,\n// the files every site built with Ascribe writes again: the collection, the\n// route, a layout that loads the elements, and the sidebar's list. From then\n// on they're the site's own, as `ascribe templates eject` leaves a project's\n// templates; `init` never writes over a file.\n//\n// The files are in `starter/`, as `examples/astro-site/src` has them; the\n// example's are what `init` writes for its project, which a test holds. Two\n// things differ from one project to the next: the schema's path, and the\n// sidebar's pages, which `init` lists from a build.\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { findBinary } from \"./binary.js\";\nimport { navFor, type NavGroup } from \"./nav.js\";\nimport { readProject, type ProjectInfo } from \"./project.js\";\nimport { sitePages } from \"./projects.js\";\nimport { runBuild } from \"./run.js\";\n\n/** The files `init` writes, by path from the Astro root. */\nexport const STARTER_FILES = [\n \"src/content.config.ts\",\n \"src/pages/[...slug].astro\",\n \"src/layouts/Docs.astro\",\n \"src/nav.ts\",\n] as const;\n\n/** The starter's files, in the package beside `src/` and `dist/`. */\nconst STARTER = fileURLToPath(new URL(\"../starter/\", import.meta.url));\n\n/** The import of the schema in the starter's `content.config.ts`, whose path `init` replaces. */\nconst SCHEMA_IMPORT = /^(import \\{ schema \\} from )\"[^\"]*\";$/m;\n\n/** The list in the starter's `nav.ts`, which `init` replaces. */\nconst NAV_LIST = /^export const nav: NavGroup\\[\\] = \\[\\n[\\s\\S]*?^\\];$/m;\n\n/** What `init` is told. */\nexport interface InitOptions {\n /** The Astro root, where the files go. */\n root: string;\n /** The directory holding `ascribe.toml`, relative to the root. Default: the root. */\n project?: string | undefined;\n /** The build whose site output is the collection. Default: the project's one build. */\n build?: string | undefined;\n}\n\n/** What `init` did. */\nexport interface InitResult {\n /** The build it listed the pages of, which the integration's `build` option names. */\n build: string;\n /** The files it wrote, by path from the root. */\n written: string[];\n}\n\n/**\n * Writes the starter's files into the Astro project at `root`, with the\n * sidebar's list from a build of the project. Writes nothing, and throws, when\n * any of them is there already, when the build can't be chosen, or when the\n * build fails.\n */\nexport async function init(options: InitOptions): Promise<InitResult> {\n const root = path.resolve(options.root);\n const project = readProject(path.resolve(root, options.project ?? \".\"));\n const build = chooseBuild(project, options.build);\n const there = STARTER_FILES.filter((file) => existsSync(path.join(root, file)));\n if (there.length > 0) {\n throw new Error(\n `@ascribed/astro init writes only files that aren't there, and ${there.join(\", \")} ${there.length === 1 ? \"is\" : \"are\"}. It wrote nothing. Move ${there.length === 1 ? \"it\" : \"them\"} aside to start from the starter.`,\n );\n }\n await runBuild({\n binary: findBinary({ root }),\n configPath: project.configPath,\n build,\n cwd: project.dir,\n });\n const files = starterFiles({\n schema: schemaImport(root, project, build),\n nav: navFor(sitePages(project, build)),\n });\n for (const [file, text] of files) {\n mkdirSync(path.dirname(path.join(root, file)), { recursive: true });\n writeFileSync(path.join(root, file), text);\n }\n return { build, written: [...files.keys()] };\n}\n\n/** The build `init` lists: the one asked for, or the project's only one. */\nexport function chooseBuild(project: ProjectInfo, asked: string | undefined): string {\n const builds = project.builds.length === 0 ? [\"site\"] : project.builds;\n if (asked !== undefined) {\n if (builds.includes(asked)) return asked;\n throw new Error(\n `@ascribed/astro init: ${project.configPath} has no build \"${asked}\". Its builds are ${quoted(builds)}.`,\n );\n }\n const [only] = builds;\n if (builds.length === 1 && only !== undefined) return only;\n throw new Error(\n `@ascribed/astro init: ${project.configPath} has several builds, ${quoted(builds)}. Say which the site shows with --build.`,\n );\n}\n\n/**\n * The path `src/content.config.ts` imports the schema from: the generated file\n * in the build's site output when the project is inside the Astro root, and\n * the integration's copy inside the root when it's outside, where TypeScript\n * can't find `astro/zod` from the original.\n */\nexport function schemaImport(root: string, project: ProjectInfo, build: string): string {\n const schema = path.join(project.siteRoot(build), \"_ascribe\", \"schema.ts\");\n const fromRoot = path.relative(root, schema);\n const inside = !fromRoot.startsWith(\"..\") && !path.isAbsolute(fromRoot);\n const target = inside ? schema : path.join(root, \".astro/integrations/_ascribed_astro/schema.ts\");\n return path.relative(path.join(root, \"src\"), target).split(path.sep).join(\"/\");\n}\n\n/** The starter's files, by path from the Astro root, with the schema's path and the sidebar's list filled in. */\nexport function starterFiles(options: {\n schema: string;\n nav: readonly NavGroup[];\n}): Map<string, string> {\n const files = new Map<string, string>();\n for (const file of STARTER_FILES) {\n let text = readFileSync(path.join(STARTER, file), \"utf8\");\n if (file === \"src/content.config.ts\")\n text = fill(\n text,\n SCHEMA_IMPORT,\n (_, start: string) => `${start}${JSON.stringify(options.schema)};`,\n );\n if (file === \"src/nav.ts\") text = fill(text, NAV_LIST, () => navList(options.nav));\n files.set(file, text);\n }\n return files;\n}\n\n/** `text` with the one match of `pattern` replaced. The starter's files are the package's own, so a miss is its bug. */\nfunction fill(\n text: string,\n pattern: RegExp,\n replacement: (match: string, ...groups: string[]) => string,\n): string {\n if (!pattern.test(text))\n throw new Error(`@ascribed/astro init: the starter has no ${pattern.source}`);\n return text.replace(pattern, replacement);\n}\n\n/** The sidebar's list as `nav.ts` declares it, laid out as Prettier would, at 100 columns. */\nfunction navList(nav: readonly NavGroup[]): string {\n const lines = [\"export const nav: NavGroup[] = [\"];\n for (const group of nav) {\n const pages = `[${group.pages.map((page) => JSON.stringify(page)).join(\", \")}]`;\n const line = ` { label: ${JSON.stringify(group.label)}, pages: ${pages} },`;\n if (line.length <= 100) {\n lines.push(line);\n continue;\n }\n lines.push(\" {\", ` label: ${JSON.stringify(group.label)},`);\n if (` pages: ${pages},`.length <= 100) lines.push(` pages: ${pages},`);\n else\n lines.push(\n \" pages: [\",\n ...group.pages.map((page) => ` ${JSON.stringify(page)},`),\n \" ],\",\n );\n lines.push(\" },\");\n }\n lines.push(\"];\");\n return lines.join(\"\\n\");\n}\n\nfunction quoted(names: readonly string[]): string {\n return names.map((name) => `\"${name}\"`).join(\", \");\n}\n"]}
package/dist/names.d.ts CHANGED
@@ -15,6 +15,11 @@ export declare const ELEMENT_AVAILABILITY = "ascribe-availability";
15
15
  export declare const ELEMENT_AVAILABILITY_TARGET = "ascribe-availability-target";
16
16
  /** `<ascribe-group>`: a project widget's group (packages/elements/CONTRACT.md §6). */
17
17
  export declare const ELEMENT_GROUP = "ascribe-group";
18
+ /**
19
+ * `<ascribe-for-agents>`: the visually hidden pointer to `llms.txt` at the top
20
+ * of a page, for agents (packages/elements/CONTRACT.md §8).
21
+ */
22
+ export declare const ELEMENT_FOR_AGENTS = "ascribe-for-agents";
18
23
  /** `<ascribe-attributes>`: the attribute marker (site-render contract §1). */
19
24
  export declare const ELEMENT_ATTRIBUTES = "ascribe-attributes";
20
25
  /** The name an anchor comment starts with, `<!--ascribe-anchor` (site-render contract §7.3). */
package/dist/names.js CHANGED
@@ -18,6 +18,11 @@ export const ELEMENT_AVAILABILITY = "ascribe-availability";
18
18
  export const ELEMENT_AVAILABILITY_TARGET = "ascribe-availability-target";
19
19
  /** `<ascribe-group>`: a project widget's group (packages/elements/CONTRACT.md §6). */
20
20
  export const ELEMENT_GROUP = "ascribe-group";
21
+ /**
22
+ * `<ascribe-for-agents>`: the visually hidden pointer to `llms.txt` at the top
23
+ * of a page, for agents (packages/elements/CONTRACT.md §8).
24
+ */
25
+ export const ELEMENT_FOR_AGENTS = "ascribe-for-agents";
21
26
  /** `<ascribe-attributes>`: the attribute marker (site-render contract §1). */
22
27
  export const ELEMENT_ATTRIBUTES = "ascribe-attributes";
23
28
  /** The name an anchor comment starts with, `<!--ascribe-anchor` (site-render contract §7.3). */
package/dist/names.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"names.js","sourceRoot":"","sources":["../src/names.ts"],"names":[],"mappings":"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","sourcesContent":["// The names Ascribe puts on a page: elements, attributes, classes, and ids.\n// Generated from crates/ascribe-core/src/names.rs by\n// `ASCRIBE_BLESS=1 cargo test -p ascribe-core --test names`. Don't edit it.\n\n/** `<ascribe-note>`: a note (packages/elements/CONTRACT.md §1). */\nexport const ELEMENT_NOTE = \"ascribe-note\";\n\n/** `<ascribe-steps>`: a procedure (packages/elements/CONTRACT.md §2). */\nexport const ELEMENT_STEPS = \"ascribe-steps\";\n\n/** `<ascribe-tabs>`: a variant group of several arms (packages/elements/CONTRACT.md §3). */\nexport const ELEMENT_TABS = \"ascribe-tabs\";\n\n/** `<ascribe-tab>`: one arm of `<ascribe-tabs>` (packages/elements/CONTRACT.md §3). */\nexport const ELEMENT_TAB = \"ascribe-tab\";\n\n/** `<ascribe-availability>`: a badge or filter (packages/elements/CONTRACT.md §4). */\nexport const ELEMENT_AVAILABILITY = \"ascribe-availability\";\n\n/**\n * `<ascribe-availability-target>`: one target of `<ascribe-availability>`\n * (packages/elements/CONTRACT.md §4).\n */\nexport const ELEMENT_AVAILABILITY_TARGET = \"ascribe-availability-target\";\n\n/** `<ascribe-group>`: a project widget's group (packages/elements/CONTRACT.md §6). */\nexport const ELEMENT_GROUP = \"ascribe-group\";\n\n/** `<ascribe-attributes>`: the attribute marker (site-render contract §1). */\nexport const ELEMENT_ATTRIBUTES = \"ascribe-attributes\";\n\n/** The name an anchor comment starts with, `<!--ascribe-anchor` (site-render contract §7.3). */\nexport const COMMENT_ANCHOR = \"ascribe-anchor\";\n\n/** A block's source anchor (site-render contract §7.1). */\nexport const DATA_SOURCE = \"data-ascribe-source\";\n\n/** The includes a block came through (site-render contract §7.1). */\nexport const DATA_VIA = \"data-ascribe-via\";\n\n/** A glossary term's id, on its link (packages/elements/CONTRACT.md §7). */\nexport const DATA_TERM = \"data-ascribe-term\";\n\n/** The element the report draws into. */\nexport const ID_REPORT = \"ascribe-review\";\n\n/** The `<script type=\"application/json\">` holding the report's data. */\nexport const ID_REPORT_DATA = \"ascribe-review-data\";\n\n/**\n * The page's light or dark scheme, `light` or `dark`, on the root\n * element (docs/content/guides/astro.md).\n */\nexport const DATA_SCHEME = \"data-ascribe-scheme\";\n\n/** On a marked page's root: what it shows, `changes`, `will`, or `was`. */\nexport const DATA_SHOW = \"data-ascribe-show\";\n\n/**\n * On a marked block: its change, `added`, `changed`, `removed`, `moved`,\n * or `moved-from`.\n */\nexport const DATA_CHANGE = \"data-ascribe-change\";\n\n/** On every element review adds to the page, so it can be taken away again. */\nexport const DATA_UI = \"data-ascribe-ui\";\n\n/** On a change's label: the change. */\nexport const DATA_LABEL = \"data-ascribe-label\";\n\n/** On a tab's hint: `added` or `changed`. */\nexport const DATA_HINT = \"data-ascribe-hint\";\n\n/** On a moved block: the id its \"moved from\" link points at. */\nexport const DATA_MOVE = \"data-ascribe-move\";\n\n/** On a changed block whose copy as it was follows it. */\nexport const DATA_HAS_WAS = \"data-ascribe-has-was\";\n\n/** On a copy of a block as it was, shown only with the page as it was. */\nexport const DATA_WAS_ONLY = \"data-ascribe-was-only\";\n\n/** On a changed, removed, or moved block: its source anchor as it was. */\nexport const DATA_WAS_SOURCE = \"data-ascribe-was-source\";\n\n/** On the elements that hold the threads' overlay. */\nexport const DATA_OVERLAY = \"data-ascribe-overlay\";\n\n/** On the style element the Astro dev toolbar adds for the marks. */\nexport const DATA_REVIEW = \"data-ascribe-review\";\n\n/** On the root of a page whose changes are marked. */\nexport const CLASS_MARKS = \"ascribe-marks\";\n\n/** A change's label. */\nexport const CLASS_LABEL = \"ascribe-label\";\n\n/** A label placed before its block rather than over it. */\nexport const CLASS_LABEL_BEFORE = \"ascribe-label-before\";\n\n/** Inserted text. */\nexport const CLASS_INS = \"ascribe-ins\";\n\n/** Deleted text. */\nexport const CLASS_DEL = \"ascribe-del\";\n\n/** A removed block. */\nexport const CLASS_REMOVED = \"ascribe-removed\";\n\n/** A removed block's content. */\nexport const CLASS_REMOVED_BODY = \"ascribe-removed-body\";\n\n/** The button that shows or collapses a removed block. */\nexport const CLASS_TOGGLE = \"ascribe-toggle\";\n\n/** On a removed block that's shown. */\nexport const CLASS_OPEN = \"ascribe-open\";\n\n/** What stands where a moved block was. */\nexport const CLASS_MOVED_FROM = \"ascribe-moved-from\";\n\n/** The note with a moved block's link. */\nexport const CLASS_MOVE_NOTE = \"ascribe-move-note\";\n\n/** A move note after its block, not inside it. */\nexport const CLASS_MOVE_AFTER = \"ascribe-move-after\";\n\n/** The link between a moved block and where it was. */\nexport const CLASS_MOVE_LINK = \"ascribe-move-link\";\n\n/** A moved block's copy as it was, where it was. */\nexport const CLASS_WAS_COPY = \"ascribe-was-copy\";\n\n/** A tab's hint that it holds changes. */\nexport const CLASS_HINT = \"ascribe-hint\";\n\n/** A block flashed after going to it. */\nexport const CLASS_FLASH = \"ascribe-flash\";\n\n/** The tip that shows a block's source on hover and focus. */\nexport const CLASS_WHERE = \"ascribe-where\";\n"]}
1
+ {"version":3,"file":"names.js","sourceRoot":"","sources":["../src/names.ts"],"names":[],"mappings":"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","sourcesContent":["// The names Ascribe puts on a page: elements, attributes, classes, and ids.\n// Generated from crates/ascribe-core/src/names.rs by\n// `ASCRIBE_BLESS=1 cargo test -p ascribe-core --test names`. Don't edit it.\n\n/** `<ascribe-note>`: a note (packages/elements/CONTRACT.md §1). */\nexport const ELEMENT_NOTE = \"ascribe-note\";\n\n/** `<ascribe-steps>`: a procedure (packages/elements/CONTRACT.md §2). */\nexport const ELEMENT_STEPS = \"ascribe-steps\";\n\n/** `<ascribe-tabs>`: a variant group of several arms (packages/elements/CONTRACT.md §3). */\nexport const ELEMENT_TABS = \"ascribe-tabs\";\n\n/** `<ascribe-tab>`: one arm of `<ascribe-tabs>` (packages/elements/CONTRACT.md §3). */\nexport const ELEMENT_TAB = \"ascribe-tab\";\n\n/** `<ascribe-availability>`: a badge or filter (packages/elements/CONTRACT.md §4). */\nexport const ELEMENT_AVAILABILITY = \"ascribe-availability\";\n\n/**\n * `<ascribe-availability-target>`: one target of `<ascribe-availability>`\n * (packages/elements/CONTRACT.md §4).\n */\nexport const ELEMENT_AVAILABILITY_TARGET = \"ascribe-availability-target\";\n\n/** `<ascribe-group>`: a project widget's group (packages/elements/CONTRACT.md §6). */\nexport const ELEMENT_GROUP = \"ascribe-group\";\n\n/**\n * `<ascribe-for-agents>`: the visually hidden pointer to `llms.txt` at the top\n * of a page, for agents (packages/elements/CONTRACT.md §8).\n */\nexport const ELEMENT_FOR_AGENTS = \"ascribe-for-agents\";\n\n/** `<ascribe-attributes>`: the attribute marker (site-render contract §1). */\nexport const ELEMENT_ATTRIBUTES = \"ascribe-attributes\";\n\n/** The name an anchor comment starts with, `<!--ascribe-anchor` (site-render contract §7.3). */\nexport const COMMENT_ANCHOR = \"ascribe-anchor\";\n\n/** A block's source anchor (site-render contract §7.1). */\nexport const DATA_SOURCE = \"data-ascribe-source\";\n\n/** The includes a block came through (site-render contract §7.1). */\nexport const DATA_VIA = \"data-ascribe-via\";\n\n/** A glossary term's id, on its link (packages/elements/CONTRACT.md §7). */\nexport const DATA_TERM = \"data-ascribe-term\";\n\n/** The element the report draws into. */\nexport const ID_REPORT = \"ascribe-review\";\n\n/** The `<script type=\"application/json\">` holding the report's data. */\nexport const ID_REPORT_DATA = \"ascribe-review-data\";\n\n/**\n * The page's light or dark scheme, `light` or `dark`, on the root\n * element (docs/content/guides/astro.md).\n */\nexport const DATA_SCHEME = \"data-ascribe-scheme\";\n\n/** On a marked page's root: what it shows, `changes`, `will`, or `was`. */\nexport const DATA_SHOW = \"data-ascribe-show\";\n\n/**\n * On a marked block: its change, `added`, `changed`, `removed`, `moved`,\n * or `moved-from`.\n */\nexport const DATA_CHANGE = \"data-ascribe-change\";\n\n/** On every element review adds to the page, so it can be taken away again. */\nexport const DATA_UI = \"data-ascribe-ui\";\n\n/** On a change's label: the change. */\nexport const DATA_LABEL = \"data-ascribe-label\";\n\n/** On a tab's hint: `added` or `changed`. */\nexport const DATA_HINT = \"data-ascribe-hint\";\n\n/** On a moved block: the id its \"moved from\" link points at. */\nexport const DATA_MOVE = \"data-ascribe-move\";\n\n/** On a changed block whose copy as it was follows it. */\nexport const DATA_HAS_WAS = \"data-ascribe-has-was\";\n\n/** On a copy of a block as it was, shown only with the page as it was. */\nexport const DATA_WAS_ONLY = \"data-ascribe-was-only\";\n\n/** On a changed, removed, or moved block: its source anchor as it was. */\nexport const DATA_WAS_SOURCE = \"data-ascribe-was-source\";\n\n/** On the elements that hold the threads' overlay. */\nexport const DATA_OVERLAY = \"data-ascribe-overlay\";\n\n/** On the style element the Astro dev toolbar adds for the marks. */\nexport const DATA_REVIEW = \"data-ascribe-review\";\n\n/** On the root of a page whose changes are marked. */\nexport const CLASS_MARKS = \"ascribe-marks\";\n\n/** A change's label. */\nexport const CLASS_LABEL = \"ascribe-label\";\n\n/** A label placed before its block rather than over it. */\nexport const CLASS_LABEL_BEFORE = \"ascribe-label-before\";\n\n/** Inserted text. */\nexport const CLASS_INS = \"ascribe-ins\";\n\n/** Deleted text. */\nexport const CLASS_DEL = \"ascribe-del\";\n\n/** A removed block. */\nexport const CLASS_REMOVED = \"ascribe-removed\";\n\n/** A removed block's content. */\nexport const CLASS_REMOVED_BODY = \"ascribe-removed-body\";\n\n/** The button that shows or collapses a removed block. */\nexport const CLASS_TOGGLE = \"ascribe-toggle\";\n\n/** On a removed block that's shown. */\nexport const CLASS_OPEN = \"ascribe-open\";\n\n/** What stands where a moved block was. */\nexport const CLASS_MOVED_FROM = \"ascribe-moved-from\";\n\n/** The note with a moved block's link. */\nexport const CLASS_MOVE_NOTE = \"ascribe-move-note\";\n\n/** A move note after its block, not inside it. */\nexport const CLASS_MOVE_AFTER = \"ascribe-move-after\";\n\n/** The link between a moved block and where it was. */\nexport const CLASS_MOVE_LINK = \"ascribe-move-link\";\n\n/** A moved block's copy as it was, where it was. */\nexport const CLASS_WAS_COPY = \"ascribe-was-copy\";\n\n/** A tab's hint that it holds changes. */\nexport const CLASS_HINT = \"ascribe-hint\";\n\n/** A block flashed after going to it. */\nexport const CLASS_FLASH = \"ascribe-flash\";\n\n/** The tip that shows a block's source on hover and focus. */\nexport const CLASS_WHERE = \"ascribe-where\";\n"]}
package/dist/nav.d.ts ADDED
@@ -0,0 +1,51 @@
1
+ /** A group of the sidebar: a label, and its pages' source files, in order. */
2
+ export interface NavGroup {
3
+ label: string;
4
+ /** Source files, relative to the content root, as `Guides/My Setup.md`. */
5
+ pages: string[];
6
+ }
7
+ /** A page of the sidebar: its collection entry, and its address. */
8
+ export interface SidebarPage<E> {
9
+ entry: E;
10
+ href: string;
11
+ }
12
+ /** A group of the sidebar, each of its pages with its entry. */
13
+ export interface SidebarGroup<E> {
14
+ label: string;
15
+ pages: SidebarPage<E>[];
16
+ }
17
+ /** What the check needs of a collection entry: its id, and the file it was loaded from. */
18
+ export interface NavEntry {
19
+ id: string;
20
+ filePath?: string | undefined;
21
+ }
22
+ /**
23
+ * A page's entry id, as Astro's `glob` loader computes it from the page's
24
+ * path in the site output: each segment slugged, without the extension, and
25
+ * without a final `/index`.
26
+ */
27
+ export declare function entryId(pagePath: string): string;
28
+ /**
29
+ * A page's route, as Ascribe's router writes every link to it: the base path
30
+ * plus its entry id, and the root page (`index`) at the base path itself.
31
+ */
32
+ export declare function pageRoute(id: string, basePath: string, trailingSlash: "always" | "never"): string;
33
+ /**
34
+ * The ways the list and the collection disagree, as sentences: a page the
35
+ * list leaves out, a file it names that isn't a page, and a page it names twice.
36
+ * `source` names an entry for a person, by its source file where it can.
37
+ */
38
+ export declare function navProblems(nav: readonly NavGroup[], entries: readonly NavEntry[], source?: (entry: NavEntry) => string): string[];
39
+ /**
40
+ * The sidebar's groups, each page with its entry and address. Throws, naming
41
+ * each, when the list leaves out a page of the collection, names a file that
42
+ * isn't one, or names a page twice, so the list stays complete.
43
+ */
44
+ export declare function sidebarGroups<E extends NavEntry>(nav: readonly NavGroup[], entries: readonly E[], route: (id: string) => string, source?: (entry: NavEntry) => string): SidebarGroup<E>[];
45
+ /**
46
+ * The starter's list for a project's pages, by their paths in the site
47
+ * output: the pages at the content root in a group named "Start", the root
48
+ * page first, then a group for each folder, named as the folder is, in order
49
+ * of their names.
50
+ */
51
+ export declare function navFor(pages: readonly string[]): NavGroup[];
package/dist/nav.js ADDED
@@ -0,0 +1,97 @@
1
+ // A site's sidebar: its list of pages, which the starter writes as the site's
2
+ // `src/nav.ts` (`npx @ascribed/astro init`), checked against the collection.
3
+ // Ascribe's content model has no page order or grouping yet, so the site keeps
4
+ // the list, and the check keeps it complete: `ascribe.toml` giving a site its
5
+ // navigation is the surface audit's finding 28, which has no design yet.
6
+ import { slug } from "github-slugger";
7
+ /**
8
+ * A page's entry id, as Astro's `glob` loader computes it from the page's
9
+ * path in the site output: each segment slugged, without the extension, and
10
+ * without a final `/index`.
11
+ */
12
+ export function entryId(pagePath) {
13
+ return pagePath
14
+ .replace(/\.md$/, "")
15
+ .split("/")
16
+ .map((segment) => slug(segment))
17
+ .join("/")
18
+ .replace(/\/index$/, "");
19
+ }
20
+ /**
21
+ * A page's route, as Ascribe's router writes every link to it: the base path
22
+ * plus its entry id, and the root page (`index`) at the base path itself.
23
+ */
24
+ export function pageRoute(id, basePath, trailingSlash) {
25
+ if (id === "index")
26
+ return trailingSlash === "never" && basePath !== "/" ? basePath.slice(0, -1) : basePath;
27
+ return `${basePath}${id}${trailingSlash === "always" ? "/" : ""}`;
28
+ }
29
+ /**
30
+ * The ways the list and the collection disagree, as sentences: a page the
31
+ * list leaves out, a file it names that isn't a page, and a page it names twice.
32
+ * `source` names an entry for a person, by its source file where it can.
33
+ */
34
+ export function navProblems(nav, entries, source = (entry) => entry.id) {
35
+ const listed = nav.flatMap((group) => group.pages);
36
+ const ids = new Set(entries.map((entry) => entry.id));
37
+ const listedIds = new Set(listed.map(entryId));
38
+ const problems = [];
39
+ for (const entry of entries) {
40
+ if (!listedIds.has(entry.id))
41
+ problems.push(`${source(entry)} isn't in the sidebar's list. Add it to a group.`);
42
+ }
43
+ for (const [i, file] of listed.entries()) {
44
+ if (!ids.has(entryId(file)))
45
+ problems.push(`the sidebar's list names ${file}, which isn't a page of the site.`);
46
+ else if (listed.findIndex((other) => entryId(other) === entryId(file)) !== i)
47
+ problems.push(`the sidebar's list names ${file} twice.`);
48
+ }
49
+ return problems;
50
+ }
51
+ /**
52
+ * The sidebar's groups, each page with its entry and address. Throws, naming
53
+ * each, when the list leaves out a page of the collection, names a file that
54
+ * isn't one, or names a page twice, so the list stays complete.
55
+ */
56
+ export function sidebarGroups(nav, entries, route, source) {
57
+ const problems = navProblems(nav, entries, source);
58
+ if (problems.length > 0) {
59
+ throw new Error(`@ascribed/astro: the sidebar's list (src/nav.ts) doesn't match the site's pages:\n${problems.map((problem) => `- ${problem}`).join("\n")}`);
60
+ }
61
+ const byId = new Map(entries.map((entry) => [entry.id, entry]));
62
+ return nav.map((group) => ({
63
+ label: group.label,
64
+ pages: group.pages.flatMap((file) => {
65
+ const entry = byId.get(entryId(file));
66
+ return entry === undefined ? [] : [{ entry, href: route(entry.id) }];
67
+ }),
68
+ }));
69
+ }
70
+ /**
71
+ * The starter's list for a project's pages, by their paths in the site
72
+ * output: the pages at the content root in a group named "Start", the root
73
+ * page first, then a group for each folder, named as the folder is, in order
74
+ * of their names.
75
+ */
76
+ export function navFor(pages) {
77
+ const groups = new Map();
78
+ const sorted = pages.toSorted((a, b) => {
79
+ const rootA = a === "index.md";
80
+ const rootB = b === "index.md";
81
+ if (rootA !== rootB)
82
+ return rootA ? -1 : 1;
83
+ return a < b ? -1 : a > b ? 1 : 0;
84
+ });
85
+ for (const page of sorted) {
86
+ const slash = page.indexOf("/");
87
+ const label = slash === -1 ? "Start" : page.slice(0, slash);
88
+ groups.set(label, [...(groups.get(label) ?? []), page]);
89
+ }
90
+ const start = groups.get("Start");
91
+ groups.delete("Start");
92
+ return [
93
+ ...(start === undefined ? [] : [{ label: "Start", pages: start }]),
94
+ ...[...groups].map(([label, files]) => ({ label, pages: files })),
95
+ ];
96
+ }
97
+ //# sourceMappingURL=nav.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nav.js","sourceRoot":"","sources":["../src/nav.ts"],"names":[],"mappings":"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","sourcesContent":["// A site's sidebar: its list of pages, which the starter writes as the site's\n// `src/nav.ts` (`npx @ascribed/astro init`), checked against the collection.\n// Ascribe's content model has no page order or grouping yet, so the site keeps\n// the list, and the check keeps it complete: `ascribe.toml` giving a site its\n// navigation is the surface audit's finding 28, which has no design yet.\nimport { slug } from \"github-slugger\";\n\n/** A group of the sidebar: a label, and its pages' source files, in order. */\nexport interface NavGroup {\n label: string;\n /** Source files, relative to the content root, as `Guides/My Setup.md`. */\n pages: string[];\n}\n\n/** A page of the sidebar: its collection entry, and its address. */\nexport interface SidebarPage<E> {\n entry: E;\n href: string;\n}\n\n/** A group of the sidebar, each of its pages with its entry. */\nexport interface SidebarGroup<E> {\n label: string;\n pages: SidebarPage<E>[];\n}\n\n/** What the check needs of a collection entry: its id, and the file it was loaded from. */\nexport interface NavEntry {\n id: string;\n filePath?: string | undefined;\n}\n\n/**\n * A page's entry id, as Astro's `glob` loader computes it from the page's\n * path in the site output: each segment slugged, without the extension, and\n * without a final `/index`.\n */\nexport function entryId(pagePath: string): string {\n return pagePath\n .replace(/\\.md$/, \"\")\n .split(\"/\")\n .map((segment) => slug(segment))\n .join(\"/\")\n .replace(/\\/index$/, \"\");\n}\n\n/**\n * A page's route, as Ascribe's router writes every link to it: the base path\n * plus its entry id, and the root page (`index`) at the base path itself.\n */\nexport function pageRoute(id: string, basePath: string, trailingSlash: \"always\" | \"never\"): string {\n if (id === \"index\")\n return trailingSlash === \"never\" && basePath !== \"/\" ? basePath.slice(0, -1) : basePath;\n return `${basePath}${id}${trailingSlash === \"always\" ? \"/\" : \"\"}`;\n}\n\n/**\n * The ways the list and the collection disagree, as sentences: a page the\n * list leaves out, a file it names that isn't a page, and a page it names twice.\n * `source` names an entry for a person, by its source file where it can.\n */\nexport function navProblems(\n nav: readonly NavGroup[],\n entries: readonly NavEntry[],\n source: (entry: NavEntry) => string = (entry) => entry.id,\n): string[] {\n const listed = nav.flatMap((group) => group.pages);\n const ids = new Set(entries.map((entry) => entry.id));\n const listedIds = new Set(listed.map(entryId));\n const problems: string[] = [];\n for (const entry of entries) {\n if (!listedIds.has(entry.id))\n problems.push(`${source(entry)} isn't in the sidebar's list. Add it to a group.`);\n }\n for (const [i, file] of listed.entries()) {\n if (!ids.has(entryId(file)))\n problems.push(`the sidebar's list names ${file}, which isn't a page of the site.`);\n else if (listed.findIndex((other) => entryId(other) === entryId(file)) !== i)\n problems.push(`the sidebar's list names ${file} twice.`);\n }\n return problems;\n}\n\n/**\n * The sidebar's groups, each page with its entry and address. Throws, naming\n * each, when the list leaves out a page of the collection, names a file that\n * isn't one, or names a page twice, so the list stays complete.\n */\nexport function sidebarGroups<E extends NavEntry>(\n nav: readonly NavGroup[],\n entries: readonly E[],\n route: (id: string) => string,\n source?: (entry: NavEntry) => string,\n): SidebarGroup<E>[] {\n const problems = navProblems(nav, entries, source);\n if (problems.length > 0) {\n throw new Error(\n `@ascribed/astro: the sidebar's list (src/nav.ts) doesn't match the site's pages:\\n${problems.map((problem) => `- ${problem}`).join(\"\\n\")}`,\n );\n }\n const byId = new Map(entries.map((entry) => [entry.id, entry]));\n return nav.map((group) => ({\n label: group.label,\n pages: group.pages.flatMap((file) => {\n const entry = byId.get(entryId(file));\n return entry === undefined ? [] : [{ entry, href: route(entry.id) }];\n }),\n }));\n}\n\n/**\n * The starter's list for a project's pages, by their paths in the site\n * output: the pages at the content root in a group named \"Start\", the root\n * page first, then a group for each folder, named as the folder is, in order\n * of their names.\n */\nexport function navFor(pages: readonly string[]): NavGroup[] {\n const groups = new Map<string, string[]>();\n const sorted = pages.toSorted((a, b) => {\n const rootA = a === \"index.md\";\n const rootB = b === \"index.md\";\n if (rootA !== rootB) return rootA ? -1 : 1;\n return a < b ? -1 : a > b ? 1 : 0;\n });\n for (const page of sorted) {\n const slash = page.indexOf(\"/\");\n const label = slash === -1 ? \"Start\" : page.slice(0, slash);\n groups.set(label, [...(groups.get(label) ?? []), page]);\n }\n const start = groups.get(\"Start\");\n groups.delete(\"Start\");\n return [\n ...(start === undefined ? [] : [{ label: \"Start\", pages: start }]),\n ...[...groups].map(([label, files]) => ({ label, pages: files })),\n ];\n}\n"]}