@lupinum/ginko-content 1.0.0-beta.4 → 1.0.0-beta.5
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 +3 -3
- package/dist/module.d.mts +11 -2
- package/dist/module.json +1 -1
- package/dist/module.mjs +30 -16
- package/dist/runtime/server/api/agent-raw.js +7 -3
- package/dist/runtime/server/plugins/agent-errors.js +5 -8
- package/dist/types/module.d.ts +11 -2
- package/dist/web-types.json +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
</p>
|
|
16
16
|
|
|
17
17
|
> [!WARNING]
|
|
18
|
-
> Version `1.0.0-beta.
|
|
18
|
+
> Version `1.0.0-beta.5` is a prerelease. Install it from npm's `next`
|
|
19
19
|
> channel. The stable `0.3` line remains on `latest`.
|
|
20
20
|
|
|
21
21
|
## Why use this package?
|
|
@@ -40,13 +40,13 @@ output.
|
|
|
40
40
|
Use the Nuxt CLI:
|
|
41
41
|
|
|
42
42
|
```bash
|
|
43
|
-
npx nuxi module add @lupinum/ginko-content@1.0.0-beta.
|
|
43
|
+
npx nuxi module add @lupinum/ginko-content@1.0.0-beta.5
|
|
44
44
|
```
|
|
45
45
|
|
|
46
46
|
Or install and register the module by hand:
|
|
47
47
|
|
|
48
48
|
```bash
|
|
49
|
-
pnpm add @lupinum/ginko-content@1.0.0-beta.
|
|
49
|
+
pnpm add @lupinum/ginko-content@1.0.0-beta.5
|
|
50
50
|
```
|
|
51
51
|
|
|
52
52
|
```ts
|
package/dist/module.d.mts
CHANGED
|
@@ -850,8 +850,17 @@ type ContentLinksOptions = Record<string, Record<string, ContentLinkRouteTarget>
|
|
|
850
850
|
interface ContentAgentRouteOptions {
|
|
851
851
|
routes?: boolean;
|
|
852
852
|
linkHeaders?: boolean;
|
|
853
|
-
|
|
854
|
-
|
|
853
|
+
/**
|
|
854
|
+
* Select static page delivery or request-time Nitro negotiation.
|
|
855
|
+
*
|
|
856
|
+
* `static` prerenders public pages and keeps raw Markdown as the canonical
|
|
857
|
+
* agent representation. `runtime` lets Nitro crawl pages to retain their
|
|
858
|
+
* data dependencies, then removes the generated HTML so Nitro can negotiate
|
|
859
|
+
* each page request.
|
|
860
|
+
*
|
|
861
|
+
* @default 'static'
|
|
862
|
+
*/
|
|
863
|
+
delivery?: 'static' | 'runtime';
|
|
855
864
|
}
|
|
856
865
|
interface ModuleOptions {
|
|
857
866
|
api: {
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { addTypeTemplate, addImports, addServerImports, addComponentsDir, getLayerDirectories, addPlugin, addServerHandler, hasNuxtModule, defineNuxtModule, createResolver, useLogger, addTemplate, resolvePath } from '@nuxt/kit';
|
|
2
2
|
import { readFile, readdir, rm } from 'node:fs/promises';
|
|
3
|
-
import { join as join$1, basename, resolve as resolve$1, dirname, isAbsolute as isAbsolute$1 } from 'node:path';
|
|
3
|
+
import { join as join$1, basename, resolve as resolve$1, dirname, relative as relative$1, isAbsolute as isAbsolute$1 } from 'node:path';
|
|
4
4
|
import { buildResolvedContentContract } from '../dist/cms-contract/index.js';
|
|
5
5
|
import { writeResolvedContentContractArtifact } from '../dist/cms-contract-node/artifact.js';
|
|
6
6
|
import fs, { existsSync } from 'fs';
|
|
@@ -34,7 +34,7 @@ import { assertCanonicalHighlightOptionNames } from '../dist/parsers/markdown-pl
|
|
|
34
34
|
import { BUILTIN_MARKDOWN_RENDER_CONTRACTS } from '../dist/core/markdown/builtin-render-contracts.js';
|
|
35
35
|
|
|
36
36
|
const name = "@lupinum/ginko-content";
|
|
37
|
-
const version = "1.0.0-beta.
|
|
37
|
+
const version = "1.0.0-beta.5";
|
|
38
38
|
const peerDependencies = {
|
|
39
39
|
nuxt: ">=4.5.1 <5"};
|
|
40
40
|
|
|
@@ -439,15 +439,13 @@ const normalizeAgentRouteOptions = (options) => {
|
|
|
439
439
|
return {
|
|
440
440
|
routes: false,
|
|
441
441
|
linkHeaders: false,
|
|
442
|
-
|
|
443
|
-
prerender: false
|
|
442
|
+
delivery: "static"
|
|
444
443
|
};
|
|
445
444
|
}
|
|
446
445
|
return {
|
|
447
446
|
routes: options.agent?.routes !== false,
|
|
448
447
|
linkHeaders: options.agent?.linkHeaders !== false,
|
|
449
|
-
|
|
450
|
-
prerender: options.agent?.prerender !== false
|
|
448
|
+
delivery: options.agent?.delivery || "static"
|
|
451
449
|
};
|
|
452
450
|
};
|
|
453
451
|
|
|
@@ -540,7 +538,7 @@ const registerContentServerHandlers = (nuxt, options, resolveRuntimeModule, buil
|
|
|
540
538
|
handler: resolveRuntimeModule("./server/api/agent-raw.js")
|
|
541
539
|
});
|
|
542
540
|
}
|
|
543
|
-
if (agent.
|
|
541
|
+
if (agent.delivery === "runtime") {
|
|
544
542
|
addServerHandler({
|
|
545
543
|
middleware: true,
|
|
546
544
|
handler: resolveRuntimeModule("./server/middleware/agent-markdown.js")
|
|
@@ -1173,7 +1171,7 @@ ${details}` : "")
|
|
|
1173
1171
|
}
|
|
1174
1172
|
}
|
|
1175
1173
|
const agentRoutes = normalizeAgentRouteOptions(options);
|
|
1176
|
-
if (agentRoutes.routes &&
|
|
1174
|
+
if (agentRoutes.routes && appContentConfig.agent) {
|
|
1177
1175
|
const defaultLocale = resolvedI18n.defaultLocale;
|
|
1178
1176
|
const locales = resolvedI18n.locales;
|
|
1179
1177
|
const llmsRoutes = [
|
|
@@ -1306,17 +1304,33 @@ const registerContentNitroIntegrationHooks = (nitroConfig, options, contentConte
|
|
|
1306
1304
|
};
|
|
1307
1305
|
nitroConfig.hooks ||= {};
|
|
1308
1306
|
const usesFilesystemProviderAtRegistration = !contentContext.provider || contentContext.provider === "filesystem";
|
|
1309
|
-
if (usesFilesystemProviderAtRegistration) {
|
|
1307
|
+
if (usesFilesystemProviderAtRegistration || options.removePrerenderedHtml) {
|
|
1310
1308
|
let prerenderingPublicDir;
|
|
1311
1309
|
appendHook(nitroConfig.hooks, "prerender:init", async (nitro) => {
|
|
1312
1310
|
prerenderingPublicDir = nitro.options.output.publicDir;
|
|
1313
1311
|
});
|
|
1314
|
-
appendHook(nitroConfig.hooks, "prerender:done", async () => {
|
|
1312
|
+
appendHook(nitroConfig.hooks, "prerender:done", async (result) => {
|
|
1315
1313
|
if (!prerenderingPublicDir) {
|
|
1316
1314
|
return;
|
|
1317
1315
|
}
|
|
1318
|
-
const
|
|
1319
|
-
|
|
1316
|
+
const publicDir = prerenderingPublicDir;
|
|
1317
|
+
if (usesFilesystemProviderAtRegistration) {
|
|
1318
|
+
const staleArtifactPath = join$1(publicDir, options.cacheRoute);
|
|
1319
|
+
await rm(staleArtifactPath, { recursive: true, force: true });
|
|
1320
|
+
}
|
|
1321
|
+
if (options.removePrerenderedHtml) {
|
|
1322
|
+
await Promise.all((result.prerenderedRoutes || []).map(async (route) => {
|
|
1323
|
+
if (!route.contentType?.includes("text/html") || !route.fileName) {
|
|
1324
|
+
return;
|
|
1325
|
+
}
|
|
1326
|
+
const artifactPath = resolve$1(publicDir, route.fileName.replace(/^\/+/, ""));
|
|
1327
|
+
const relativeArtifactPath = relative$1(publicDir, artifactPath);
|
|
1328
|
+
if (relativeArtifactPath.startsWith("..") || isAbsolute$1(relativeArtifactPath)) {
|
|
1329
|
+
throw new Error(`[content] refused to remove a prerendered HTML artifact outside publicDir: ${route.fileName}`);
|
|
1330
|
+
}
|
|
1331
|
+
await rm(artifactPath, { recursive: true, force: true });
|
|
1332
|
+
}));
|
|
1333
|
+
}
|
|
1320
1334
|
});
|
|
1321
1335
|
}
|
|
1322
1336
|
if (contentContext.sitemap && contentContext.sitemap.assert?.enabled) {
|
|
@@ -1369,6 +1383,7 @@ const registerContentNitroConfig = ({
|
|
|
1369
1383
|
}) => {
|
|
1370
1384
|
hookNuxtBoundary$1(nuxt, "nitro:config", (nitroConfig) => {
|
|
1371
1385
|
const searchRuntime = getSearchRuntime();
|
|
1386
|
+
const agentRoutes = normalizeAgentRouteOptions(options);
|
|
1372
1387
|
nitroConfig.prerender = nitroConfig.prerender || {};
|
|
1373
1388
|
nitroConfig.prerender.routes = nitroConfig.prerender.routes || [];
|
|
1374
1389
|
const usesFilesystemProvider = !contentContext.provider || contentContext.provider === "filesystem";
|
|
@@ -1432,6 +1447,7 @@ const registerContentNitroConfig = ({
|
|
|
1432
1447
|
}
|
|
1433
1448
|
registerContentNitroIntegrationHooks(nitroConfig, {
|
|
1434
1449
|
cacheRoute,
|
|
1450
|
+
removePrerenderedHtml: agentRoutes.delivery === "runtime" && !("_generate" in nuxt.options && nuxt.options._generate === true),
|
|
1435
1451
|
sitemapPrerenderRoutes: () => contentContext.sitemap === false ? [] : resolveNuxtSitemapPrerenderRoutes(nuxt),
|
|
1436
1452
|
resolveContentContext: () => {
|
|
1437
1453
|
const resolved = getResolvedContentContext();
|
|
@@ -1441,7 +1457,6 @@ const registerContentNitroConfig = ({
|
|
|
1441
1457
|
sitemap: contentContext.sitemap,
|
|
1442
1458
|
provider: contentContext.provider
|
|
1443
1459
|
});
|
|
1444
|
-
const agentRoutes = normalizeAgentRouteOptions(options);
|
|
1445
1460
|
if (agentRoutes.routes && appContentConfig.agent) {
|
|
1446
1461
|
nitroConfig.plugins ||= [];
|
|
1447
1462
|
const agentErrorsPlugin = resolveRuntimeModule("server/plugins/agent-errors.js");
|
|
@@ -1449,7 +1464,7 @@ const registerContentNitroConfig = ({
|
|
|
1449
1464
|
nitroConfig.plugins.push(agentErrorsPlugin);
|
|
1450
1465
|
}
|
|
1451
1466
|
}
|
|
1452
|
-
if (agentRoutes.routes &&
|
|
1467
|
+
if (agentRoutes.routes && appContentConfig.agent) {
|
|
1453
1468
|
nitroConfig.prerender.routes.push("/llms.txt", "/llms-full.txt");
|
|
1454
1469
|
for (const locale of resolvedI18n.locales || []) {
|
|
1455
1470
|
if (locale && locale !== resolvedI18n.defaultLocale) {
|
|
@@ -1658,8 +1673,7 @@ const contentModuleDefaults = {
|
|
|
1658
1673
|
agent: {
|
|
1659
1674
|
routes: true,
|
|
1660
1675
|
linkHeaders: true,
|
|
1661
|
-
|
|
1662
|
-
prerender: true
|
|
1676
|
+
delivery: "static"
|
|
1663
1677
|
},
|
|
1664
1678
|
respectPathCase: false
|
|
1665
1679
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { createError, defineEventHandler } from "h3";
|
|
1
|
+
import { createError, defineEventHandler, setResponseStatus } from "h3";
|
|
2
2
|
import { localeFromAgentPath, resolveMarkdownForPublicRoute } from "../agent-site.js";
|
|
3
|
-
import { setAgentMarkdownHeaders } from "../agent-http.js";
|
|
3
|
+
import { addVaryHeader, renderAgentNotFoundMarkdown, setAgentMarkdownHeaders } from "../agent-http.js";
|
|
4
4
|
import { agentRoutePathFromRawSlug, isUnsafeAgentRoutePath } from "../../../features/agent/agent-paths.js";
|
|
5
5
|
export default defineEventHandler(async (event) => {
|
|
6
6
|
const routePath = agentRoutePathFromRawSlug(event.context.params?.slug);
|
|
@@ -10,8 +10,12 @@ export default defineEventHandler(async (event) => {
|
|
|
10
10
|
const locale = localeFromAgentPath(routePath);
|
|
11
11
|
const page = await resolveMarkdownForPublicRoute(event, routePath, locale);
|
|
12
12
|
if (!page) {
|
|
13
|
-
|
|
13
|
+
setResponseStatus(event, 404, "Markdown page not found");
|
|
14
|
+
addVaryHeader(event, "accept");
|
|
15
|
+
setAgentMarkdownHeaders(event, { noindex: true });
|
|
16
|
+
return renderAgentNotFoundMarkdown(routePath);
|
|
14
17
|
}
|
|
18
|
+
addVaryHeader(event, "accept");
|
|
15
19
|
setAgentMarkdownHeaders(event, { noindex: true });
|
|
16
20
|
return page.markdown;
|
|
17
21
|
});
|
|
@@ -7,17 +7,14 @@ import {
|
|
|
7
7
|
shouldSkipAgentMarkdownPath
|
|
8
8
|
} from "../agent-http.js";
|
|
9
9
|
export default defineNitroPlugin((nitro) => {
|
|
10
|
-
nitro.hooks.hook("
|
|
10
|
+
nitro.hooks.hook("beforeResponse", (event, response) => {
|
|
11
11
|
const { pathname } = getRequestURL(event);
|
|
12
|
-
if (
|
|
12
|
+
if (event.node.res.statusCode !== 404 || shouldSkipAgentMarkdownPath(pathname) || !acceptsMarkdown(event)) {
|
|
13
13
|
return;
|
|
14
14
|
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
"x-robots-tag": "noindex",
|
|
19
|
-
"vary": mergeVaryHeader(response.headers?.vary, "accept")
|
|
20
|
-
};
|
|
15
|
+
event.node.res.setHeader("content-type", "text/markdown; charset=utf-8");
|
|
16
|
+
event.node.res.setHeader("x-robots-tag", "noindex");
|
|
17
|
+
event.node.res.setHeader("vary", mergeVaryHeader(event.node.res.getHeader("vary"), "accept"));
|
|
21
18
|
response.body = renderAgentNotFoundMarkdown(pathname);
|
|
22
19
|
});
|
|
23
20
|
});
|
package/dist/types/module.d.ts
CHANGED
|
@@ -296,8 +296,17 @@ export interface ContentValidationRouteFacts {
|
|
|
296
296
|
export interface ContentAgentRouteOptions {
|
|
297
297
|
routes?: boolean;
|
|
298
298
|
linkHeaders?: boolean;
|
|
299
|
-
|
|
300
|
-
|
|
299
|
+
/**
|
|
300
|
+
* Select static page delivery or request-time Nitro negotiation.
|
|
301
|
+
*
|
|
302
|
+
* `static` prerenders public pages and keeps raw Markdown as the canonical
|
|
303
|
+
* agent representation. `runtime` lets Nitro crawl pages to retain their
|
|
304
|
+
* data dependencies, then removes the generated HTML so Nitro can negotiate
|
|
305
|
+
* each page request.
|
|
306
|
+
*
|
|
307
|
+
* @default 'static'
|
|
308
|
+
*/
|
|
309
|
+
delivery?: 'static' | 'runtime';
|
|
301
310
|
}
|
|
302
311
|
export interface ModuleOptions {
|
|
303
312
|
api: {
|
package/dist/web-types.json
CHANGED