@ascribed/astro 0.2.1-next.15 → 0.2.1-next.17
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/README.md +21 -7
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +62 -0
- package/dist/cli.js.map +1 -0
- package/dist/content.d.ts +27 -0
- package/dist/content.js +71 -1
- package/dist/content.js.map +1 -1
- package/dist/files.d.ts +5 -2
- package/dist/files.js +13 -5
- package/dist/files.js.map +1 -1
- package/dist/head-check.d.ts +6 -0
- package/dist/head-check.js +28 -0
- package/dist/head-check.js.map +1 -0
- package/dist/head.d.ts +54 -0
- package/dist/head.js +114 -0
- package/dist/head.js.map +1 -0
- package/dist/headers.d.ts +50 -0
- package/dist/headers.js +155 -0
- package/dist/headers.js.map +1 -0
- package/dist/index.d.ts +12 -1
- package/dist/index.js +124 -14
- package/dist/index.js.map +1 -1
- package/dist/init.d.ts +41 -0
- package/dist/init.js +130 -0
- package/dist/init.js.map +1 -0
- package/dist/nav.d.ts +51 -0
- package/dist/nav.js +97 -0
- package/dist/nav.js.map +1 -0
- package/dist/permalinks.d.ts +6 -0
- package/dist/permalinks.js +13 -0
- package/dist/permalinks.js.map +1 -1
- package/dist/project.d.ts +26 -0
- package/dist/project.js +32 -0
- package/dist/project.js.map +1 -1
- package/dist/projects.d.ts +0 -6
- package/dist/projects.js +1 -14
- package/dist/projects.js.map +1 -1
- package/dist/records.d.ts +136 -0
- package/dist/records.js +182 -0
- package/dist/records.js.map +1 -0
- package/dist/root-files.d.ts +68 -0
- package/dist/root-files.js +103 -0
- package/dist/root-files.js.map +1 -0
- package/dist/run.js +3 -2
- package/dist/run.js.map +1 -1
- package/package.json +12 -6
- package/src/Head.astro +58 -0
- package/starter/src/content.config.ts +8 -0
- package/starter/src/layouts/Docs.astro +87 -0
- package/starter/src/nav.ts +13 -0
- 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\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 { mkdirSync } from \"node:fs\";\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, type DevBuilds } from \"./dev.js\";\nimport {\n agentsMiddleware,\n copyAgentFiles,\n copyPublishedFiles,\n filesMiddleware,\n folderUnder,\n} from \"./files.js\";\nimport { hasPermalinks, permalinkPattern, readPermalinks } from \"./permalinks.js\";\nimport { consumerMismatches, homeRoute, readProject } from \"./project.js\";\nimport {\n basePathClashes,\n nameProblems,\n pagesUnderOtherPaths,\n permalinkProblems,\n type ProjectEntry,\n type ResolvedEntry,\n} from \"./projects.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 { 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\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.\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:\n | {\n base: string;\n trailingSlash: string;\n site: string | undefined;\n }\n | 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 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 }) => {\n const root = fileURLToPath(config.root);\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 // `ascribe.toml`'s routing must be Astro's, or every link Ascribe writes is wrong.\n const astro = { base: config.base, trailingSlash: config.trailingSlash, site: config.site };\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\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, config.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, config.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 ...(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 home = ${JSON.stringify(homeRoute(config.base, config.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 : 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 server.middlewares.use(agentsMiddleware(entry.agentsRoot, base));\n }\n },\n },\n ],\n },\n });\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, logger }) => {\n const base = routing?.base ?? \"/\";\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//\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
|
package/dist/init.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,4EAA4E;AAC5E,6EAA6E;AAC7E,6EAA6E;AAC7E,8CAA8C;AAC9C,EAAE;AACF,0EAA0E;AAC1E,4EAA4E;AAC5E,yEAAyE;AACzE,oDAAoD;AACpD,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,MAAM,EAAiB,MAAM,UAAU,CAAC;AACjD,OAAO,EAAE,WAAW,EAAoB,MAAM,cAAc,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEpC,4DAA4D;AAC5D,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,uBAAuB;IACvB,2BAA2B;IAC3B,wBAAwB;IACxB,YAAY;CACJ,CAAC;AAEX,qEAAqE;AACrE,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,aAAa,EAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAEvE,iGAAiG;AACjG,MAAM,aAAa,GAAG,wCAAwC,CAAC;AAE/D,iEAAiE;AACjE,MAAM,QAAQ,GAAG,sDAAsD,CAAC;AAoBxE;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,OAAoB;IAC7C,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,IAAI,GAAG,CAAC,CAAC,CAAC;IACxE,MAAM,KAAK,GAAG,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IAClD,MAAM,KAAK,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IAChF,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CACb,iEAAiE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,4BAA4B,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,mCAAmC,CACxN,CAAC;IACJ,CAAC;IACD,MAAM,QAAQ,CAAC;QACb,MAAM,EAAE,UAAU,CAAC,EAAE,IAAI,EAAE,CAAC;QAC5B,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,KAAK;QACL,GAAG,EAAE,OAAO,CAAC,GAAG;KACjB,CAAC,CAAC;IACH,MAAM,KAAK,GAAG,YAAY,CAAC;QACzB,MAAM,EAAE,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC;QAC1C,GAAG,EAAE,MAAM,CAAC,SAAS,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;KACvC,CAAC,CAAC;IACH,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,KAAK,EAAE,CAAC;QACjC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACpE,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;IAC7C,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;AAC/C,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,WAAW,CAAC,OAAoB,EAAE,KAAyB;IACzE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;IACvE,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;QACzC,MAAM,IAAI,KAAK,CACb,yBAAyB,OAAO,CAAC,UAAU,kBAAkB,KAAK,qBAAqB,MAAM,CAAC,MAAM,CAAC,GAAG,CACzG,CAAC;IACJ,CAAC;IACD,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;IACtB,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAC3D,MAAM,IAAI,KAAK,CACb,yBAAyB,OAAO,CAAC,UAAU,wBAAwB,MAAM,CAAC,MAAM,CAAC,0CAA0C,CAC5H,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,OAAoB,EAAE,KAAa;IAC5E,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;IAC3E,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC7C,MAAM,MAAM,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IACxE,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,+CAA+C,CAAC,CAAC;IAClG,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACjF,CAAC;AAED,iHAAiH;AACjH,MAAM,UAAU,YAAY,CAAC,OAG5B;IACC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;IACxC,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;QACjC,IAAI,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;QAC1D,IAAI,IAAI,KAAK,uBAAuB;YAClC,IAAI,GAAG,IAAI,CACT,IAAI,EACJ,aAAa,EACb,CAAC,CAAC,EAAE,KAAa,EAAE,EAAE,CAAC,GAAG,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CACnE,CAAC;QACJ,IAAI,IAAI,KAAK,YAAY;YAAE,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;QACnF,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACxB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,wHAAwH;AACxH,SAAS,IAAI,CACX,IAAY,EACZ,OAAe,EACf,WAA2D;IAE3D,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,4CAA4C,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAChF,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;AAC5C,CAAC;AAED,8FAA8F;AAC9F,SAAS,OAAO,CAAC,GAAwB;IACvC,MAAM,KAAK,GAAG,CAAC,kCAAkC,CAAC,CAAC;IACnD,KAAK,MAAM,KAAK,IAAI,GAAG,EAAE,CAAC;QACxB,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;QAChF,MAAM,IAAI,GAAG,cAAc,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,YAAY,KAAK,KAAK,CAAC;QAC7E,IAAI,IAAI,CAAC,MAAM,IAAI,GAAG,EAAE,CAAC;YACvB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACjB,SAAS;QACX,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,cAAc,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAChE,IAAI,cAAc,KAAK,GAAG,CAAC,MAAM,IAAI,GAAG;YAAE,KAAK,CAAC,IAAI,CAAC,cAAc,KAAK,GAAG,CAAC,CAAC;;YAE3E,KAAK,CAAC,IAAI,CACR,cAAc,EACd,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,EAC9D,QAAQ,CACT,CAAC;QACJ,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACrB,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,MAAM,CAAC,KAAwB;IACtC,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACrD,CAAC","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/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
|
package/dist/nav.js.map
ADDED
|
@@ -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"]}
|
package/dist/permalinks.d.ts
CHANGED
|
@@ -70,3 +70,9 @@ export declare function servedList(sources: readonly PermalinkSource[]): {
|
|
|
70
70
|
path: string;
|
|
71
71
|
home: string;
|
|
72
72
|
} | undefined;
|
|
73
|
+
/**
|
|
74
|
+
* The routes of the forwarding pages, from the host's root: one for each name
|
|
75
|
+
* in `lists`, at the path of the list the route serves, as `hasPermalinks`
|
|
76
|
+
* picks it. They aren't pages of a build, and no sitemap lists them.
|
|
77
|
+
*/
|
|
78
|
+
export declare function forwardingRoutes(lists: readonly (PermalinkList | undefined)[]): string[];
|
package/dist/permalinks.js
CHANGED
|
@@ -98,4 +98,17 @@ export function servedList(sources) {
|
|
|
98
98
|
}
|
|
99
99
|
return first;
|
|
100
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* The routes of the forwarding pages, from the host's root: one for each name
|
|
103
|
+
* in `lists`, at the path of the list the route serves, as `hasPermalinks`
|
|
104
|
+
* picks it. They aren't pages of a build, and no sitemap lists them.
|
|
105
|
+
*/
|
|
106
|
+
export function forwardingRoutes(lists) {
|
|
107
|
+
const known = lists.filter((list) => list !== undefined);
|
|
108
|
+
const served = known.find(hasPermalinks) ?? known[0];
|
|
109
|
+
if (served === undefined)
|
|
110
|
+
return [];
|
|
111
|
+
const at = normalizeBase(served.path);
|
|
112
|
+
return known.flatMap((list) => [...Object.keys(list.permalinks), ...Object.keys(list.removed ?? {})].map((id) => `${at}${id}`));
|
|
113
|
+
}
|
|
101
114
|
//# sourceMappingURL=permalinks.js.map
|