@sitecore-content-sdk/nextjs 2.4.1-canary.20260910103731 → 2.4.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/dist/cjs/cache/sitecore-cache-tags.js +0 -22
- package/dist/cjs/cache/sitecore-edge-webhook-revalidation.js +82 -28
- package/dist/cjs/cache/sitecore-page-cache-tags.js +2 -2
- package/dist/cjs/route-handler/sitecore-revalidate-route-handler.js +10 -21
- package/dist/cjs/tools/generate-map.js +7 -6
- package/dist/esm/cache/sitecore-cache-tags.js +0 -21
- package/dist/esm/cache/sitecore-edge-webhook-revalidation.js +78 -29
- package/dist/esm/cache/sitecore-page-cache-tags.js +2 -2
- package/dist/esm/route-handler/sitecore-revalidate-route-handler.js +11 -22
- package/dist/esm/tools/generate-map.js +2 -1
- package/package.json +3 -3
- package/types/cache/sitecore-cache-tags.d.ts +0 -19
- package/types/cache/sitecore-cache-tags.d.ts.map +1 -1
- package/types/cache/sitecore-edge-webhook-revalidation.d.ts +33 -10
- package/types/cache/sitecore-edge-webhook-revalidation.d.ts.map +1 -1
- package/types/cache/sitecore-page-cache-tags.d.ts +2 -2
- package/types/route-handler/sitecore-revalidate-route-handler.d.ts +11 -11
- package/types/route-handler/sitecore-revalidate-route-handler.d.ts.map +1 -1
- package/types/tools/generate-map.d.ts.map +1 -1
|
@@ -6,7 +6,6 @@ exports.normalizeSitecoreItemIdForCacheTag = normalizeSitecoreItemIdForCacheTag;
|
|
|
6
6
|
exports.buildSitecoreRouteCacheTag = buildSitecoreRouteCacheTag;
|
|
7
7
|
exports.buildSitecoreItemCacheTag = buildSitecoreItemCacheTag;
|
|
8
8
|
exports.buildSitecoreDictionaryCacheTag = buildSitecoreDictionaryCacheTag;
|
|
9
|
-
exports.buildSitecoreDictionaryCacheTagsFromSites = buildSitecoreDictionaryCacheTagsFromSites;
|
|
10
9
|
exports.buildSitecoreItemCacheTagFromRouteData = buildSitecoreItemCacheTagFromRouteData;
|
|
11
10
|
exports.dedupeSitecoreCacheTags = dedupeSitecoreCacheTags;
|
|
12
11
|
/**
|
|
@@ -76,27 +75,6 @@ function buildSitecoreDictionaryCacheTag(params) {
|
|
|
76
75
|
const locale = sanitizeSitecoreCacheTagSegment(params.locale);
|
|
77
76
|
return `${exports.SITECORE_CONTENT_CACHE_TAG_PREFIX}:dict:${site}:${locale}`;
|
|
78
77
|
}
|
|
79
|
-
/**
|
|
80
|
-
* Builds deduplicated dictionary cache tags from a sites list.
|
|
81
|
-
* @param {BuildSitecoreDictionaryCacheTagsFromSitesParams} params - Sites list and fallback locale.
|
|
82
|
-
* @internal
|
|
83
|
-
*/
|
|
84
|
-
function buildSitecoreDictionaryCacheTagsFromSites(params) {
|
|
85
|
-
var _a;
|
|
86
|
-
const seen = new Set();
|
|
87
|
-
const out = [];
|
|
88
|
-
const push = (tag) => {
|
|
89
|
-
if (!seen.has(tag)) {
|
|
90
|
-
seen.add(tag);
|
|
91
|
-
out.push(tag);
|
|
92
|
-
}
|
|
93
|
-
};
|
|
94
|
-
for (const site of params.sites) {
|
|
95
|
-
const locale = ((_a = site.language) === null || _a === void 0 ? void 0 : _a.trim()) ? site.language : params.baseLocale;
|
|
96
|
-
push(buildSitecoreDictionaryCacheTag({ site: site.name, locale }));
|
|
97
|
-
}
|
|
98
|
-
return out;
|
|
99
|
-
}
|
|
100
78
|
/**
|
|
101
79
|
* Builds an item cache tag from Sitecore layout route data when `itemId` is present.
|
|
102
80
|
* Prefers `itemLanguage` from Sitecore when set; otherwise uses `fallbackLocale`.
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.extractSitecoreEdgeContentId = extractSitecoreEdgeContentId;
|
|
7
|
+
exports.isSitecoreDictionaryEntryUpdate = isSitecoreDictionaryEntryUpdate;
|
|
8
|
+
exports.resolveSitecoreDictionarySiteNameFromIdentifier = resolveSitecoreDictionarySiteNameFromIdentifier;
|
|
4
9
|
exports.collectSitecoreTagsFromEdgeRevalidateRequestBody = collectSitecoreTagsFromEdgeRevalidateRequestBody;
|
|
5
10
|
const sitecore_cache_tags_1 = require("./sitecore-cache-tags");
|
|
11
|
+
const debug_1 = __importDefault(require("../debug"));
|
|
6
12
|
/**
|
|
7
13
|
* Strips Experience Edge style suffixes from an `identifier` so the value can be used as an item id in cache tags.
|
|
8
14
|
* Handles `{GUID}`, `{GUID}-media`, `{GUID}-layout` style strings.
|
|
@@ -16,51 +22,99 @@ function extractSitecoreEdgeContentId(identifier) {
|
|
|
16
22
|
const trimmed = identifier.trim();
|
|
17
23
|
return trimmed.replace(/-(?:media|layout)$/i, '');
|
|
18
24
|
}
|
|
19
|
-
const FULL_TAG_PREFIX = `${sitecore_cache_tags_1.SITECORE_CONTENT_CACHE_TAG_PREFIX}:`;
|
|
20
25
|
/**
|
|
21
|
-
*
|
|
22
|
-
* @
|
|
26
|
+
* `entity_definition` value Experience Edge sends for Dictionary entry updates. This is the literal value Experience Edge sends.
|
|
27
|
+
* @internal
|
|
28
|
+
*/
|
|
29
|
+
const DICTIONARY_ENTRY_ENTITY_DEFINITION = 'DictionaryEntry';
|
|
30
|
+
/**
|
|
31
|
+
* Whether a webhook update row is a Dictionary entry change (`entity_definition: "DictionaryEntry"`).
|
|
32
|
+
* @param {string} [entityDefinition] - `entity_definition` from a webhook update row.
|
|
33
|
+
* @internal
|
|
34
|
+
*/
|
|
35
|
+
function isSitecoreDictionaryEntryUpdate(entityDefinition) {
|
|
36
|
+
return entityDefinition === DICTIONARY_ENTRY_ENTITY_DEFINITION;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Resolves which configured site a Dictionary entry webhook `identifier` belongs to.
|
|
40
|
+
*
|
|
41
|
+
* Dictionary identifiers follow `<site name>-<dictionary folder id>-<value>-<language>`, but the
|
|
42
|
+
* folder id, value, and language segments can themselves contain hyphens (and the value can contain
|
|
43
|
+
* spaces), so splitting the identifier on `-` is not reliable. Instead this matches the identifier
|
|
44
|
+
* against the known configured site names, preferring the longest name so a more specific name wins
|
|
45
|
+
* over a shorter overlapping one (e.g. `my-site-2` over `my-site`).
|
|
46
|
+
* @param {string} identifier - Raw `identifier` from a Dictionary entry update row.
|
|
47
|
+
* @param {string[]} siteNames - Configured site names (e.g. from `.sitecore/sites.json`).
|
|
48
|
+
* @returns The matched site name, or `undefined` when no configured site name prefixes `identifier`.
|
|
49
|
+
* @internal
|
|
50
|
+
*/
|
|
51
|
+
function resolveSitecoreDictionarySiteNameFromIdentifier(identifier, siteNames) {
|
|
52
|
+
const normalized = identifier.trim().toLowerCase();
|
|
53
|
+
if (!normalized) {
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
return matchSitecoreDictionarySiteName(normalized, sortSiteNamesByLengthDesc(siteNames));
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Sorts site names longest-first, for {@link matchSitecoreDictionarySiteName}.
|
|
60
|
+
* @param {string[]} siteNames - Configured site names.
|
|
61
|
+
* @internal
|
|
23
62
|
*/
|
|
24
|
-
function
|
|
25
|
-
return
|
|
63
|
+
function sortSiteNamesByLengthDesc(siteNames) {
|
|
64
|
+
return [...siteNames].sort((a, b) => b.length - a.length);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Matches a normalized (trimmed, lowercased) identifier against site names already sorted
|
|
68
|
+
* longest-first. Split out of {@link resolveSitecoreDictionarySiteNameFromIdentifier} so a request
|
|
69
|
+
* with many Dictionary entry updates in one payload sorts `siteNames` once instead of per update.
|
|
70
|
+
* @param {string} normalizedIdentifier - Identifier, already trimmed and lowercased.
|
|
71
|
+
* @param {string[]} siteNamesByLengthDesc - Site names sorted longest-first.
|
|
72
|
+
* @internal
|
|
73
|
+
*/
|
|
74
|
+
function matchSitecoreDictionarySiteName(normalizedIdentifier, siteNamesByLengthDesc) {
|
|
75
|
+
for (const siteName of siteNamesByLengthDesc) {
|
|
76
|
+
const prefix = `${siteName.trim().toLowerCase()}-`;
|
|
77
|
+
if (prefix.length > 1 && normalizedIdentifier.startsWith(prefix)) {
|
|
78
|
+
return siteName;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return undefined;
|
|
26
82
|
}
|
|
27
83
|
/**
|
|
28
84
|
* Maps an Experience Edge webhook JSON body to Content SDK cache tag strings used by
|
|
29
85
|
* {@link collectSitecorePageCacheTags} / {@link buildSitecoreItemCacheTag} (`sc:item:...`), so
|
|
30
86
|
* `revalidateTag` matches tags registered during cached reads.
|
|
31
|
-
* **`updates`** rows resolve to **`sc:item:…`** (locale from `entity_culture` or `defaultLocale`)
|
|
32
|
-
*
|
|
33
|
-
*
|
|
87
|
+
* **`updates`** rows resolve to **`sc:item:…`** (locale from `entity_culture` or `defaultLocale`), except
|
|
88
|
+
* rows where `entity_definition` is `"DictionaryEntry"`, which resolve to **`sc:dict:…`** scoped to the
|
|
89
|
+
* site resolved from the identifier (see {@link resolveSitecoreDictionarySiteNameFromIdentifier}) and the
|
|
90
|
+
* same locale. Route/variant tags are not inferred.
|
|
91
|
+
* @param {SitecoreEdgeRevalidateRequestBody | null | undefined} body - Webhook JSON body (updates).
|
|
92
|
+
* @param {CollectSitecoreTagsFromEdgeBodyOptions} options - Default locale, and site names for Dictionary entry updates.
|
|
34
93
|
* @internal
|
|
35
94
|
*/
|
|
36
95
|
function collectSitecoreTagsFromEdgeRevalidateRequestBody(body, options) {
|
|
37
96
|
var _a, _b, _c, _d;
|
|
38
|
-
const { defaultLocale } = options;
|
|
97
|
+
const { defaultLocale, siteNames = [] } = options;
|
|
98
|
+
const siteNamesByLengthDesc = sortSiteNamesByLengthDesc(siteNames);
|
|
39
99
|
const out = [];
|
|
40
|
-
for (const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
else {
|
|
52
|
-
const id = extractSitecoreEdgeContentId(s);
|
|
53
|
-
if (id) {
|
|
54
|
-
out.push((0, sitecore_cache_tags_1.buildSitecoreItemCacheTag)({ itemId: id, locale: defaultLocale }));
|
|
100
|
+
for (const u of (_a = body === null || body === void 0 ? void 0 : body.updates) !== null && _a !== void 0 ? _a : []) {
|
|
101
|
+
const locale = ((_b = u === null || u === void 0 ? void 0 : u.entity_culture) === null || _b === void 0 ? void 0 : _b.trim()) || defaultLocale;
|
|
102
|
+
if (isSitecoreDictionaryEntryUpdate(u === null || u === void 0 ? void 0 : u.entity_definition)) {
|
|
103
|
+
const identifier = ((_c = u === null || u === void 0 ? void 0 : u.identifier) !== null && _c !== void 0 ? _c : '').trim().toLowerCase();
|
|
104
|
+
const site = identifier
|
|
105
|
+
? matchSitecoreDictionarySiteName(identifier, siteNamesByLengthDesc)
|
|
106
|
+
: undefined;
|
|
107
|
+
if (!site) {
|
|
108
|
+
debug_1.default.revalidate('could not resolve site for Dictionary entry identifier %o, skipping', identifier);
|
|
109
|
+
continue;
|
|
55
110
|
}
|
|
111
|
+
out.push((0, sitecore_cache_tags_1.buildSitecoreDictionaryCacheTag)({ site, locale }));
|
|
112
|
+
continue;
|
|
56
113
|
}
|
|
57
|
-
|
|
58
|
-
for (const u of (_b = body === null || body === void 0 ? void 0 : body.updates) !== null && _b !== void 0 ? _b : []) {
|
|
59
|
-
const id = extractSitecoreEdgeContentId((_c = u === null || u === void 0 ? void 0 : u.identifier) !== null && _c !== void 0 ? _c : '');
|
|
114
|
+
const id = extractSitecoreEdgeContentId((_d = u === null || u === void 0 ? void 0 : u.identifier) !== null && _d !== void 0 ? _d : '');
|
|
60
115
|
if (!id) {
|
|
61
116
|
continue;
|
|
62
117
|
}
|
|
63
|
-
const locale = ((_d = u === null || u === void 0 ? void 0 : u.entity_culture) === null || _d === void 0 ? void 0 : _d.trim()) || defaultLocale;
|
|
64
118
|
out.push((0, sitecore_cache_tags_1.buildSitecoreItemCacheTag)({ itemId: id, locale }));
|
|
65
119
|
}
|
|
66
120
|
return (0, sitecore_cache_tags_1.dedupeSitecoreCacheTags)(out).filter(Boolean);
|
|
@@ -27,8 +27,8 @@ function routeSegmentsFromPathname(pathname) {
|
|
|
27
27
|
* `buildSitecoreDictionaryCacheTag` on a dedicated `use cache` helper).
|
|
28
28
|
*
|
|
29
29
|
* Registers **`sc:route:…`** and **`sc:item:…`** (when layout has `itemId`). Edge-style webhooks emit
|
|
30
|
-
* item ids, which the Sitecore revalidate route handler maps to **`sc:item:…`**; route tags are
|
|
31
|
-
* invalidated
|
|
30
|
+
* item ids, which the Sitecore revalidate route handler maps to **`sc:item:…`**; route tags are not
|
|
31
|
+
* invalidated by that webhook flow.
|
|
32
32
|
*
|
|
33
33
|
* Personalization variants are isolated naturally by URL path (each variant rewrite yields a distinct
|
|
34
34
|
* Cache Components key) so no `sc:pvv:…` tag is added here. If a personalize-specific webhook is wired
|
|
@@ -29,27 +29,21 @@ function resolveConfiguredRevalidateSecret(secretOption, envValue) {
|
|
|
29
29
|
*
|
|
30
30
|
* - **`updates[]`** — Sitecore publish-event rows. Each row's `identifier` (with `-media` / `-layout`
|
|
31
31
|
* suffix stripped) maps to an `sc:item:<id>:<locale>` tag, using `entity_culture` for locale
|
|
32
|
-
* (falling back to the handler's `defaultLocale`)
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
* When **`sites`** is configured, the handler also appends one `sc:dict:<site>:<locale>` tag per
|
|
38
|
-
* site so dictionary updates flow through the same call.
|
|
32
|
+
* (falling back to the handler's `defaultLocale`) — except rows where `entity_definition` is
|
|
33
|
+
* `"DictionaryEntry"`, which map to `sc:dict:<site>:<locale>` for the site resolved from the
|
|
34
|
+
* identifier via the configured **`sites`** option (skipped, with a debug log, when no configured
|
|
35
|
+
* site matches). Only updates that are actually Dictionary changes revalidate dictionary tags — a
|
|
36
|
+
* webhook for an unrelated item never touches them.
|
|
39
37
|
*
|
|
40
38
|
* Auth (optional): when `SITECORE_REVALIDATE_SECRET` (or the `secret` option) is non-empty, callers must
|
|
41
39
|
* send the same value in the **`x-revalidate-secret`** header. When unset or blank, no header is required.
|
|
42
|
-
* @param {SitecoreRevalidateRouteHandlerOptions} [options] - Optional inline `secret`, `cacheProfile`, locale,
|
|
40
|
+
* @param {SitecoreRevalidateRouteHandlerOptions} [options] - Optional inline `secret`, `cacheProfile`, locale, and sites options.
|
|
43
41
|
* @public
|
|
44
42
|
*/
|
|
45
43
|
function createSitecoreRevalidateRouteHandler(options = {}) {
|
|
44
|
+
var _a;
|
|
46
45
|
const { defaultLocale = 'en', sites, secret, cacheProfile = 'max' } = options;
|
|
47
|
-
const
|
|
48
|
-
? (0, sitecore_cache_tags_1.buildSitecoreDictionaryCacheTagsFromSites)({
|
|
49
|
-
sites,
|
|
50
|
-
baseLocale: defaultLocale,
|
|
51
|
-
})
|
|
52
|
-
: [];
|
|
46
|
+
const siteNames = (_a = sites === null || sites === void 0 ? void 0 : sites.map((site) => site.name)) !== null && _a !== void 0 ? _a : [];
|
|
53
47
|
const POST = async (req) => {
|
|
54
48
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
55
49
|
const startTimestamp = Date.now();
|
|
@@ -82,18 +76,13 @@ function createSitecoreRevalidateRouteHandler(options = {}) {
|
|
|
82
76
|
invocation_id: (_a = webhookBody.invocation_id) !== null && _a !== void 0 ? _a : null,
|
|
83
77
|
continues: (_b = webhookBody.continues) !== null && _b !== void 0 ? _b : false,
|
|
84
78
|
updatesCount: (_d = (_c = webhookBody.updates) === null || _c === void 0 ? void 0 : _c.length) !== null && _d !== void 0 ? _d : 0,
|
|
85
|
-
tagsCount: Array.isArray(webhookBody.tags) ? webhookBody.tags.length : 0,
|
|
86
|
-
dictionaryTagsCount: dictionaryTags.length,
|
|
87
79
|
defaultLocale,
|
|
88
80
|
});
|
|
89
|
-
const tags = (0, sitecore_cache_tags_1.dedupeSitecoreCacheTags)(
|
|
90
|
-
...(0, sitecore_edge_webhook_revalidation_1.collectSitecoreTagsFromEdgeRevalidateRequestBody)(webhookBody, { defaultLocale }),
|
|
91
|
-
...dictionaryTags,
|
|
92
|
-
]);
|
|
81
|
+
const tags = (0, sitecore_cache_tags_1.dedupeSitecoreCacheTags)((0, sitecore_edge_webhook_revalidation_1.collectSitecoreTagsFromEdgeRevalidateRequestBody)(webhookBody, { defaultLocale, siteNames }));
|
|
93
82
|
if (tags.length === 0) {
|
|
94
83
|
debug_1.default.revalidate('sitecore revalidate: no tags resolved in %dms', Date.now() - startTimestamp);
|
|
95
84
|
return server_1.NextResponse.json({
|
|
96
|
-
error: 'Provide non-empty `updates` (with identifiers)
|
|
85
|
+
error: 'Provide non-empty `updates` (with identifiers) that resolve to at least one cache tag.',
|
|
97
86
|
}, { status: 400 });
|
|
98
87
|
}
|
|
99
88
|
for (const tag of tags) {
|
|
@@ -35,6 +35,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.generateMap = exports.defaultClientMapTemplate = exports.defaultServerMapTemplate = void 0;
|
|
37
37
|
const tools_1 = require("@sitecore-content-sdk/content/tools");
|
|
38
|
+
const node_tools_1 = require("@sitecore-content-sdk/content/node-tools");
|
|
38
39
|
const path = __importStar(require("path"));
|
|
39
40
|
const fs = __importStar(require("fs"));
|
|
40
41
|
const utils_1 = require("./templating/utils");
|
|
@@ -74,10 +75,10 @@ const isComponentMapTemplate = (fn) => fn.length === 2;
|
|
|
74
75
|
// Default App Router (server) component map template
|
|
75
76
|
const defaultServerMapTemplate = (components, componentImports, ctx) => {
|
|
76
77
|
var _a, _b;
|
|
77
|
-
const entries = (_a = ctx === null || ctx === void 0 ? void 0 : ctx.entries) !== null && _a !== void 0 ? _a : (0,
|
|
78
|
+
const entries = (_a = ctx === null || ctx === void 0 ? void 0 : ctx.entries) !== null && _a !== void 0 ? _a : (0, node_tools_1.prepareComponentsForMap)(components, {
|
|
78
79
|
includeVariants: (_b = ctx === null || ctx === void 0 ? void 0 : ctx.includeVariants) !== null && _b !== void 0 ? _b : true,
|
|
79
80
|
});
|
|
80
|
-
return (0,
|
|
81
|
+
return (0, node_tools_1.buildComponentMapContent)(entries, componentImports, {
|
|
81
82
|
framework: 'nextjs',
|
|
82
83
|
isClientMap: false,
|
|
83
84
|
builtInImports: APP_ROUTER_BUILTIN_IMPORTS,
|
|
@@ -88,11 +89,11 @@ exports.defaultServerMapTemplate = defaultServerMapTemplate;
|
|
|
88
89
|
// Default client-safe component map template for App Router
|
|
89
90
|
const defaultClientMapTemplate = (components, componentImports, ctx) => {
|
|
90
91
|
var _a, _b;
|
|
91
|
-
const entries = (_a = ctx === null || ctx === void 0 ? void 0 : ctx.entries) !== null && _a !== void 0 ? _a : (0,
|
|
92
|
+
const entries = (_a = ctx === null || ctx === void 0 ? void 0 : ctx.entries) !== null && _a !== void 0 ? _a : (0, node_tools_1.prepareComponentsForMap)(components, {
|
|
92
93
|
includeVariants: (_b = ctx === null || ctx === void 0 ? void 0 : ctx.includeVariants) !== null && _b !== void 0 ? _b : true,
|
|
93
94
|
shouldAnnotateClient: true,
|
|
94
95
|
});
|
|
95
|
-
return (0,
|
|
96
|
+
return (0, node_tools_1.buildComponentMapContent)(entries, componentImports, {
|
|
96
97
|
framework: 'nextjs',
|
|
97
98
|
headerComment: 'Client-safe component map for App Router',
|
|
98
99
|
isClientMap: true,
|
|
@@ -112,7 +113,7 @@ const collectComponents = (opts) => {
|
|
|
112
113
|
}
|
|
113
114
|
return {
|
|
114
115
|
raw: filtered,
|
|
115
|
-
entries: (0,
|
|
116
|
+
entries: (0, node_tools_1.prepareComponentsForMap)(filtered, {
|
|
116
117
|
includeVariants: opts.includeVariants,
|
|
117
118
|
shouldAnnotateClient: true,
|
|
118
119
|
}),
|
|
@@ -153,7 +154,7 @@ const generateMap = ({ paths, destination = '.sitecore', exclude, componentImpor
|
|
|
153
154
|
includeVariants,
|
|
154
155
|
isClientMap: false,
|
|
155
156
|
})
|
|
156
|
-
: (0,
|
|
157
|
+
: (0, node_tools_1.buildComponentMapContent)(allComponents.entries, componentImports, {
|
|
157
158
|
framework: 'nextjs',
|
|
158
159
|
isClientMap: false,
|
|
159
160
|
builtInImports: PAGES_ROUTER_BUILTIN_IMPORTS,
|
|
@@ -65,27 +65,6 @@ export function buildSitecoreDictionaryCacheTag(params) {
|
|
|
65
65
|
const locale = sanitizeSitecoreCacheTagSegment(params.locale);
|
|
66
66
|
return `${SITECORE_CONTENT_CACHE_TAG_PREFIX}:dict:${site}:${locale}`;
|
|
67
67
|
}
|
|
68
|
-
/**
|
|
69
|
-
* Builds deduplicated dictionary cache tags from a sites list.
|
|
70
|
-
* @param {BuildSitecoreDictionaryCacheTagsFromSitesParams} params - Sites list and fallback locale.
|
|
71
|
-
* @internal
|
|
72
|
-
*/
|
|
73
|
-
export function buildSitecoreDictionaryCacheTagsFromSites(params) {
|
|
74
|
-
var _a;
|
|
75
|
-
const seen = new Set();
|
|
76
|
-
const out = [];
|
|
77
|
-
const push = (tag) => {
|
|
78
|
-
if (!seen.has(tag)) {
|
|
79
|
-
seen.add(tag);
|
|
80
|
-
out.push(tag);
|
|
81
|
-
}
|
|
82
|
-
};
|
|
83
|
-
for (const site of params.sites) {
|
|
84
|
-
const locale = ((_a = site.language) === null || _a === void 0 ? void 0 : _a.trim()) ? site.language : params.baseLocale;
|
|
85
|
-
push(buildSitecoreDictionaryCacheTag({ site: site.name, locale }));
|
|
86
|
-
}
|
|
87
|
-
return out;
|
|
88
|
-
}
|
|
89
68
|
/**
|
|
90
69
|
* Builds an item cache tag from Sitecore layout route data when `itemId` is present.
|
|
91
70
|
* Prefers `itemLanguage` from Sitecore when set; otherwise uses `fallbackLocale`.
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { buildSitecoreDictionaryCacheTag, buildSitecoreItemCacheTag, dedupeSitecoreCacheTags, } from './sitecore-cache-tags';
|
|
2
|
+
import debug from '../debug';
|
|
2
3
|
/**
|
|
3
4
|
* Strips Experience Edge style suffixes from an `identifier` so the value can be used as an item id in cache tags.
|
|
4
5
|
* Handles `{GUID}`, `{GUID}-media`, `{GUID}-layout` style strings.
|
|
@@ -12,51 +13,99 @@ export function extractSitecoreEdgeContentId(identifier) {
|
|
|
12
13
|
const trimmed = identifier.trim();
|
|
13
14
|
return trimmed.replace(/-(?:media|layout)$/i, '');
|
|
14
15
|
}
|
|
15
|
-
const FULL_TAG_PREFIX = `${SITECORE_CONTENT_CACHE_TAG_PREFIX}:`;
|
|
16
16
|
/**
|
|
17
|
-
*
|
|
18
|
-
* @
|
|
17
|
+
* `entity_definition` value Experience Edge sends for Dictionary entry updates. This is the literal value Experience Edge sends.
|
|
18
|
+
* @internal
|
|
19
|
+
*/
|
|
20
|
+
const DICTIONARY_ENTRY_ENTITY_DEFINITION = 'DictionaryEntry';
|
|
21
|
+
/**
|
|
22
|
+
* Whether a webhook update row is a Dictionary entry change (`entity_definition: "DictionaryEntry"`).
|
|
23
|
+
* @param {string} [entityDefinition] - `entity_definition` from a webhook update row.
|
|
24
|
+
* @internal
|
|
25
|
+
*/
|
|
26
|
+
export function isSitecoreDictionaryEntryUpdate(entityDefinition) {
|
|
27
|
+
return entityDefinition === DICTIONARY_ENTRY_ENTITY_DEFINITION;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Resolves which configured site a Dictionary entry webhook `identifier` belongs to.
|
|
31
|
+
*
|
|
32
|
+
* Dictionary identifiers follow `<site name>-<dictionary folder id>-<value>-<language>`, but the
|
|
33
|
+
* folder id, value, and language segments can themselves contain hyphens (and the value can contain
|
|
34
|
+
* spaces), so splitting the identifier on `-` is not reliable. Instead this matches the identifier
|
|
35
|
+
* against the known configured site names, preferring the longest name so a more specific name wins
|
|
36
|
+
* over a shorter overlapping one (e.g. `my-site-2` over `my-site`).
|
|
37
|
+
* @param {string} identifier - Raw `identifier` from a Dictionary entry update row.
|
|
38
|
+
* @param {string[]} siteNames - Configured site names (e.g. from `.sitecore/sites.json`).
|
|
39
|
+
* @returns The matched site name, or `undefined` when no configured site name prefixes `identifier`.
|
|
40
|
+
* @internal
|
|
41
|
+
*/
|
|
42
|
+
export function resolveSitecoreDictionarySiteNameFromIdentifier(identifier, siteNames) {
|
|
43
|
+
const normalized = identifier.trim().toLowerCase();
|
|
44
|
+
if (!normalized) {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
return matchSitecoreDictionarySiteName(normalized, sortSiteNamesByLengthDesc(siteNames));
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Sorts site names longest-first, for {@link matchSitecoreDictionarySiteName}.
|
|
51
|
+
* @param {string[]} siteNames - Configured site names.
|
|
52
|
+
* @internal
|
|
19
53
|
*/
|
|
20
|
-
function
|
|
21
|
-
return
|
|
54
|
+
function sortSiteNamesByLengthDesc(siteNames) {
|
|
55
|
+
return [...siteNames].sort((a, b) => b.length - a.length);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Matches a normalized (trimmed, lowercased) identifier against site names already sorted
|
|
59
|
+
* longest-first. Split out of {@link resolveSitecoreDictionarySiteNameFromIdentifier} so a request
|
|
60
|
+
* with many Dictionary entry updates in one payload sorts `siteNames` once instead of per update.
|
|
61
|
+
* @param {string} normalizedIdentifier - Identifier, already trimmed and lowercased.
|
|
62
|
+
* @param {string[]} siteNamesByLengthDesc - Site names sorted longest-first.
|
|
63
|
+
* @internal
|
|
64
|
+
*/
|
|
65
|
+
function matchSitecoreDictionarySiteName(normalizedIdentifier, siteNamesByLengthDesc) {
|
|
66
|
+
for (const siteName of siteNamesByLengthDesc) {
|
|
67
|
+
const prefix = `${siteName.trim().toLowerCase()}-`;
|
|
68
|
+
if (prefix.length > 1 && normalizedIdentifier.startsWith(prefix)) {
|
|
69
|
+
return siteName;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return undefined;
|
|
22
73
|
}
|
|
23
74
|
/**
|
|
24
75
|
* Maps an Experience Edge webhook JSON body to Content SDK cache tag strings used by
|
|
25
76
|
* {@link collectSitecorePageCacheTags} / {@link buildSitecoreItemCacheTag} (`sc:item:...`), so
|
|
26
77
|
* `revalidateTag` matches tags registered during cached reads.
|
|
27
|
-
* **`updates`** rows resolve to **`sc:item:…`** (locale from `entity_culture` or `defaultLocale`)
|
|
28
|
-
*
|
|
29
|
-
*
|
|
78
|
+
* **`updates`** rows resolve to **`sc:item:…`** (locale from `entity_culture` or `defaultLocale`), except
|
|
79
|
+
* rows where `entity_definition` is `"DictionaryEntry"`, which resolve to **`sc:dict:…`** scoped to the
|
|
80
|
+
* site resolved from the identifier (see {@link resolveSitecoreDictionarySiteNameFromIdentifier}) and the
|
|
81
|
+
* same locale. Route/variant tags are not inferred.
|
|
82
|
+
* @param {SitecoreEdgeRevalidateRequestBody | null | undefined} body - Webhook JSON body (updates).
|
|
83
|
+
* @param {CollectSitecoreTagsFromEdgeBodyOptions} options - Default locale, and site names for Dictionary entry updates.
|
|
30
84
|
* @internal
|
|
31
85
|
*/
|
|
32
86
|
export function collectSitecoreTagsFromEdgeRevalidateRequestBody(body, options) {
|
|
33
87
|
var _a, _b, _c, _d;
|
|
34
|
-
const { defaultLocale } = options;
|
|
88
|
+
const { defaultLocale, siteNames = [] } = options;
|
|
89
|
+
const siteNamesByLengthDesc = sortSiteNamesByLengthDesc(siteNames);
|
|
35
90
|
const out = [];
|
|
36
|
-
for (const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
else {
|
|
48
|
-
const id = extractSitecoreEdgeContentId(s);
|
|
49
|
-
if (id) {
|
|
50
|
-
out.push(buildSitecoreItemCacheTag({ itemId: id, locale: defaultLocale }));
|
|
91
|
+
for (const u of (_a = body === null || body === void 0 ? void 0 : body.updates) !== null && _a !== void 0 ? _a : []) {
|
|
92
|
+
const locale = ((_b = u === null || u === void 0 ? void 0 : u.entity_culture) === null || _b === void 0 ? void 0 : _b.trim()) || defaultLocale;
|
|
93
|
+
if (isSitecoreDictionaryEntryUpdate(u === null || u === void 0 ? void 0 : u.entity_definition)) {
|
|
94
|
+
const identifier = ((_c = u === null || u === void 0 ? void 0 : u.identifier) !== null && _c !== void 0 ? _c : '').trim().toLowerCase();
|
|
95
|
+
const site = identifier
|
|
96
|
+
? matchSitecoreDictionarySiteName(identifier, siteNamesByLengthDesc)
|
|
97
|
+
: undefined;
|
|
98
|
+
if (!site) {
|
|
99
|
+
debug.revalidate('could not resolve site for Dictionary entry identifier %o, skipping', identifier);
|
|
100
|
+
continue;
|
|
51
101
|
}
|
|
102
|
+
out.push(buildSitecoreDictionaryCacheTag({ site, locale }));
|
|
103
|
+
continue;
|
|
52
104
|
}
|
|
53
|
-
|
|
54
|
-
for (const u of (_b = body === null || body === void 0 ? void 0 : body.updates) !== null && _b !== void 0 ? _b : []) {
|
|
55
|
-
const id = extractSitecoreEdgeContentId((_c = u === null || u === void 0 ? void 0 : u.identifier) !== null && _c !== void 0 ? _c : '');
|
|
105
|
+
const id = extractSitecoreEdgeContentId((_d = u === null || u === void 0 ? void 0 : u.identifier) !== null && _d !== void 0 ? _d : '');
|
|
56
106
|
if (!id) {
|
|
57
107
|
continue;
|
|
58
108
|
}
|
|
59
|
-
const locale = ((_d = u === null || u === void 0 ? void 0 : u.entity_culture) === null || _d === void 0 ? void 0 : _d.trim()) || defaultLocale;
|
|
60
109
|
out.push(buildSitecoreItemCacheTag({ itemId: id, locale }));
|
|
61
110
|
}
|
|
62
111
|
return dedupeSitecoreCacheTags(out).filter(Boolean);
|
|
@@ -24,8 +24,8 @@ function routeSegmentsFromPathname(pathname) {
|
|
|
24
24
|
* `buildSitecoreDictionaryCacheTag` on a dedicated `use cache` helper).
|
|
25
25
|
*
|
|
26
26
|
* Registers **`sc:route:…`** and **`sc:item:…`** (when layout has `itemId`). Edge-style webhooks emit
|
|
27
|
-
* item ids, which the Sitecore revalidate route handler maps to **`sc:item:…`**; route tags are
|
|
28
|
-
* invalidated
|
|
27
|
+
* item ids, which the Sitecore revalidate route handler maps to **`sc:item:…`**; route tags are not
|
|
28
|
+
* invalidated by that webhook flow.
|
|
29
29
|
*
|
|
30
30
|
* Personalization variants are isolated naturally by URL path (each variant rewrite yields a distinct
|
|
31
31
|
* Cache Components key) so no `sc:pvv:…` tag is added here. If a personalize-specific webhook is wired
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { collectSitecoreTagsFromEdgeRevalidateRequestBody, } from '../cache/sitecore-edge-webhook-revalidation';
|
|
2
|
-
import {
|
|
2
|
+
import { dedupeSitecoreCacheTags } from '../cache/sitecore-cache-tags';
|
|
3
3
|
import debug from '../debug';
|
|
4
4
|
import { revalidateTag } from 'next/cache';
|
|
5
5
|
import { NextResponse } from 'next/server';
|
|
@@ -23,27 +23,21 @@ function resolveConfiguredRevalidateSecret(secretOption, envValue) {
|
|
|
23
23
|
*
|
|
24
24
|
* - **`updates[]`** — Sitecore publish-event rows. Each row's `identifier` (with `-media` / `-layout`
|
|
25
25
|
* suffix stripped) maps to an `sc:item:<id>:<locale>` tag, using `entity_culture` for locale
|
|
26
|
-
* (falling back to the handler's `defaultLocale`)
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
* When **`sites`** is configured, the handler also appends one `sc:dict:<site>:<locale>` tag per
|
|
32
|
-
* site so dictionary updates flow through the same call.
|
|
26
|
+
* (falling back to the handler's `defaultLocale`) — except rows where `entity_definition` is
|
|
27
|
+
* `"DictionaryEntry"`, which map to `sc:dict:<site>:<locale>` for the site resolved from the
|
|
28
|
+
* identifier via the configured **`sites`** option (skipped, with a debug log, when no configured
|
|
29
|
+
* site matches). Only updates that are actually Dictionary changes revalidate dictionary tags — a
|
|
30
|
+
* webhook for an unrelated item never touches them.
|
|
33
31
|
*
|
|
34
32
|
* Auth (optional): when `SITECORE_REVALIDATE_SECRET` (or the `secret` option) is non-empty, callers must
|
|
35
33
|
* send the same value in the **`x-revalidate-secret`** header. When unset or blank, no header is required.
|
|
36
|
-
* @param {SitecoreRevalidateRouteHandlerOptions} [options] - Optional inline `secret`, `cacheProfile`, locale,
|
|
34
|
+
* @param {SitecoreRevalidateRouteHandlerOptions} [options] - Optional inline `secret`, `cacheProfile`, locale, and sites options.
|
|
37
35
|
* @public
|
|
38
36
|
*/
|
|
39
37
|
export function createSitecoreRevalidateRouteHandler(options = {}) {
|
|
38
|
+
var _a;
|
|
40
39
|
const { defaultLocale = 'en', sites, secret, cacheProfile = 'max' } = options;
|
|
41
|
-
const
|
|
42
|
-
? buildSitecoreDictionaryCacheTagsFromSites({
|
|
43
|
-
sites,
|
|
44
|
-
baseLocale: defaultLocale,
|
|
45
|
-
})
|
|
46
|
-
: [];
|
|
40
|
+
const siteNames = (_a = sites === null || sites === void 0 ? void 0 : sites.map((site) => site.name)) !== null && _a !== void 0 ? _a : [];
|
|
47
41
|
const POST = async (req) => {
|
|
48
42
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
49
43
|
const startTimestamp = Date.now();
|
|
@@ -76,18 +70,13 @@ export function createSitecoreRevalidateRouteHandler(options = {}) {
|
|
|
76
70
|
invocation_id: (_a = webhookBody.invocation_id) !== null && _a !== void 0 ? _a : null,
|
|
77
71
|
continues: (_b = webhookBody.continues) !== null && _b !== void 0 ? _b : false,
|
|
78
72
|
updatesCount: (_d = (_c = webhookBody.updates) === null || _c === void 0 ? void 0 : _c.length) !== null && _d !== void 0 ? _d : 0,
|
|
79
|
-
tagsCount: Array.isArray(webhookBody.tags) ? webhookBody.tags.length : 0,
|
|
80
|
-
dictionaryTagsCount: dictionaryTags.length,
|
|
81
73
|
defaultLocale,
|
|
82
74
|
});
|
|
83
|
-
const tags = dedupeSitecoreCacheTags(
|
|
84
|
-
...collectSitecoreTagsFromEdgeRevalidateRequestBody(webhookBody, { defaultLocale }),
|
|
85
|
-
...dictionaryTags,
|
|
86
|
-
]);
|
|
75
|
+
const tags = dedupeSitecoreCacheTags(collectSitecoreTagsFromEdgeRevalidateRequestBody(webhookBody, { defaultLocale, siteNames }));
|
|
87
76
|
if (tags.length === 0) {
|
|
88
77
|
debug.revalidate('sitecore revalidate: no tags resolved in %dms', Date.now() - startTimestamp);
|
|
89
78
|
return NextResponse.json({
|
|
90
|
-
error: 'Provide non-empty `updates` (with identifiers)
|
|
79
|
+
error: 'Provide non-empty `updates` (with identifiers) that resolve to at least one cache tag.',
|
|
91
80
|
}, { status: 400 });
|
|
92
81
|
}
|
|
93
82
|
for (const tag of tags) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { filterComponentsByType,
|
|
1
|
+
import { filterComponentsByType, } from '@sitecore-content-sdk/content/tools';
|
|
2
|
+
import { prepareComponentsForMap, buildComponentMapContent, } from '@sitecore-content-sdk/content/node-tools';
|
|
2
3
|
import * as path from 'path';
|
|
3
4
|
import * as fs from 'fs';
|
|
4
5
|
import { detectRouterType, getComponentListWithTypes, ROUTER_TYPE } from './templating/utils';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sitecore-content-sdk/nextjs",
|
|
3
|
-
"version": "2.4.1
|
|
3
|
+
"version": "2.4.1",
|
|
4
4
|
"main": "dist/cjs/index.js",
|
|
5
5
|
"module": "dist/esm/index.js",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -90,10 +90,10 @@
|
|
|
90
90
|
},
|
|
91
91
|
"dependencies": {
|
|
92
92
|
"@babel/parser": "^7.27.2",
|
|
93
|
-
"@sitecore-content-sdk/content": "2.3.1
|
|
93
|
+
"@sitecore-content-sdk/content": "^2.3.1",
|
|
94
94
|
"@sitecore-content-sdk/core": "^2.1.4",
|
|
95
95
|
"@sitecore-content-sdk/events": "^2.1.2",
|
|
96
|
-
"@sitecore-content-sdk/react": "2.4.
|
|
96
|
+
"@sitecore-content-sdk/react": "^2.4.0",
|
|
97
97
|
"recast": "^0.23.11",
|
|
98
98
|
"regex-parser": "^2.3.1"
|
|
99
99
|
},
|
|
@@ -68,25 +68,6 @@ export type BuildSitecoreDictionaryCacheTagParams = {
|
|
|
68
68
|
* @public
|
|
69
69
|
*/
|
|
70
70
|
export declare function buildSitecoreDictionaryCacheTag(params: BuildSitecoreDictionaryCacheTagParams): string;
|
|
71
|
-
/**
|
|
72
|
-
* Parameters for buildSitecoreDictionaryCacheTagsFromSites.
|
|
73
|
-
* @internal
|
|
74
|
-
*/
|
|
75
|
-
export type BuildSitecoreDictionaryCacheTagsFromSitesParams = {
|
|
76
|
-
/** Sites list (e.g. from generated multisite JSON). */
|
|
77
|
-
sites: readonly {
|
|
78
|
-
name: string;
|
|
79
|
-
language?: string;
|
|
80
|
-
}[];
|
|
81
|
-
/** Locale used when a site has no `language` value. */
|
|
82
|
-
baseLocale: string;
|
|
83
|
-
};
|
|
84
|
-
/**
|
|
85
|
-
* Builds deduplicated dictionary cache tags from a sites list.
|
|
86
|
-
* @param {BuildSitecoreDictionaryCacheTagsFromSitesParams} params - Sites list and fallback locale.
|
|
87
|
-
* @internal
|
|
88
|
-
*/
|
|
89
|
-
export declare function buildSitecoreDictionaryCacheTagsFromSites(params: BuildSitecoreDictionaryCacheTagsFromSitesParams): string[];
|
|
90
71
|
/**
|
|
91
72
|
* Builds an item cache tag from Sitecore layout route data when `itemId` is present.
|
|
92
73
|
* Prefers `itemLanguage` from Sitecore when set; otherwise uses `fallbackLocale`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sitecore-cache-tags.d.ts","sourceRoot":"","sources":["../../src/cache/sitecore-cache-tags.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sCAAsC,CAAC;AAEtE;;;;GAIG;AACH,eAAO,MAAM,iCAAiC,OAAO,CAAC;AAEtD;;;;;GAKG;AACH,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKrE;AAED;;;;;;;GAOG;AACH,wBAAgB,kCAAkC,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAOzE;AAED;;;GAGG;AACH,MAAM,MAAM,gCAAgC,GAAG;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,gCAAgC,GAAG,MAAM,CAM3F;AAED;;;GAGG;AACH,MAAM,MAAM,+BAA+B,GAAG;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,+BAA+B,GAAG,MAAM,CAIzF;AAED;;;GAGG;AACH,MAAM,MAAM,qCAAqC,GAAG;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,+BAA+B,CAC7C,MAAM,EAAE,qCAAqC,GAC5C,MAAM,CAIR;AAED
|
|
1
|
+
{"version":3,"file":"sitecore-cache-tags.d.ts","sourceRoot":"","sources":["../../src/cache/sitecore-cache-tags.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sCAAsC,CAAC;AAEtE;;;;GAIG;AACH,eAAO,MAAM,iCAAiC,OAAO,CAAC;AAEtD;;;;;GAKG;AACH,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKrE;AAED;;;;;;;GAOG;AACH,wBAAgB,kCAAkC,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAOzE;AAED;;;GAGG;AACH,MAAM,MAAM,gCAAgC,GAAG;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,gCAAgC,GAAG,MAAM,CAM3F;AAED;;;GAGG;AACH,MAAM,MAAM,+BAA+B,GAAG;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,+BAA+B,GAAG,MAAM,CAIzF;AAED;;;GAGG;AACH,MAAM,MAAM,qCAAqC,GAAG;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,+BAA+B,CAC7C,MAAM,EAAE,qCAAqC,GAC5C,MAAM,CAIR;AAED;;;;;;;;;GASG;AACH,wBAAgB,sCAAsC,CACpD,KAAK,EAAE,SAAS,GAAG,IAAI,GAAG,SAAS,EACnC,cAAc,EAAE,MAAM,GACrB,MAAM,GAAG,IAAI,CASf;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAUhE"}
|
|
@@ -17,12 +17,6 @@ export type SitecoreEdgeRevalidateRequestBody = {
|
|
|
17
17
|
invocation_id?: string;
|
|
18
18
|
updates?: SitecoreEdgeRevalidateUpdate[];
|
|
19
19
|
continues?: boolean;
|
|
20
|
-
/**
|
|
21
|
-
* Extra tag strings. Values starting with the Sitecore cache prefix (`sc:`) are used as-is.
|
|
22
|
-
* Bare values are treated as Sitecore item ids (with optional `-media` / `-layout` suffix stripped)
|
|
23
|
-
* and mapped to {@link buildSitecoreItemCacheTag} using the handler default locale when culture is missing.
|
|
24
|
-
*/
|
|
25
|
-
tags?: string[];
|
|
26
20
|
};
|
|
27
21
|
/**
|
|
28
22
|
* Strips Experience Edge style suffixes from an `identifier` so the value can be used as an item id in cache tags.
|
|
@@ -31,23 +25,52 @@ export type SitecoreEdgeRevalidateRequestBody = {
|
|
|
31
25
|
* @internal
|
|
32
26
|
*/
|
|
33
27
|
export declare function extractSitecoreEdgeContentId(identifier: string): string;
|
|
28
|
+
/**
|
|
29
|
+
* Whether a webhook update row is a Dictionary entry change (`entity_definition: "DictionaryEntry"`).
|
|
30
|
+
* @param {string} [entityDefinition] - `entity_definition` from a webhook update row.
|
|
31
|
+
* @internal
|
|
32
|
+
*/
|
|
33
|
+
export declare function isSitecoreDictionaryEntryUpdate(entityDefinition?: string): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Resolves which configured site a Dictionary entry webhook `identifier` belongs to.
|
|
36
|
+
*
|
|
37
|
+
* Dictionary identifiers follow `<site name>-<dictionary folder id>-<value>-<language>`, but the
|
|
38
|
+
* folder id, value, and language segments can themselves contain hyphens (and the value can contain
|
|
39
|
+
* spaces), so splitting the identifier on `-` is not reliable. Instead this matches the identifier
|
|
40
|
+
* against the known configured site names, preferring the longest name so a more specific name wins
|
|
41
|
+
* over a shorter overlapping one (e.g. `my-site-2` over `my-site`).
|
|
42
|
+
* @param {string} identifier - Raw `identifier` from a Dictionary entry update row.
|
|
43
|
+
* @param {string[]} siteNames - Configured site names (e.g. from `.sitecore/sites.json`).
|
|
44
|
+
* @returns The matched site name, or `undefined` when no configured site name prefixes `identifier`.
|
|
45
|
+
* @internal
|
|
46
|
+
*/
|
|
47
|
+
export declare function resolveSitecoreDictionarySiteNameFromIdentifier(identifier: string, siteNames: readonly string[]): string | undefined;
|
|
34
48
|
/**
|
|
35
49
|
* Options for {@link collectSitecoreTagsFromEdgeRevalidateRequestBody}.
|
|
36
50
|
* @internal
|
|
37
51
|
*/
|
|
38
52
|
export type CollectSitecoreTagsFromEdgeBodyOptions = {
|
|
39
53
|
/**
|
|
40
|
-
* Used when an update omits `entity_culture
|
|
54
|
+
* Used when an update omits `entity_culture`.
|
|
41
55
|
*/
|
|
42
56
|
defaultLocale: string;
|
|
57
|
+
/**
|
|
58
|
+
* Configured site names (e.g. from `.sitecore/sites.json`), used only to resolve which site a
|
|
59
|
+
* Dictionary entry update (`entity_definition: "DictionaryEntry"`) belongs to. When omitted (or when
|
|
60
|
+
* an identifier matches none of them), that update's Dictionary tag is skipped rather than guessed.
|
|
61
|
+
*/
|
|
62
|
+
siteNames?: readonly string[];
|
|
43
63
|
};
|
|
44
64
|
/**
|
|
45
65
|
* Maps an Experience Edge webhook JSON body to Content SDK cache tag strings used by
|
|
46
66
|
* {@link collectSitecorePageCacheTags} / {@link buildSitecoreItemCacheTag} (`sc:item:...`), so
|
|
47
67
|
* `revalidateTag` matches tags registered during cached reads.
|
|
48
|
-
* **`updates`** rows resolve to **`sc:item:…`** (locale from `entity_culture` or `defaultLocale`)
|
|
49
|
-
*
|
|
50
|
-
*
|
|
68
|
+
* **`updates`** rows resolve to **`sc:item:…`** (locale from `entity_culture` or `defaultLocale`), except
|
|
69
|
+
* rows where `entity_definition` is `"DictionaryEntry"`, which resolve to **`sc:dict:…`** scoped to the
|
|
70
|
+
* site resolved from the identifier (see {@link resolveSitecoreDictionarySiteNameFromIdentifier}) and the
|
|
71
|
+
* same locale. Route/variant tags are not inferred.
|
|
72
|
+
* @param {SitecoreEdgeRevalidateRequestBody | null | undefined} body - Webhook JSON body (updates).
|
|
73
|
+
* @param {CollectSitecoreTagsFromEdgeBodyOptions} options - Default locale, and site names for Dictionary entry updates.
|
|
51
74
|
* @internal
|
|
52
75
|
*/
|
|
53
76
|
export declare function collectSitecoreTagsFromEdgeRevalidateRequestBody(body: SitecoreEdgeRevalidateRequestBody | null | undefined, options: CollectSitecoreTagsFromEdgeBodyOptions): string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sitecore-edge-webhook-revalidation.d.ts","sourceRoot":"","sources":["../../src/cache/sitecore-edge-webhook-revalidation.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sitecore-edge-webhook-revalidation.d.ts","sourceRoot":"","sources":["../../src/cache/sitecore-edge-webhook-revalidation.ts"],"names":[],"mappings":"AAOA;;;;GAIG;AACH,MAAM,MAAM,4BAA4B,GAAG;IACzC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,iCAAiC,GAAG;IAC9C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,4BAA4B,EAAE,CAAC;IACzC,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAMvE;AAQD;;;;GAIG;AACH,wBAAgB,+BAA+B,CAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,OAAO,CAElF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,+CAA+C,CAC7D,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,SAAS,MAAM,EAAE,GAC3B,MAAM,GAAG,SAAS,CAMpB;AAgCD;;;GAGG;AACH,MAAM,MAAM,sCAAsC,GAAG;IACnD;;OAEG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC/B,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,wBAAgB,gDAAgD,CAC9D,IAAI,EAAE,iCAAiC,GAAG,IAAI,GAAG,SAAS,EAC1D,OAAO,EAAE,sCAAsC,GAC9C,MAAM,EAAE,CAoCV"}
|
|
@@ -23,8 +23,8 @@ export type CollectSitecorePageCacheTagsParams = {
|
|
|
23
23
|
* `buildSitecoreDictionaryCacheTag` on a dedicated `use cache` helper).
|
|
24
24
|
*
|
|
25
25
|
* Registers **`sc:route:…`** and **`sc:item:…`** (when layout has `itemId`). Edge-style webhooks emit
|
|
26
|
-
* item ids, which the Sitecore revalidate route handler maps to **`sc:item:…`**; route tags are
|
|
27
|
-
* invalidated
|
|
26
|
+
* item ids, which the Sitecore revalidate route handler maps to **`sc:item:…`**; route tags are not
|
|
27
|
+
* invalidated by that webhook flow.
|
|
28
28
|
*
|
|
29
29
|
* Personalization variants are isolated naturally by URL path (each variant rewrite yields a distinct
|
|
30
30
|
* Cache Components key) so no `sc:pvv:…` tag is added here. If a personalize-specific webhook is wired
|
|
@@ -24,13 +24,15 @@ export type SitecoreRevalidateRouteHandlerOptions = {
|
|
|
24
24
|
*/
|
|
25
25
|
cacheProfile?: RevalidateTagCacheProfile;
|
|
26
26
|
/**
|
|
27
|
-
* Locale for item
|
|
27
|
+
* Locale for item and dictionary tags when an update omits `entity_culture`.
|
|
28
28
|
* Defaults to `'en'` when omitted.
|
|
29
29
|
*/
|
|
30
30
|
defaultLocale?: string;
|
|
31
31
|
/**
|
|
32
|
-
* Sites list (e.g. from `.sitecore/sites.json`)
|
|
33
|
-
*
|
|
32
|
+
* Sites list (e.g. from `.sitecore/sites.json`), used to resolve which site a Dictionary entry
|
|
33
|
+
* update (`entity_definition: "DictionaryEntry"`) belongs to, so only that site's
|
|
34
|
+
* `sc:dict:<site>:<locale>` tag is revalidated instead of every configured site's. `generateSites`
|
|
35
|
+
* always includes the configured default site.
|
|
34
36
|
*/
|
|
35
37
|
sites?: SiteInfo[];
|
|
36
38
|
};
|
|
@@ -42,17 +44,15 @@ export type SitecoreRevalidateRouteHandlerOptions = {
|
|
|
42
44
|
*
|
|
43
45
|
* - **`updates[]`** — Sitecore publish-event rows. Each row's `identifier` (with `-media` / `-layout`
|
|
44
46
|
* suffix stripped) maps to an `sc:item:<id>:<locale>` tag, using `entity_culture` for locale
|
|
45
|
-
* (falling back to the handler's `defaultLocale`)
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* When **`sites`** is configured, the handler also appends one `sc:dict:<site>:<locale>` tag per
|
|
51
|
-
* site so dictionary updates flow through the same call.
|
|
47
|
+
* (falling back to the handler's `defaultLocale`) — except rows where `entity_definition` is
|
|
48
|
+
* `"DictionaryEntry"`, which map to `sc:dict:<site>:<locale>` for the site resolved from the
|
|
49
|
+
* identifier via the configured **`sites`** option (skipped, with a debug log, when no configured
|
|
50
|
+
* site matches). Only updates that are actually Dictionary changes revalidate dictionary tags — a
|
|
51
|
+
* webhook for an unrelated item never touches them.
|
|
52
52
|
*
|
|
53
53
|
* Auth (optional): when `SITECORE_REVALIDATE_SECRET` (or the `secret` option) is non-empty, callers must
|
|
54
54
|
* send the same value in the **`x-revalidate-secret`** header. When unset or blank, no header is required.
|
|
55
|
-
* @param {SitecoreRevalidateRouteHandlerOptions} [options] - Optional inline `secret`, `cacheProfile`, locale,
|
|
55
|
+
* @param {SitecoreRevalidateRouteHandlerOptions} [options] - Optional inline `secret`, `cacheProfile`, locale, and sites options.
|
|
56
56
|
* @public
|
|
57
57
|
*/
|
|
58
58
|
export declare function createSitecoreRevalidateRouteHandler(options?: SitecoreRevalidateRouteHandlerOptions): {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sitecore-revalidate-route-handler.d.ts","sourceRoot":"","sources":["../../src/route-handler/sitecore-revalidate-route-handler.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAC;AAmBnE;;;;GAIG;AACH,MAAM,MAAM,yBAAyB,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;AAE5E;;;GAGG;AACH,MAAM,MAAM,qCAAqC,GAAG;IAClD;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,YAAY,CAAC,EAAE,yBAAyB,CAAC;IACzC;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB
|
|
1
|
+
{"version":3,"file":"sitecore-revalidate-route-handler.d.ts","sourceRoot":"","sources":["../../src/route-handler/sitecore-revalidate-route-handler.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAC;AAmBnE;;;;GAIG;AACH,MAAM,MAAM,yBAAyB,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;AAE5E;;;GAGG;AACH,MAAM,MAAM,qCAAqC,GAAG;IAClD;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,YAAY,CAAC,EAAE,yBAAyB,CAAC;IACzC;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;CACpB,CAAC;AAEF;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,oCAAoC,CAClD,OAAO,GAAE,qCAA0C;gBAK1B,WAAW;;;;;;;;EAsFrC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-map.d.ts","sourceRoot":"","sources":["../../src/tools/generate-map.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,mBAAmB,EAGnB,4BAA4B,
|
|
1
|
+
{"version":3,"file":"generate-map.d.ts","sourceRoot":"","sources":["../../src/tools/generate-map.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,mBAAmB,EAGnB,4BAA4B,EAG7B,MAAM,qCAAqC,CAAC;AAoD7C,eAAO,MAAM,wBAAwB,EAAE,4BAiBtC,CAAC;AAGF,eAAO,MAAM,wBAAwB,EAAE,4BAmBtC,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,QAAQ,GAAG,QAAQ,GAAG,WAAW,CAAC;AAgCtE;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,WAAW,EAAE,mBAkGzB,CAAC"}
|