@ascribed/astro 0.2.1-next.13 → 0.2.1-next.14
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 +17 -3
- package/dist/content.d.ts +3 -0
- package/dist/content.js +31 -2
- package/dist/content.js.map +1 -1
- package/dist/dev.d.ts +2 -1
- package/dist/dev.js +6 -5
- package/dist/dev.js.map +1 -1
- package/dist/files.d.ts +13 -5
- package/dist/files.js +23 -9
- package/dist/files.js.map +1 -1
- package/dist/index.d.ts +27 -11
- package/dist/index.js +199 -108
- package/dist/index.js.map +1 -1
- package/dist/permalinks.d.ts +20 -2
- package/dist/permalinks.js +45 -16
- package/dist/permalinks.js.map +1 -1
- package/dist/project.d.ts +3 -2
- package/dist/project.js +6 -4
- package/dist/project.js.map +1 -1
- package/dist/projects.d.ts +44 -0
- package/dist/projects.js +140 -0
- package/dist/projects.js.map +1 -0
- package/dist/review/devfile.d.ts +6 -1
- package/dist/review/devfile.js +12 -2
- package/dist/review/devfile.js.map +1 -1
- package/dist/run.d.ts +2 -2
- package/dist/run.js +1 -1
- package/dist/run.js.map +1 -1
- package/package.json +6 -5
- package/src/MissingPermalink.astro +9 -6
- package/src/Permalink.astro +4 -3
package/dist/index.js
CHANGED
|
@@ -22,14 +22,27 @@
|
|
|
22
22
|
//
|
|
23
23
|
// // src/pages/404.astro
|
|
24
24
|
// import MissingPermalink from "@ascribed/astro/MissingPermalink.astro"; // a permalink that isn't here
|
|
25
|
+
//
|
|
26
|
+
// Several projects in one site, each entry named, and each collection naming its entry:
|
|
27
|
+
//
|
|
28
|
+
// ascribe({
|
|
29
|
+
// projects: [
|
|
30
|
+
// { name: "docs", project: "../docs", build: "site" },
|
|
31
|
+
// { name: "home", project: "home", build: "site" },
|
|
32
|
+
// ],
|
|
33
|
+
// review: "docs",
|
|
34
|
+
// })
|
|
35
|
+
// ascribeCollection({ schema, name: "docs" })
|
|
36
|
+
import { mkdirSync } from "node:fs";
|
|
25
37
|
import path from "node:path";
|
|
26
38
|
import { fileURLToPath } from "node:url";
|
|
27
39
|
import { findBinary } from "./binary.js";
|
|
28
40
|
import { codeTitles } from "./code-titles.js";
|
|
29
41
|
import { SeenFiles, watchDev } from "./dev.js";
|
|
30
|
-
import { agentsMiddleware, copyAgentFiles, copyPublishedFiles, filesMiddleware } from "./files.js";
|
|
31
|
-
import { permalinkPattern, readPermalinks } from "./permalinks.js";
|
|
42
|
+
import { agentsMiddleware, copyAgentFiles, copyPublishedFiles, filesMiddleware, folderUnder, } from "./files.js";
|
|
43
|
+
import { hasPermalinks, permalinkPattern, readPermalinks } from "./permalinks.js";
|
|
32
44
|
import { consumerMismatches, homeRoute, readProject } from "./project.js";
|
|
45
|
+
import { basePathClashes, nameProblems, pagesUnderOtherPaths, permalinkProblems, } from "./projects.js";
|
|
33
46
|
import rehypeAscribeAttributes from "./rehype.js";
|
|
34
47
|
import { removeDevFile, siteUrl, writeDevFile } from "./review/devfile.js";
|
|
35
48
|
import { runDiff, runPrompt } from "./review/diff.js";
|
|
@@ -41,26 +54,30 @@ import { satteriAscribeAttributes } from "./satteri.js";
|
|
|
41
54
|
import { copySchema } from "./schema.js";
|
|
42
55
|
export { default as rehypeAscribeAttributes } from "./rehype.js";
|
|
43
56
|
export { satteriAscribeAttributes } from "./satteri.js";
|
|
44
|
-
/** The virtual module `content.ts` reads the resolved site output
|
|
57
|
+
/** The virtual module `content.ts` reads the resolved site output roots from. */
|
|
45
58
|
const SITE_MODULE = "virtual:ascribe/site";
|
|
46
59
|
/** The toolbar app's icon: a speech bubble over a page. */
|
|
47
60
|
const ICON = '<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>';
|
|
61
|
+
function fail(problems, what) {
|
|
62
|
+
if (problems.length > 0)
|
|
63
|
+
throw new Error(`@ascribed/astro: ${what}:\n- ${problems.join("\n- ")}`);
|
|
64
|
+
}
|
|
48
65
|
/**
|
|
49
|
-
* Runs `ascribe build
|
|
50
|
-
* permalink's address, and serves published files, and, with `[consumer] agents = true`,
|
|
51
|
-
* and each page's Markdown.
|
|
66
|
+
* Runs `ascribe build` for each project, checks the site's routing, adds the markdown plugin, adds a
|
|
67
|
+
* page for each permalink's address, and serves published files, and, with `[consumer] agents = true`,
|
|
68
|
+
* `llms.txt` and each page's Markdown, each at its project's base path.
|
|
52
69
|
*/
|
|
53
70
|
export default function ascribe(options) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
let
|
|
57
|
-
let
|
|
58
|
-
let
|
|
59
|
-
let rebuild;
|
|
71
|
+
/** With `projects`; otherwise the one entry has no name a collection gives. */
|
|
72
|
+
const named = options.projects !== undefined;
|
|
73
|
+
let entries = [];
|
|
74
|
+
let groups = [];
|
|
75
|
+
let routing;
|
|
60
76
|
/** The dev server's sources as its first build read them. */
|
|
61
77
|
const seen = new SeenFiles();
|
|
62
78
|
let binary;
|
|
63
|
-
let
|
|
79
|
+
let reviewed;
|
|
80
|
+
let devCommand = false;
|
|
64
81
|
let devHttps = false;
|
|
65
82
|
let review;
|
|
66
83
|
return {
|
|
@@ -68,19 +85,44 @@ export default function ascribe(options) {
|
|
|
68
85
|
hooks: {
|
|
69
86
|
"astro:config:setup": async ({ config, command, logger, updateConfig, addDevToolbarApp, createCodegenDir, injectRoute, }) => {
|
|
70
87
|
const root = fileURLToPath(config.root);
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
88
|
+
const list = options.projects ?? [
|
|
89
|
+
{
|
|
90
|
+
name: "",
|
|
91
|
+
build: options.build,
|
|
92
|
+
...(options.project === undefined ? {} : { project: options.project }),
|
|
93
|
+
},
|
|
94
|
+
];
|
|
95
|
+
if (named)
|
|
96
|
+
fail(nameProblems(list), "the `projects` option is wrong");
|
|
97
|
+
const codegen = command === "preview" ? "" : fileURLToPath(createCodegenDir());
|
|
98
|
+
entries = list.map((entry) => {
|
|
99
|
+
const project = readProject(path.resolve(root, entry.project ?? "."));
|
|
100
|
+
return {
|
|
101
|
+
name: entry.name,
|
|
102
|
+
build: entry.build,
|
|
103
|
+
project,
|
|
104
|
+
// An unknown build is `ascribe build`'s to report: it knows the implicit `site` build.
|
|
105
|
+
siteRoot: project.siteRoot(entry.build),
|
|
106
|
+
agentsRoot: project.consumer.agents ? project.plainRoot(entry.build) : undefined,
|
|
107
|
+
schemaDir: named ? path.join(codegen, entry.name) : codegen,
|
|
108
|
+
};
|
|
81
109
|
});
|
|
82
|
-
|
|
83
|
-
|
|
110
|
+
// `ascribe.toml`'s routing must be Astro's, or every link Ascribe writes is wrong.
|
|
111
|
+
const astro = { base: config.base, trailingSlash: config.trailingSlash, site: config.site };
|
|
112
|
+
for (const entry of entries) {
|
|
113
|
+
fail(consumerMismatches(entry.project, astro), named
|
|
114
|
+
? `"${entry.name}"'s ascribe.toml and astro.config disagree`
|
|
115
|
+
: "ascribe.toml and astro.config disagree");
|
|
116
|
+
}
|
|
117
|
+
fail(basePathClashes(entries), "two projects share a base path");
|
|
118
|
+
if (typeof options.review === "string" && !entries.some((e) => e.name === options.review)) {
|
|
119
|
+
throw new Error(`@ascribed/astro: \`review\` names "${options.review}", and no entry of \`projects\` has that name.`);
|
|
120
|
+
}
|
|
121
|
+
if (reviewFor(options.review, command)) {
|
|
122
|
+
reviewed =
|
|
123
|
+
typeof options.review === "string"
|
|
124
|
+
? entries.find((e) => e.name === options.review)
|
|
125
|
+
: entries[0];
|
|
84
126
|
}
|
|
85
127
|
// Where a markdown plugin goes depends on the processor Astro 7.3 runs.
|
|
86
128
|
const processor = config.markdown.processor;
|
|
@@ -95,13 +137,8 @@ export default function ascribe(options) {
|
|
|
95
137
|
throw new Error(`@ascribed/astro: the markdown processor "${processor.name}" is not one it can add its plugin to. ` +
|
|
96
138
|
"Use Astro's default (satteri) or unified(), or add `rehypeAscribeAttributes` to your own.");
|
|
97
139
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
trailingSlash: config.trailingSlash,
|
|
101
|
-
site: config.site,
|
|
102
|
-
};
|
|
103
|
-
reviewing = reviewFor(options.review, command);
|
|
104
|
-
if (reviewing) {
|
|
140
|
+
routing = astro;
|
|
141
|
+
if (reviewed !== undefined) {
|
|
105
142
|
addDevToolbarApp({
|
|
106
143
|
id: APP_ID,
|
|
107
144
|
name: "Ascribe review",
|
|
@@ -112,22 +149,20 @@ export default function ascribe(options) {
|
|
|
112
149
|
if (command !== "preview") {
|
|
113
150
|
const found = findBinary({ binary: options.binary, root });
|
|
114
151
|
binary = found;
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
rebuild = async () => {
|
|
118
|
-
logger.info(`running ${path.basename(found)} build for "${options.build}"`);
|
|
152
|
+
const buildEntry = async (entry) => {
|
|
153
|
+
logger.info(`running ${path.basename(found)} build for "${entry.build}"${named ? ` (${entry.name})` : ""}`);
|
|
119
154
|
const result = await runBuild({
|
|
120
155
|
binary: found,
|
|
121
|
-
configPath: project.configPath,
|
|
122
|
-
build:
|
|
123
|
-
cwd: project.dir,
|
|
124
|
-
anchors: anchorsFor(options.anchors, command,
|
|
156
|
+
configPath: entry.project.configPath,
|
|
157
|
+
build: entry.build,
|
|
158
|
+
cwd: entry.project.dir,
|
|
159
|
+
anchors: anchorsFor(options.anchors, command, entry === reviewed),
|
|
125
160
|
outputs: [
|
|
126
161
|
"site",
|
|
127
162
|
// `llms.txt` and each page's Markdown, which agents read.
|
|
128
|
-
...(agentsRoot === undefined ? [] : ["plain"]),
|
|
163
|
+
...(entry.agentsRoot === undefined ? [] : ["plain"]),
|
|
129
164
|
// While review is on, the JSON output says which page is at each route.
|
|
130
|
-
...(review?.active ? ["json"] : []),
|
|
165
|
+
...(entry === reviewed && review?.active ? ["json"] : []),
|
|
131
166
|
],
|
|
132
167
|
});
|
|
133
168
|
if (hasWarnings(result.diagnostics))
|
|
@@ -136,24 +171,58 @@ export default function ascribe(options) {
|
|
|
136
171
|
logger.info(result.diagnostics);
|
|
137
172
|
if (result.summary !== "")
|
|
138
173
|
logger.info(result.summary);
|
|
139
|
-
|
|
174
|
+
// The schema's copy inside the Astro root, for content.config.ts to import.
|
|
175
|
+
mkdirSync(entry.schemaDir, { recursive: true });
|
|
176
|
+
copySchema(entry.siteRoot, entry.schemaDir);
|
|
177
|
+
};
|
|
178
|
+
// What the projects share, which no one project's build can see.
|
|
179
|
+
const checkShared = () => {
|
|
180
|
+
if (entries.length < 2)
|
|
181
|
+
return;
|
|
182
|
+
const current = entries.map((entry) => ({
|
|
183
|
+
...entry,
|
|
184
|
+
project: readProject(entry.project.dir),
|
|
185
|
+
}));
|
|
186
|
+
fail(basePathClashes(current), "two projects share a base path");
|
|
187
|
+
fail(pagesUnderOtherPaths(current), "a page is under another project's base path");
|
|
188
|
+
fail(permalinkProblems(current, current.map((entry) => readPermalinks(entry.siteRoot))), "the projects' permalinks can't share one route");
|
|
140
189
|
};
|
|
190
|
+
// One group for each project: a change rebuilds the project it's in.
|
|
191
|
+
const byDir = new Map();
|
|
192
|
+
for (const entry of entries) {
|
|
193
|
+
byDir.set(entry.project.dir, [...(byDir.get(entry.project.dir) ?? []), entry]);
|
|
194
|
+
}
|
|
195
|
+
groups = [...byDir.values()].map((group) => ({
|
|
196
|
+
project: group[0].project,
|
|
197
|
+
entries: group,
|
|
198
|
+
rebuild: async () => {
|
|
199
|
+
for (const entry of group)
|
|
200
|
+
await buildEntry(entry);
|
|
201
|
+
checkShared();
|
|
202
|
+
},
|
|
203
|
+
}));
|
|
141
204
|
// The sources as the first build reads them: the watcher may report their edits late.
|
|
142
|
-
if (command === "dev")
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
205
|
+
if (command === "dev") {
|
|
206
|
+
for (const group of groups)
|
|
207
|
+
seen.prime([group.project.contentRoot, group.project.configPath]);
|
|
208
|
+
}
|
|
209
|
+
for (const entry of entries)
|
|
210
|
+
await buildEntry(entry);
|
|
211
|
+
checkShared();
|
|
212
|
+
devCommand = command === "dev";
|
|
213
|
+
// Each permalink's address, a page that forwards to its heading. One route serves every
|
|
214
|
+
// list, at the path of the first that names anything.
|
|
215
|
+
const lists = entries.flatMap((entry) => readPermalinks(entry.siteRoot) ?? []);
|
|
216
|
+
const served = lists.find(hasPermalinks) ?? lists[0];
|
|
217
|
+
if (served !== undefined) {
|
|
150
218
|
injectRoute({
|
|
151
|
-
pattern: permalinkPattern(
|
|
219
|
+
pattern: permalinkPattern(served.path, config.base),
|
|
152
220
|
entrypoint: new URL("../src/Permalink.astro", import.meta.url),
|
|
153
221
|
prerender: true,
|
|
154
222
|
});
|
|
155
223
|
}
|
|
156
224
|
}
|
|
225
|
+
const projectHome = (entry) => homeRoute(entry.project.consumer.basePath, config.trailingSlash);
|
|
157
226
|
// Dev serving of `_ascribe/files/`, and of the plain output for agents; the build copies them in `astro:build:done`.
|
|
158
227
|
updateConfig({
|
|
159
228
|
...(options.codeTitles === false
|
|
@@ -167,17 +236,21 @@ export default function ascribe(options) {
|
|
|
167
236
|
name: "@ascribed/astro:site",
|
|
168
237
|
resolveId: (id) => (id === SITE_MODULE ? `\0${SITE_MODULE}` : undefined),
|
|
169
238
|
load: (id) => id === `\0${SITE_MODULE}`
|
|
170
|
-
? `export const siteRoot = ${JSON.stringify(siteRoot)};\n` +
|
|
171
|
-
`export const home = ${JSON.stringify(homeRoute(config.base, config.trailingSlash))}
|
|
239
|
+
? `export const siteRoot = ${JSON.stringify(entries[0]?.siteRoot ?? "")};\n` +
|
|
240
|
+
`export const home = ${JSON.stringify(homeRoute(config.base, config.trailingSlash))};\n` +
|
|
241
|
+
`export const collections = ${JSON.stringify(named ? Object.fromEntries(entries.map((e) => [e.name, e.siteRoot])) : {})};\n` +
|
|
242
|
+
`export const permalinks = ${JSON.stringify(entries.map((e) => ({ siteRoot: e.siteRoot, home: projectHome(e) })))};`
|
|
172
243
|
: undefined,
|
|
173
244
|
},
|
|
174
245
|
{
|
|
175
246
|
name: "@ascribed/astro:files",
|
|
176
247
|
configureServer(server) {
|
|
177
|
-
const
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
248
|
+
for (const entry of entries) {
|
|
249
|
+
const base = entry.project.consumer.basePath;
|
|
250
|
+
server.middlewares.use(filesMiddleware(entry.siteRoot, base));
|
|
251
|
+
if (entry.agentsRoot !== undefined)
|
|
252
|
+
server.middlewares.use(agentsMiddleware(entry.agentsRoot, base));
|
|
253
|
+
}
|
|
181
254
|
},
|
|
182
255
|
},
|
|
183
256
|
],
|
|
@@ -185,73 +258,91 @@ export default function ascribe(options) {
|
|
|
185
258
|
});
|
|
186
259
|
},
|
|
187
260
|
"astro:server:setup": ({ server, refreshContent, logger, toolbar }) => {
|
|
188
|
-
if (
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
261
|
+
if (!devCommand || !routing)
|
|
262
|
+
return;
|
|
263
|
+
if (!refreshContent)
|
|
264
|
+
throw new Error("@ascribed/astro: this Astro version does not support refreshContent.");
|
|
265
|
+
devHttps = Boolean(server.config.server.https);
|
|
266
|
+
for (const group of groups) {
|
|
267
|
+
group.builds = watchDev({
|
|
194
268
|
server,
|
|
195
269
|
seen,
|
|
196
270
|
refreshContent: () => refreshContent({}),
|
|
197
271
|
logger,
|
|
198
|
-
project,
|
|
199
|
-
astro:
|
|
200
|
-
|
|
201
|
-
rebuild,
|
|
202
|
-
onBuilt: () =>
|
|
272
|
+
project: group.project,
|
|
273
|
+
astro: routing,
|
|
274
|
+
builds: group.entries.map((entry) => entry.build),
|
|
275
|
+
rebuild: group.rebuild,
|
|
276
|
+
onBuilt: () => {
|
|
277
|
+
if (reviewed !== undefined && group.entries.includes(reviewed))
|
|
278
|
+
review?.rebuilt();
|
|
279
|
+
},
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
const group = groups.find((g) => reviewed !== undefined && g.entries.includes(reviewed));
|
|
283
|
+
if (reviewed !== undefined && group?.builds !== undefined && binary !== undefined) {
|
|
284
|
+
const entry = reviewed;
|
|
285
|
+
const builds = group.builds;
|
|
286
|
+
const run = { binary, configPath: entry.project.configPath, cwd: entry.project.dir };
|
|
287
|
+
const jsonRoot = path.join(path.dirname(entry.siteRoot), "json");
|
|
288
|
+
review = new ReviewServer({
|
|
289
|
+
channel: toolbar,
|
|
290
|
+
logger,
|
|
291
|
+
build: entry.build,
|
|
292
|
+
contentRoot: entry.project.contentRoot,
|
|
293
|
+
channelProblem: channelProblem(server.config),
|
|
294
|
+
diff: (base) => runDiff({ ...run, build: entry.build, base }),
|
|
295
|
+
prompt: (page, base) => runPrompt({ ...run, build: entry.build, base, path: page }),
|
|
296
|
+
projectDir: entry.project.dir,
|
|
297
|
+
connect: async () => (await import("./review/github.js")).connect(entry.project.dir),
|
|
298
|
+
writeRoutes: () => builds.inTurn(async () => {
|
|
299
|
+
await runBuild({ ...run, build: entry.build, outputs: ["json"] });
|
|
300
|
+
}),
|
|
301
|
+
readRoutes: () => readRoutes(jsonRoot),
|
|
203
302
|
});
|
|
204
|
-
if (reviewing && binary !== undefined) {
|
|
205
|
-
const found = binary;
|
|
206
|
-
const run = { binary: found, configPath: project.configPath, cwd: project.dir };
|
|
207
|
-
const jsonRoot = path.join(path.dirname(siteRoot), "json");
|
|
208
|
-
review = new ReviewServer({
|
|
209
|
-
channel: toolbar,
|
|
210
|
-
logger,
|
|
211
|
-
build: options.build,
|
|
212
|
-
contentRoot: project.contentRoot,
|
|
213
|
-
channelProblem: channelProblem(server.config),
|
|
214
|
-
diff: (base) => runDiff({ ...run, build: options.build, base }),
|
|
215
|
-
prompt: (page, base) => runPrompt({ ...run, build: options.build, base, path: page }),
|
|
216
|
-
projectDir: project.dir,
|
|
217
|
-
connect: async () => (await import("./review/github.js")).connect(project.dir),
|
|
218
|
-
writeRoutes: () => builds.inTurn(async () => {
|
|
219
|
-
await runBuild({ ...run, build: options.build, outputs: ["json"] });
|
|
220
|
-
}),
|
|
221
|
-
readRoutes: () => readRoutes(jsonRoot),
|
|
222
|
-
});
|
|
223
|
-
}
|
|
224
303
|
}
|
|
225
304
|
},
|
|
226
305
|
"astro:server:start": ({ address, logger }) => {
|
|
227
306
|
review?.listening(address.address);
|
|
228
|
-
if (!
|
|
307
|
+
if (!devCommand)
|
|
229
308
|
return;
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
309
|
+
// Each project's folder gets its own file, with its own address: its base path.
|
|
310
|
+
for (const group of groups) {
|
|
311
|
+
const entry = group.entries[0];
|
|
312
|
+
const dir = group.project.dir;
|
|
313
|
+
try {
|
|
314
|
+
writeDevFile(dir, {
|
|
315
|
+
url: siteUrl(address, { https: devHttps, base: entry.project.consumer.basePath }),
|
|
316
|
+
build: entry.build,
|
|
317
|
+
pid: process.pid,
|
|
318
|
+
});
|
|
319
|
+
// Vite exits on a signal before `astro:server:done` runs.
|
|
320
|
+
process.once("exit", () => removeDevFile(dir, process.pid));
|
|
321
|
+
}
|
|
322
|
+
catch (error) {
|
|
323
|
+
logger.warn(`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)}`);
|
|
324
|
+
}
|
|
242
325
|
}
|
|
243
326
|
},
|
|
244
327
|
"astro:server:done": () => {
|
|
245
328
|
review?.dispose();
|
|
246
329
|
review = undefined;
|
|
247
|
-
if (
|
|
248
|
-
|
|
330
|
+
if (devCommand)
|
|
331
|
+
for (const group of groups)
|
|
332
|
+
removeDevFile(group.project.dir, process.pid);
|
|
249
333
|
},
|
|
250
334
|
"astro:build:done": async ({ dir, logger }) => {
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
335
|
+
const base = routing?.base ?? "/";
|
|
336
|
+
// Entries of one project publish at one base path: the first entry's copies go last, so they win.
|
|
337
|
+
for (const entry of [...entries].reverse()) {
|
|
338
|
+
const folder = folderUnder(entry.project.consumer.basePath, base);
|
|
339
|
+
const where = folder === "" ? "" : ` to ${folder}`;
|
|
340
|
+
if (await copyPublishedFiles(entry.siteRoot, dir, folder))
|
|
341
|
+
logger.info(`copied _ascribe/files/${where}`);
|
|
342
|
+
if (entry.agentsRoot !== undefined &&
|
|
343
|
+
(await copyAgentFiles(entry.agentsRoot, dir, folder)))
|
|
344
|
+
logger.info(`copied llms.txt and each page's Markdown${where}`);
|
|
345
|
+
}
|
|
255
346
|
},
|
|
256
347
|
},
|
|
257
348
|
};
|
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\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { AstroIntegration } from \"astro\";\nimport { findBinary } from \"./binary.js\";\nimport { codeTitles } from \"./code-titles.js\";\nimport { SeenFiles, watchDev } from \"./dev.js\";\nimport { agentsMiddleware, copyAgentFiles, copyPublishedFiles, filesMiddleware } from \"./files.js\";\nimport { permalinkPattern, readPermalinks } from \"./permalinks.js\";\nimport { consumerMismatches, homeRoute, readProject } from \"./project.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\";\n\n/** The virtual module `content.ts` reads the resolved site output root from. */\nconst SITE_MODULE = \"virtual:ascribe/site\";\n\n/** Options of the integration. */\nexport interface AscribeOptions {\n /** The build whose site output is the collection (a name in `ascribe.toml`). */\n build: string;\n /** The directory holding `ascribe.toml`, relative to the Astro root. Default: the root. */\n project?: string;\n /**\n * The `ascribe` binary, relative to the Astro root. Default: `ASCRIBE_BIN`, then\n * the platform binary installed with `@ascribed/cli`.\n */\n binary?: string;\n /**\n * Mark each block of the site output with the source lines it came from\n * (source anchors), for review: `\"dev\"` in `astro dev` only, `true` always.\n * Default: `false`, though `review` has them in `astro dev`.\n */\n anchors?: boolean | \"dev\";\n /**\n * Review in the site preview: an **Ascribe review** app in `astro dev`'s\n * toolbar, which marks the page's changes and shows the pull request's\n * comments, with source anchors in `astro dev`. Default `true`; `false`\n * removes the app. `astro build` never has it.\n */\n review?: boolean;\n /**\n * Show a code block's title (`title=\"…\"` in its info string, as `@snippet`\n * writes it) above it, with a Shiki transformer that puts the block in a\n * `<figure class=\"code-title\">` with a `<figcaption>`. Default `true`.\n */\n codeTitles?: boolean;\n}\n\n/** The toolbar app's icon: a speech bubble over a page. */\nconst ICON =\n '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M6 3h8l4 4v6\"/><path d=\"M14 3v4h4\"/><path d=\"M6 3v15\"/><path d=\"M11 14h10v6h-6l-3 2v-2h-1z\"/></svg>';\n\n/**\n * Runs `ascribe build`, checks the site's routing, adds the markdown plugin, adds a page for each\n * permalink's address, and serves published files, and, with `[consumer] agents = true`, `llms.txt`\n * and each page's Markdown.\n */\nexport default function ascribe(options: AscribeOptions): AstroIntegration {\n let siteRoot = \"\";\n /** The plain output's root, when the project publishes it for agents. */\n let agentsRoot: string | undefined;\n let devProject: ReturnType<typeof readProject> | undefined;\n let devConfig:\n | {\n base: string;\n trailingSlash: string;\n site: string | undefined;\n }\n | undefined;\n let rebuild: (() => Promise<void>) | undefined;\n /** The dev server's sources as its first build read them. */\n const seen = new SeenFiles();\n let binary: string | undefined;\n let reviewing = false;\n let devHttps = false;\n let review: ReviewServer | undefined;\n return {\n name: \"@ascribed/astro\",\n hooks: {\n \"astro:config:setup\": async ({\n config,\n command,\n logger,\n updateConfig,\n addDevToolbarApp,\n createCodegenDir,\n injectRoute,\n }) => {\n const root = fileURLToPath(config.root);\n const project = readProject(path.resolve(root, options.project ?? \".\"));\n // An unknown build is `ascribe build`'s to report: it knows the implicit `site` build.\n siteRoot = project.siteRoot(options.build);\n if (project.consumer.agents) agentsRoot = project.plainRoot(options.build);\n\n // `ascribe.toml`'s routing must be Astro's, or every link Ascribe writes is wrong.\n const problems = consumerMismatches(project, {\n base: config.base,\n trailingSlash: config.trailingSlash,\n site: config.site,\n });\n if (problems.length > 0) {\n throw new Error(\n `@ascribed/astro: ascribe.toml and astro.config disagree:\\n- ${problems.join(\"\\n- \")}`,\n );\n }\n\n // Where a markdown plugin goes depends on the processor Astro 7.3 runs.\n const processor = config.markdown.processor;\n const pluginLists = processor.options as {\n rehypePlugins?: unknown[];\n hastPlugins?: unknown[];\n };\n if (processor.name === \"satteri\" && pluginLists.hastPlugins !== undefined) {\n pluginLists.hastPlugins.push(satteriAscribeAttributes());\n } else if (processor.name === \"unified\" && pluginLists.rehypePlugins !== undefined) {\n pluginLists.rehypePlugins.push(rehypeAscribeAttributes);\n } else {\n throw new Error(\n `@ascribed/astro: the markdown processor \"${processor.name}\" is not one it can add its plugin to. ` +\n \"Use Astro's default (satteri) or unified(), or add `rehypeAscribeAttributes` to your own.\",\n );\n }\n\n devConfig = {\n base: config.base,\n trailingSlash: config.trailingSlash,\n site: config.site,\n };\n\n reviewing = reviewFor(options.review, command);\n if (reviewing) {\n addDevToolbarApp({\n id: APP_ID,\n name: \"Ascribe review\",\n icon: ICON,\n entrypoint: new URL(\"./toolbar/app.js\", import.meta.url),\n });\n }\n\n if (command !== \"preview\") {\n const found = findBinary({ binary: options.binary, root });\n binary = found;\n // The schema's copy inside the Astro root, for content.config.ts to import.\n const codegen = fileURLToPath(createCodegenDir());\n rebuild = async () => {\n logger.info(`running ${path.basename(found)} build for \"${options.build}\"`);\n const result = await runBuild({\n binary: found,\n configPath: project.configPath,\n build: options.build,\n cwd: project.dir,\n anchors: anchorsFor(options.anchors, command, reviewing),\n outputs: [\n \"site\",\n // `llms.txt` and each page's Markdown, which agents read.\n ...(agentsRoot === undefined ? [] : ([\"plain\"] as const)),\n // While review is on, the JSON output says which page is at each route.\n ...(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 copySchema(siteRoot, codegen);\n };\n // The sources as the first build reads them: the watcher may report their edits late.\n if (command === \"dev\") seen.prime([project.contentRoot, project.configPath]);\n await rebuild();\n if (command === \"dev\") devProject = project;\n\n // Each permalink's address, a page that forwards to its heading.\n const permalinks = readPermalinks(siteRoot);\n if (permalinks !== undefined) {\n injectRoute({\n pattern: permalinkPattern(permalinks.path, config.base),\n entrypoint: new URL(\"../src/Permalink.astro\", import.meta.url),\n prerender: true,\n });\n }\n }\n\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(siteRoot)};\\n` +\n `export const home = ${JSON.stringify(homeRoute(config.base, config.trailingSlash))};`\n : undefined,\n },\n {\n name: \"@ascribed/astro:files\",\n configureServer(server) {\n const base = config.base.endsWith(\"/\") ? config.base : `${config.base}/`;\n server.middlewares.use(filesMiddleware(siteRoot, base));\n if (agentsRoot !== undefined)\n server.middlewares.use(agentsMiddleware(agentsRoot, base));\n },\n },\n ],\n },\n });\n },\n \"astro:server:setup\": ({ server, refreshContent, logger, toolbar }) => {\n if (devProject && rebuild && devConfig) {\n if (!refreshContent)\n throw new Error(\"@ascribed/astro: this Astro version does not support refreshContent.\");\n const project = devProject;\n devHttps = Boolean(server.config.server.https);\n const builds = watchDev({\n server,\n seen,\n refreshContent: () => refreshContent({}),\n logger,\n project,\n astro: devConfig,\n build: options.build,\n rebuild,\n onBuilt: () => review?.rebuilt(),\n });\n if (reviewing && binary !== undefined) {\n const found = binary;\n const run = { binary: found, configPath: project.configPath, cwd: project.dir };\n const jsonRoot = path.join(path.dirname(siteRoot), \"json\");\n review = new ReviewServer({\n channel: toolbar as ToolbarChannel,\n logger,\n build: options.build,\n contentRoot: project.contentRoot,\n channelProblem: channelProblem(server.config),\n diff: (base) => runDiff({ ...run, build: options.build, base }),\n prompt: (page, base) => runPrompt({ ...run, build: options.build, base, path: page }),\n projectDir: project.dir,\n connect: async () => (await import(\"./review/github.js\")).connect(project.dir),\n writeRoutes: () =>\n builds.inTurn(async () => {\n await runBuild({ ...run, build: options.build, outputs: [\"json\"] });\n }),\n readRoutes: () => readRoutes(jsonRoot),\n });\n }\n }\n },\n \"astro:server:start\": ({ address, logger }) => {\n review?.listening(address.address);\n if (!devProject || !devConfig) return;\n const dir = devProject.dir;\n try {\n writeDevFile(dir, {\n url: siteUrl(address, { https: devHttps, base: devConfig.base }),\n build: options.build,\n pid: process.pid,\n });\n // Vite exits on a signal before `astro:server:done` runs.\n process.once(\"exit\", () => removeDevFile(dir, process.pid));\n } catch (error) {\n logger.warn(\n `couldn't write .ascribe/dev.json, which the editor's Open Site Preview reads: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n },\n \"astro:server:done\": () => {\n review?.dispose();\n review = undefined;\n if (devProject) removeDevFile(devProject.dir, process.pid);\n },\n \"astro:build:done\": async ({ dir, logger }) => {\n if (await copyPublishedFiles(siteRoot, dir)) logger.info(\"copied _ascribe/files/\");\n if (agentsRoot !== undefined && (await copyAgentFiles(agentsRoot, dir)))\n logger.info(\"copied llms.txt and each page's Markdown\");\n },\n },\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,SAAS;AACT,EAAE;AACF,wBAAwB;AACxB,2CAA2C;AAC3C,kCAAkC;AAClC,oFAAoF;AACpF,kDAAkD;AAClD,QAAQ;AACR,EAAE;AACF,6BAA6B;AAC7B,sDAAsD;AACtD,iEAAiE;AACjE,iFAAiF;AACjF,mFAAmF;AACnF,6EAA6E;AAC7E,0FAA0F;AAC1F,EAAE;AACF,gBAAgB;AAChB,+FAA+F;AAC/F,gGAAgG;AAChG,EAAE;AACF,2BAA2B;AAC3B,0GAA0G;AAC1G,EAAE;AACF,wFAAwF;AACxF,EAAE;AACF,cAAc;AACd,kBAAkB;AAClB,6DAA6D;AAC7D,0DAA0D;AAC1D,SAAS;AACT,sBAAsB;AACtB,OAAO;AACP,gDAAgD;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAkB,MAAM,UAAU,CAAC;AAC/D,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,WAAW,GACZ,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAClF,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC1E,OAAO,EACL,eAAe,EACf,YAAY,EACZ,oBAAoB,EACpB,iBAAiB,GAGlB,MAAM,eAAe,CAAC;AACvB,OAAO,uBAAuB,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAC3E,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,YAAY,EAAuB,MAAM,oBAAoB,CAAC;AACvF,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACxE,OAAO,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,OAAO,EAAE,OAAO,IAAI,uBAAuB,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAGxD,iFAAiF;AACjF,MAAM,WAAW,GAAG,sBAAsB,CAAC;AAmD3C,2DAA2D;AAC3D,MAAM,IAAI,GACR,8QAA8Q,CAAC;AAmBjR,SAAS,IAAI,CAAC,QAAkB,EAAE,IAAY;IAC5C,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,IAAI,QAAQ,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AACpG,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,OAAO,UAAU,OAAO,CAAC,OAAuB;IACrD,+EAA+E;IAC/E,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,KAAK,SAAS,CAAC;IAC7C,IAAI,OAAO,GAAY,EAAE,CAAC;IAC1B,IAAI,MAAM,GAAe,EAAE,CAAC;IAC5B,IAAI,OAMS,CAAC;IACd,6DAA6D;IAC7D,MAAM,IAAI,GAAG,IAAI,SAAS,EAAE,CAAC;IAC7B,IAAI,MAA0B,CAAC;IAC/B,IAAI,QAA2B,CAAC;IAChC,IAAI,UAAU,GAAG,KAAK,CAAC;IACvB,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,IAAI,MAAgC,CAAC;IACrC,OAAO;QACL,IAAI,EAAE,iBAAiB;QACvB,KAAK,EAAE;YACL,oBAAoB,EAAE,KAAK,EAAE,EAC3B,MAAM,EACN,OAAO,EACP,MAAM,EACN,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAChB,WAAW,GACZ,EAAE,EAAE;gBACH,MAAM,IAAI,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBACxC,MAAM,IAAI,GAAmB,OAAO,CAAC,QAAQ,IAAI;oBAC/C;wBACE,IAAI,EAAE,EAAE;wBACR,KAAK,EAAE,OAAO,CAAC,KAAK;wBACpB,GAAG,CAAC,OAAO,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC;qBACvE;iBACF,CAAC;gBACF,IAAI,KAAK;oBAAE,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,gCAAgC,CAAC,CAAC;gBACtE,MAAM,OAAO,GAAG,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,gBAAgB,EAAE,CAAC,CAAC;gBAC/E,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;oBAC3B,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,OAAO,IAAI,GAAG,CAAC,CAAC,CAAC;oBACtE,OAAO;wBACL,IAAI,EAAE,KAAK,CAAC,IAAI;wBAChB,KAAK,EAAE,KAAK,CAAC,KAAK;wBAClB,OAAO;wBACP,uFAAuF;wBACvF,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC;wBACvC,UAAU,EAAE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS;wBAChF,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO;qBAC5D,CAAC;gBACJ,CAAC,CAAC,CAAC;gBAEH,mFAAmF;gBACnF,MAAM,KAAK,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,aAAa,EAAE,MAAM,CAAC,aAAa,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;gBAC5F,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;oBAC5B,IAAI,CACF,kBAAkB,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,EACxC,KAAK;wBACH,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,4CAA4C;wBAC5D,CAAC,CAAC,wCAAwC,CAC7C,CAAC;gBACJ,CAAC;gBACD,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE,gCAAgC,CAAC,CAAC;gBAEjE,IAAI,OAAO,OAAO,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;oBAC1F,MAAM,IAAI,KAAK,CACb,sCAAsC,OAAO,CAAC,MAAM,gDAAgD,CACrG,CAAC;gBACJ,CAAC;gBACD,IAAI,SAAS,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;oBACvC,QAAQ;wBACN,OAAO,OAAO,CAAC,MAAM,KAAK,QAAQ;4BAChC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC;4BAChD,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;gBACnB,CAAC;gBAED,wEAAwE;gBACxE,MAAM,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC;gBAC5C,MAAM,WAAW,GAAG,SAAS,CAAC,OAG7B,CAAC;gBACF,IAAI,SAAS,CAAC,IAAI,KAAK,SAAS,IAAI,WAAW,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;oBAC1E,WAAW,CAAC,WAAW,CAAC,IAAI,CAAC,wBAAwB,EAAE,CAAC,CAAC;gBAC3D,CAAC;qBAAM,IAAI,SAAS,CAAC,IAAI,KAAK,SAAS,IAAI,WAAW,CAAC,aAAa,KAAK,SAAS,EAAE,CAAC;oBACnF,WAAW,CAAC,aAAa,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;gBAC1D,CAAC;qBAAM,CAAC;oBACN,MAAM,IAAI,KAAK,CACb,4CAA4C,SAAS,CAAC,IAAI,yCAAyC;wBACjG,2FAA2F,CAC9F,CAAC;gBACJ,CAAC;gBAED,OAAO,GAAG,KAAK,CAAC;gBAEhB,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;oBAC3B,gBAAgB,CAAC;wBACf,EAAE,EAAE,MAAM;wBACV,IAAI,EAAE,gBAAgB;wBACtB,IAAI,EAAE,IAAI;wBACV,UAAU,EAAE,IAAI,GAAG,CAAC,kBAAkB,EAAE,OAAO,IAAI,CAAC,GAAG,CAAC;qBACzD,CAAC,CAAC;gBACL,CAAC;gBAED,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;oBAC1B,MAAM,KAAK,GAAG,UAAU,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;oBAC3D,MAAM,GAAG,KAAK,CAAC;oBACf,MAAM,UAAU,GAAG,KAAK,EAAE,KAAY,EAAE,EAAE;wBACxC,MAAM,CAAC,IAAI,CACT,WAAW,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,eAAe,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAC/F,CAAC;wBACF,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC;4BAC5B,MAAM,EAAE,KAAK;4BACb,UAAU,EAAE,KAAK,CAAC,OAAO,CAAC,UAAU;4BACpC,KAAK,EAAE,KAAK,CAAC,KAAK;4BAClB,GAAG,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG;4BACtB,OAAO,EAAE,UAAU,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,KAAK,QAAQ,CAAC;4BACjE,OAAO,EAAE;gCACP,MAAM;gCACN,0DAA0D;gCAC1D,GAAG,CAAC,KAAK,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAE,CAAC,OAAO,CAAW,CAAC;gCAC/D,wEAAwE;gCACxE,GAAG,CAAC,KAAK,KAAK,QAAQ,IAAI,MAAM,EAAE,MAAM,CAAC,CAAC,CAAE,CAAC,MAAM,CAAW,CAAC,CAAC,CAAC,EAAE,CAAC;6BACrE;yBACF,CAAC,CAAC;wBACH,IAAI,WAAW,CAAC,MAAM,CAAC,WAAW,CAAC;4BAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;6BAChE,IAAI,MAAM,CAAC,WAAW,KAAK,EAAE;4BAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;wBACpE,IAAI,MAAM,CAAC,OAAO,KAAK,EAAE;4BAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;wBACvD,4EAA4E;wBAC5E,SAAS,CAAC,KAAK,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;wBAChD,UAAU,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;oBAC9C,CAAC,CAAC;oBACF,iEAAiE;oBACjE,MAAM,WAAW,GAAG,GAAG,EAAE;wBACvB,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;4BAAE,OAAO;wBAC/B,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;4BACtC,GAAG,KAAK;4BACR,OAAO,EAAE,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;yBACxC,CAAC,CAAC,CAAC;wBACJ,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE,gCAAgC,CAAC,CAAC;wBACjE,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC,EAAE,6CAA6C,CAAC,CAAC;wBACnF,IAAI,CACF,iBAAiB,CACf,OAAO,EACP,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CACvD,EACD,gDAAgD,CACjD,CAAC;oBACJ,CAAC,CAAC;oBACF,qEAAqE;oBACrE,MAAM,KAAK,GAAG,IAAI,GAAG,EAAmB,CAAC;oBACzC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;wBAC5B,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;oBACjF,CAAC;oBACD,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;wBAC3C,OAAO,EAAG,KAAK,CAAC,CAAC,CAAW,CAAC,OAAO;wBACpC,OAAO,EAAE,KAAK;wBACd,OAAO,EAAE,KAAK,IAAI,EAAE;4BAClB,KAAK,MAAM,KAAK,IAAI,KAAK;gCAAE,MAAM,UAAU,CAAC,KAAK,CAAC,CAAC;4BACnD,WAAW,EAAE,CAAC;wBAChB,CAAC;qBACF,CAAC,CAAC,CAAC;oBACJ,sFAAsF;oBACtF,IAAI,OAAO,KAAK,KAAK,EAAE,CAAC;wBACtB,KAAK,MAAM,KAAK,IAAI,MAAM;4BACxB,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;oBACtE,CAAC;oBACD,KAAK,MAAM,KAAK,IAAI,OAAO;wBAAE,MAAM,UAAU,CAAC,KAAK,CAAC,CAAC;oBACrD,WAAW,EAAE,CAAC;oBACd,UAAU,GAAG,OAAO,KAAK,KAAK,CAAC;oBAE/B,wFAAwF;oBACxF,sDAAsD;oBACtD,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;oBAC/E,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC;oBACrD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;wBACzB,WAAW,CAAC;4BACV,OAAO,EAAE,gBAAgB,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC;4BACnD,UAAU,EAAE,IAAI,GAAG,CAAC,wBAAwB,EAAE,OAAO,IAAI,CAAC,GAAG,CAAC;4BAC9D,SAAS,EAAE,IAAI;yBAChB,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;gBAED,MAAM,WAAW,GAAG,CAAC,KAAY,EAAE,EAAE,CACnC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,aAAa,CAAC,CAAC;gBACnE,qHAAqH;gBACrH,YAAY,CAAC;oBACX,GAAG,CAAC,OAAO,CAAC,UAAU,KAAK,KAAK;wBAC9B,CAAC,CAAC,EAAE;wBACJ,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE,WAAW,EAAE,EAAE,YAAY,EAAE,CAAC,UAAU,CAAC,EAAE,EAAE,EAAE,CAAC;oBAClE,IAAI,EAAE;wBACJ,2FAA2F;wBAC3F,GAAG,EAAE,EAAE,UAAU,EAAE,CAAC,iBAAiB,CAAC,EAAE;wBACxC,OAAO,EAAE;4BACP;gCACE,IAAI,EAAE,sBAAsB;gCAC5B,SAAS,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,WAAW,CAAC,CAAC,CAAC,KAAK,WAAW,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;gCACxE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,CACX,EAAE,KAAK,KAAK,WAAW,EAAE;oCACvB,CAAC,CAAC,2BAA2B,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,QAAQ,IAAI,EAAE,CAAC,KAAK;wCAC1E,uBAAuB,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,aAAa,CAAC,CAAC,KAAK;wCACxF,8BAA8B,IAAI,CAAC,SAAS,CAC1C,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAC1E,KAAK;wCACN,6BAA6B,IAAI,CAAC,SAAS,CACzC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CACrE,GAAG;oCACN,CAAC,CAAC,SAAS;6BAChB;4BACD;gCACE,IAAI,EAAE,uBAAuB;gCAC7B,eAAe,CAAC,MAAM;oCACpB,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;wCAC5B,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC;wCAC7C,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,eAAe,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC;wCAC9D,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS;4CAChC,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,gBAAgB,CAAC,KAAK,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC;oCACrE,CAAC;gCACH,CAAC;6BACF;yBACF;qBACF;iBACF,CAAC,CAAC;YACL,CAAC;YACD,oBAAoB,EAAE,CAAC,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE;gBACpE,IAAI,CAAC,UAAU,IAAI,CAAC,OAAO;oBAAE,OAAO;gBACpC,IAAI,CAAC,cAAc;oBACjB,MAAM,IAAI,KAAK,CAAC,sEAAsE,CAAC,CAAC;gBAC1F,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAC/C,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;oBAC3B,KAAK,CAAC,MAAM,GAAG,QAAQ,CAAC;wBACtB,MAAM;wBACN,IAAI;wBACJ,cAAc,EAAE,GAAG,EAAE,CAAC,cAAc,CAAC,EAAE,CAAC;wBACxC,MAAM;wBACN,OAAO,EAAE,KAAK,CAAC,OAAO;wBACtB,KAAK,EAAE,OAAO;wBACd,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC;wBACjD,OAAO,EAAE,KAAK,CAAC,OAAO;wBACtB,OAAO,EAAE,GAAG,EAAE;4BACZ,IAAI,QAAQ,KAAK,SAAS,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC;gCAAE,MAAM,EAAE,OAAO,EAAE,CAAC;wBACpF,CAAC;qBACF,CAAC,CAAC;gBACL,CAAC;gBACD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,KAAK,SAAS,IAAI,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;gBACzF,IAAI,QAAQ,KAAK,SAAS,IAAI,KAAK,EAAE,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;oBAClF,MAAM,KAAK,GAAG,QAAQ,CAAC;oBACvB,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;oBAC5B,MAAM,GAAG,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,GAAG,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;oBACrF,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,CAAC;oBACjE,MAAM,GAAG,IAAI,YAAY,CAAC;wBACxB,OAAO,EAAE,OAAyB;wBAClC,MAAM;wBACN,KAAK,EAAE,KAAK,CAAC,KAAK;wBAClB,WAAW,EAAE,KAAK,CAAC,OAAO,CAAC,WAAW;wBACtC,cAAc,EAAE,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC;wBAC7C,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,GAAG,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC;wBAC7D,MAAM,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,GAAG,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;wBACnF,UAAU,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG;wBAC7B,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;wBACpF,WAAW,EAAE,GAAG,EAAE,CAChB,MAAM,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE;4BACvB,MAAM,QAAQ,CAAC,EAAE,GAAG,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;wBACpE,CAAC,CAAC;wBACJ,UAAU,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC;qBACvC,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YACD,oBAAoB,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE;gBAC5C,MAAM,EAAE,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;gBACnC,IAAI,CAAC,UAAU;oBAAE,OAAO;gBACxB,gFAAgF;gBAChF,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;oBAC3B,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAU,CAAC;oBACxC,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;oBAC9B,IAAI,CAAC;wBACH,YAAY,CAAC,GAAG,EAAE;4BAChB,GAAG,EAAE,OAAO,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;4BACjF,KAAK,EAAE,KAAK,CAAC,KAAK;4BAClB,GAAG,EAAE,OAAO,CAAC,GAAG;yBACjB,CAAC,CAAC;wBACH,0DAA0D;wBAC1D,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;oBAC9D,CAAC;oBAAC,OAAO,KAAK,EAAE,CAAC;wBACf,MAAM,CAAC,IAAI,CACT,kBAAkB,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,mBAAmB,iDAAiD,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAC5M,CAAC;oBACJ,CAAC;gBACH,CAAC;YACH,CAAC;YACD,mBAAmB,EAAE,GAAG,EAAE;gBACxB,MAAM,EAAE,OAAO,EAAE,CAAC;gBAClB,MAAM,GAAG,SAAS,CAAC;gBACnB,IAAI,UAAU;oBAAE,KAAK,MAAM,KAAK,IAAI,MAAM;wBAAE,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;YAC5F,CAAC;YACD,kBAAkB,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE;gBAC5C,MAAM,IAAI,GAAG,OAAO,EAAE,IAAI,IAAI,GAAG,CAAC;gBAClC,kGAAkG;gBAClG,KAAK,MAAM,KAAK,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;oBAC3C,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;oBAClE,MAAM,KAAK,GAAG,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,MAAM,EAAE,CAAC;oBACnD,IAAI,MAAM,kBAAkB,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,EAAE,MAAM,CAAC;wBACvD,MAAM,CAAC,IAAI,CAAC,yBAAyB,KAAK,EAAE,CAAC,CAAC;oBAChD,IACE,KAAK,CAAC,UAAU,KAAK,SAAS;wBAC9B,CAAC,MAAM,cAAc,CAAC,KAAK,CAAC,UAAU,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;wBAErD,MAAM,CAAC,IAAI,CAAC,2CAA2C,KAAK,EAAE,CAAC,CAAC;gBACpE,CAAC;YACH,CAAC;SACF;KACF,CAAC;AACJ,CAAC","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"]}
|
package/dist/permalinks.d.ts
CHANGED
|
@@ -31,7 +31,13 @@ export type Forwarding = {
|
|
|
31
31
|
dimensions: Record<string, string[]>;
|
|
32
32
|
} | {
|
|
33
33
|
reason: string;
|
|
34
|
+
home?: string;
|
|
34
35
|
};
|
|
36
|
+
/** A build's site output whose list the route serves, and the route of its project's root. */
|
|
37
|
+
export interface PermalinkSource {
|
|
38
|
+
siteRoot: string;
|
|
39
|
+
home: string;
|
|
40
|
+
}
|
|
35
41
|
/** The list's text in a build's site output, or `undefined` when there isn't one. */
|
|
36
42
|
export declare function permalinksText(siteRoot: string): string | undefined;
|
|
37
43
|
/** The list in a build's site output, or `undefined` when there isn't one. */
|
|
@@ -44,11 +50,23 @@ export declare function readPermalinks(siteRoot: string): PermalinkList | undefi
|
|
|
44
50
|
export declare function permalinkPattern(listPath: string, base: string): string;
|
|
45
51
|
/**
|
|
46
52
|
* `getStaticPaths` for the route: one page for each permalink in the site
|
|
47
|
-
*
|
|
53
|
+
* outputs' lists, and one for each retired permalink they list as removed,
|
|
54
|
+
* whose page links to its project's root. A name in more than one list gets
|
|
55
|
+
* the first's page; the integration refuses one that two projects declare.
|
|
48
56
|
*/
|
|
49
|
-
export declare function forwardingPaths(
|
|
57
|
+
export declare function forwardingPaths(sources: string | readonly PermalinkSource[]): {
|
|
50
58
|
params: {
|
|
51
59
|
id: string;
|
|
52
60
|
};
|
|
53
61
|
props: Forwarding;
|
|
54
62
|
}[];
|
|
63
|
+
/** Whether a list names anything: a permalink, or a retired one it lists as removed. */
|
|
64
|
+
export declare function hasPermalinks(list: PermalinkList): boolean;
|
|
65
|
+
/**
|
|
66
|
+
* The list a site's not-found page explains addresses from, and the route of
|
|
67
|
+
* its project's root: the first that has a permalink, or else the first list.
|
|
68
|
+
*/
|
|
69
|
+
export declare function servedList(sources: readonly PermalinkSource[]): {
|
|
70
|
+
path: string;
|
|
71
|
+
home: string;
|
|
72
|
+
} | undefined;
|