@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.js
CHANGED
|
@@ -2,18 +2,23 @@ import {
|
|
|
2
2
|
ArticlePage,
|
|
3
3
|
DocsPage,
|
|
4
4
|
ListPage
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-MHVWHSKC.js";
|
|
6
6
|
import {
|
|
7
|
-
fetchResolver
|
|
8
|
-
|
|
7
|
+
fetchResolver,
|
|
8
|
+
workspaceTags
|
|
9
|
+
} from "./chunk-7VCMJUPC.js";
|
|
9
10
|
import {
|
|
10
11
|
Cp1ClientError,
|
|
11
|
-
createRevalidationCallbackRoute
|
|
12
|
-
|
|
12
|
+
createRevalidationCallbackRoute,
|
|
13
|
+
listPublicationPaths
|
|
14
|
+
} from "./chunk-HFUJRNFP.js";
|
|
13
15
|
|
|
14
16
|
// src/next/page.tsx
|
|
15
17
|
import { notFound, permanentRedirect, redirect } from "next/navigation";
|
|
16
18
|
|
|
19
|
+
// src/next/options.ts
|
|
20
|
+
import { unstable_rethrow } from "next/navigation";
|
|
21
|
+
|
|
17
22
|
// src/next/paths.ts
|
|
18
23
|
function normalizeBasePath(basePath) {
|
|
19
24
|
const value = (basePath ?? "").replace(/\/+$/, "");
|
|
@@ -21,6 +26,7 @@ function normalizeBasePath(basePath) {
|
|
|
21
26
|
if (!/^\/[^\s?#\\]+$/.test(value) || value.includes("//")) throw new TypeError(`basePath must look like "/learn", got "${basePath}"`);
|
|
22
27
|
return value;
|
|
23
28
|
}
|
|
29
|
+
var MAX_PATH_LENGTH = 1024;
|
|
24
30
|
function sitePathFrom(basePath, segments) {
|
|
25
31
|
const decoded = [];
|
|
26
32
|
for (const raw of segments ?? []) {
|
|
@@ -30,10 +36,12 @@ function sitePathFrom(basePath, segments) {
|
|
|
30
36
|
} catch {
|
|
31
37
|
return void 0;
|
|
32
38
|
}
|
|
39
|
+
if (segment !== segment.normalize("NFC")) return void 0;
|
|
33
40
|
if (segment === "" || segment === "." || segment === ".." || /[/\\\u0000-\u001f\u007f]/.test(segment)) return void 0;
|
|
34
41
|
decoded.push(segment);
|
|
35
42
|
}
|
|
36
|
-
|
|
43
|
+
const path = decoded.length === 0 ? basePath || "/" : `${basePath}/${decoded.join("/")}`;
|
|
44
|
+
return path.length > MAX_PATH_LENGTH ? void 0 : path;
|
|
37
45
|
}
|
|
38
46
|
function safeRedirectTarget(to) {
|
|
39
47
|
if (typeof to !== "string" || !to.startsWith("/") || to.startsWith("//")) return void 0;
|
|
@@ -44,77 +52,135 @@ function safeRedirectTarget(to) {
|
|
|
44
52
|
function resolverFor(options) {
|
|
45
53
|
return options.resolver ?? fetchResolver(options);
|
|
46
54
|
}
|
|
47
|
-
var
|
|
55
|
+
var CURSOR = /^[A-Za-z0-9_-]{1,256}$/;
|
|
56
|
+
var validCursor = (value) => typeof value === "string" && CURSOR.test(value) ? value : void 0;
|
|
57
|
+
var LOCALE_TAG = /^[a-z]{2,3}(-[A-Za-z0-9]{2,8})*$/;
|
|
58
|
+
var MAX_LOCALE_LENGTH = 35;
|
|
48
59
|
function routeContext(options, params) {
|
|
49
60
|
const basePath = normalizeBasePath(options.basePath);
|
|
50
61
|
const segments = params[options.param ?? "hyle"];
|
|
51
62
|
const path = sitePathFrom(basePath, typeof segments === "string" ? [segments] : segments);
|
|
52
63
|
const given = typeof options.locale === "function" ? options.locale(params) : options.locale;
|
|
53
|
-
const locale = typeof given === "string" && LOCALE_TAG.test(given) ? given : void 0;
|
|
64
|
+
const locale = typeof given === "string" && given.length <= MAX_LOCALE_LENGTH && LOCALE_TAG.test(given) ? given : void 0;
|
|
54
65
|
const prefix = options.localePrefix ?? (() => "");
|
|
55
66
|
const toHref = (sitePath, linkLocale = locale) => (linkLocale ? prefix(linkLocale) : "") + sitePath;
|
|
56
67
|
return { basePath, path, locale, toHref };
|
|
57
68
|
}
|
|
69
|
+
function isRejectedRequest(error) {
|
|
70
|
+
unstable_rethrow(error);
|
|
71
|
+
return error instanceof Cp1ClientError && error.status >= 400 && error.status < 500 && ![401, 403, 429].includes(error.status);
|
|
72
|
+
}
|
|
58
73
|
|
|
59
74
|
// src/next/page.tsx
|
|
60
75
|
import { jsx } from "react/jsx-runtime";
|
|
61
76
|
function hylePage(options) {
|
|
62
77
|
const resolve = resolverFor(options);
|
|
63
|
-
return async function HylePage({ params }) {
|
|
78
|
+
return async function HylePage({ params, searchParams }) {
|
|
64
79
|
const { path, locale, toHref } = routeContext(options, await params ?? {});
|
|
65
80
|
if (path === void 0) notFound();
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
+
try {
|
|
82
|
+
const cursor = options.paginate === "searchParams" ? validCursor((await searchParams)?.cursor) : void 0;
|
|
83
|
+
const result = await resolve(path, locale, options.listLimit, cursor);
|
|
84
|
+
switch (result.kind) {
|
|
85
|
+
case "article": {
|
|
86
|
+
const props = { article: result, components: options.components, slots: options.slots, locale, toHref };
|
|
87
|
+
return options.layout === "docs" ? /* @__PURE__ */ jsx(DocsPage, { ...props }) : /* @__PURE__ */ jsx(ArticlePage, { ...props });
|
|
88
|
+
}
|
|
89
|
+
case "list": {
|
|
90
|
+
const list = options.list?.title ? { ...result, section: { ...result.section, title: options.list.title } } : result;
|
|
91
|
+
const next = options.paginate === "searchParams" ? validCursor(result.next_cursor) : void 0;
|
|
92
|
+
const olderHref = next ? `${toHref(path)}?cursor=${next}` : void 0;
|
|
93
|
+
return /* @__PURE__ */ jsx(ListPage, { list, ...olderHref ? { olderHref } : {}, ...options.list?.description ? { description: options.list.description } : {}, components: options.components, slots: options.slots, locale, toHref });
|
|
94
|
+
}
|
|
95
|
+
case "redirect": {
|
|
96
|
+
const to = safeRedirectTarget(result.to);
|
|
97
|
+
if (to === void 0) throw new Cp1ClientError("INVALID_RESPONSE", "hyle returned an unsafe redirect target", 502, "");
|
|
98
|
+
const target = safeRedirectTarget(toHref(to));
|
|
99
|
+
if (target === void 0) throw new Cp1ClientError("INVALID_RESPONSE", "hyle returned an unsafe redirect target", 502, "");
|
|
100
|
+
if (target === toHref(path)) notFound();
|
|
101
|
+
return result.status === 301 ? permanentRedirect(target) : redirect(target);
|
|
102
|
+
}
|
|
103
|
+
case "notfound":
|
|
104
|
+
case "disabled":
|
|
105
|
+
notFound();
|
|
81
106
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
107
|
+
} catch (error) {
|
|
108
|
+
if (isRejectedRequest(error)) notFound();
|
|
109
|
+
if (!options.onError) throw error;
|
|
110
|
+
console.error(`hyle: ${error instanceof Error ? error.name : "UnknownError"}`);
|
|
111
|
+
return options.onError(error);
|
|
85
112
|
}
|
|
86
113
|
};
|
|
87
114
|
}
|
|
88
115
|
|
|
116
|
+
// src/next/sitemap.ts
|
|
117
|
+
var ISO_DATE = /^\d{4}-\d{2}-\d{2}T/;
|
|
118
|
+
function httpsOrigin(origin) {
|
|
119
|
+
let url;
|
|
120
|
+
try {
|
|
121
|
+
url = new URL(origin);
|
|
122
|
+
} catch {
|
|
123
|
+
throw new TypeError("hyleSitemap: `origin` must be an https origin such as https://example.com");
|
|
124
|
+
}
|
|
125
|
+
if (url.protocol !== "https:" || url.origin !== origin.replace(/\/$/, "")) {
|
|
126
|
+
throw new TypeError("hyleSitemap: `origin` must be an https origin with no path, query or credentials");
|
|
127
|
+
}
|
|
128
|
+
return url.origin;
|
|
129
|
+
}
|
|
130
|
+
async function hyleSitemap(options) {
|
|
131
|
+
const origin = httpsOrigin(options.origin);
|
|
132
|
+
const resolve = resolverFor(options);
|
|
133
|
+
const locale = typeof options.locale === "string" ? options.locale : void 0;
|
|
134
|
+
const { basePath, toHref } = routeContext({ ...options, locale: () => locale }, {});
|
|
135
|
+
const client = { resolve: ({ path, locale: l, limit, cursor }) => resolve(path, l, limit, cursor) };
|
|
136
|
+
const { paths, complete } = await listPublicationPaths({ client, basePath, ...options.sections ? { sections: options.sections } : {}, ...locale ? { locale } : {} });
|
|
137
|
+
if (!complete && (options.onIncomplete === "throw" || options.onIncomplete === void 0 && paths.length === 0)) {
|
|
138
|
+
throw new Error("hyleSitemap: hyle could not be listed completely (see onIncomplete)");
|
|
139
|
+
}
|
|
140
|
+
return paths.map(({ path, publishedAt }) => ({
|
|
141
|
+
url: origin + encodeURI(toHref(path)),
|
|
142
|
+
...ISO_DATE.test(publishedAt) && !Number.isNaN(Date.parse(publishedAt)) ? { lastModified: publishedAt } : {}
|
|
143
|
+
}));
|
|
144
|
+
}
|
|
145
|
+
|
|
89
146
|
// src/next/metadata.ts
|
|
90
147
|
function hyleMetadata(options) {
|
|
91
148
|
const resolve = resolverFor(options);
|
|
92
149
|
return async function generateMetadata({ params }) {
|
|
93
150
|
const { path, locale, toHref } = routeContext(options, await params ?? {});
|
|
94
151
|
if (path === void 0) return {};
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
},
|
|
108
|
-
openGraph: {
|
|
109
|
-
type: "article",
|
|
152
|
+
try {
|
|
153
|
+
const result = await resolve(path, locale, options.listLimit);
|
|
154
|
+
if (result.kind === "list") {
|
|
155
|
+
const title = options.list?.title || result.section.title;
|
|
156
|
+
const description2 = options.list?.description;
|
|
157
|
+
return { title, ...description2 ? { description: description2 } : {}, openGraph: { title, ...description2 ? { description: description2 } : {} } };
|
|
158
|
+
}
|
|
159
|
+
if (result.kind !== "article") return {};
|
|
160
|
+
const { publication: pub, alternates } = result;
|
|
161
|
+
const canonical = toHref(pub.canonical_path, pub.locale);
|
|
162
|
+
const description = pub.description ?? void 0;
|
|
163
|
+
return {
|
|
110
164
|
title: pub.title,
|
|
111
165
|
...description ? { description } : {},
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
166
|
+
alternates: {
|
|
167
|
+
canonical,
|
|
168
|
+
...alternates.length > 1 ? { languages: Object.fromEntries(alternates.map((a) => [a.locale, toHref(a.canonical_path, a.locale)])) } : {}
|
|
169
|
+
},
|
|
170
|
+
openGraph: {
|
|
171
|
+
type: "article",
|
|
172
|
+
title: pub.title,
|
|
173
|
+
...description ? { description } : {},
|
|
174
|
+
url: canonical,
|
|
175
|
+
locale: pub.locale,
|
|
176
|
+
publishedTime: pub.published_at,
|
|
177
|
+
modifiedTime: pub.updated_at
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
} catch (error) {
|
|
181
|
+
if (isRejectedRequest(error)) return {};
|
|
182
|
+
throw error;
|
|
183
|
+
}
|
|
118
184
|
};
|
|
119
185
|
}
|
|
120
186
|
|
|
@@ -140,6 +206,9 @@ function createRevalidateRoute(options) {
|
|
|
140
206
|
}
|
|
141
207
|
export {
|
|
142
208
|
createRevalidateRoute,
|
|
209
|
+
fetchResolver,
|
|
143
210
|
hyleMetadata,
|
|
144
|
-
hylePage
|
|
211
|
+
hylePage,
|
|
212
|
+
hyleSitemap,
|
|
213
|
+
workspaceTags
|
|
145
214
|
};
|
package/dist/react.cjs
CHANGED
|
@@ -28,6 +28,7 @@ __export(react_exports, {
|
|
|
28
28
|
NotFound: () => NotFound,
|
|
29
29
|
Redirecting: () => Redirecting,
|
|
30
30
|
TrustedServerHtml: () => TrustedServerHtml,
|
|
31
|
+
Unavailable: () => Unavailable,
|
|
31
32
|
isSafeUrl: () => isSafeUrl,
|
|
32
33
|
sanitizeHast: () => sanitizeHast,
|
|
33
34
|
scopeId: () => scopeId,
|
|
@@ -280,7 +281,10 @@ var en = {
|
|
|
280
281
|
rdBody: "You are being taken to its new address.",
|
|
281
282
|
from: "From",
|
|
282
283
|
to: "To",
|
|
283
|
-
rdFallback: "If nothing happens, go to the new address."
|
|
284
|
+
rdFallback: "If nothing happens, go to the new address.",
|
|
285
|
+
unKind: "Unavailable",
|
|
286
|
+
unTitle: "This page is temporarily unavailable",
|
|
287
|
+
unBody: "The content could not be loaded. Please try again in a moment."
|
|
284
288
|
};
|
|
285
289
|
var fr = {
|
|
286
290
|
toc: "Sur cette page",
|
|
@@ -316,7 +320,10 @@ var fr = {
|
|
|
316
320
|
rdBody: "Vous \xEAtes redirig\xE9 vers sa nouvelle adresse.",
|
|
317
321
|
from: "De",
|
|
318
322
|
to: "Vers",
|
|
319
|
-
rdFallback: "Si rien ne se passe, allez \xE0 la nouvelle adresse."
|
|
323
|
+
rdFallback: "Si rien ne se passe, allez \xE0 la nouvelle adresse.",
|
|
324
|
+
unKind: "Indisponible",
|
|
325
|
+
unTitle: "Cette page est momentan\xE9ment indisponible",
|
|
326
|
+
unBody: "Le contenu n'a pas pu \xEAtre charg\xE9. R\xE9essayez dans un instant."
|
|
320
327
|
};
|
|
321
328
|
var es = {
|
|
322
329
|
toc: "En esta p\xE1gina",
|
|
@@ -352,7 +359,10 @@ var es = {
|
|
|
352
359
|
rdBody: "Te estamos llevando a su nueva direcci\xF3n.",
|
|
353
360
|
from: "Desde",
|
|
354
361
|
to: "A",
|
|
355
|
-
rdFallback: "Si no pasa nada, ve a la nueva direcci\xF3n."
|
|
362
|
+
rdFallback: "Si no pasa nada, ve a la nueva direcci\xF3n.",
|
|
363
|
+
unKind: "No disponible",
|
|
364
|
+
unTitle: "Esta p\xE1gina no est\xE1 disponible por el momento",
|
|
365
|
+
unBody: "No se pudo cargar el contenido. Int\xE9ntalo de nuevo en un momento."
|
|
356
366
|
};
|
|
357
367
|
var TABLE = { en, fr, es };
|
|
358
368
|
function stringsFor(locale) {
|
|
@@ -716,6 +726,14 @@ function NotFound({ path, homeHref = "/", ...base }) {
|
|
|
716
726
|
] })
|
|
717
727
|
] }) });
|
|
718
728
|
}
|
|
729
|
+
function Unavailable(base) {
|
|
730
|
+
const c = ctx(base, "en");
|
|
731
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Shell, { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("section", { className: "hyle-state", "data-hyle-page": "unavailable", lang: c.locale, role: "status", children: [
|
|
732
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "kind", children: c.s.unKind }),
|
|
733
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h1", { children: c.s.unTitle }),
|
|
734
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { children: c.s.unBody })
|
|
735
|
+
] }) });
|
|
736
|
+
}
|
|
719
737
|
function Redirecting({ from, to, ...base }) {
|
|
720
738
|
const c = ctx(base, "en");
|
|
721
739
|
const { Link, s } = c;
|
|
@@ -748,6 +766,7 @@ function Redirecting({ from, to, ...base }) {
|
|
|
748
766
|
NotFound,
|
|
749
767
|
Redirecting,
|
|
750
768
|
TrustedServerHtml,
|
|
769
|
+
Unavailable,
|
|
751
770
|
isSafeUrl,
|
|
752
771
|
sanitizeHast,
|
|
753
772
|
scopeId,
|
package/dist/react.d.cts
CHANGED
|
@@ -62,6 +62,8 @@ interface NotFoundProps extends PageBaseProps {
|
|
|
62
62
|
homeHref?: string;
|
|
63
63
|
}
|
|
64
64
|
declare function NotFound({ path, homeHref, ...base }: NotFoundProps): ReactElement;
|
|
65
|
+
/** The fail-safe state `hylePage` renders when hyle cannot be reached. It takes no error: nothing internal can reach the markup. */
|
|
66
|
+
declare function Unavailable(base: PageBaseProps): ReactElement;
|
|
65
67
|
interface RedirectingProps extends PageBaseProps {
|
|
66
68
|
from?: string;
|
|
67
69
|
to: string;
|
|
@@ -108,9 +110,12 @@ declare const en: {
|
|
|
108
110
|
from: string;
|
|
109
111
|
to: string;
|
|
110
112
|
rdFallback: string;
|
|
113
|
+
unKind: string;
|
|
114
|
+
unTitle: string;
|
|
115
|
+
unBody: string;
|
|
111
116
|
};
|
|
112
117
|
type Strings = typeof en;
|
|
113
118
|
/** Strings for a BCP 47 tag; the primary subtag decides, anything unknown falls back to English. */
|
|
114
119
|
declare function stringsFor(locale: string | undefined): Strings;
|
|
115
120
|
|
|
116
|
-
export { ArticlePage, type ArticlePageProps, DocsPage, HastContent, type HastContentProps, HastLimitError, HyleComponents, ListPage, type ListPageProps, NotFound, type NotFoundProps, PageBaseProps, Redirecting, type RedirectingProps, type Strings, TrustedServerHtml, isSafeUrl, sanitizeHast, scopeId, stringsFor };
|
|
121
|
+
export { ArticlePage, type ArticlePageProps, DocsPage, HastContent, type HastContentProps, HastLimitError, HyleComponents, ListPage, type ListPageProps, NotFound, type NotFoundProps, PageBaseProps, Redirecting, type RedirectingProps, type Strings, TrustedServerHtml, Unavailable, isSafeUrl, sanitizeHast, scopeId, stringsFor };
|
package/dist/react.d.ts
CHANGED
|
@@ -62,6 +62,8 @@ interface NotFoundProps extends PageBaseProps {
|
|
|
62
62
|
homeHref?: string;
|
|
63
63
|
}
|
|
64
64
|
declare function NotFound({ path, homeHref, ...base }: NotFoundProps): ReactElement;
|
|
65
|
+
/** The fail-safe state `hylePage` renders when hyle cannot be reached. It takes no error: nothing internal can reach the markup. */
|
|
66
|
+
declare function Unavailable(base: PageBaseProps): ReactElement;
|
|
65
67
|
interface RedirectingProps extends PageBaseProps {
|
|
66
68
|
from?: string;
|
|
67
69
|
to: string;
|
|
@@ -108,9 +110,12 @@ declare const en: {
|
|
|
108
110
|
from: string;
|
|
109
111
|
to: string;
|
|
110
112
|
rdFallback: string;
|
|
113
|
+
unKind: string;
|
|
114
|
+
unTitle: string;
|
|
115
|
+
unBody: string;
|
|
111
116
|
};
|
|
112
117
|
type Strings = typeof en;
|
|
113
118
|
/** Strings for a BCP 47 tag; the primary subtag decides, anything unknown falls back to English. */
|
|
114
119
|
declare function stringsFor(locale: string | undefined): Strings;
|
|
115
120
|
|
|
116
|
-
export { ArticlePage, type ArticlePageProps, DocsPage, HastContent, type HastContentProps, HastLimitError, HyleComponents, ListPage, type ListPageProps, NotFound, type NotFoundProps, PageBaseProps, Redirecting, type RedirectingProps, type Strings, TrustedServerHtml, isSafeUrl, sanitizeHast, scopeId, stringsFor };
|
|
121
|
+
export { ArticlePage, type ArticlePageProps, DocsPage, HastContent, type HastContentProps, HastLimitError, HyleComponents, ListPage, type ListPageProps, NotFound, type NotFoundProps, PageBaseProps, Redirecting, type RedirectingProps, type Strings, TrustedServerHtml, Unavailable, isSafeUrl, sanitizeHast, scopeId, stringsFor };
|
package/dist/react.js
CHANGED
|
@@ -7,11 +7,12 @@ import {
|
|
|
7
7
|
NotFound,
|
|
8
8
|
Redirecting,
|
|
9
9
|
TrustedServerHtml,
|
|
10
|
+
Unavailable,
|
|
10
11
|
isSafeUrl,
|
|
11
12
|
sanitizeHast,
|
|
12
13
|
scopeId,
|
|
13
14
|
stringsFor
|
|
14
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-MHVWHSKC.js";
|
|
15
16
|
export {
|
|
16
17
|
ArticlePage,
|
|
17
18
|
DocsPage,
|
|
@@ -21,6 +22,7 @@ export {
|
|
|
21
22
|
NotFound,
|
|
22
23
|
Redirecting,
|
|
23
24
|
TrustedServerHtml,
|
|
25
|
+
Unavailable,
|
|
24
26
|
isSafeUrl,
|
|
25
27
|
sanitizeHast,
|
|
26
28
|
scopeId,
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { R as Resolved } from './types-DjXf6iPo.cjs';
|
|
2
|
+
|
|
3
|
+
/** Resolves a site path to a result. The two built-in strategies are `fetchResolver` (default) and `cachedResolver` (`@tdacorp/hyle-sdk/next/use-cache`). */
|
|
4
|
+
type HyleResolver = (path: string, locale: string | undefined, limit?: number, cursor?: string) => Promise<Resolved>;
|
|
5
|
+
interface FetchResolverOptions {
|
|
6
|
+
readonly baseUrl: string;
|
|
7
|
+
readonly token: string;
|
|
8
|
+
/** The workspace id (HYLE_WORKSPACE_ID): the fetch is tagged before the response exists, so tags are built from it. */
|
|
9
|
+
readonly workspaceId: string;
|
|
10
|
+
/** Seconds before a cached page is revalidated in the background. Webhooks purge sooner. Default 300. */
|
|
11
|
+
readonly revalidate?: number;
|
|
12
|
+
/** Section slugs this mount can show besides the default "posts". Used only for tagging. */
|
|
13
|
+
readonly sections?: readonly string[];
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* The fetch cache tags for a workspace, in the contract's format (`hyle:1:ws:<id>`, `hyle:1:sec:<ws>:<section>`; docs/cp1-spec.md
|
|
17
|
+
* section 5.8). Tags known BEFORE the response, bounded however many URLs a visitor requests: the workspace tag, the default section
|
|
18
|
+
* and the configured `sections`. A publish, unpublish, rename or edit purges the section tag of the page's section, and the
|
|
19
|
+
* workspace tag covers section renames and the kill switch (docs/cp1-spec.md section 5.8), so a page refreshes without its
|
|
20
|
+
* own publication tag. A bad `workspaceId` or section slug throws a TypeError. A section not listed in `sections` falls back to `revalidate`, as does cross-section wikilink refresh.
|
|
21
|
+
*/
|
|
22
|
+
declare function workspaceTags(workspaceId: string, sections?: readonly string[]): string[];
|
|
23
|
+
/**
|
|
24
|
+
* Next's fetch cache, tagged with `workspaceTags`: the default resolver of `hylePage`, exported to wrap (for example to adjust a
|
|
25
|
+
* result) or to reuse in a host's own routes. Works with no host configuration. Throws a TypeError without `workspaceId`.
|
|
26
|
+
*/
|
|
27
|
+
declare function fetchResolver(options: FetchResolverOptions): HyleResolver;
|
|
28
|
+
|
|
29
|
+
export { type FetchResolverOptions as F, type HyleResolver as H, fetchResolver as f, workspaceTags as w };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { R as Resolved } from './types-DjXf6iPo.js';
|
|
2
|
+
|
|
3
|
+
/** Resolves a site path to a result. The two built-in strategies are `fetchResolver` (default) and `cachedResolver` (`@tdacorp/hyle-sdk/next/use-cache`). */
|
|
4
|
+
type HyleResolver = (path: string, locale: string | undefined, limit?: number, cursor?: string) => Promise<Resolved>;
|
|
5
|
+
interface FetchResolverOptions {
|
|
6
|
+
readonly baseUrl: string;
|
|
7
|
+
readonly token: string;
|
|
8
|
+
/** The workspace id (HYLE_WORKSPACE_ID): the fetch is tagged before the response exists, so tags are built from it. */
|
|
9
|
+
readonly workspaceId: string;
|
|
10
|
+
/** Seconds before a cached page is revalidated in the background. Webhooks purge sooner. Default 300. */
|
|
11
|
+
readonly revalidate?: number;
|
|
12
|
+
/** Section slugs this mount can show besides the default "posts". Used only for tagging. */
|
|
13
|
+
readonly sections?: readonly string[];
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* The fetch cache tags for a workspace, in the contract's format (`hyle:1:ws:<id>`, `hyle:1:sec:<ws>:<section>`; docs/cp1-spec.md
|
|
17
|
+
* section 5.8). Tags known BEFORE the response, bounded however many URLs a visitor requests: the workspace tag, the default section
|
|
18
|
+
* and the configured `sections`. A publish, unpublish, rename or edit purges the section tag of the page's section, and the
|
|
19
|
+
* workspace tag covers section renames and the kill switch (docs/cp1-spec.md section 5.8), so a page refreshes without its
|
|
20
|
+
* own publication tag. A bad `workspaceId` or section slug throws a TypeError. A section not listed in `sections` falls back to `revalidate`, as does cross-section wikilink refresh.
|
|
21
|
+
*/
|
|
22
|
+
declare function workspaceTags(workspaceId: string, sections?: readonly string[]): string[];
|
|
23
|
+
/**
|
|
24
|
+
* Next's fetch cache, tagged with `workspaceTags`: the default resolver of `hylePage`, exported to wrap (for example to adjust a
|
|
25
|
+
* result) or to reuse in a host's own routes. Works with no host configuration. Throws a TypeError without `workspaceId`.
|
|
26
|
+
*/
|
|
27
|
+
declare function fetchResolver(options: FetchResolverOptions): HyleResolver;
|
|
28
|
+
|
|
29
|
+
export { type FetchResolverOptions as F, type HyleResolver as H, fetchResolver as f, workspaceTags as w };
|
package/dist/use-cache.cjs
CHANGED
|
@@ -125,11 +125,11 @@ var MAX_TAGS = 128;
|
|
|
125
125
|
var DISABLED_REVALIDATE = 30;
|
|
126
126
|
var tokens = /* @__PURE__ */ new Map();
|
|
127
127
|
var keyOf = (baseUrl, workspaceId) => `${baseUrl}\0${workspaceId}`;
|
|
128
|
-
async function resolveCached(baseUrl, workspaceId, path, locale, limit, revalidate) {
|
|
128
|
+
async function resolveCached(baseUrl, workspaceId, path, locale, limit, cursor, revalidate) {
|
|
129
129
|
"use cache";
|
|
130
130
|
const token = tokens.get(keyOf(baseUrl, workspaceId));
|
|
131
131
|
if (!token) throw new Error("hyle: unknown cache configuration");
|
|
132
|
-
const result = await createHyleClient({ baseUrl, token }).resolve({ path, ...locale ? { locale } : {}, ...limit > 0 ? { limit } : {} });
|
|
132
|
+
const result = await createHyleClient({ baseUrl, token }).resolve({ path, ...locale ? { locale } : {}, ...limit > 0 ? { limit } : {}, ...cursor ? { cursor } : {} });
|
|
133
133
|
if (result.kind !== "disabled") (0, import_cache.cacheTag)(...result.cache.tags.filter(isValidCacheTag).slice(0, MAX_TAGS));
|
|
134
134
|
(0, import_cache.cacheLife)({ stale: 30, revalidate: result.kind === "disabled" ? Math.min(revalidate, DISABLED_REVALIDATE) : revalidate });
|
|
135
135
|
return result;
|
|
@@ -137,7 +137,7 @@ async function resolveCached(baseUrl, workspaceId, path, locale, limit, revalida
|
|
|
137
137
|
function cachedResolver(options) {
|
|
138
138
|
tokens.set(keyOf(options.baseUrl, options.workspaceId), options.token);
|
|
139
139
|
const revalidate = options.revalidate ?? DEFAULT_REVALIDATE;
|
|
140
|
-
return (path, locale, limit) => resolveCached(options.baseUrl, options.workspaceId, path, locale ?? "", limit ?? 0, revalidate);
|
|
140
|
+
return (path, locale, limit, cursor) => resolveCached(options.baseUrl, options.workspaceId, path, locale ?? "", limit ?? 0, cursor ?? "", revalidate);
|
|
141
141
|
}
|
|
142
142
|
// Annotate the CommonJS export names for ESM import in node:
|
|
143
143
|
0 && (module.exports = {
|
package/dist/use-cache.d.cts
CHANGED
package/dist/use-cache.d.ts
CHANGED
package/dist/use-cache.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
DEFAULT_REVALIDATE
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-7VCMJUPC.js";
|
|
4
4
|
import {
|
|
5
5
|
createHyleClient,
|
|
6
6
|
isValidCacheTag
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-HFUJRNFP.js";
|
|
8
8
|
|
|
9
9
|
// src/next/use-cache.ts
|
|
10
10
|
import { cacheLife, cacheTag } from "next/cache";
|
|
@@ -12,11 +12,11 @@ var MAX_TAGS = 128;
|
|
|
12
12
|
var DISABLED_REVALIDATE = 30;
|
|
13
13
|
var tokens = /* @__PURE__ */ new Map();
|
|
14
14
|
var keyOf = (baseUrl, workspaceId) => `${baseUrl}\0${workspaceId}`;
|
|
15
|
-
async function resolveCached(baseUrl, workspaceId, path, locale, limit, revalidate) {
|
|
15
|
+
async function resolveCached(baseUrl, workspaceId, path, locale, limit, cursor, revalidate) {
|
|
16
16
|
"use cache";
|
|
17
17
|
const token = tokens.get(keyOf(baseUrl, workspaceId));
|
|
18
18
|
if (!token) throw new Error("hyle: unknown cache configuration");
|
|
19
|
-
const result = await createHyleClient({ baseUrl, token }).resolve({ path, ...locale ? { locale } : {}, ...limit > 0 ? { limit } : {} });
|
|
19
|
+
const result = await createHyleClient({ baseUrl, token }).resolve({ path, ...locale ? { locale } : {}, ...limit > 0 ? { limit } : {}, ...cursor ? { cursor } : {} });
|
|
20
20
|
if (result.kind !== "disabled") cacheTag(...result.cache.tags.filter(isValidCacheTag).slice(0, MAX_TAGS));
|
|
21
21
|
cacheLife({ stale: 30, revalidate: result.kind === "disabled" ? Math.min(revalidate, DISABLED_REVALIDATE) : revalidate });
|
|
22
22
|
return result;
|
|
@@ -24,7 +24,7 @@ async function resolveCached(baseUrl, workspaceId, path, locale, limit, revalida
|
|
|
24
24
|
function cachedResolver(options) {
|
|
25
25
|
tokens.set(keyOf(options.baseUrl, options.workspaceId), options.token);
|
|
26
26
|
const revalidate = options.revalidate ?? DEFAULT_REVALIDATE;
|
|
27
|
-
return (path, locale, limit) => resolveCached(options.baseUrl, options.workspaceId, path, locale ?? "", limit ?? 0, revalidate);
|
|
27
|
+
return (path, locale, limit, cursor) => resolveCached(options.baseUrl, options.workspaceId, path, locale ?? "", limit ?? 0, cursor ?? "", revalidate);
|
|
28
28
|
}
|
|
29
29
|
export {
|
|
30
30
|
cachedResolver
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tdacorp/hyle-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "hyle SDK: a typed client for hyle's resolve endpoint, a hast renderer for React, and a Next.js catch-all page with tag-based revalidation.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
package/dist/chunk-HVAWEEHG.js
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
createHyleClient,
|
|
3
|
-
isValidCacheTag
|
|
4
|
-
} from "./chunk-RI3BP4MI.js";
|
|
5
|
-
|
|
6
|
-
// src/next/resolve.ts
|
|
7
|
-
var DEFAULT_REVALIDATE = 300;
|
|
8
|
-
var MAX_TAGS = 64;
|
|
9
|
-
function fetchTags(workspaceId, sections = []) {
|
|
10
|
-
const slugs = /* @__PURE__ */ new Set(["posts", ...sections]);
|
|
11
|
-
return [`hyle:1:ws:${workspaceId}`, ...[...slugs].map((s) => `hyle:1:sec:${workspaceId}:${s}`)].filter(isValidCacheTag).slice(0, MAX_TAGS);
|
|
12
|
-
}
|
|
13
|
-
function fetchResolver(options) {
|
|
14
|
-
if (!options.workspaceId) throw new TypeError("hylePage: `workspaceId` is required for the fetch cache (or pass a cachedResolver)");
|
|
15
|
-
const client = createHyleClient({ baseUrl: options.baseUrl, token: options.token });
|
|
16
|
-
const revalidate = options.revalidate ?? DEFAULT_REVALIDATE;
|
|
17
|
-
const tags = fetchTags(options.workspaceId, options.sections);
|
|
18
|
-
return (path, locale, limit) => client.resolve({
|
|
19
|
-
path,
|
|
20
|
-
...locale !== void 0 ? { locale } : {},
|
|
21
|
-
...limit !== void 0 ? { limit } : {},
|
|
22
|
-
init: { next: { revalidate, tags } }
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export {
|
|
27
|
-
DEFAULT_REVALIDATE,
|
|
28
|
-
fetchResolver
|
|
29
|
-
};
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { R as Resolved } from './types-DjXf6iPo.js';
|
|
2
|
-
|
|
3
|
-
/** Resolves a site path to a result. The two built-in strategies are `fetchResolver` (default) and `cachedResolver` (`@tdacorp/hyle-sdk/next/use-cache`). */
|
|
4
|
-
type HyleResolver = (path: string, locale: string | undefined, limit?: number) => Promise<Resolved>;
|
|
5
|
-
interface FetchResolverOptions {
|
|
6
|
-
readonly baseUrl: string;
|
|
7
|
-
readonly token: string;
|
|
8
|
-
/** The workspace id (HYLE_WORKSPACE_ID): the fetch is tagged before the response exists, so tags are built from it. */
|
|
9
|
-
readonly workspaceId: string;
|
|
10
|
-
/** Seconds before a cached page is revalidated in the background. Webhooks purge sooner. Default 300. */
|
|
11
|
-
readonly revalidate?: number;
|
|
12
|
-
/** Section slugs this mount can show besides the default "posts". Used only for tagging. */
|
|
13
|
-
readonly sections?: readonly string[];
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export type { FetchResolverOptions as F, HyleResolver as H };
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { R as Resolved } from './types-DjXf6iPo.cjs';
|
|
2
|
-
|
|
3
|
-
/** Resolves a site path to a result. The two built-in strategies are `fetchResolver` (default) and `cachedResolver` (`@tdacorp/hyle-sdk/next/use-cache`). */
|
|
4
|
-
type HyleResolver = (path: string, locale: string | undefined, limit?: number) => Promise<Resolved>;
|
|
5
|
-
interface FetchResolverOptions {
|
|
6
|
-
readonly baseUrl: string;
|
|
7
|
-
readonly token: string;
|
|
8
|
-
/** The workspace id (HYLE_WORKSPACE_ID): the fetch is tagged before the response exists, so tags are built from it. */
|
|
9
|
-
readonly workspaceId: string;
|
|
10
|
-
/** Seconds before a cached page is revalidated in the background. Webhooks purge sooner. Default 300. */
|
|
11
|
-
readonly revalidate?: number;
|
|
12
|
-
/** Section slugs this mount can show besides the default "posts". Used only for tagging. */
|
|
13
|
-
readonly sections?: readonly string[];
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export type { FetchResolverOptions as F, HyleResolver as H };
|