@publish.os/nextjs 0.0.1-alpha.3 → 0.0.1-alpha.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 -9
- package/dist/index.cjs +26 -23
- package/dist/index.js +26 -23
- package/dist/kernel/components/blocks/design-system-preview.cjs +18 -17
- package/dist/kernel/components/blocks/design-system-preview.js +18 -17
- package/dist/kernel/components/blocks/link-playground.cjs +3 -3
- package/dist/kernel/components/blocks/link-playground.js +3 -3
- package/dist/kernel/components/blocks/navbar.cjs +1 -1
- package/dist/kernel/components/blocks/navbar.js +1 -1
- package/dist/kernel/components/blocks/navigation-progress-playground.cjs +2 -2
- package/dist/kernel/components/blocks/navigation-progress-playground.js +2 -2
- package/dist/kernel/components/ui/button-group.cjs +2 -3
- package/dist/kernel/components/ui/button-group.d.cts +2 -2
- package/dist/kernel/components/ui/button-group.d.ts +2 -2
- package/dist/kernel/components/ui/button-group.js +2 -3
- package/dist/kernel/components/ui/button.cjs +4 -12
- package/dist/kernel/components/ui/button.d.cts +3 -4
- package/dist/kernel/components/ui/button.d.ts +3 -4
- package/dist/kernel/components/ui/button.js +4 -12
- package/dist/kernel/components/ui/card.d.cts +1 -1
- package/dist/kernel/components/ui/card.d.ts +1 -1
- package/dist/kernel/components/ui/tag.cjs +104 -0
- package/dist/kernel/components/ui/tag.d.cts +14 -0
- package/dist/kernel/components/ui/tag.d.ts +14 -0
- package/dist/kernel/components/ui/tag.js +76 -0
- package/dist/kernel/components/ui/text.d.cts +1 -1
- package/dist/kernel/components/ui/text.d.ts +1 -1
- package/dist/kernel/components/ui/theme-toggle.cjs +1 -1
- package/dist/kernel/components/ui/theme-toggle.js +1 -1
- package/dist/kernel/defaults.registry.cjs +4 -4
- package/dist/kernel/defaults.registry.d.cts +4 -4
- package/dist/kernel/defaults.registry.d.ts +4 -4
- package/dist/kernel/defaults.registry.js +4 -4
- package/dist/kernel/routes/agent/markdown.cjs +5 -11
- package/dist/kernel/routes/agent/markdown.d.cts +0 -1
- package/dist/kernel/routes/agent/markdown.d.ts +0 -1
- package/dist/kernel/routes/agent/markdown.js +5 -11
- package/dist/kernel/routes/metadata/feed.cjs +17 -21
- package/dist/kernel/routes/metadata/feed.d.cts +0 -1
- package/dist/kernel/routes/metadata/feed.d.ts +0 -1
- package/dist/kernel/routes/metadata/feed.js +17 -21
- package/dist/kernel/routes/metadata/llms.cjs +21 -16
- package/dist/kernel/routes/metadata/llms.d.cts +0 -1
- package/dist/kernel/routes/metadata/llms.d.ts +0 -1
- package/dist/kernel/routes/metadata/llms.js +21 -16
- package/dist/kernel/routes/metadata/robots.cjs +21 -11
- package/dist/kernel/routes/metadata/robots.js +21 -11
- package/dist/kernel/routes/metadata/sitemap.cjs +29 -19
- package/dist/kernel/routes/metadata/sitemap.js +29 -19
- package/package.json +28 -5
- package/release/package.json +23 -0
- package/release/pnpm-lock.yaml +1215 -0
- package/release/release.json +39 -0
- package/dist/kernel/components/ui/badge.cjs +0 -75
- package/dist/kernel/components/ui/badge.d.cts +0 -12
- package/dist/kernel/components/ui/badge.d.ts +0 -12
- package/dist/kernel/components/ui/badge.js +0 -47
|
@@ -11,7 +11,6 @@ type FeedRouteOptions = {
|
|
|
11
11
|
type PrecomputedFeedOutput = {
|
|
12
12
|
body: string;
|
|
13
13
|
contentType: string;
|
|
14
|
-
etag?: string;
|
|
15
14
|
};
|
|
16
15
|
declare function createRssFeedRoute(manifest: ManifestLike, options?: FeedRouteOptions): () => Promise<Response>;
|
|
17
16
|
declare function createAtomFeedRoute(manifest: ManifestLike, options?: FeedRouteOptions): () => Promise<Response>;
|
|
@@ -11,7 +11,6 @@ type FeedRouteOptions = {
|
|
|
11
11
|
type PrecomputedFeedOutput = {
|
|
12
12
|
body: string;
|
|
13
13
|
contentType: string;
|
|
14
|
-
etag?: string;
|
|
15
14
|
};
|
|
16
15
|
declare function createRssFeedRoute(manifest: ManifestLike, options?: FeedRouteOptions): () => Promise<Response>;
|
|
17
16
|
declare function createAtomFeedRoute(manifest: ManifestLike, options?: FeedRouteOptions): () => Promise<Response>;
|
|
@@ -75,22 +75,28 @@ function cachedTextHeaders(contentType, options = {}) {
|
|
|
75
75
|
headers.set("vercel-cdn-cache-control", cdnCacheControl(options.cachePolicy));
|
|
76
76
|
headers.set("content-type", contentType);
|
|
77
77
|
headers.set("x-content-type-options", "nosniff");
|
|
78
|
-
if (options.etag) headers.set("etag", options.etag);
|
|
79
78
|
if (options.noindex) headers.set("x-robots-tag", "noindex");
|
|
80
79
|
return headers;
|
|
81
80
|
}
|
|
82
81
|
function createCachedTextResponse(options) {
|
|
83
82
|
const status = options.status ?? 200;
|
|
84
|
-
const method = options.method ??
|
|
83
|
+
const method = options.method ?? "GET";
|
|
85
84
|
const headers = cachedTextHeaders(options.contentType, options);
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
85
|
+
return new Response(method === "HEAD" ? null : options.body, {
|
|
86
|
+
headers,
|
|
87
|
+
status
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// src/kernel/routes/metadata/canonical-url.ts
|
|
92
|
+
function canonicalUrl(manifest, path) {
|
|
93
|
+
const origin = manifest.site.url?.replace(/\/+$/, "");
|
|
94
|
+
if (!origin) return path;
|
|
95
|
+
try {
|
|
96
|
+
return new URL(path, `${origin}/`).toString();
|
|
97
|
+
} catch {
|
|
98
|
+
return path;
|
|
99
|
+
}
|
|
94
100
|
}
|
|
95
101
|
|
|
96
102
|
// src/kernel/routes/metadata/feed.ts
|
|
@@ -103,15 +109,6 @@ function pageTimestamp(page) {
|
|
|
103
109
|
const timestamp = Date.parse(value);
|
|
104
110
|
return Number.isNaN(timestamp) ? -Infinity : timestamp;
|
|
105
111
|
}
|
|
106
|
-
function canonicalUrl(manifest, path) {
|
|
107
|
-
const origin = manifest.site.url?.replace(/\/+$/, "");
|
|
108
|
-
if (!origin) return path;
|
|
109
|
-
try {
|
|
110
|
-
return new URL(path, `${origin}/`).toString();
|
|
111
|
-
} catch {
|
|
112
|
-
return path;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
112
|
function pageInScope(page, options) {
|
|
116
113
|
if (options.scope === "site" || !options.group) return true;
|
|
117
114
|
if (options.scope === "self") return page.group === options.group;
|
|
@@ -256,8 +253,7 @@ function createPrecomputedFeedRoute(output) {
|
|
|
256
253
|
return function GET() {
|
|
257
254
|
return createCachedTextResponse({
|
|
258
255
|
body: output.body,
|
|
259
|
-
contentType: output.contentType
|
|
260
|
-
etag: output.etag
|
|
256
|
+
contentType: output.contentType
|
|
261
257
|
});
|
|
262
258
|
};
|
|
263
259
|
}
|
|
@@ -102,22 +102,28 @@ function cachedTextHeaders(contentType, options = {}) {
|
|
|
102
102
|
headers.set("vercel-cdn-cache-control", cdnCacheControl(options.cachePolicy));
|
|
103
103
|
headers.set("content-type", contentType);
|
|
104
104
|
headers.set("x-content-type-options", "nosniff");
|
|
105
|
-
if (options.etag) headers.set("etag", options.etag);
|
|
106
105
|
if (options.noindex) headers.set("x-robots-tag", "noindex");
|
|
107
106
|
return headers;
|
|
108
107
|
}
|
|
109
108
|
function createCachedTextResponse(options) {
|
|
110
109
|
const status = options.status ?? 200;
|
|
111
|
-
const method = options.method ??
|
|
110
|
+
const method = options.method ?? "GET";
|
|
112
111
|
const headers = cachedTextHeaders(options.contentType, options);
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
112
|
+
return new Response(method === "HEAD" ? null : options.body, {
|
|
113
|
+
headers,
|
|
114
|
+
status
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// src/kernel/routes/metadata/canonical-url.ts
|
|
119
|
+
function canonicalUrl(manifest, path) {
|
|
120
|
+
const origin = manifest.site.url?.replace(/\/+$/, "");
|
|
121
|
+
if (!origin) return path;
|
|
122
|
+
try {
|
|
123
|
+
return new URL(path, `${origin}/`).toString();
|
|
124
|
+
} catch {
|
|
125
|
+
return path;
|
|
126
|
+
}
|
|
121
127
|
}
|
|
122
128
|
|
|
123
129
|
// src/kernel/routes/metadata/llms.ts
|
|
@@ -146,10 +152,10 @@ async function llmsTxt(manifest, options = {}) {
|
|
|
146
152
|
const visiblePages = options.limit ? pages.slice(0, options.limit) : pages;
|
|
147
153
|
const lines = visiblePages.map((page) => {
|
|
148
154
|
const description = options.includeDescriptions && page.description ? ` - ${page.description}` : "";
|
|
149
|
-
return `- [${page.title}](${page.path})${description}`;
|
|
155
|
+
return `- [${page.title}](${canonicalUrl(manifest, page.path)})${description}`;
|
|
150
156
|
});
|
|
151
157
|
const linkLines = (options.links ?? []).map(
|
|
152
|
-
(link) => `- [${link.title}](${link.path})`
|
|
158
|
+
(link) => `- [${link.title}](${canonicalUrl(manifest, link.path)})`
|
|
153
159
|
);
|
|
154
160
|
const linkSection = linkLines.length ? `
|
|
155
161
|
|
|
@@ -175,8 +181,7 @@ function createPrecomputedLlmsTxtRoute(output) {
|
|
|
175
181
|
return function GET() {
|
|
176
182
|
return createCachedTextResponse({
|
|
177
183
|
body: output.body,
|
|
178
|
-
contentType: "text/plain; charset=utf-8"
|
|
179
|
-
etag: output.etag
|
|
184
|
+
contentType: "text/plain; charset=utf-8"
|
|
180
185
|
});
|
|
181
186
|
};
|
|
182
187
|
}
|
|
@@ -184,8 +189,8 @@ async function llmsFullTxt(manifest, artifacts, options = {}) {
|
|
|
184
189
|
const maxBytes = options.maxBytes ?? DEFAULT_LLMS_FULL_MAX_BYTES;
|
|
185
190
|
const header = `# ${manifest.site.name} Full Content
|
|
186
191
|
|
|
187
|
-
> LLMS index: /llms.txt
|
|
188
|
-
> Sitemap: /sitemap.md
|
|
192
|
+
> LLMS index: ${canonicalUrl(manifest, "/llms.txt")}
|
|
193
|
+
> Sitemap: ${canonicalUrl(manifest, "/sitemap.md")}
|
|
189
194
|
|
|
190
195
|
`;
|
|
191
196
|
const sections = [];
|
|
@@ -17,7 +17,6 @@ type LlmsFullRouteOptions = {
|
|
|
17
17
|
};
|
|
18
18
|
type PrecomputedLlmsTxtOutput = {
|
|
19
19
|
body: string;
|
|
20
|
-
etag?: string;
|
|
21
20
|
};
|
|
22
21
|
declare function createLlmsTxtRoute(manifest: ManifestLike, options?: LlmsRouteOptions): () => Promise<Response>;
|
|
23
22
|
declare function createPrecomputedLlmsTxtRoute(output: PrecomputedLlmsTxtOutput): () => Response;
|
|
@@ -17,7 +17,6 @@ type LlmsFullRouteOptions = {
|
|
|
17
17
|
};
|
|
18
18
|
type PrecomputedLlmsTxtOutput = {
|
|
19
19
|
body: string;
|
|
20
|
-
etag?: string;
|
|
21
20
|
};
|
|
22
21
|
declare function createLlmsTxtRoute(manifest: ManifestLike, options?: LlmsRouteOptions): () => Promise<Response>;
|
|
23
22
|
declare function createPrecomputedLlmsTxtRoute(output: PrecomputedLlmsTxtOutput): () => Response;
|
|
@@ -75,22 +75,28 @@ function cachedTextHeaders(contentType, options = {}) {
|
|
|
75
75
|
headers.set("vercel-cdn-cache-control", cdnCacheControl(options.cachePolicy));
|
|
76
76
|
headers.set("content-type", contentType);
|
|
77
77
|
headers.set("x-content-type-options", "nosniff");
|
|
78
|
-
if (options.etag) headers.set("etag", options.etag);
|
|
79
78
|
if (options.noindex) headers.set("x-robots-tag", "noindex");
|
|
80
79
|
return headers;
|
|
81
80
|
}
|
|
82
81
|
function createCachedTextResponse(options) {
|
|
83
82
|
const status = options.status ?? 200;
|
|
84
|
-
const method = options.method ??
|
|
83
|
+
const method = options.method ?? "GET";
|
|
85
84
|
const headers = cachedTextHeaders(options.contentType, options);
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
85
|
+
return new Response(method === "HEAD" ? null : options.body, {
|
|
86
|
+
headers,
|
|
87
|
+
status
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// src/kernel/routes/metadata/canonical-url.ts
|
|
92
|
+
function canonicalUrl(manifest, path) {
|
|
93
|
+
const origin = manifest.site.url?.replace(/\/+$/, "");
|
|
94
|
+
if (!origin) return path;
|
|
95
|
+
try {
|
|
96
|
+
return new URL(path, `${origin}/`).toString();
|
|
97
|
+
} catch {
|
|
98
|
+
return path;
|
|
99
|
+
}
|
|
94
100
|
}
|
|
95
101
|
|
|
96
102
|
// src/kernel/routes/metadata/llms.ts
|
|
@@ -119,10 +125,10 @@ async function llmsTxt(manifest, options = {}) {
|
|
|
119
125
|
const visiblePages = options.limit ? pages.slice(0, options.limit) : pages;
|
|
120
126
|
const lines = visiblePages.map((page) => {
|
|
121
127
|
const description = options.includeDescriptions && page.description ? ` - ${page.description}` : "";
|
|
122
|
-
return `- [${page.title}](${page.path})${description}`;
|
|
128
|
+
return `- [${page.title}](${canonicalUrl(manifest, page.path)})${description}`;
|
|
123
129
|
});
|
|
124
130
|
const linkLines = (options.links ?? []).map(
|
|
125
|
-
(link) => `- [${link.title}](${link.path})`
|
|
131
|
+
(link) => `- [${link.title}](${canonicalUrl(manifest, link.path)})`
|
|
126
132
|
);
|
|
127
133
|
const linkSection = linkLines.length ? `
|
|
128
134
|
|
|
@@ -148,8 +154,7 @@ function createPrecomputedLlmsTxtRoute(output) {
|
|
|
148
154
|
return function GET() {
|
|
149
155
|
return createCachedTextResponse({
|
|
150
156
|
body: output.body,
|
|
151
|
-
contentType: "text/plain; charset=utf-8"
|
|
152
|
-
etag: output.etag
|
|
157
|
+
contentType: "text/plain; charset=utf-8"
|
|
153
158
|
});
|
|
154
159
|
};
|
|
155
160
|
}
|
|
@@ -157,8 +162,8 @@ async function llmsFullTxt(manifest, artifacts, options = {}) {
|
|
|
157
162
|
const maxBytes = options.maxBytes ?? DEFAULT_LLMS_FULL_MAX_BYTES;
|
|
158
163
|
const header = `# ${manifest.site.name} Full Content
|
|
159
164
|
|
|
160
|
-
> LLMS index: /llms.txt
|
|
161
|
-
> Sitemap: /sitemap.md
|
|
165
|
+
> LLMS index: ${canonicalUrl(manifest, "/llms.txt")}
|
|
166
|
+
> Sitemap: ${canonicalUrl(manifest, "/sitemap.md")}
|
|
162
167
|
|
|
163
168
|
`;
|
|
164
169
|
const sections = [];
|
|
@@ -99,22 +99,28 @@ function cachedTextHeaders(contentType, options = {}) {
|
|
|
99
99
|
headers.set("vercel-cdn-cache-control", cdnCacheControl(options.cachePolicy));
|
|
100
100
|
headers.set("content-type", contentType);
|
|
101
101
|
headers.set("x-content-type-options", "nosniff");
|
|
102
|
-
if (options.etag) headers.set("etag", options.etag);
|
|
103
102
|
if (options.noindex) headers.set("x-robots-tag", "noindex");
|
|
104
103
|
return headers;
|
|
105
104
|
}
|
|
106
105
|
function createCachedTextResponse(options) {
|
|
107
106
|
const status = options.status ?? 200;
|
|
108
|
-
const method = options.method ??
|
|
107
|
+
const method = options.method ?? "GET";
|
|
109
108
|
const headers = cachedTextHeaders(options.contentType, options);
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
109
|
+
return new Response(method === "HEAD" ? null : options.body, {
|
|
110
|
+
headers,
|
|
111
|
+
status
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// src/kernel/routes/metadata/canonical-url.ts
|
|
116
|
+
function canonicalUrl(manifest, path) {
|
|
117
|
+
const origin = manifest.site.url?.replace(/\/+$/, "");
|
|
118
|
+
if (!origin) return path;
|
|
119
|
+
try {
|
|
120
|
+
return new URL(path, `${origin}/`).toString();
|
|
121
|
+
} catch {
|
|
122
|
+
return path;
|
|
123
|
+
}
|
|
118
124
|
}
|
|
119
125
|
|
|
120
126
|
// src/kernel/routes/metadata/robots.ts
|
|
@@ -122,7 +128,11 @@ async function robotsTxt(manifest) {
|
|
|
122
128
|
"use cache";
|
|
123
129
|
(0, import_cache.cacheLife)("page");
|
|
124
130
|
(0, import_cache.cacheTag)(tags.site(), tags.robots(), tags.manifest(manifest.contentHash));
|
|
125
|
-
|
|
131
|
+
const sitemapUrl = canonicalUrl(manifest, "/sitemap.xml");
|
|
132
|
+
return `User-agent: *
|
|
133
|
+
Allow: /
|
|
134
|
+
Sitemap: ${sitemapUrl}
|
|
135
|
+
`;
|
|
126
136
|
}
|
|
127
137
|
function createRobotsTxtRoute(manifest) {
|
|
128
138
|
return async function GET() {
|
|
@@ -75,22 +75,28 @@ function cachedTextHeaders(contentType, options = {}) {
|
|
|
75
75
|
headers.set("vercel-cdn-cache-control", cdnCacheControl(options.cachePolicy));
|
|
76
76
|
headers.set("content-type", contentType);
|
|
77
77
|
headers.set("x-content-type-options", "nosniff");
|
|
78
|
-
if (options.etag) headers.set("etag", options.etag);
|
|
79
78
|
if (options.noindex) headers.set("x-robots-tag", "noindex");
|
|
80
79
|
return headers;
|
|
81
80
|
}
|
|
82
81
|
function createCachedTextResponse(options) {
|
|
83
82
|
const status = options.status ?? 200;
|
|
84
|
-
const method = options.method ??
|
|
83
|
+
const method = options.method ?? "GET";
|
|
85
84
|
const headers = cachedTextHeaders(options.contentType, options);
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
85
|
+
return new Response(method === "HEAD" ? null : options.body, {
|
|
86
|
+
headers,
|
|
87
|
+
status
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// src/kernel/routes/metadata/canonical-url.ts
|
|
92
|
+
function canonicalUrl(manifest, path) {
|
|
93
|
+
const origin = manifest.site.url?.replace(/\/+$/, "");
|
|
94
|
+
if (!origin) return path;
|
|
95
|
+
try {
|
|
96
|
+
return new URL(path, `${origin}/`).toString();
|
|
97
|
+
} catch {
|
|
98
|
+
return path;
|
|
99
|
+
}
|
|
94
100
|
}
|
|
95
101
|
|
|
96
102
|
// src/kernel/routes/metadata/robots.ts
|
|
@@ -98,7 +104,11 @@ async function robotsTxt(manifest) {
|
|
|
98
104
|
"use cache";
|
|
99
105
|
cacheLife("page");
|
|
100
106
|
cacheTag(tags.site(), tags.robots(), tags.manifest(manifest.contentHash));
|
|
101
|
-
|
|
107
|
+
const sitemapUrl = canonicalUrl(manifest, "/sitemap.xml");
|
|
108
|
+
return `User-agent: *
|
|
109
|
+
Allow: /
|
|
110
|
+
Sitemap: ${sitemapUrl}
|
|
111
|
+
`;
|
|
102
112
|
}
|
|
103
113
|
function createRobotsTxtRoute(manifest) {
|
|
104
114
|
return async function GET() {
|
|
@@ -100,22 +100,28 @@ function cachedTextHeaders(contentType, options = {}) {
|
|
|
100
100
|
headers.set("vercel-cdn-cache-control", cdnCacheControl(options.cachePolicy));
|
|
101
101
|
headers.set("content-type", contentType);
|
|
102
102
|
headers.set("x-content-type-options", "nosniff");
|
|
103
|
-
if (options.etag) headers.set("etag", options.etag);
|
|
104
103
|
if (options.noindex) headers.set("x-robots-tag", "noindex");
|
|
105
104
|
return headers;
|
|
106
105
|
}
|
|
107
106
|
function createCachedTextResponse(options) {
|
|
108
107
|
const status = options.status ?? 200;
|
|
109
|
-
const method = options.method ??
|
|
108
|
+
const method = options.method ?? "GET";
|
|
110
109
|
const headers = cachedTextHeaders(options.contentType, options);
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
110
|
+
return new Response(method === "HEAD" ? null : options.body, {
|
|
111
|
+
headers,
|
|
112
|
+
status
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// src/kernel/routes/metadata/canonical-url.ts
|
|
117
|
+
function canonicalUrl(manifest, path) {
|
|
118
|
+
const origin = manifest.site.url?.replace(/\/+$/, "");
|
|
119
|
+
if (!origin) return path;
|
|
120
|
+
try {
|
|
121
|
+
return new URL(path, `${origin}/`).toString();
|
|
122
|
+
} catch {
|
|
123
|
+
return path;
|
|
124
|
+
}
|
|
119
125
|
}
|
|
120
126
|
|
|
121
127
|
// src/kernel/routes/metadata/sitemap.ts
|
|
@@ -132,7 +138,9 @@ async function sitemapXml(manifest) {
|
|
|
132
138
|
...manifest.pages.filter((page) => page.status === "published").map((page) => page.path)
|
|
133
139
|
];
|
|
134
140
|
const uniqueUrls = [...new Set(urls)];
|
|
135
|
-
const body = uniqueUrls.map(
|
|
141
|
+
const body = uniqueUrls.map(
|
|
142
|
+
(url) => ` <url><loc>${xmlEscape(canonicalUrl(manifest, url))}</loc></url>`
|
|
143
|
+
).join("\n");
|
|
136
144
|
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
137
145
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
138
146
|
${body}
|
|
@@ -148,22 +156,24 @@ function createSitemapXmlRoute(manifest) {
|
|
|
148
156
|
};
|
|
149
157
|
}
|
|
150
158
|
async function sitemapMarkdown(manifest, artifactManifest) {
|
|
151
|
-
const groups = Object.values(manifest.groups).sort((a, b) => a.path.localeCompare(b.path)).map(
|
|
159
|
+
const groups = Object.values(manifest.groups).sort((a, b) => a.path.localeCompare(b.path)).map(
|
|
160
|
+
(group) => `- [${group.title}](${canonicalUrl(manifest, group.path)})`
|
|
161
|
+
);
|
|
152
162
|
const pages = manifest.pages.filter((page) => page.status === "published").sort((a, b) => a.path.localeCompare(b.path)).map((page) => {
|
|
153
163
|
const markdownPath = artifactManifest.byHtmlPath[page.path];
|
|
154
|
-
const markdown = markdownPath ? ` ([Markdown](${markdownPath}))` : "";
|
|
155
|
-
return `- [${page.title}](${page.path})${markdown}`;
|
|
164
|
+
const markdown = markdownPath ? ` ([Markdown](${canonicalUrl(manifest, markdownPath)}))` : "";
|
|
165
|
+
return `- [${page.title}](${canonicalUrl(manifest, page.path)})${markdown}`;
|
|
156
166
|
});
|
|
157
167
|
return [
|
|
158
168
|
`# ${manifest.site.name} Sitemap`,
|
|
159
169
|
"## Agent indexes",
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
170
|
+
`- [LLMS index](${canonicalUrl(manifest, "/llms.txt")})`,
|
|
171
|
+
`- [Full LLMS index](${canonicalUrl(manifest, "/llms-full.txt")})`,
|
|
172
|
+
`- [XML sitemap](${canonicalUrl(manifest, "/sitemap.xml")})`,
|
|
163
173
|
"## Sections",
|
|
164
|
-
groups.length ? groups.join("\n") :
|
|
174
|
+
groups.length ? groups.join("\n") : `- [Home](${canonicalUrl(manifest, "/")})`,
|
|
165
175
|
"## Pages",
|
|
166
|
-
pages.length ? pages.join("\n") :
|
|
176
|
+
pages.length ? pages.join("\n") : `- [Home](${canonicalUrl(manifest, "/")})`,
|
|
167
177
|
""
|
|
168
178
|
].join("\n\n");
|
|
169
179
|
}
|
|
@@ -75,22 +75,28 @@ function cachedTextHeaders(contentType, options = {}) {
|
|
|
75
75
|
headers.set("vercel-cdn-cache-control", cdnCacheControl(options.cachePolicy));
|
|
76
76
|
headers.set("content-type", contentType);
|
|
77
77
|
headers.set("x-content-type-options", "nosniff");
|
|
78
|
-
if (options.etag) headers.set("etag", options.etag);
|
|
79
78
|
if (options.noindex) headers.set("x-robots-tag", "noindex");
|
|
80
79
|
return headers;
|
|
81
80
|
}
|
|
82
81
|
function createCachedTextResponse(options) {
|
|
83
82
|
const status = options.status ?? 200;
|
|
84
|
-
const method = options.method ??
|
|
83
|
+
const method = options.method ?? "GET";
|
|
85
84
|
const headers = cachedTextHeaders(options.contentType, options);
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
85
|
+
return new Response(method === "HEAD" ? null : options.body, {
|
|
86
|
+
headers,
|
|
87
|
+
status
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// src/kernel/routes/metadata/canonical-url.ts
|
|
92
|
+
function canonicalUrl(manifest, path) {
|
|
93
|
+
const origin = manifest.site.url?.replace(/\/+$/, "");
|
|
94
|
+
if (!origin) return path;
|
|
95
|
+
try {
|
|
96
|
+
return new URL(path, `${origin}/`).toString();
|
|
97
|
+
} catch {
|
|
98
|
+
return path;
|
|
99
|
+
}
|
|
94
100
|
}
|
|
95
101
|
|
|
96
102
|
// src/kernel/routes/metadata/sitemap.ts
|
|
@@ -107,7 +113,9 @@ async function sitemapXml(manifest) {
|
|
|
107
113
|
...manifest.pages.filter((page) => page.status === "published").map((page) => page.path)
|
|
108
114
|
];
|
|
109
115
|
const uniqueUrls = [...new Set(urls)];
|
|
110
|
-
const body = uniqueUrls.map(
|
|
116
|
+
const body = uniqueUrls.map(
|
|
117
|
+
(url) => ` <url><loc>${xmlEscape(canonicalUrl(manifest, url))}</loc></url>`
|
|
118
|
+
).join("\n");
|
|
111
119
|
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
112
120
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
113
121
|
${body}
|
|
@@ -123,22 +131,24 @@ function createSitemapXmlRoute(manifest) {
|
|
|
123
131
|
};
|
|
124
132
|
}
|
|
125
133
|
async function sitemapMarkdown(manifest, artifactManifest) {
|
|
126
|
-
const groups = Object.values(manifest.groups).sort((a, b) => a.path.localeCompare(b.path)).map(
|
|
134
|
+
const groups = Object.values(manifest.groups).sort((a, b) => a.path.localeCompare(b.path)).map(
|
|
135
|
+
(group) => `- [${group.title}](${canonicalUrl(manifest, group.path)})`
|
|
136
|
+
);
|
|
127
137
|
const pages = manifest.pages.filter((page) => page.status === "published").sort((a, b) => a.path.localeCompare(b.path)).map((page) => {
|
|
128
138
|
const markdownPath = artifactManifest.byHtmlPath[page.path];
|
|
129
|
-
const markdown = markdownPath ? ` ([Markdown](${markdownPath}))` : "";
|
|
130
|
-
return `- [${page.title}](${page.path})${markdown}`;
|
|
139
|
+
const markdown = markdownPath ? ` ([Markdown](${canonicalUrl(manifest, markdownPath)}))` : "";
|
|
140
|
+
return `- [${page.title}](${canonicalUrl(manifest, page.path)})${markdown}`;
|
|
131
141
|
});
|
|
132
142
|
return [
|
|
133
143
|
`# ${manifest.site.name} Sitemap`,
|
|
134
144
|
"## Agent indexes",
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
145
|
+
`- [LLMS index](${canonicalUrl(manifest, "/llms.txt")})`,
|
|
146
|
+
`- [Full LLMS index](${canonicalUrl(manifest, "/llms-full.txt")})`,
|
|
147
|
+
`- [XML sitemap](${canonicalUrl(manifest, "/sitemap.xml")})`,
|
|
138
148
|
"## Sections",
|
|
139
|
-
groups.length ? groups.join("\n") :
|
|
149
|
+
groups.length ? groups.join("\n") : `- [Home](${canonicalUrl(manifest, "/")})`,
|
|
140
150
|
"## Pages",
|
|
141
|
-
pages.length ? pages.join("\n") :
|
|
151
|
+
pages.length ? pages.join("\n") : `- [Home](${canonicalUrl(manifest, "/")})`,
|
|
142
152
|
""
|
|
143
153
|
].join("\n\n");
|
|
144
154
|
}
|
package/package.json
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@publish.os/nextjs",
|
|
3
|
-
"version": "0.0.1-alpha.
|
|
3
|
+
"version": "0.0.1-alpha.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
|
+
"engines": {
|
|
7
|
+
"node": ">=22.13"
|
|
8
|
+
},
|
|
6
9
|
"repository": {
|
|
7
10
|
"type": "git",
|
|
8
11
|
"url": "git+https://github.com/PublishOS/publishOS.git",
|
|
@@ -10,6 +13,7 @@
|
|
|
10
13
|
},
|
|
11
14
|
"files": [
|
|
12
15
|
"dist/**",
|
|
16
|
+
"release/**",
|
|
13
17
|
"package.json",
|
|
14
18
|
"README.md"
|
|
15
19
|
],
|
|
@@ -54,6 +58,26 @@
|
|
|
54
58
|
"types": "./dist/kernel/defaults.registry.d.ts",
|
|
55
59
|
"default": "./dist/kernel/defaults.registry.js"
|
|
56
60
|
},
|
|
61
|
+
"./kernel/routes/agent/*": {
|
|
62
|
+
"types": "./dist/kernel/routes/agent/*.d.ts",
|
|
63
|
+
"default": "./dist/kernel/routes/agent/*.js"
|
|
64
|
+
},
|
|
65
|
+
"./kernel/routes/layouts/*": {
|
|
66
|
+
"types": "./dist/kernel/routes/layouts/*.d.ts",
|
|
67
|
+
"default": "./dist/kernel/routes/layouts/*.js"
|
|
68
|
+
},
|
|
69
|
+
"./kernel/routes/metadata/*": {
|
|
70
|
+
"types": "./dist/kernel/routes/metadata/*.d.ts",
|
|
71
|
+
"default": "./dist/kernel/routes/metadata/*.js"
|
|
72
|
+
},
|
|
73
|
+
"./kernel/routes/pages/*": {
|
|
74
|
+
"types": "./dist/kernel/routes/pages/*.d.ts",
|
|
75
|
+
"default": "./dist/kernel/routes/pages/*.js"
|
|
76
|
+
},
|
|
77
|
+
"./kernel/routes/*": {
|
|
78
|
+
"types": "./dist/kernel/routes/*.d.ts",
|
|
79
|
+
"default": "./dist/kernel/routes/*.js"
|
|
80
|
+
},
|
|
57
81
|
"./kernel/*": {
|
|
58
82
|
"types": "./dist/kernel/*.d.ts",
|
|
59
83
|
"default": "./dist/kernel/*.js"
|
|
@@ -86,11 +110,10 @@
|
|
|
86
110
|
"react": "^19.2.0",
|
|
87
111
|
"react-medium-image-zoom": "^5.4.8",
|
|
88
112
|
"remark-gfm": "^4.0.1",
|
|
89
|
-
"tailwind-merge": "^3.0.0"
|
|
90
|
-
"tslib": "^2.8.1"
|
|
113
|
+
"tailwind-merge": "^3.0.0"
|
|
91
114
|
},
|
|
92
115
|
"peerDependencies": {
|
|
93
|
-
"next": ">=16.
|
|
116
|
+
"next": ">=16.2.11",
|
|
94
117
|
"react": ">=19.0.0",
|
|
95
118
|
"react-dom": ">=19.0.0",
|
|
96
119
|
"typescript": ">=5.0.0"
|
|
@@ -99,4 +122,4 @@
|
|
|
99
122
|
"registry": "https://registry.npmjs.org",
|
|
100
123
|
"access": "public"
|
|
101
124
|
}
|
|
102
|
-
}
|
|
125
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "publish-os-nextjs-release-base",
|
|
3
|
+
"private": true,
|
|
4
|
+
"type": "module",
|
|
5
|
+
"engines": {
|
|
6
|
+
"node": ">=22.13"
|
|
7
|
+
},
|
|
8
|
+
"dependencies": {
|
|
9
|
+
"@base-ui/react": "1.5.0",
|
|
10
|
+
"@tailwindcss/postcss": "4.3.0",
|
|
11
|
+
"@types/node": "22.19.17",
|
|
12
|
+
"@types/react": "19.2.2",
|
|
13
|
+
"@types/react-dom": "19.2.2",
|
|
14
|
+
"class-variance-authority": "0.7.1",
|
|
15
|
+
"next": "16.2.11",
|
|
16
|
+
"next-themes": "0.4.6",
|
|
17
|
+
"pagefind": "1.5.2",
|
|
18
|
+
"react": "19.2.0",
|
|
19
|
+
"react-dom": "19.2.0",
|
|
20
|
+
"tailwindcss": "4.3.0",
|
|
21
|
+
"typescript": "5.9.2"
|
|
22
|
+
}
|
|
23
|
+
}
|