@ascribed/astro 0.3.1 → 0.3.2-next.23

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.
package/dist/index.js CHANGED
@@ -21,6 +21,7 @@
21
21
  // import Elements from "@ascribed/astro/Elements.astro"; // <Elements /> in <head>
22
22
  // import Availability from "@ascribed/astro/Availability.astro"; // the page's availability
23
23
  // import Head from "@ascribed/astro/Head.astro"; // <Head entry={entry} /> in <head>
24
+ // import Versions from "@ascribed/astro/Versions.astro"; // the lines that have the page
24
25
  //
25
26
  // // the sidebar: src/nav.ts's list, checked against the collection
26
27
  // import { sidebar } from "@ascribed/astro/content";
@@ -46,7 +47,7 @@ import { fileURLToPath } from "node:url";
46
47
  import { findBinary } from "./binary.js";
47
48
  import { codeTitles } from "./code-titles.js";
48
49
  import { SeenFiles, watchDev } from "./dev.js";
49
- import { agentsMiddleware, copyAgentFiles, copyPublishedFiles, filesMiddleware, folderUnder, } from "./files.js";
50
+ import { agentsMiddleware, copyAgentFiles, copyPublishedFiles, filesMiddleware, folderUnder, inOrder, } from "./files.js";
50
51
  import { WARN as HEAD_WARN } from "./head-check.js";
51
52
  import { headersFor, headersOutcome, mergeRules, readHeaders } from "./headers.js";
52
53
  import { forwardingRoutes, hasPermalinks, permalinkPattern, readPermalinks } from "./permalinks.js";
@@ -63,6 +64,7 @@ import { devRouted, devSitePages, rootFiles, rootFilesMiddleware, } from "./root
63
64
  import { anchorsFor, hasWarnings, reviewFor, runBuild } from "./run.js";
64
65
  import { satteriAscribeAttributes } from "./satteri.js";
65
66
  import { copySchema } from "./schema.js";
67
+ import { linesOf, olderLines } from "./versions.js";
66
68
  export { default as rehypeAscribeAttributes } from "./rehype.js";
67
69
  export { satteriAscribeAttributes } from "./satteri.js";
68
70
  /** The virtual module `content.ts` reads the resolved site output roots from. */
@@ -112,7 +114,11 @@ export default function ascribe(options) {
112
114
  }
113
115
  const root = normalizeBase(base);
