@praxium/sdk 0.2.17 → 0.2.22
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/dist/revalidation.d.ts +54 -1
- package/dist/revalidation.js +18 -2
- package/package.json +1 -1
package/dist/revalidation.d.ts
CHANGED
|
@@ -5,6 +5,11 @@
|
|
|
5
5
|
* revalidation on the tenant's public website. This handler
|
|
6
6
|
* validates the HMAC signature and calls Next.js revalidatePath().
|
|
7
7
|
*
|
|
8
|
+
* Architecture (entity-driven, three-layer path agnosticism):
|
|
9
|
+
* - Monolith sends { entity } — knows WHAT changed, not WHERE
|
|
10
|
+
* - SDK looks up pathMap[entity] — pure lookup + security, path-agnostic
|
|
11
|
+
* - Tenant website provides pathMap — owns WHERE pages live (locale-prefixed)
|
|
12
|
+
*
|
|
8
13
|
* Signature scheme (H6):
|
|
9
14
|
* X-Praxium-Signature: t={unix_timestamp},sha256={HMAC-SHA256(secret, timestamp.body)}
|
|
10
15
|
*
|
|
@@ -21,6 +26,13 @@
|
|
|
21
26
|
*
|
|
22
27
|
* export const POST = createRevalidationHandler({
|
|
23
28
|
* secret: process.env.PRAXIUM_REVALIDATION_SECRET!,
|
|
29
|
+
* pathMap: {
|
|
30
|
+
* 'team': ['/nl/team', '/en/team'],
|
|
31
|
+
* 'rates': ['/nl/tarieven', '/en/rates'],
|
|
32
|
+
* 'faq': ['/nl/faq', '/en/faq'],
|
|
33
|
+
* 'opening-hours': ['/nl', '/en'],
|
|
34
|
+
* 'all': ['/nl', '/en'],
|
|
35
|
+
* },
|
|
24
36
|
* })
|
|
25
37
|
* ```
|
|
26
38
|
*/
|
|
@@ -29,14 +41,55 @@ interface RevalidationConfig {
|
|
|
29
41
|
secret: string;
|
|
30
42
|
/** Maximum age of request timestamp in milliseconds (default: 5 minutes) */
|
|
31
43
|
maxTimestampAge?: number;
|
|
44
|
+
/**
|
|
45
|
+
* Entity → full paths to revalidate (including locale prefix).
|
|
46
|
+
*
|
|
47
|
+
* Paths are pre-computed by the tenant website — SDK does no path manipulation.
|
|
48
|
+
* Each tenant configures its own paths based on its URL structure and locales.
|
|
49
|
+
*
|
|
50
|
+
* When a webhook arrives with `{ entity: 'team' }`, the SDK looks up
|
|
51
|
+
* `pathMap['team']` and calls `revalidatePath()` for each path.
|
|
52
|
+
*
|
|
53
|
+
* Unknown entities fall back to revalidating ALL registered paths (union of
|
|
54
|
+
* all pathMap values) with a console warning.
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* pathMap: {
|
|
58
|
+
* 'team': ['/nl/team', '/en/team'],
|
|
59
|
+
* 'rates': ['/nl/tarieven', '/en/rates'],
|
|
60
|
+
* 'opening-hours': ['/nl', '/en'],
|
|
61
|
+
* }
|
|
62
|
+
*/
|
|
63
|
+
pathMap: Record<string, string[]>;
|
|
32
64
|
}
|
|
65
|
+
/**
|
|
66
|
+
* Resolve entity to revalidation paths using the tenant's pathMap.
|
|
67
|
+
*
|
|
68
|
+
* The SDK is path-agnostic — it performs a pure lookup against the
|
|
69
|
+
* tenant-provided pathMap. Paths are pre-computed by the tenant website
|
|
70
|
+
* including locale prefixes (e.g., '/nl/tarieven', '/en/rates').
|
|
71
|
+
*
|
|
72
|
+
* Resolution priority:
|
|
73
|
+
* 1. pathMap[entity] → pre-computed paths for this entity
|
|
74
|
+
* 2. Unknown/missing entity → deduplicated union of ALL pathMap values
|
|
75
|
+
* (full site revalidation as safe fallback)
|
|
76
|
+
*
|
|
77
|
+
* @returns paths to revalidate and whether fallback was used
|
|
78
|
+
*/
|
|
79
|
+
declare function resolveRevalidationPaths(entity: string | undefined, pathMap: Record<string, string[]>): {
|
|
80
|
+
paths: string[];
|
|
81
|
+
fallback: boolean;
|
|
82
|
+
};
|
|
33
83
|
/**
|
|
34
84
|
* Creates a Next.js route handler that revalidates ISR pages
|
|
35
85
|
* when triggered by the Praxium platform webhook.
|
|
36
86
|
*
|
|
37
87
|
* Authentication uses HMAC-SHA256 signature verification with
|
|
38
88
|
* timestamp-based replay protection (H6 security scheme).
|
|
89
|
+
*
|
|
90
|
+
* Path resolution is entity-driven: the monolith sends `{ entity }`,
|
|
91
|
+
* the SDK looks up `pathMap[entity]` for pre-computed full paths.
|
|
39
92
|
*/
|
|
40
93
|
declare function createRevalidationHandler(config: RevalidationConfig): (request: Request) => Promise<Response>;
|
|
41
94
|
|
|
42
|
-
export { createRevalidationHandler };
|
|
95
|
+
export { createRevalidationHandler, resolveRevalidationPaths };
|
package/dist/revalidation.js
CHANGED
|
@@ -46,6 +46,13 @@ function parseSignatureHeader(headerValue) {
|
|
|
46
46
|
signature: signatureMatch[1]
|
|
47
47
|
};
|
|
48
48
|
}
|
|
49
|
+
function resolveRevalidationPaths(entity, pathMap) {
|
|
50
|
+
if (entity && pathMap[entity]) {
|
|
51
|
+
return { paths: pathMap[entity], fallback: false };
|
|
52
|
+
}
|
|
53
|
+
const allPaths = [...new Set(Object.values(pathMap).flat())];
|
|
54
|
+
return { paths: allPaths, fallback: true };
|
|
55
|
+
}
|
|
49
56
|
function createRevalidationHandler(config) {
|
|
50
57
|
const maxTimestampAge = config.maxTimestampAge ?? DEFAULT_MAX_TIMESTAMP_AGE_MS;
|
|
51
58
|
return async (request) => {
|
|
@@ -94,7 +101,15 @@ function createRevalidationHandler(config) {
|
|
|
94
101
|
} catch {
|
|
95
102
|
return Response.json({ error: "Invalid JSON body" }, { status: 400 });
|
|
96
103
|
}
|
|
97
|
-
const paths
|
|
104
|
+
const { paths, fallback } = resolveRevalidationPaths(
|
|
105
|
+
body.entity,
|
|
106
|
+
config.pathMap
|
|
107
|
+
);
|
|
108
|
+
if (fallback) {
|
|
109
|
+
console.warn(
|
|
110
|
+
`[Revalidation] Unknown entity "${body.entity ?? "(none)"}" \u2014 falling back to full revalidation (${paths.length} paths)`
|
|
111
|
+
);
|
|
112
|
+
}
|
|
98
113
|
try {
|
|
99
114
|
const { revalidatePath } = await import("next/cache");
|
|
100
115
|
for (const path of paths) {
|
|
@@ -110,5 +125,6 @@ function createRevalidationHandler(config) {
|
|
|
110
125
|
};
|
|
111
126
|
}
|
|
112
127
|
export {
|
|
113
|
-
createRevalidationHandler
|
|
128
|
+
createRevalidationHandler,
|
|
129
|
+
resolveRevalidationPaths
|
|
114
130
|
};
|