@tdacorp/hyle-sdk 0.1.1 → 0.2.1
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 +41 -6
- package/dist/chunk-7VCMJUPC.js +35 -0
- package/dist/{chunk-RI3BP4MI.js → chunk-HFUJRNFP.js} +42 -1
- package/dist/{chunk-XODMIT6N.js → chunk-MHVWHSKC.js} +21 -3
- package/dist/index.cjs +42 -0
- package/dist/index.d.cts +30 -1
- package/dist/index.d.ts +30 -1
- package/dist/index.js +3 -1
- package/dist/next.cjs +178 -54
- package/dist/next.d.cts +62 -4
- package/dist/next.d.ts +62 -4
- package/dist/next.js +118 -49
- package/dist/react.cjs +22 -3
- package/dist/react.d.cts +6 -1
- package/dist/react.d.ts +6 -1
- package/dist/react.js +3 -1
- package/dist/resolve-B_p0p4Zn.d.cts +29 -0
- package/dist/resolve-fMx2W8RR.d.ts +29 -0
- package/dist/use-cache.cjs +3 -3
- package/dist/use-cache.d.cts +1 -1
- package/dist/use-cache.d.ts +1 -1
- package/dist/use-cache.js +5 -5
- package/package.json +1 -1
- package/dist/chunk-HVAWEEHG.js +0 -29
- package/dist/resolve-Cz-3Q7T-.d.ts +0 -16
- package/dist/resolve-DrmTGaCr.d.cts +0 -16
package/dist/next.cjs
CHANGED
|
@@ -21,13 +21,16 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var next_exports = {};
|
|
22
22
|
__export(next_exports, {
|
|
23
23
|
createRevalidateRoute: () => createRevalidateRoute,
|
|
24
|
+
fetchResolver: () => fetchResolver,
|
|
24
25
|
hyleMetadata: () => hyleMetadata,
|
|
25
|
-
hylePage: () => hylePage
|
|
26
|
+
hylePage: () => hylePage,
|
|
27
|
+
hyleSitemap: () => hyleSitemap,
|
|
28
|
+
workspaceTags: () => workspaceTags
|
|
26
29
|
});
|
|
27
30
|
module.exports = __toCommonJS(next_exports);
|
|
28
31
|
|
|
29
32
|
// src/next/page.tsx
|
|
30
|
-
var
|
|
33
|
+
var import_navigation2 = require("next/navigation");
|
|
31
34
|
|
|
32
35
|
// src/errors.ts
|
|
33
36
|
var Cp1ClientError = class extends Error {
|
|
@@ -268,6 +271,46 @@ function okResponse(purged) {
|
|
|
268
271
|
});
|
|
269
272
|
}
|
|
270
273
|
|
|
274
|
+
// src/sitemap.ts
|
|
275
|
+
var PAGE_LIMIT = 100;
|
|
276
|
+
var DEFAULT_MAX_PAGES = 20;
|
|
277
|
+
var SECTION_SLUG = /^[A-Za-z0-9][A-Za-z0-9_-]*$/;
|
|
278
|
+
var UNSAFE_PATH = /[\\?#<>&"'\u0000- \u007f]/;
|
|
279
|
+
async function listPublicationPaths(options) {
|
|
280
|
+
const maxPages = options.maxPages ?? DEFAULT_MAX_PAGES;
|
|
281
|
+
const prefix = `${options.basePath}/`;
|
|
282
|
+
const indexes = [options.basePath || "/"];
|
|
283
|
+
for (const slug of options.sections ?? []) if (slug !== "posts" && SECTION_SLUG.test(slug)) indexes.push(`${options.basePath}/${slug}`);
|
|
284
|
+
const found = /* @__PURE__ */ new Map();
|
|
285
|
+
let complete = true;
|
|
286
|
+
try {
|
|
287
|
+
for (const index of new Set(indexes)) {
|
|
288
|
+
let cursor;
|
|
289
|
+
for (let page = 0; page < maxPages; page++) {
|
|
290
|
+
const result = await options.client.resolve({
|
|
291
|
+
path: index,
|
|
292
|
+
limit: PAGE_LIMIT,
|
|
293
|
+
...options.locale !== void 0 ? { locale: options.locale } : {},
|
|
294
|
+
...cursor !== void 0 ? { cursor } : {}
|
|
295
|
+
});
|
|
296
|
+
if (result.kind !== "list") {
|
|
297
|
+
complete = false;
|
|
298
|
+
break;
|
|
299
|
+
}
|
|
300
|
+
for (const item of result.items) {
|
|
301
|
+
if (item.canonical_path.startsWith(prefix) && !UNSAFE_PATH.test(item.canonical_path)) found.set(item.canonical_path, item.published_at);
|
|
302
|
+
}
|
|
303
|
+
if (!result.next_cursor) break;
|
|
304
|
+
if (page === maxPages - 1) complete = false;
|
|
305
|
+
cursor = result.next_cursor;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
} catch {
|
|
309
|
+
complete = false;
|
|
310
|
+
}
|
|
311
|
+
return { paths: [...found].map(([path, publishedAt]) => ({ path, publishedAt })), complete };
|
|
312
|
+
}
|
|
313
|
+
|
|
271
314
|
// src/react/content.tsx
|
|
272
315
|
var import_hast_util_to_jsx_runtime = require("hast-util-to-jsx-runtime");
|
|
273
316
|
var import_react = require("react");
|
|
@@ -513,7 +556,10 @@ var en = {
|
|
|
513
556
|
rdBody: "You are being taken to its new address.",
|
|
514
557
|
from: "From",
|
|
515
558
|
to: "To",
|
|
516
|
-
rdFallback: "If nothing happens, go to the new address."
|
|
559
|
+
rdFallback: "If nothing happens, go to the new address.",
|
|
560
|
+
unKind: "Unavailable",
|
|
561
|
+
unTitle: "This page is temporarily unavailable",
|
|
562
|
+
unBody: "The content could not be loaded. Please try again in a moment."
|
|
517
563
|
};
|
|
518
564
|
var fr = {
|
|
519
565
|
toc: "Sur cette page",
|
|
@@ -549,7 +595,10 @@ var fr = {
|
|
|
549
595
|
rdBody: "Vous \xEAtes redirig\xE9 vers sa nouvelle adresse.",
|
|
550
596
|
from: "De",
|
|
551
597
|
to: "Vers",
|
|
552
|
-
rdFallback: "Si rien ne se passe, allez \xE0 la nouvelle adresse."
|
|
598
|
+
rdFallback: "Si rien ne se passe, allez \xE0 la nouvelle adresse.",
|
|
599
|
+
unKind: "Indisponible",
|
|
600
|
+
unTitle: "Cette page est momentan\xE9ment indisponible",
|
|
601
|
+
unBody: "Le contenu n'a pas pu \xEAtre charg\xE9. R\xE9essayez dans un instant."
|
|
553
602
|
};
|
|
554
603
|
var es = {
|
|
555
604
|
toc: "En esta p\xE1gina",
|
|
@@ -585,7 +634,10 @@ var es = {
|
|
|
585
634
|
rdBody: "Te estamos llevando a su nueva direcci\xF3n.",
|
|
586
635
|
from: "Desde",
|
|
587
636
|
to: "A",
|
|
588
|
-
rdFallback: "Si no pasa nada, ve a la nueva direcci\xF3n."
|
|
637
|
+
rdFallback: "Si no pasa nada, ve a la nueva direcci\xF3n.",
|
|
638
|
+
unKind: "No disponible",
|
|
639
|
+
unTitle: "Esta p\xE1gina no est\xE1 disponible por el momento",
|
|
640
|
+
unBody: "No se pudo cargar el contenido. Int\xE9ntalo de nuevo en un momento."
|
|
589
641
|
};
|
|
590
642
|
var TABLE = { en, fr, es };
|
|
591
643
|
function stringsFor(locale) {
|
|
@@ -932,6 +984,9 @@ function DocsPage({ article, ...base }) {
|
|
|
932
984
|
] }) });
|
|
933
985
|
}
|
|
934
986
|
|
|
987
|
+
// src/next/options.ts
|
|
988
|
+
var import_navigation = require("next/navigation");
|
|
989
|
+
|
|
935
990
|
// src/next/paths.ts
|
|
936
991
|
function normalizeBasePath(basePath) {
|
|
937
992
|
const value = (basePath ?? "").replace(/\/+$/, "");
|
|
@@ -939,6 +994,7 @@ function normalizeBasePath(basePath) {
|
|
|
939
994
|
if (!/^\/[^\s?#\\]+$/.test(value) || value.includes("//")) throw new TypeError(`basePath must look like "/learn", got "${basePath}"`);
|
|
940
995
|
return value;
|
|
941
996
|
}
|
|
997
|
+
var MAX_PATH_LENGTH = 1024;
|
|
942
998
|
function sitePathFrom(basePath, segments) {
|
|
943
999
|
const decoded = [];
|
|
944
1000
|
for (const raw of segments ?? []) {
|
|
@@ -948,10 +1004,12 @@ function sitePathFrom(basePath, segments) {
|
|
|
948
1004
|
} catch {
|
|
949
1005
|
return void 0;
|
|
950
1006
|
}
|
|
1007
|
+
if (segment !== segment.normalize("NFC")) return void 0;
|
|
951
1008
|
if (segment === "" || segment === "." || segment === ".." || /[/\\\u0000-\u001f\u007f]/.test(segment)) return void 0;
|
|
952
1009
|
decoded.push(segment);
|
|
953
1010
|
}
|
|
954
|
-
|
|
1011
|
+
const path = decoded.length === 0 ? basePath || "/" : `${basePath}/${decoded.join("/")}`;
|
|
1012
|
+
return path.length > MAX_PATH_LENGTH ? void 0 : path;
|
|
955
1013
|
}
|
|
956
1014
|
function safeRedirectTarget(to) {
|
|
957
1015
|
if (typeof to !== "string" || !to.startsWith("/") || to.startsWith("//")) return void 0;
|
|
@@ -961,19 +1019,24 @@ function safeRedirectTarget(to) {
|
|
|
961
1019
|
// src/next/resolve.ts
|
|
962
1020
|
var DEFAULT_REVALIDATE = 300;
|
|
963
1021
|
var MAX_TAGS2 = 64;
|
|
964
|
-
function
|
|
1022
|
+
function workspaceTags(workspaceId, sections = []) {
|
|
1023
|
+
const workspaceTag = `hyle:1:ws:${workspaceId}`;
|
|
1024
|
+
if (!isValidCacheTag(workspaceTag)) throw new TypeError("hyle: `workspaceId` is not a valid workspace id (a uuid)");
|
|
965
1025
|
const slugs = /* @__PURE__ */ new Set(["posts", ...sections]);
|
|
966
|
-
|
|
1026
|
+
const tags = [...slugs].map((slug) => `hyle:1:sec:${workspaceId}:${slug}`);
|
|
1027
|
+
if (!tags.every(isValidCacheTag)) throw new TypeError("hyle: a configured `sections` slug cannot be used in a cache tag (printable ASCII, at most 200 characters)");
|
|
1028
|
+
return [workspaceTag, ...tags].slice(0, MAX_TAGS2);
|
|
967
1029
|
}
|
|
968
1030
|
function fetchResolver(options) {
|
|
969
1031
|
if (!options.workspaceId) throw new TypeError("hylePage: `workspaceId` is required for the fetch cache (or pass a cachedResolver)");
|
|
970
1032
|
const client = createHyleClient({ baseUrl: options.baseUrl, token: options.token });
|
|
971
1033
|
const revalidate = options.revalidate ?? DEFAULT_REVALIDATE;
|
|
972
|
-
const tags =
|
|
973
|
-
return (path, locale, limit) => client.resolve({
|
|
1034
|
+
const tags = workspaceTags(options.workspaceId, options.sections);
|
|
1035
|
+
return (path, locale, limit, cursor) => client.resolve({
|
|
974
1036
|
path,
|
|
975
1037
|
...locale !== void 0 ? { locale } : {},
|
|
976
1038
|
...limit !== void 0 ? { limit } : {},
|
|
1039
|
+
...cursor !== void 0 ? { cursor } : {},
|
|
977
1040
|
init: { next: { revalidate, tags } }
|
|
978
1041
|
});
|
|
979
1042
|
}
|
|
@@ -982,77 +1045,135 @@ function fetchResolver(options) {
|
|
|
982
1045
|
function resolverFor(options) {
|
|
983
1046
|
return options.resolver ?? fetchResolver(options);
|
|
984
1047
|
}
|
|
985
|
-
var
|
|
1048
|
+
var CURSOR = /^[A-Za-z0-9_-]{1,256}$/;
|
|
1049
|
+
var validCursor = (value) => typeof value === "string" && CURSOR.test(value) ? value : void 0;
|
|
1050
|
+
var LOCALE_TAG = /^[a-z]{2,3}(-[A-Za-z0-9]{2,8})*$/;
|
|
1051
|
+
var MAX_LOCALE_LENGTH = 35;
|
|
986
1052
|
function routeContext(options, params) {
|
|
987
1053
|
const basePath = normalizeBasePath(options.basePath);
|
|
988
1054
|
const segments = params[options.param ?? "hyle"];
|
|
989
1055
|
const path = sitePathFrom(basePath, typeof segments === "string" ? [segments] : segments);
|
|
990
1056
|
const given = typeof options.locale === "function" ? options.locale(params) : options.locale;
|
|
991
|
-
const locale = typeof given === "string" && LOCALE_TAG.test(given) ? given : void 0;
|
|
1057
|
+
const locale = typeof given === "string" && given.length <= MAX_LOCALE_LENGTH && LOCALE_TAG.test(given) ? given : void 0;
|
|
992
1058
|
const prefix = options.localePrefix ?? (() => "");
|
|
993
1059
|
const toHref = (sitePath, linkLocale = locale) => (linkLocale ? prefix(linkLocale) : "") + sitePath;
|
|
994
1060
|
return { basePath, path, locale, toHref };
|
|
995
1061
|
}
|
|
1062
|
+
function isRejectedRequest(error) {
|
|
1063
|
+
(0, import_navigation.unstable_rethrow)(error);
|
|
1064
|
+
return error instanceof Cp1ClientError && error.status >= 400 && error.status < 500 && ![401, 403, 429].includes(error.status);
|
|
1065
|
+
}
|
|
996
1066
|
|
|
997
1067
|
// src/next/page.tsx
|
|
998
1068
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
999
1069
|
function hylePage(options) {
|
|
1000
1070
|
const resolve = resolverFor(options);
|
|
1001
|
-
return async function HylePage({ params }) {
|
|
1071
|
+
return async function HylePage({ params, searchParams }) {
|
|
1002
1072
|
const { path, locale, toHref } = routeContext(options, await params ?? {});
|
|
1003
|
-
if (path === void 0) (0,
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1073
|
+
if (path === void 0) (0, import_navigation2.notFound)();
|
|
1074
|
+
try {
|
|
1075
|
+
const cursor = options.paginate === "searchParams" ? validCursor((await searchParams)?.cursor) : void 0;
|
|
1076
|
+
const result = await resolve(path, locale, options.listLimit, cursor);
|
|
1077
|
+
switch (result.kind) {
|
|
1078
|
+
case "article": {
|
|
1079
|
+
const props = { article: result, components: options.components, slots: options.slots, locale, toHref };
|
|
1080
|
+
return options.layout === "docs" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(DocsPage, { ...props }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ArticlePage, { ...props });
|
|
1081
|
+
}
|
|
1082
|
+
case "list": {
|
|
1083
|
+
const list = options.list?.title ? { ...result, section: { ...result.section, title: options.list.title } } : result;
|
|
1084
|
+
const next = options.paginate === "searchParams" ? validCursor(result.next_cursor) : void 0;
|
|
1085
|
+
const olderHref = next ? `${toHref(path)}?cursor=${next}` : void 0;
|
|
1086
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ListPage, { list, ...olderHref ? { olderHref } : {}, ...options.list?.description ? { description: options.list.description } : {}, components: options.components, slots: options.slots, locale, toHref });
|
|
1087
|
+
}
|
|
1088
|
+
case "redirect": {
|
|
1089
|
+
const to = safeRedirectTarget(result.to);
|
|
1090
|
+
if (to === void 0) throw new Cp1ClientError("INVALID_RESPONSE", "hyle returned an unsafe redirect target", 502, "");
|
|
1091
|
+
const target = safeRedirectTarget(toHref(to));
|
|
1092
|
+
if (target === void 0) throw new Cp1ClientError("INVALID_RESPONSE", "hyle returned an unsafe redirect target", 502, "");
|
|
1093
|
+
if (target === toHref(path)) (0, import_navigation2.notFound)();
|
|
1094
|
+
return result.status === 301 ? (0, import_navigation2.permanentRedirect)(target) : (0, import_navigation2.redirect)(target);
|
|
1095
|
+
}
|
|
1096
|
+
case "notfound":
|
|
1097
|
+
case "disabled":
|
|
1098
|
+
(0, import_navigation2.notFound)();
|
|
1019
1099
|
}
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1100
|
+
} catch (error) {
|
|
1101
|
+
if (isRejectedRequest(error)) (0, import_navigation2.notFound)();
|
|
1102
|
+
if (!options.onError) throw error;
|
|
1103
|
+
console.error(`hyle: ${error instanceof Error ? error.name : "UnknownError"}`);
|
|
1104
|
+
return options.onError(error);
|
|
1023
1105
|
}
|
|
1024
1106
|
};
|
|
1025
1107
|
}
|
|
1026
1108
|
|
|
1109
|
+
// src/next/sitemap.ts
|
|
1110
|
+
var ISO_DATE = /^\d{4}-\d{2}-\d{2}T/;
|
|
1111
|
+
function httpsOrigin(origin) {
|
|
1112
|
+
let url;
|
|
1113
|
+
try {
|
|
1114
|
+
url = new URL(origin);
|
|
1115
|
+
} catch {
|
|
1116
|
+
throw new TypeError("hyleSitemap: `origin` must be an https origin such as https://example.com");
|
|
1117
|
+
}
|
|
1118
|
+
if (url.protocol !== "https:" || url.origin !== origin.replace(/\/$/, "")) {
|
|
1119
|
+
throw new TypeError("hyleSitemap: `origin` must be an https origin with no path, query or credentials");
|
|
1120
|
+
}
|
|
1121
|
+
return url.origin;
|
|
1122
|
+
}
|
|
1123
|
+
async function hyleSitemap(options) {
|
|
1124
|
+
const origin = httpsOrigin(options.origin);
|
|
1125
|
+
const resolve = resolverFor(options);
|
|
1126
|
+
const locale = typeof options.locale === "string" ? options.locale : void 0;
|
|
1127
|
+
const { basePath, toHref } = routeContext({ ...options, locale: () => locale }, {});
|
|
1128
|
+
const client = { resolve: ({ path, locale: l, limit, cursor }) => resolve(path, l, limit, cursor) };
|
|
1129
|
+
const { paths, complete } = await listPublicationPaths({ client, basePath, ...options.sections ? { sections: options.sections } : {}, ...locale ? { locale } : {} });
|
|
1130
|
+
if (!complete && (options.onIncomplete === "throw" || options.onIncomplete === void 0 && paths.length === 0)) {
|
|
1131
|
+
throw new Error("hyleSitemap: hyle could not be listed completely (see onIncomplete)");
|
|
1132
|
+
}
|
|
1133
|
+
return paths.map(({ path, publishedAt }) => ({
|
|
1134
|
+
url: origin + encodeURI(toHref(path)),
|
|
1135
|
+
...ISO_DATE.test(publishedAt) && !Number.isNaN(Date.parse(publishedAt)) ? { lastModified: publishedAt } : {}
|
|
1136
|
+
}));
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1027
1139
|
// src/next/metadata.ts
|
|
1028
1140
|
function hyleMetadata(options) {
|
|
1029
1141
|
const resolve = resolverFor(options);
|
|
1030
1142
|
return async function generateMetadata({ params }) {
|
|
1031
1143
|
const { path, locale, toHref } = routeContext(options, await params ?? {});
|
|
1032
1144
|
if (path === void 0) return {};
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
},
|
|
1046
|
-
openGraph: {
|
|
1047
|
-
type: "article",
|
|
1145
|
+
try {
|
|
1146
|
+
const result = await resolve(path, locale, options.listLimit);
|
|
1147
|
+
if (result.kind === "list") {
|
|
1148
|
+
const title = options.list?.title || result.section.title;
|
|
1149
|
+
const description2 = options.list?.description;
|
|
1150
|
+
return { title, ...description2 ? { description: description2 } : {}, openGraph: { title, ...description2 ? { description: description2 } : {} } };
|
|
1151
|
+
}
|
|
1152
|
+
if (result.kind !== "article") return {};
|
|
1153
|
+
const { publication: pub, alternates } = result;
|
|
1154
|
+
const canonical = toHref(pub.canonical_path, pub.locale);
|
|
1155
|
+
const description = pub.description ?? void 0;
|
|
1156
|
+
return {
|
|
1048
1157
|
title: pub.title,
|
|
1049
1158
|
...description ? { description } : {},
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1159
|
+
alternates: {
|
|
1160
|
+
canonical,
|
|
1161
|
+
...alternates.length > 1 ? { languages: Object.fromEntries(alternates.map((a) => [a.locale, toHref(a.canonical_path, a.locale)])) } : {}
|
|
1162
|
+
},
|
|
1163
|
+
openGraph: {
|
|
1164
|
+
type: "article",
|
|
1165
|
+
title: pub.title,
|
|
1166
|
+
...description ? { description } : {},
|
|
1167
|
+
url: canonical,
|
|
1168
|
+
locale: pub.locale,
|
|
1169
|
+
publishedTime: pub.published_at,
|
|
1170
|
+
modifiedTime: pub.updated_at
|
|
1171
|
+
}
|
|
1172
|
+
};
|
|
1173
|
+
} catch (error) {
|
|
1174
|
+
if (isRejectedRequest(error)) return {};
|
|
1175
|
+
throw error;
|
|
1176
|
+
}
|
|
1056
1177
|
};
|
|
1057
1178
|
}
|
|
1058
1179
|
|
|
@@ -1079,6 +1200,9 @@ function createRevalidateRoute(options) {
|
|
|
1079
1200
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1080
1201
|
0 && (module.exports = {
|
|
1081
1202
|
createRevalidateRoute,
|
|
1203
|
+
fetchResolver,
|
|
1082
1204
|
hyleMetadata,
|
|
1083
|
-
hylePage
|
|
1205
|
+
hylePage,
|
|
1206
|
+
hyleSitemap,
|
|
1207
|
+
workspaceTags
|
|
1084
1208
|
});
|
package/dist/next.d.cts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { ReactElement } from 'react';
|
|
2
2
|
import { H as HyleComponents, a as HyleSlots } from './types-DLWvqanV.cjs';
|
|
3
|
-
import { F as FetchResolverOptions, H as HyleResolver } from './resolve-
|
|
4
|
-
|
|
3
|
+
import { F as FetchResolverOptions, H as HyleResolver } from './resolve-B_p0p4Zn.cjs';
|
|
4
|
+
export { f as fetchResolver, w as workspaceTags } from './resolve-B_p0p4Zn.cjs';
|
|
5
|
+
import { MetadataRoute, Metadata } from 'next';
|
|
5
6
|
import { a as RevalidationCallbackRoute } from './revalidation-callback-D7Ms_Puz.cjs';
|
|
6
7
|
import './types-DjXf6iPo.cjs';
|
|
7
8
|
|
|
@@ -28,6 +29,33 @@ interface CommonOptions {
|
|
|
28
29
|
readonly layout?: "article" | "docs";
|
|
29
30
|
/** Items per list page (server default 20, maximum 100). */
|
|
30
31
|
readonly listLimit?: number;
|
|
32
|
+
/**
|
|
33
|
+
* Heading and description of the list page (the mount path's index). hyle names the default section after its slug
|
|
34
|
+
* ("Posts"); `list.title` replaces that in the page's h1, the `<title>` and Open Graph, and `list.description` fills the
|
|
35
|
+
* page description, `<meta name="description">` and Open Graph. Each falls back separately: title to the hyle section
|
|
36
|
+
* title, description to none. Article pages are unaffected.
|
|
37
|
+
*/
|
|
38
|
+
readonly list?: {
|
|
39
|
+
readonly title?: string;
|
|
40
|
+
readonly description?: string;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* `"searchParams"` makes list pages paginate: `?cursor=` is read, sent to hyle, and an "Older posts" link is built from
|
|
44
|
+
* `next_cursor`. Default off, and the trade-off is real: reading `searchParams` makes the route dynamic, so it can no longer
|
|
45
|
+
* be statically generated or served from ISR (hyle's fetch cache still applies). Leave it off when one page of `listLimit`
|
|
46
|
+
* items is enough. A malformed `cursor` is ignored (the first page is shown); one that is well-formed but unknown to hyle is a 404.
|
|
47
|
+
*/
|
|
48
|
+
readonly paginate?: "searchParams";
|
|
49
|
+
/**
|
|
50
|
+
* Opt-in custom UI for transient or operational hyle failures (network error, timeout, 5xx, 401, 403, 429, a malformed
|
|
51
|
+
* response, a refused redirect target). Without it `hylePage` rethrows them, so Next keeps serving the last good ISR page
|
|
52
|
+
* when a revalidation fails (and a failure on a first render is an uncached 500). With it, the returned element is a NORMAL
|
|
53
|
+
* render: it is cached for the revalidate window and replaces the last good page for that long, so prefer a boundary
|
|
54
|
+
* (`error.tsx`) unless you want that. The `error` can carry `Cp1ClientError.message` and `requestId`: never render it.
|
|
55
|
+
* Only its name is logged. A 4xx rejection of the request (400, 404, ...) is always `notFound()` and never reaches this, and
|
|
56
|
+
* `notFound()` and redirects are Next control flow that always propagate.
|
|
57
|
+
*/
|
|
58
|
+
readonly onError?: (error: unknown) => ReactElement;
|
|
31
59
|
}
|
|
32
60
|
/**
|
|
33
61
|
* Pass either the fetch-cache settings (works with no host configuration) or a `resolver` from
|
|
@@ -40,6 +68,8 @@ type HyleNextOptions = CommonOptions & (({
|
|
|
40
68
|
});
|
|
41
69
|
interface PageProps {
|
|
42
70
|
readonly params?: Promise<RouteParams>;
|
|
71
|
+
/** Read only with `paginate: "searchParams"`. */
|
|
72
|
+
readonly searchParams?: Promise<Record<string, string | string[] | undefined>>;
|
|
43
73
|
}
|
|
44
74
|
|
|
45
75
|
/**
|
|
@@ -50,17 +80,45 @@ interface PageProps {
|
|
|
50
80
|
* in front, and 301 maps to permanentRedirect (308) while 307 maps to redirect (temporary). A target equal to the current
|
|
51
81
|
* URL would loop, so it is treated as not found.
|
|
52
82
|
*
|
|
83
|
+
* Failure: a 4xx rejection of the request (400, 404, ...) is `notFound()`. Every other failure (network error, timeout, 5xx,
|
|
84
|
+
* 401, 403, 429, a malformed response, a refused redirect target) is RETHROWN, so under ISR Next keeps serving the last good
|
|
85
|
+
* page when a revalidation fails, and a first-render failure is an uncached 500 rather than a cached soft 200. `onError`
|
|
86
|
+
* opts in to a custom element instead (see its docs). `notFound()` and redirects always propagate (`unstable_rethrow`).
|
|
87
|
+
*
|
|
53
88
|
* Host requirement: no parent layout or page above the mount may export `dynamicParams = false`. Next inherits it, the
|
|
54
89
|
* route is compiled with `"fallback": false` and every article not known at build time is a hard 404 (it falls through
|
|
55
90
|
* to a `[locale]/[...rest]` catch-all). A page-level `dynamicParams = true` does not override a parent's false.
|
|
56
91
|
*/
|
|
57
92
|
declare function hylePage(options: HyleNextOptions): (props: PageProps) => Promise<ReactElement>;
|
|
58
93
|
|
|
94
|
+
type HyleSitemapOptions = HyleNextOptions & {
|
|
95
|
+
/** The site's public origin, for example "https://tdacorp.in": https, no path, query or credentials. */
|
|
96
|
+
readonly origin: string;
|
|
97
|
+
/** Section slugs to include besides the default section (their index must be `basePath/<slug>`). */
|
|
98
|
+
readonly sections?: readonly string[];
|
|
99
|
+
/**
|
|
100
|
+
* What to do when hyle fails or a listing is cut off. `"partial"`: return what was collected. `"throw"`: throw, so a build
|
|
101
|
+
* during a hyle outage fails instead of shipping a partial sitemap. Default: throw only when nothing was collected.
|
|
102
|
+
*/
|
|
103
|
+
readonly onIncomplete?: "partial" | "throw";
|
|
104
|
+
};
|
|
105
|
+
/**
|
|
106
|
+
* Sitemap entries for the mount, to spread into the host's `app/sitemap.ts`: `[...staticEntries, ...(await hyleSitemap({ ...sameOptionsAsHylePage, origin }))]`.
|
|
107
|
+
* Uses the same resolver (so the same cache and tags) as `hylePage`, and `localePrefix` for the URLs. `locale` is used only
|
|
108
|
+
* when it is a string: a function of the route params is never called here, so the sitemap is for the default locale.
|
|
109
|
+
* It pages each section index through `listPublicationPaths`, so only the default section and the listed `sections` appear,
|
|
110
|
+
* at most 2000 pages per section; paths are percent-encoded and `lastModified` is the publish time (omitted if it is not an
|
|
111
|
+
* ISO date). An invalid `origin` throws; see `onIncomplete` for hyle failures.
|
|
112
|
+
*/
|
|
113
|
+
declare function hyleSitemap(options: HyleSitemapOptions): Promise<MetadataRoute.Sitemap>;
|
|
114
|
+
|
|
59
115
|
/**
|
|
60
116
|
* `export const generateMetadata = hyleMetadata({ ... })` with the same options as `hylePage`. Title, description, a canonical
|
|
61
117
|
* URL in the page's own locale (so a fallback copy under another locale prefix points at the original), hreflang alternates
|
|
62
118
|
* from the response's `alternates`, and Open Graph. Paths are relative: set `metadataBase` in the host's root layout.
|
|
63
|
-
* Redirects, 404s and a switched-off read surface produce no metadata; `hylePage` handles those.
|
|
119
|
+
* Redirects, 404s and a switched-off read surface produce no metadata; `hylePage` handles those. A 4xx rejection of the request
|
|
120
|
+
* gives no metadata; any other failure (network, timeout, 5xx, 401, 403, 429) is rethrown, so a transient outage is not
|
|
121
|
+
* cached as a page; Next control flow is rethrown.
|
|
64
122
|
*/
|
|
65
123
|
declare function hyleMetadata(options: HyleNextOptions): (props: PageProps) => Promise<Metadata>;
|
|
66
124
|
|
|
@@ -81,4 +139,4 @@ interface RevalidateRouteOptions {
|
|
|
81
139
|
*/
|
|
82
140
|
declare function createRevalidateRoute(options: RevalidateRouteOptions): RevalidationCallbackRoute;
|
|
83
141
|
|
|
84
|
-
export { FetchResolverOptions, type HyleNextOptions, HyleResolver, type PageProps, type RevalidateRouteOptions, type RouteParams, createRevalidateRoute, hyleMetadata, hylePage };
|
|
142
|
+
export { FetchResolverOptions, type HyleNextOptions, HyleResolver, type HyleSitemapOptions, type PageProps, type RevalidateRouteOptions, type RouteParams, createRevalidateRoute, hyleMetadata, hylePage, hyleSitemap };
|
package/dist/next.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { ReactElement } from 'react';
|
|
2
2
|
import { H as HyleComponents, a as HyleSlots } from './types-BNaGecO7.js';
|
|
3
|
-
import { F as FetchResolverOptions, H as HyleResolver } from './resolve-
|
|
4
|
-
|
|
3
|
+
import { F as FetchResolverOptions, H as HyleResolver } from './resolve-fMx2W8RR.js';
|
|
4
|
+
export { f as fetchResolver, w as workspaceTags } from './resolve-fMx2W8RR.js';
|
|
5
|
+
import { MetadataRoute, Metadata } from 'next';
|
|
5
6
|
import { a as RevalidationCallbackRoute } from './revalidation-callback-D7Ms_Puz.js';
|
|
6
7
|
import './types-DjXf6iPo.js';
|
|
7
8
|
|
|
@@ -28,6 +29,33 @@ interface CommonOptions {
|
|
|
28
29
|
readonly layout?: "article" | "docs";
|
|
29
30
|
/** Items per list page (server default 20, maximum 100). */
|
|
30
31
|
readonly listLimit?: number;
|
|
32
|
+
/**
|
|
33
|
+
* Heading and description of the list page (the mount path's index). hyle names the default section after its slug
|
|
34
|
+
* ("Posts"); `list.title` replaces that in the page's h1, the `<title>` and Open Graph, and `list.description` fills the
|
|
35
|
+
* page description, `<meta name="description">` and Open Graph. Each falls back separately: title to the hyle section
|
|
36
|
+
* title, description to none. Article pages are unaffected.
|
|
37
|
+
*/
|
|
38
|
+
readonly list?: {
|
|
39
|
+
readonly title?: string;
|
|
40
|
+
readonly description?: string;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* `"searchParams"` makes list pages paginate: `?cursor=` is read, sent to hyle, and an "Older posts" link is built from
|
|
44
|
+
* `next_cursor`. Default off, and the trade-off is real: reading `searchParams` makes the route dynamic, so it can no longer
|
|
45
|
+
* be statically generated or served from ISR (hyle's fetch cache still applies). Leave it off when one page of `listLimit`
|
|
46
|
+
* items is enough. A malformed `cursor` is ignored (the first page is shown); one that is well-formed but unknown to hyle is a 404.
|
|
47
|
+
*/
|
|
48
|
+
readonly paginate?: "searchParams";
|
|
49
|
+
/**
|
|
50
|
+
* Opt-in custom UI for transient or operational hyle failures (network error, timeout, 5xx, 401, 403, 429, a malformed
|
|
51
|
+
* response, a refused redirect target). Without it `hylePage` rethrows them, so Next keeps serving the last good ISR page
|
|
52
|
+
* when a revalidation fails (and a failure on a first render is an uncached 500). With it, the returned element is a NORMAL
|
|
53
|
+
* render: it is cached for the revalidate window and replaces the last good page for that long, so prefer a boundary
|
|
54
|
+
* (`error.tsx`) unless you want that. The `error` can carry `Cp1ClientError.message` and `requestId`: never render it.
|
|
55
|
+
* Only its name is logged. A 4xx rejection of the request (400, 404, ...) is always `notFound()` and never reaches this, and
|
|
56
|
+
* `notFound()` and redirects are Next control flow that always propagate.
|
|
57
|
+
*/
|
|
58
|
+
readonly onError?: (error: unknown) => ReactElement;
|
|
31
59
|
}
|
|
32
60
|
/**
|
|
33
61
|
* Pass either the fetch-cache settings (works with no host configuration) or a `resolver` from
|
|
@@ -40,6 +68,8 @@ type HyleNextOptions = CommonOptions & (({
|
|
|
40
68
|
});
|
|
41
69
|
interface PageProps {
|
|
42
70
|
readonly params?: Promise<RouteParams>;
|
|
71
|
+
/** Read only with `paginate: "searchParams"`. */
|
|
72
|
+
readonly searchParams?: Promise<Record<string, string | string[] | undefined>>;
|
|
43
73
|
}
|
|
44
74
|
|
|
45
75
|
/**
|
|
@@ -50,17 +80,45 @@ interface PageProps {
|
|
|
50
80
|
* in front, and 301 maps to permanentRedirect (308) while 307 maps to redirect (temporary). A target equal to the current
|
|
51
81
|
* URL would loop, so it is treated as not found.
|
|
52
82
|
*
|
|
83
|
+
* Failure: a 4xx rejection of the request (400, 404, ...) is `notFound()`. Every other failure (network error, timeout, 5xx,
|
|
84
|
+
* 401, 403, 429, a malformed response, a refused redirect target) is RETHROWN, so under ISR Next keeps serving the last good
|
|
85
|
+
* page when a revalidation fails, and a first-render failure is an uncached 500 rather than a cached soft 200. `onError`
|
|
86
|
+
* opts in to a custom element instead (see its docs). `notFound()` and redirects always propagate (`unstable_rethrow`).
|
|
87
|
+
*
|
|
53
88
|
* Host requirement: no parent layout or page above the mount may export `dynamicParams = false`. Next inherits it, the
|
|
54
89
|
* route is compiled with `"fallback": false` and every article not known at build time is a hard 404 (it falls through
|
|
55
90
|
* to a `[locale]/[...rest]` catch-all). A page-level `dynamicParams = true` does not override a parent's false.
|
|
56
91
|
*/
|
|
57
92
|
declare function hylePage(options: HyleNextOptions): (props: PageProps) => Promise<ReactElement>;
|
|
58
93
|
|
|
94
|
+
type HyleSitemapOptions = HyleNextOptions & {
|
|
95
|
+
/** The site's public origin, for example "https://tdacorp.in": https, no path, query or credentials. */
|
|
96
|
+
readonly origin: string;
|
|
97
|
+
/** Section slugs to include besides the default section (their index must be `basePath/<slug>`). */
|
|
98
|
+
readonly sections?: readonly string[];
|
|
99
|
+
/**
|
|
100
|
+
* What to do when hyle fails or a listing is cut off. `"partial"`: return what was collected. `"throw"`: throw, so a build
|
|
101
|
+
* during a hyle outage fails instead of shipping a partial sitemap. Default: throw only when nothing was collected.
|
|
102
|
+
*/
|
|
103
|
+
readonly onIncomplete?: "partial" | "throw";
|
|
104
|
+
};
|
|
105
|
+
/**
|
|
106
|
+
* Sitemap entries for the mount, to spread into the host's `app/sitemap.ts`: `[...staticEntries, ...(await hyleSitemap({ ...sameOptionsAsHylePage, origin }))]`.
|
|
107
|
+
* Uses the same resolver (so the same cache and tags) as `hylePage`, and `localePrefix` for the URLs. `locale` is used only
|
|
108
|
+
* when it is a string: a function of the route params is never called here, so the sitemap is for the default locale.
|
|
109
|
+
* It pages each section index through `listPublicationPaths`, so only the default section and the listed `sections` appear,
|
|
110
|
+
* at most 2000 pages per section; paths are percent-encoded and `lastModified` is the publish time (omitted if it is not an
|
|
111
|
+
* ISO date). An invalid `origin` throws; see `onIncomplete` for hyle failures.
|
|
112
|
+
*/
|
|
113
|
+
declare function hyleSitemap(options: HyleSitemapOptions): Promise<MetadataRoute.Sitemap>;
|
|
114
|
+
|
|
59
115
|
/**
|
|
60
116
|
* `export const generateMetadata = hyleMetadata({ ... })` with the same options as `hylePage`. Title, description, a canonical
|
|
61
117
|
* URL in the page's own locale (so a fallback copy under another locale prefix points at the original), hreflang alternates
|
|
62
118
|
* from the response's `alternates`, and Open Graph. Paths are relative: set `metadataBase` in the host's root layout.
|
|
63
|
-
* Redirects, 404s and a switched-off read surface produce no metadata; `hylePage` handles those.
|
|
119
|
+
* Redirects, 404s and a switched-off read surface produce no metadata; `hylePage` handles those. A 4xx rejection of the request
|
|
120
|
+
* gives no metadata; any other failure (network, timeout, 5xx, 401, 403, 429) is rethrown, so a transient outage is not
|
|
121
|
+
* cached as a page; Next control flow is rethrown.
|
|
64
122
|
*/
|
|
65
123
|
declare function hyleMetadata(options: HyleNextOptions): (props: PageProps) => Promise<Metadata>;
|
|
66
124
|
|
|
@@ -81,4 +139,4 @@ interface RevalidateRouteOptions {
|
|
|
81
139
|
*/
|
|
82
140
|
declare function createRevalidateRoute(options: RevalidateRouteOptions): RevalidationCallbackRoute;
|
|
83
141
|
|
|
84
|
-
export { FetchResolverOptions, type HyleNextOptions, HyleResolver, type PageProps, type RevalidateRouteOptions, type RouteParams, createRevalidateRoute, hyleMetadata, hylePage };
|
|
142
|
+
export { FetchResolverOptions, type HyleNextOptions, HyleResolver, type HyleSitemapOptions, type PageProps, type RevalidateRouteOptions, type RouteParams, createRevalidateRoute, hyleMetadata, hylePage, hyleSitemap };
|