114
116
  return {
115
- projects: records.map(pageList),
117
+ projects: [
118
+ ...records.map(pageList),
119
+ // An older line's pages are the site's too: those the current line has point at it.
120
+ ...entries.flatMap((entry) => olderLines(entry.siteRoot).map((line) => pageList(readRecords(line.siteRoot)))),
121
+ ],
116
122
  routed,
117
123
  sitePages,
118
124
  excluded: [
@@ -203,16 +209,20 @@ export default function ascribe(options) {
203
209
  binary = found;
204
210
  const buildEntry = async (entry) => {
205
211
  logger.info(`running ${path.basename(found)} build for "${entry.build}"${named ? ` (${entry.name})` : ""}`);
206
- const result = await runBuild({
212
+ const run = {
207
213
  binary: found,
208
214
  configPath: entry.project.configPath,
209
- build: entry.build,
210
215
  cwd: entry.project.dir,
211
216
  anchors: anchorsFor(options.anchors, command, entry === reviewed),
217
+ };
218
+ // `llms.txt` and each page's Markdown, which agents read.
219
+ const plain = entry.agentsRoot === undefined ? [] : ["plain"];
220
+ const result = await runBuild({
221
+ ...run,
222
+ build: entry.build,
212
223
  outputs: [
213
224
  "site",
214
- // `llms.txt` and each page's Markdown, which agents read.
215
- ...(entry.agentsRoot === undefined ? [] : ["plain"]),
225
+ ...plain,
216
226
  // While review is on, the JSON output says which page is at each route.
217
227
  ...(entry === reviewed && review?.active ? ["json"] : []),
218
228
  ],
@@ -223,6 +233,23 @@ export default function ascribe(options) {
223
233
  logger.info(result.diagnostics);
224
234
  if (result.summary !== "")
225
235
  logger.info(result.summary);
236
+ // A versioned build's other lines, which the build's `versions.json` names, once the
237
+ // current line's build has written it. An error in one fails this run as it would the
238
+ // first; `ascribe check` reports every line's warnings, so only what was built is said.
239
+ const older = olderLines(entry.siteRoot).map((line) => line.build);
240
+ if (older.length > 0) {
241
+ const lines = await runBuild({
242
+ ...run,
243
+ build: older,
244
+ outputs: [
245
+ "site",
246
+ ...plain,
247
+ ...(entry === reviewed && review?.active ? ["json"] : []),
248
+ ],
249
+ });
250
+ if (lines.summary !== "")
251
+ logger.info(lines.summary);
252
+ }
226
253
  // The schema's copy inside the Astro root, for content.config.ts to import.
227
254
  mkdirSync(entry.schemaDir, { recursive: true });
228
255
  copySchema(entry.siteRoot, entry.schemaDir);
@@ -315,9 +342,13 @@ export default function ascribe(options) {
315
342
  for (const entry of entries) {
316
343
  const base = entry.project.consumer.basePath;
317
344
  server.middlewares.use(filesMiddleware(entry.siteRoot, base));
345
+ // Each older line's, at its own base path; the lines are read as each request comes.
346
+ server.middlewares.use((req, res, next) => inOrder(olderLines(entry.siteRoot).map((line) => filesMiddleware(line.siteRoot, line.base)), req, res, next));
318
347
  if (entry.agentsRoot !== undefined) {
319
348
  const siteRoot = entry.siteRoot;
320
349
  server.middlewares.use(agentsMiddleware(entry.agentsRoot, base, (pathname) => headersFor(siteRoot, pathname)));
350
+ // Each older line's outputs for agents, at its own base path.
351
+ server.middlewares.use((req, res, next) => inOrder(olderLines(siteRoot).map((line) => agentsMiddleware(line.plainRoot, line.base, (pathname) => headersFor(line.siteRoot, pathname))), req, res, next));
321
352
  }
322
353
  }
323
354
  // The sitemap and robots.txt, as the build would write them now.
@@ -358,21 +389,38 @@ export default function ascribe(options) {
358
389
  const entry = reviewed;
359
390
  const builds = group.builds;
360
391
  const run = { binary, configPath: entry.project.configPath, cwd: entry.project.dir };
361
- const jsonRoot = path.join(path.dirname(entry.siteRoot), "json");
392
+ // A versioned build is reviewed in every line, the current one first, each line's
393
+ // routes from its own JSON output.
394
+ const lines = () => linesOf(entry.siteRoot)?.map((line) => ({
395
+ build: line.build,
396
+ siteRoot: line.siteRoot,
397
+ })) ?? [{ build: entry.build, siteRoot: entry.siteRoot }];
398
+ const lineBuilds = () => lines().map((line) => line.build);
362
399
  review = new ReviewServer({
363
400
  channel: toolbar,
364
401
  logger,
365
402
  build: entry.build,
366
403
  contentRoot: entry.project.contentRoot,
367
404
  channelProblem: channelProblem(server.config),
368
- diff: (base) => runDiff({ ...run, build: entry.build, base }),
369
- prompt: (page, base) => runPrompt({ ...run, build: entry.build, base, path: page }),
405
+ diff: (base) => runDiff({ ...run, build: lineBuilds(), base }),
406
+ prompt: (page, base) => runPrompt({ ...run, build: lineBuilds(), base, path: page }),
370
407
  projectDir: entry.project.dir,
371
408
  connect: async () => (await import("./review/github.js")).connect(entry.project.dir),
372
409
  writeRoutes: () => builds.inTurn(async () => {
373
- await runBuild({ ...run, build: entry.build, outputs: ["json"] });
410
+ await runBuild({ ...run, build: lineBuilds(), outputs: ["json"] });
374
411
  }),
375
- readRoutes: () => readRoutes(jsonRoot),
412
+ readRoutes: async () => {
413
+ const all = new Map();
414
+ const versioned = lines().length > 1;
415
+ for (const line of lines()) {
416
+ const jsonRoot = path.join(path.dirname(line.siteRoot), "json");
417
+ for (const [route, page] of await readRoutes(jsonRoot)) {
418
+ if (!all.has(route))
419
+ all.set(route, versioned ? { ...page, build: line.build } : page);
420
+ }
421
+ }
422
+ return all;
423
+ },
376
424
  });
377
425
  }
378
426
  },
@@ -431,7 +479,7 @@ export default function ascribe(options) {
431
479
  const headers = headersOutcome({
432
480
  rules: mergeRules(entries
433
481
  .filter((entry) => entry.project.consumer.headers === "netlify")
434
- .map((entry) => readHeaders(entry.siteRoot) ?? [])),
482
+ .flatMap((entry) => [entry.siteRoot, ...olderLines(entry.siteRoot).map((line) => line.siteRoot)].map((siteRoot) => readHeaders(siteRoot) ?? []))),
435
483
  base,
436
484
  own: existsSync(ownHeaders) ? readFileSync(ownHeaders, "utf8") : undefined,
437
485
  });
@@ -449,9 +497,21 @@ export default function ascribe(options) {
449
497
  const where = folder === "" ? "" : ` to ${folder}`;
450
498
  if (await copyPublishedFiles(entry.siteRoot, dir, folder))
451
499
  logger.info(`copied _ascribe/files/${where}`);
500
+ for (const line of olderLines(entry.siteRoot)) {
501
+ const lineFolder = folderUnder(line.base, base);
502
+ if (await copyPublishedFiles(line.siteRoot, dir, lineFolder))
503
+ logger.info(`copied ${line.build}'s _ascribe/files/ to ${lineFolder}`);
504
+ }
452
505
  if (entry.agentsRoot !== undefined &&
453
506
  (await copyAgentFiles(entry.agentsRoot, dir, folder)))
454
507
  logger.info(`copied llms.txt and each page's Markdown${where}`);
508
+ if (entry.agentsRoot !== undefined) {
509
+ for (const line of olderLines(entry.siteRoot)) {
510
+ const lineFolder = folderUnder(line.base, base);
511
+ if (await copyAgentFiles(line.plainRoot, dir, lineFolder))
512
+ logger.info(`copied ${line.build}'s llms.txt and each page's Markdown to ${lineFolder}`);
513
+ }
514
+ }
455
515
  }
456
516
  },
457
517
  },
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// // `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), and what a tested example was tested with (`tested=\"…\"`),\n * 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"]}
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// import Versions from \"@ascribed/astro/Versions.astro\"; // the lines that have the page\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 inOrder,\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, type RoutedPage } 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\";\nimport { linesOf, olderLines } from \"./versions.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), and what a tested example was tested with (`tested=\"…\"`),\n * 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: [\n ...records.map(pageList),\n // An older line's pages are the site's too: those the current line has point at it.\n ...entries.flatMap((entry) =>\n olderLines(entry.siteRoot).map((line) => pageList(readRecords(line.siteRoot))),\n ),\n ],\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 run = {\n binary: found,\n configPath: entry.project.configPath,\n cwd: entry.project.dir,\n anchors: anchorsFor(options.anchors, command, entry === reviewed),\n };\n // `llms.txt` and each page's Markdown, which agents read.\n const plain = entry.agentsRoot === undefined ? [] : ([\"plain\"] as const);\n const result = await runBuild({\n ...run,\n build: entry.build,\n outputs: [\n \"site\",\n ...plain,\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 // A versioned build's other lines, which the build's `versions.json` names, once the\n // current line's build has written it. An error in one fails this run as it would the\n // first; `ascribe check` reports every line's warnings, so only what was built is said.\n const older = olderLines(entry.siteRoot).map((line) => line.build);\n if (older.length > 0) {\n const lines = await runBuild({\n ...run,\n build: older,\n outputs: [\n \"site\",\n ...plain,\n ...(entry === reviewed && review?.active ? ([\"json\"] as const) : []),\n ],\n });\n if (lines.summary !== \"\") logger.info(lines.summary);\n }\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 // Each older line's, at its own base path; the lines are read as each request comes.\n server.middlewares.use((req, res, next) =>\n inOrder(\n olderLines(entry.siteRoot).map((line) =>\n filesMiddleware(line.siteRoot, line.base),\n ),\n req,\n res,\n next,\n ),\n );\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 // Each older line's outputs for agents, at its own base path.\n server.middlewares.use((req, res, next) =>\n inOrder(\n olderLines(siteRoot).map((line) =>\n agentsMiddleware(line.plainRoot, line.base, (pathname) =>\n headersFor(line.siteRoot, pathname),\n ),\n ),\n req,\n res,\n next,\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 // A versioned build is reviewed in every line, the current one first, each line's\n // routes from its own JSON output.\n const lines = () =>\n linesOf(entry.siteRoot)?.map((line) => ({\n build: line.build,\n siteRoot: line.siteRoot,\n })) ?? [{ build: entry.build, siteRoot: entry.siteRoot }];\n const lineBuilds = () => lines().map((line) => line.build);\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: lineBuilds(), base }),\n prompt: (page, base) => runPrompt({ ...run, build: lineBuilds(), 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: lineBuilds(), outputs: [\"json\"] });\n }),\n readRoutes: async () => {\n const all = new Map<string, RoutedPage>();\n const versioned = lines().length > 1;\n for (const line of lines()) {\n const jsonRoot = path.join(path.dirname(line.siteRoot), \"json\");\n for (const [route, page] of await readRoutes(jsonRoot)) {\n if (!all.has(route))\n all.set(route, versioned ? { ...page, build: line.build } : page);\n }\n }\n return all;\n },\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 .flatMap((entry) =>\n [entry.siteRoot, ...olderLines(entry.siteRoot).map((line) => line.siteRoot)].map(\n (siteRoot) => readHeaders(siteRoot) ?? [],\n ),\n ),\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 for (const line of olderLines(entry.siteRoot)) {\n const lineFolder = folderUnder(line.base, base);\n if (await copyPublishedFiles(line.siteRoot, dir, lineFolder))\n logger.info(`copied ${line.build}'s _ascribe/files/ to ${lineFolder}`);\n }\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 if (entry.agentsRoot !== undefined) {\n for (const line of olderLines(entry.siteRoot)) {\n const lineFolder = folderUnder(line.base, base);\n if (await copyAgentFiles(line.plainRoot, dir, lineFolder))\n logger.info(\n `copied ${line.build}'s llms.txt and each page's Markdown to ${lineFolder}`,\n );\n }\n }\n }\n },\n },\n };\n}\n"]}
package/dist/names.d.ts CHANGED
@@ -41,6 +41,8 @@ export declare const DATA_SOURCE = "data-ascribe-source";
41
41
  export declare const DATA_VIA = "data-ascribe-via";
42
42
  /** A glossary term's id, on its link (packages/elements/CONTRACT.md §7). */
43
43
  export declare const DATA_TERM = "data-ascribe-term";
44
+ /** The line a link out of a line leads to, on its link (packages/elements/CONTRACT.md §10). */
45
+ export declare const DATA_RELEASE_LINE = "data-ascribe-release-line";
44
46
  /** The element the report draws into. */
45
47
  export declare const ID_REPORT = "ascribe-review";
46
48
  /** The `<script type="application/json">` holding the report's data. */
package/dist/names.js CHANGED
@@ -44,6 +44,8 @@ export const DATA_SOURCE = "data-ascribe-source";
44
44
  export const DATA_VIA = "data-ascribe-via";
45
45
  /** A glossary term's id, on its link (packages/elements/CONTRACT.md §7). */
46
46
  export const DATA_TERM = "data-ascribe-term";
47
+ /** The line a link out of a line leads to, on its link (packages/elements/CONTRACT.md §10). */
48
+ export const DATA_RELEASE_LINE = "data-ascribe-release-line";
47
49
  /** The element the report draws into. */
48
50
  export const ID_REPORT = "ascribe-review";
49
51
  /** The `<script type="application/json">` holding the report's data. */
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/**\n * On the visually hidden `(Available: ` and `)` around a table row's\n * `<ascribe-availability>` targets (packages/elements/CONTRACT.md §4).\n */\nexport const CLASS_AVAILABILITY_LEAD_IN = \"ascribe-availability-lead-in\";\n\n/**\n * On the line of a code block's caption that says what a tested example\n * was tested with; its lead-in, \"Tested with\", is the stylesheet's\n * (packages/elements/CONTRACT.md §9).\n */\nexport const CLASS_CODE_TESTED = \"ascribe-code-tested\";\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/astro/reference.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/**\n * On the visually hidden `(Available: ` and `)` around a table row's\n * `<ascribe-availability>` targets (packages/elements/CONTRACT.md §4).\n */\nexport const CLASS_AVAILABILITY_LEAD_IN = \"ascribe-availability-lead-in\";\n\n/**\n * On the line of a code block's caption that says what a tested example\n * was tested with; its lead-in, \"Tested with\", is the stylesheet's\n * (packages/elements/CONTRACT.md §9).\n */\nexport const CLASS_CODE_TESTED = \"ascribe-code-tested\";\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 line a link out of a line leads to, on its link (packages/elements/CONTRACT.md §10). */\nexport const DATA_RELEASE_LINE = \"data-ascribe-release-line\";\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/astro/reference.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 CHANGED
@@ -40,8 +40,16 @@ export declare function navProblems(nav: readonly NavGroup[], entries: readonly
40
40
  * The sidebar's groups, each page with its entry and address. Throws, naming
41
41
  * each, when the list leaves out a page of the collection, names a file that
42
42
  * isn't one, or names a page twice, so the list stays complete.
43
+ *
44
+ * A versioned build's collection has every line's pages, and the list is
45
+ * checked against them all: `id` gives an entry's id within its line, and
46
+ * the groups have the pages `shown` keeps, one line's, each listed page that
47
+ * line has.
43
48
  */
44
- export declare function sidebarGroups<E extends NavEntry>(nav: readonly NavGroup[], entries: readonly E[], route: (id: string) => string, source?: (entry: NavEntry) => string): SidebarGroup<E>[];
49
+ export declare function sidebarGroups<E extends NavEntry>(nav: readonly NavGroup[], entries: readonly E[], route: (id: string) => string, source?: (entry: NavEntry) => string, lines?: {
50
+ id: (entry: E) => string;
51
+ shown: (entry: E) => boolean;
52
+ }): SidebarGroup<E>[];
45
53
  /**
46
54
  * The starter's list for a project's pages, by their paths in the site
47
55
  * output: the pages at the content root in a group named "Start", the root
package/dist/nav.js CHANGED
@@ -52,13 +52,23 @@ export function navProblems(nav, entries, source = (entry) => entry.id) {
52
52
  * The sidebar's groups, each page with its entry and address. Throws, naming
53
53
  * each, when the list leaves out a page of the collection, names a file that
54
54
  * isn't one, or names a page twice, so the list stays complete.
55
+ *
56
+ * A versioned build's collection has every line's pages, and the list is
57
+ * checked against them all: `id` gives an entry's id within its line, and
58
+ * the groups have the pages `shown` keeps, one line's, each listed page that
59
+ * line has.
55
60
  */
56
- export function sidebarGroups(nav, entries, route, source) {
57
- const problems = navProblems(nav, entries, source);
61
+ export function sidebarGroups(nav, entries, route, source, lines = {
62
+ id: (entry) => entry.id,
63
+ shown: () => true,
64
+ }) {
65
+ // A page in several lines is one page of the list, and one problem.
66
+ const checked = new Map(entries.map((entry) => [{ id: lines.id(entry), filePath: entry.filePath }, entry]));
67
+ const problems = navProblems(nav, [...checked.keys()], source === undefined ? undefined : (entry) => source(checked.get(entry) ?? entry)).filter((problem, i, all) => all.indexOf(problem) === i);
58
68
  if (problems.length > 0) {
59
69
  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
70
  }
61
- const byId = new Map(entries.map((entry) => [entry.id, entry]));
71
+ const byId = new Map(entries.filter((entry) => lines.shown(entry)).map((entry) => [lines.id(entry), entry]));
62
72
  return nav.map((group) => ({
63
73
  label: group.label,
64
74
  pages: group.pages.flatMap((file) => {
package/dist/nav.js.map CHANGED
@@ -1 +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"]}
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 *\n * A versioned build's collection has every line's pages, and the list is\n * checked against them all: `id` gives an entry's id within its line, and\n * the groups have the pages `shown` keeps, one line's, each listed page that\n * line has.\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 lines: { id: (entry: E) => string; shown: (entry: E) => boolean } = {\n id: (entry) => entry.id,\n shown: () => true,\n },\n): SidebarGroup<E>[] {\n // A page in several lines is one page of the list, and one problem.\n const checked = new Map<NavEntry, E>(\n entries.map((entry) => [{ id: lines.id(entry), filePath: entry.filePath }, entry]),\n );\n const problems = navProblems(\n nav,\n [...checked.keys()],\n source === undefined ? undefined : (entry) => source(checked.get(entry) ?? entry),\n ).filter((problem, i, all) => all.indexOf(problem) === i);\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(\n entries.filter((entry) => lines.shown(entry)).map((entry) => [lines.id(entry), entry]),\n );\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"]}