@wix/web5-core 1.57.2 → 1.58.0
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/client/clientBundleUrl.js +40 -0
- package/dist/cjs/client/clientBundleUrl.js.map +1 -0
- package/dist/cjs/client/mergeClientConfig.js +59 -0
- package/dist/cjs/client/mergeClientConfig.js.map +1 -0
- package/dist/cjs/component/componentDefinitions/EntityCollectionSectionDefinition.js +159 -0
- package/dist/cjs/component/componentDefinitions/EntityCollectionSectionDefinition.js.map +1 -0
- package/dist/cjs/component/componentDefinitions/index.js +7 -1
- package/dist/cjs/component/componentDefinitions/index.js.map +1 -1
- package/dist/cjs/component/componentParser.js +38 -1
- package/dist/cjs/component/componentParser.js.map +1 -1
- package/dist/cjs/components/ui/SearchSection.css +66 -9
- package/dist/cjs/components/ui/SearchSection.js +23 -19
- package/dist/cjs/components/ui/SearchSection.js.map +1 -1
- package/dist/cjs/index.js +15 -3
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/styles/prompt-input-tokens.css +41 -34
- package/dist/cjs/utils/matchDebug.js +93 -0
- package/dist/cjs/utils/matchDebug.js.map +1 -0
- package/dist/esm/client/clientBundleUrl.js +36 -0
- package/dist/esm/client/clientBundleUrl.js.map +1 -0
- package/dist/esm/client/mergeClientConfig.js +55 -0
- package/dist/esm/client/mergeClientConfig.js.map +1 -0
- package/dist/esm/component/componentDefinitions/EntityCollectionSectionDefinition.js +154 -0
- package/dist/esm/component/componentDefinitions/EntityCollectionSectionDefinition.js.map +1 -0
- package/dist/esm/component/componentDefinitions/index.js +7 -1
- package/dist/esm/component/componentDefinitions/index.js.map +1 -1
- package/dist/esm/component/componentParser.js +38 -1
- package/dist/esm/component/componentParser.js.map +1 -1
- package/dist/esm/components/ui/SearchSection.css +66 -9
- package/dist/esm/components/ui/SearchSection.js +5 -1
- package/dist/esm/components/ui/SearchSection.js.map +1 -1
- package/dist/esm/index.js +8 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/styles/prompt-input-tokens.css +41 -34
- package/dist/esm/utils/matchDebug.js +85 -0
- package/dist/esm/utils/matchDebug.js.map +1 -0
- package/dist/types/client/clientBundleUrl.d.ts +17 -0
- package/dist/types/client/clientBundleUrl.d.ts.map +1 -0
- package/dist/types/client/mergeClientConfig.d.ts +28 -0
- package/dist/types/client/mergeClientConfig.d.ts.map +1 -0
- package/dist/types/component/componentDefinitions/EntityCollectionSectionDefinition.d.ts +51 -0
- package/dist/types/component/componentDefinitions/EntityCollectionSectionDefinition.d.ts.map +1 -0
- package/dist/types/component/componentDefinitions/index.d.ts +1 -0
- package/dist/types/component/componentDefinitions/index.d.ts.map +1 -1
- package/dist/types/component/componentParser.d.ts.map +1 -1
- package/dist/types/components/ui/SearchSection.d.ts.map +1 -1
- package/dist/types/index.d.ts +4 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/utils/matchDebug.d.ts +38 -0
- package/dist/types/utils/matchDebug.d.ts.map +1 -0
- package/package.json +2 -2
- package/src/components/ui/SearchSection.css +66 -9
- package/src/styles/prompt-input-tokens.css +41 -34
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.resolveClientBundleUrl = resolveClientBundleUrl;
|
|
5
|
+
/**
|
|
6
|
+
* Client-UMD URL resolution, shared between `web50-server-ui` (the main app)
|
|
7
|
+
* and `embed-placement` (the storefront widget) — DL #094 (per-msid) + DL #129
|
|
8
|
+
* (per-template). Centralized here for the same reason as
|
|
9
|
+
* `clientBundleOverride.ts`: both callers must derive identical URLs, and
|
|
10
|
+
* divergence on which bundle a tenant executes would be a real bug.
|
|
11
|
+
*
|
|
12
|
+
* Two tiers (DL #129):
|
|
13
|
+
* - `templateId` present (DIY store) → the shared per-template bundle,
|
|
14
|
+
* `<cdn>/templates/<id>/production/…`. Every store on a template runs the
|
|
15
|
+
* same artifact; `production` is the promoted channel.
|
|
16
|
+
* - `templateId` absent (customized tier: feature-com, circana, smallflower)
|
|
17
|
+
* → the per-msid bundle at `<cdn>/<msid>/latest/…`, byte-identical to the
|
|
18
|
+
* pre-template behavior.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
const CLIENT_BUNDLE_CDN = 'https://d13cktzsgh0qls.cloudfront.net';
|
|
22
|
+
const CLIENT_BUNDLE_FILENAME = 'w5-components.umd.js';
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Template ids are kebab-case slugs from `templates/manifest.json`
|
|
26
|
+
* (`web5-seed-1`). The id becomes a CDN path segment, so anything else is a
|
|
27
|
+
* config error — resolve falls back to the per-msid path (fail-soft, and the
|
|
28
|
+
* store keeps rendering) rather than fetching a malformed URL.
|
|
29
|
+
*/
|
|
30
|
+
const TEMPLATE_ID_PATTERN = /^[a-z0-9]+(-[a-z0-9]+)*$/;
|
|
31
|
+
function resolveClientBundleUrl(msid, templateId) {
|
|
32
|
+
if (templateId) {
|
|
33
|
+
if (TEMPLATE_ID_PATTERN.test(templateId)) {
|
|
34
|
+
return `${CLIENT_BUNDLE_CDN}/templates/${templateId}/production/${CLIENT_BUNDLE_FILENAME}`;
|
|
35
|
+
}
|
|
36
|
+
console.warn(`[web5-core] Ignoring malformed templateId "${templateId}" — falling back to the per-msid bundle.`);
|
|
37
|
+
}
|
|
38
|
+
return `${CLIENT_BUNDLE_CDN}/${msid}/latest/${CLIENT_BUNDLE_FILENAME}`;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=clientBundleUrl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["CLIENT_BUNDLE_CDN","CLIENT_BUNDLE_FILENAME","TEMPLATE_ID_PATTERN","resolveClientBundleUrl","msid","templateId","test","console","warn"],"sources":["../../../src/client/clientBundleUrl.ts"],"sourcesContent":["/**\n * Client-UMD URL resolution, shared between `web50-server-ui` (the main app)\n * and `embed-placement` (the storefront widget) — DL #094 (per-msid) + DL #129\n * (per-template). Centralized here for the same reason as\n * `clientBundleOverride.ts`: both callers must derive identical URLs, and\n * divergence on which bundle a tenant executes would be a real bug.\n *\n * Two tiers (DL #129):\n * - `templateId` present (DIY store) → the shared per-template bundle,\n * `<cdn>/templates/<id>/production/…`. Every store on a template runs the\n * same artifact; `production` is the promoted channel.\n * - `templateId` absent (customized tier: feature-com, circana, smallflower)\n * → the per-msid bundle at `<cdn>/<msid>/latest/…`, byte-identical to the\n * pre-template behavior.\n */\n\nconst CLIENT_BUNDLE_CDN = 'https://d13cktzsgh0qls.cloudfront.net';\nconst CLIENT_BUNDLE_FILENAME = 'w5-components.umd.js';\n\n/**\n * Template ids are kebab-case slugs from `templates/manifest.json`\n * (`web5-seed-1`). The id becomes a CDN path segment, so anything else is a\n * config error — resolve falls back to the per-msid path (fail-soft, and the\n * store keeps rendering) rather than fetching a malformed URL.\n */\nconst TEMPLATE_ID_PATTERN = /^[a-z0-9]+(-[a-z0-9]+)*$/;\n\nexport function resolveClientBundleUrl(\n msid: string,\n templateId?: string | null,\n): string {\n if (templateId) {\n if (TEMPLATE_ID_PATTERN.test(templateId)) {\n return `${CLIENT_BUNDLE_CDN}/templates/${templateId}/production/${CLIENT_BUNDLE_FILENAME}`;\n }\n console.warn(\n `[web5-core] Ignoring malformed templateId \"${templateId}\" — falling back to the per-msid bundle.`,\n );\n }\n return `${CLIENT_BUNDLE_CDN}/${msid}/latest/${CLIENT_BUNDLE_FILENAME}`;\n}\n"],"mappings":";;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,MAAMA,iBAAiB,GAAG,uCAAuC;AACjE,MAAMC,sBAAsB,GAAG,sBAAsB;;AAErD;AACA;AACA;AACA;AACA;AACA;AACA,MAAMC,mBAAmB,GAAG,0BAA0B;AAE/C,SAASC,sBAAsBA,CACpCC,IAAY,EACZC,UAA0B,EAClB;EACR,IAAIA,UAAU,EAAE;IACd,IAAIH,mBAAmB,CAACI,IAAI,CAACD,UAAU,CAAC,EAAE;MACxC,OAAO,GAAGL,iBAAiB,cAAcK,UAAU,eAAeJ,sBAAsB,EAAE;IAC5F;IACAM,OAAO,CAACC,IAAI,CACV,8CAA8CH,UAAU,0CAC1D,CAAC;EACH;EACA,OAAO,GAAGL,iBAAiB,IAAII,IAAI,WAAWH,sBAAsB,EAAE;AACxE","ignoreList":[]}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.mergeClientConfig = mergeClientConfig;
|
|
5
|
+
/**
|
|
6
|
+
* Universal client-config merge (DL #129 Q3/Q7): the loaded client bundle's
|
|
7
|
+
* `clientConfig` is the default; the backend `Configuration.clientConfig`
|
|
8
|
+
* overrides it **per field, only where a field was actually returned**.
|
|
9
|
+
*
|
|
10
|
+
* One rule for both tiers, shared between `web50-server-ui` and
|
|
11
|
+
* `embed-placement` (the two places that load `w5-components.umd.js`):
|
|
12
|
+
* - Customized-tier clients (feature-com, circana): the backend returns no
|
|
13
|
+
* `clientConfig`, so the merge is identity — the bundle's baked config
|
|
14
|
+
* passes through byte-identical (same reference, see spec).
|
|
15
|
+
* - DIY/template stores: the backend supplies per-store deltas that grow
|
|
16
|
+
* field-by-field as the client-config port (Phase 3b) lands; each ported
|
|
17
|
+
* field takes effect here with no FE change.
|
|
18
|
+
*
|
|
19
|
+
* Semantics — presence, not truthiness:
|
|
20
|
+
* - The wire omits unset proto fields, so key-absence means "not returned"
|
|
21
|
+
* → bundle value kept. A key that IS present wins even when falsy
|
|
22
|
+
* (`''`, `false`, `0`) — it was explicitly set.
|
|
23
|
+
* - `undefined`/`null` values are treated as absent (proto3 JSON never
|
|
24
|
+
* emits null for wrapper types; defensive against hand-written configs).
|
|
25
|
+
* - Plain objects merge per leaf; arrays replace wholesale; class
|
|
26
|
+
* instances / functions replace wholesale.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
function isPlainObject(value) {
|
|
30
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value) && (Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null);
|
|
31
|
+
}
|
|
32
|
+
function mergeClientConfig(bundleConfig,
|
|
33
|
+
// `Record<string, unknown>` admitted alongside `DeepPartial<T>`: the wire
|
|
34
|
+
// value is untyped JSON (`Configuration.clientConfig`), so callers hold it
|
|
35
|
+
// as a plain record — the runtime presence checks do the validation.
|
|
36
|
+
backendConfig) {
|
|
37
|
+
if (backendConfig === undefined || backendConfig === null) {
|
|
38
|
+
return bundleConfig;
|
|
39
|
+
}
|
|
40
|
+
if (!isPlainObject(backendConfig)) {
|
|
41
|
+
return bundleConfig;
|
|
42
|
+
}
|
|
43
|
+
const keys = Object.keys(backendConfig).filter(key => backendConfig[key] !== undefined && backendConfig[key] !== null);
|
|
44
|
+
// Empty delta → identity, same reference: the byte-identical passthrough
|
|
45
|
+
// guarantee for clients whose Configuration carries no clientConfig.
|
|
46
|
+
if (keys.length === 0) {
|
|
47
|
+
return bundleConfig;
|
|
48
|
+
}
|
|
49
|
+
const result = {
|
|
50
|
+
...bundleConfig
|
|
51
|
+
};
|
|
52
|
+
for (const key of keys) {
|
|
53
|
+
const backendValue = backendConfig[key];
|
|
54
|
+
const bundleValue = bundleConfig[key];
|
|
55
|
+
result[key] = isPlainObject(backendValue) && isPlainObject(bundleValue) ? mergeClientConfig(bundleValue, backendValue) : backendValue;
|
|
56
|
+
}
|
|
57
|
+
return result;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=mergeClientConfig.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["isPlainObject","value","Array","isArray","Object","getPrototypeOf","prototype","mergeClientConfig","bundleConfig","backendConfig","undefined","keys","filter","key","length","result","backendValue","bundleValue"],"sources":["../../../src/client/mergeClientConfig.ts"],"sourcesContent":["/**\n * Universal client-config merge (DL #129 Q3/Q7): the loaded client bundle's\n * `clientConfig` is the default; the backend `Configuration.clientConfig`\n * overrides it **per field, only where a field was actually returned**.\n *\n * One rule for both tiers, shared between `web50-server-ui` and\n * `embed-placement` (the two places that load `w5-components.umd.js`):\n * - Customized-tier clients (feature-com, circana): the backend returns no\n * `clientConfig`, so the merge is identity — the bundle's baked config\n * passes through byte-identical (same reference, see spec).\n * - DIY/template stores: the backend supplies per-store deltas that grow\n * field-by-field as the client-config port (Phase 3b) lands; each ported\n * field takes effect here with no FE change.\n *\n * Semantics — presence, not truthiness:\n * - The wire omits unset proto fields, so key-absence means \"not returned\"\n * → bundle value kept. A key that IS present wins even when falsy\n * (`''`, `false`, `0`) — it was explicitly set.\n * - `undefined`/`null` values are treated as absent (proto3 JSON never\n * emits null for wrapper types; defensive against hand-written configs).\n * - Plain objects merge per leaf; arrays replace wholesale; class\n * instances / functions replace wholesale.\n */\n\nexport type DeepPartial<T> = T extends (infer U)[]\n ? U[]\n : T extends object\n ? { [K in keyof T]?: DeepPartial<T[K]> }\n : T;\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return (\n typeof value === 'object' &&\n value !== null &&\n !Array.isArray(value) &&\n (Object.getPrototypeOf(value) === Object.prototype ||\n Object.getPrototypeOf(value) === null)\n );\n}\n\nexport function mergeClientConfig<T extends object>(\n bundleConfig: T,\n // `Record<string, unknown>` admitted alongside `DeepPartial<T>`: the wire\n // value is untyped JSON (`Configuration.clientConfig`), so callers hold it\n // as a plain record — the runtime presence checks do the validation.\n backendConfig?: DeepPartial<T> | Record<string, unknown> | null,\n): T {\n if (backendConfig === undefined || backendConfig === null) {\n return bundleConfig;\n }\n if (!isPlainObject(backendConfig)) {\n return bundleConfig;\n }\n const keys = Object.keys(backendConfig).filter(\n (key) => (backendConfig as Record<string, unknown>)[key] !== undefined &&\n (backendConfig as Record<string, unknown>)[key] !== null,\n );\n // Empty delta → identity, same reference: the byte-identical passthrough\n // guarantee for clients whose Configuration carries no clientConfig.\n if (keys.length === 0) {\n return bundleConfig;\n }\n\n const result: Record<string, unknown> = {\n ...(bundleConfig as Record<string, unknown>),\n };\n for (const key of keys) {\n const backendValue = (backendConfig as Record<string, unknown>)[key];\n const bundleValue = (bundleConfig as Record<string, unknown>)[key];\n result[key] =\n isPlainObject(backendValue) && isPlainObject(bundleValue)\n ? mergeClientConfig(bundleValue, backendValue)\n : backendValue;\n }\n return result as T;\n}\n"],"mappings":";;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAQA,SAASA,aAAaA,CAACC,KAAc,EAAoC;EACvE,OACE,OAAOA,KAAK,KAAK,QAAQ,IACzBA,KAAK,KAAK,IAAI,IACd,CAACC,KAAK,CAACC,OAAO,CAACF,KAAK,CAAC,KACpBG,MAAM,CAACC,cAAc,CAACJ,KAAK,CAAC,KAAKG,MAAM,CAACE,SAAS,IAChDF,MAAM,CAACC,cAAc,CAACJ,KAAK,CAAC,KAAK,IAAI,CAAC;AAE5C;AAEO,SAASM,iBAAiBA,CAC/BC,YAAe;AACf;AACA;AACA;AACAC,aAA+D,EAC5D;EACH,IAAIA,aAAa,KAAKC,SAAS,IAAID,aAAa,KAAK,IAAI,EAAE;IACzD,OAAOD,YAAY;EACrB;EACA,IAAI,CAACR,aAAa,CAACS,aAAa,CAAC,EAAE;IACjC,OAAOD,YAAY;EACrB;EACA,MAAMG,IAAI,GAAGP,MAAM,CAACO,IAAI,CAACF,aAAa,CAAC,CAACG,MAAM,CAC3CC,GAAG,IAAMJ,aAAa,CAA6BI,GAAG,CAAC,KAAKH,SAAS,IACnED,aAAa,CAA6BI,GAAG,CAAC,KAAK,IACxD,CAAC;EACD;EACA;EACA,IAAIF,IAAI,CAACG,MAAM,KAAK,CAAC,EAAE;IACrB,OAAON,YAAY;EACrB;EAEA,MAAMO,MAA+B,GAAG;IACtC,GAAIP;EACN,CAAC;EACD,KAAK,MAAMK,GAAG,IAAIF,IAAI,EAAE;IACtB,MAAMK,YAAY,GAAIP,aAAa,CAA6BI,GAAG,CAAC;IACpE,MAAMI,WAAW,GAAIT,YAAY,CAA6BK,GAAG,CAAC;IAClEE,MAAM,CAACF,GAAG,CAAC,GACTb,aAAa,CAACgB,YAAY,CAAC,IAAIhB,aAAa,CAACiB,WAAW,CAAC,GACrDV,iBAAiB,CAACU,WAAW,EAAED,YAAY,CAAC,GAC5CA,YAAY;EACpB;EACA,OAAOD,MAAM;AACf","ignoreList":[]}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
exports.__esModule = true;
|
|
5
|
+
exports.EntityCollectionSectionDefinition = void 0;
|
|
6
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
7
|
+
var _parseUtils = require("./parse-utils");
|
|
8
|
+
var _diagnosticTypes = require("../diagnosticTypes");
|
|
9
|
+
/**
|
|
10
|
+
* The semantic entity type this definition claims — the `<type>` segment of
|
|
11
|
+
* `web5://entity/<type>/<id>` (see the client `entityConfig.entityTypes` map).
|
|
12
|
+
*/
|
|
13
|
+
const COLLECTION_ENTITY_TYPE = 'collection';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Entity section restricted to **collection** entities
|
|
17
|
+
* (`web5://entity/collection/<id>`).
|
|
18
|
+
*
|
|
19
|
+
* Same markdown shapes as {@link EntitySectionDefinition} — an `h2`, optional
|
|
20
|
+
* intro/callout, then entity links either at the top level or as list items —
|
|
21
|
+
* but every entity link must be a collection. That makes it a strictly narrower
|
|
22
|
+
* match, so it MUST be registered **before** `EntitySectionDefinition` (which
|
|
23
|
+
* claims any `link[entityType]`, i.e. product and article sections too). Once
|
|
24
|
+
* `EntitySectionDefinition` matches, the block is consumed and no later
|
|
25
|
+
* definition is consulted.
|
|
26
|
+
*
|
|
27
|
+
* Mixed blocks (a collection next to a product or an article) fall through:
|
|
28
|
+
* the patterns only cover consecutive collection links, and `parse()` returns
|
|
29
|
+
* `null` when a non-collection entity slipped into the matched slice, handing
|
|
30
|
+
* the block to `EntitySectionDefinition`.
|
|
31
|
+
*
|
|
32
|
+
* Props are the shared {@link EntityCompProps} shape, so a client renders it
|
|
33
|
+
* with a dedicated `EntityCollectionSection` component while product/article
|
|
34
|
+
* sections keep using their own components under `EntitySectionDefinition`.
|
|
35
|
+
*/
|
|
36
|
+
class EntityCollectionSectionDefinition {
|
|
37
|
+
constructor() {
|
|
38
|
+
(0, _defineProperty2.default)(this, "sectionType", 'entityCollection');
|
|
39
|
+
/**
|
|
40
|
+
* One pattern, matching the shape the orchestrator actually emits for a
|
|
41
|
+
* collections block:
|
|
42
|
+
*
|
|
43
|
+
* <!-- section:entities, semantic:items -->
|
|
44
|
+
* ## Curated collections by theme
|
|
45
|
+
* - [](web5://entity/collection/<id>) description
|
|
46
|
+
*
|
|
47
|
+
* The head absorbs the section descriptor and any intro copy or ECHO
|
|
48
|
+
* callout; each list item is a collection link, an optional markdown image,
|
|
49
|
+
* then its description and optional per-item callout. A trailing
|
|
50
|
+
* section-level callout is intentionally left outside the pattern so it
|
|
51
|
+
* falls through to the downstream CalloutSection.
|
|
52
|
+
*
|
|
53
|
+
* Deliberately narrow: anything else (collection links at the top level
|
|
54
|
+
* rather than in a list, a block mixing entity types) falls through to
|
|
55
|
+
* `EntitySectionDefinition`, which is what handled it before this
|
|
56
|
+
* definition existed.
|
|
57
|
+
*/
|
|
58
|
+
(0, _defineProperty2.default)(this, "patterns", ['html_comment* > h2 > (html_comment | t | callout)* > list{item[1-]:link[entityType="collection"] > image? > (t | callout)*}']);
|
|
59
|
+
(0, _defineProperty2.default)(this, "defaults", {
|
|
60
|
+
title: 'Collections',
|
|
61
|
+
items: [{
|
|
62
|
+
entityId: 'example-1',
|
|
63
|
+
entityType: COLLECTION_ENTITY_TYPE,
|
|
64
|
+
entityUrl: 'web5://entity/collection/example-1',
|
|
65
|
+
linkText: 'Example collection'
|
|
66
|
+
}]
|
|
67
|
+
});
|
|
68
|
+
(0, _defineProperty2.default)(this, "fixtures", [{
|
|
69
|
+
markdown: '## Shop the collections\n\nCurated edits for the season.\n\n- [Running](web5://entity/collection/pUx3mVQ1TmyN2mVYQqQ8Jg) Shoes and kit built for the road\n- [Trail](web5://entity/collection/Rr8kQyO0S1uH2nQ0mQ2AqQ) Grip and protection off-road',
|
|
70
|
+
expected: {
|
|
71
|
+
title: 'Shop the collections',
|
|
72
|
+
description: 'Curated edits for the season.',
|
|
73
|
+
items: [{
|
|
74
|
+
entityId: 'pUx3mVQ1TmyN2mVYQqQ8Jg',
|
|
75
|
+
entityType: 'collection',
|
|
76
|
+
entityUrl: 'web5://entity/collection/pUx3mVQ1TmyN2mVYQqQ8Jg',
|
|
77
|
+
linkText: 'Running',
|
|
78
|
+
description: 'Shoes and kit built for the road'
|
|
79
|
+
}, {
|
|
80
|
+
entityId: 'Rr8kQyO0S1uH2nQ0mQ2AqQ',
|
|
81
|
+
entityType: 'collection',
|
|
82
|
+
entityUrl: 'web5://entity/collection/Rr8kQyO0S1uH2nQ0mQ2AqQ',
|
|
83
|
+
linkText: 'Trail',
|
|
84
|
+
description: 'Grip and protection off-road'
|
|
85
|
+
}]
|
|
86
|
+
}
|
|
87
|
+
}, {
|
|
88
|
+
// The shape the orchestrator emits: a section descriptor, empty link
|
|
89
|
+
// text, and a Shopify gid (which is itself a `://` url) as the entity id.
|
|
90
|
+
markdown: '<!-- section:entities, semantic:items -->\n## Curated collections by theme\n- [](web5://entity/collection/gid://shopify/Collection/347895267466) storewide assortment spanning the full product range\n- [](web5://entity/collection/gid://shopify/Collection/348001501322) artistic **Watercolor** candles with bright vessels',
|
|
91
|
+
expected: {
|
|
92
|
+
title: 'Curated collections by theme',
|
|
93
|
+
items: [{
|
|
94
|
+
entityId: 'gid://shopify/Collection/347895267466',
|
|
95
|
+
entityType: 'collection',
|
|
96
|
+
entityUrl: 'web5://entity/collection/gid://shopify/Collection/347895267466',
|
|
97
|
+
description: 'storewide assortment spanning the full product range'
|
|
98
|
+
}, {
|
|
99
|
+
entityId: 'gid://shopify/Collection/348001501322',
|
|
100
|
+
entityType: 'collection',
|
|
101
|
+
entityUrl: 'web5://entity/collection/gid://shopify/Collection/348001501322',
|
|
102
|
+
// Inline emphasis survives — descriptions keep their markdown.
|
|
103
|
+
description: 'artistic **Watercolor** candles with bright vessels'
|
|
104
|
+
}]
|
|
105
|
+
}
|
|
106
|
+
}, {
|
|
107
|
+
// Single collection — the full-width banner shape.
|
|
108
|
+
markdown: '## Winter essentials\n\n- [Shop winter](web5://entity/collection/aB1cD2eF3gH4iJ5kL6mN7o) Layers for the cold months',
|
|
109
|
+
expected: {
|
|
110
|
+
title: 'Winter essentials',
|
|
111
|
+
items: [{
|
|
112
|
+
entityId: 'aB1cD2eF3gH4iJ5kL6mN7o',
|
|
113
|
+
entityType: 'collection',
|
|
114
|
+
entityUrl: 'web5://entity/collection/aB1cD2eF3gH4iJ5kL6mN7o',
|
|
115
|
+
linkText: 'Shop winter',
|
|
116
|
+
description: 'Layers for the cold months'
|
|
117
|
+
}]
|
|
118
|
+
}
|
|
119
|
+
}]);
|
|
120
|
+
}
|
|
121
|
+
parse(parts, context) {
|
|
122
|
+
const entityRefs = (0, _parseUtils.extractEntityRefs)(parts);
|
|
123
|
+
if (entityRefs.length === 0) {
|
|
124
|
+
context == null || context.reportDiagnostic == null || context.reportDiagnostic(_diagnosticTypes.DIAGNOSTIC_TYPES.SECTION_REJECTED, 'entityCollection: no entity links found');
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Guard the pattern: anything that is not a collection means this block
|
|
129
|
+
// belongs to the generic entity section, not here.
|
|
130
|
+
if (entityRefs.some(e => e.entityType !== COLLECTION_ENTITY_TYPE)) {
|
|
131
|
+
context == null || context.reportDiagnostic == null || context.reportDiagnostic(_diagnosticTypes.DIAGNOSTIC_TYPES.SECTION_REJECTED, 'entityCollection: block mixes collections with other entity types');
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
const title = (0, _parseUtils.headingText)(parts, 2) || 'Collections';
|
|
135
|
+
const description = (0, _parseUtils.entitySectionBodyText)(parts) || undefined;
|
|
136
|
+
|
|
137
|
+
// Every entity link lives inside the list, so any top-level callout is
|
|
138
|
+
// section-level by construction — per-item callouts are nested in the list
|
|
139
|
+
// items and are picked up by extractEntityRefs instead.
|
|
140
|
+
const callout = (0, _parseUtils.calloutFromParts)(parts);
|
|
141
|
+
const items = entityRefs.map(e => ({
|
|
142
|
+
entityId: e.entityId,
|
|
143
|
+
entityType: e.entityType,
|
|
144
|
+
entityUrl: e.entityUrl,
|
|
145
|
+
linkText: e.linkText || undefined,
|
|
146
|
+
description: e.description || undefined,
|
|
147
|
+
imageUrl: e.markdownImageUrl,
|
|
148
|
+
callout: e.callout
|
|
149
|
+
}));
|
|
150
|
+
return {
|
|
151
|
+
title,
|
|
152
|
+
description,
|
|
153
|
+
callout,
|
|
154
|
+
items
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
exports.EntityCollectionSectionDefinition = EntityCollectionSectionDefinition;
|
|
159
|
+
//# sourceMappingURL=EntityCollectionSectionDefinition.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_parseUtils","require","_diagnosticTypes","COLLECTION_ENTITY_TYPE","EntityCollectionSectionDefinition","constructor","_defineProperty2","default","title","items","entityId","entityType","entityUrl","linkText","markdown","expected","description","parse","parts","context","entityRefs","extractEntityRefs","length","reportDiagnostic","DIAGNOSTIC_TYPES","SECTION_REJECTED","some","e","headingText","entitySectionBodyText","undefined","callout","calloutFromParts","map","imageUrl","markdownImageUrl","exports"],"sources":["../../../../src/component/componentDefinitions/EntityCollectionSectionDefinition.ts"],"sourcesContent":["import {\n headingText,\n entitySectionBodyText,\n extractEntityRefs,\n calloutFromParts,\n} from './parse-utils';\nimport type { Part } from '../../parts/parts';\nimport type {\n EntityCompProps,\n EntityItem,\n EntitySectionComponent,\n SectionFixture,\n} from '../types';\nimport type { SectionDefinition, ParseContext } from '../section-definition';\nimport { DIAGNOSTIC_TYPES } from '../diagnosticTypes';\n\n/**\n * The semantic entity type this definition claims — the `<type>` segment of\n * `web5://entity/<type>/<id>` (see the client `entityConfig.entityTypes` map).\n */\nconst COLLECTION_ENTITY_TYPE = 'collection';\n\n/**\n * Entity section restricted to **collection** entities\n * (`web5://entity/collection/<id>`).\n *\n * Same markdown shapes as {@link EntitySectionDefinition} — an `h2`, optional\n * intro/callout, then entity links either at the top level or as list items —\n * but every entity link must be a collection. That makes it a strictly narrower\n * match, so it MUST be registered **before** `EntitySectionDefinition` (which\n * claims any `link[entityType]`, i.e. product and article sections too). Once\n * `EntitySectionDefinition` matches, the block is consumed and no later\n * definition is consulted.\n *\n * Mixed blocks (a collection next to a product or an article) fall through:\n * the patterns only cover consecutive collection links, and `parse()` returns\n * `null` when a non-collection entity slipped into the matched slice, handing\n * the block to `EntitySectionDefinition`.\n *\n * Props are the shared {@link EntityCompProps} shape, so a client renders it\n * with a dedicated `EntityCollectionSection` component while product/article\n * sections keep using their own components under `EntitySectionDefinition`.\n */\nexport class EntityCollectionSectionDefinition\n implements SectionDefinition<EntitySectionComponent>\n{\n sectionType = 'entityCollection' as const;\n /**\n * One pattern, matching the shape the orchestrator actually emits for a\n * collections block:\n *\n * <!-- section:entities, semantic:items -->\n * ## Curated collections by theme\n * - [](web5://entity/collection/<id>) description\n *\n * The head absorbs the section descriptor and any intro copy or ECHO\n * callout; each list item is a collection link, an optional markdown image,\n * then its description and optional per-item callout. A trailing\n * section-level callout is intentionally left outside the pattern so it\n * falls through to the downstream CalloutSection.\n *\n * Deliberately narrow: anything else (collection links at the top level\n * rather than in a list, a block mixing entity types) falls through to\n * `EntitySectionDefinition`, which is what handled it before this\n * definition existed.\n */\n patterns = [\n 'html_comment* > h2 > (html_comment | t | callout)* > list{item[1-]:link[entityType=\"collection\"] > image? > (t | callout)*}',\n ];\n\n defaults: EntityCompProps = {\n title: 'Collections',\n items: [\n {\n entityId: 'example-1',\n entityType: COLLECTION_ENTITY_TYPE,\n entityUrl: 'web5://entity/collection/example-1',\n linkText: 'Example collection',\n },\n ],\n };\n\n fixtures: SectionFixture<EntityCompProps>[] = [\n {\n markdown:\n '## Shop the collections\\n\\nCurated edits for the season.\\n\\n- [Running](web5://entity/collection/pUx3mVQ1TmyN2mVYQqQ8Jg) Shoes and kit built for the road\\n- [Trail](web5://entity/collection/Rr8kQyO0S1uH2nQ0mQ2AqQ) Grip and protection off-road',\n expected: {\n title: 'Shop the collections',\n description: 'Curated edits for the season.',\n items: [\n {\n entityId: 'pUx3mVQ1TmyN2mVYQqQ8Jg',\n entityType: 'collection',\n entityUrl: 'web5://entity/collection/pUx3mVQ1TmyN2mVYQqQ8Jg',\n linkText: 'Running',\n description: 'Shoes and kit built for the road',\n },\n {\n entityId: 'Rr8kQyO0S1uH2nQ0mQ2AqQ',\n entityType: 'collection',\n entityUrl: 'web5://entity/collection/Rr8kQyO0S1uH2nQ0mQ2AqQ',\n linkText: 'Trail',\n description: 'Grip and protection off-road',\n },\n ],\n },\n },\n {\n // The shape the orchestrator emits: a section descriptor, empty link\n // text, and a Shopify gid (which is itself a `://` url) as the entity id.\n markdown:\n '<!-- section:entities, semantic:items -->\\n## Curated collections by theme\\n- [](web5://entity/collection/gid://shopify/Collection/347895267466) storewide assortment spanning the full product range\\n- [](web5://entity/collection/gid://shopify/Collection/348001501322) artistic **Watercolor** candles with bright vessels',\n expected: {\n title: 'Curated collections by theme',\n items: [\n {\n entityId: 'gid://shopify/Collection/347895267466',\n entityType: 'collection',\n entityUrl:\n 'web5://entity/collection/gid://shopify/Collection/347895267466',\n description: 'storewide assortment spanning the full product range',\n },\n {\n entityId: 'gid://shopify/Collection/348001501322',\n entityType: 'collection',\n entityUrl:\n 'web5://entity/collection/gid://shopify/Collection/348001501322',\n // Inline emphasis survives — descriptions keep their markdown.\n description: 'artistic **Watercolor** candles with bright vessels',\n },\n ],\n },\n },\n {\n // Single collection — the full-width banner shape.\n markdown:\n '## Winter essentials\\n\\n- [Shop winter](web5://entity/collection/aB1cD2eF3gH4iJ5kL6mN7o) Layers for the cold months',\n expected: {\n title: 'Winter essentials',\n items: [\n {\n entityId: 'aB1cD2eF3gH4iJ5kL6mN7o',\n entityType: 'collection',\n entityUrl: 'web5://entity/collection/aB1cD2eF3gH4iJ5kL6mN7o',\n linkText: 'Shop winter',\n description: 'Layers for the cold months',\n },\n ],\n },\n },\n ];\n\n parse(parts: Part[], context?: ParseContext): EntityCompProps | null {\n const entityRefs = extractEntityRefs(parts);\n\n if (entityRefs.length === 0) {\n context?.reportDiagnostic?.(\n DIAGNOSTIC_TYPES.SECTION_REJECTED,\n 'entityCollection: no entity links found',\n );\n return null;\n }\n\n // Guard the pattern: anything that is not a collection means this block\n // belongs to the generic entity section, not here.\n if (entityRefs.some((e) => e.entityType !== COLLECTION_ENTITY_TYPE)) {\n context?.reportDiagnostic?.(\n DIAGNOSTIC_TYPES.SECTION_REJECTED,\n 'entityCollection: block mixes collections with other entity types',\n );\n return null;\n }\n\n const title = headingText(parts, 2) || 'Collections';\n const description = entitySectionBodyText(parts) || undefined;\n\n // Every entity link lives inside the list, so any top-level callout is\n // section-level by construction — per-item callouts are nested in the list\n // items and are picked up by extractEntityRefs instead.\n const callout = calloutFromParts(parts);\n\n const items: EntityItem[] = entityRefs.map((e) => ({\n entityId: e.entityId,\n entityType: e.entityType,\n entityUrl: e.entityUrl,\n linkText: e.linkText || undefined,\n description: e.description || undefined,\n imageUrl: e.markdownImageUrl,\n callout: e.callout,\n }));\n\n return { title, description, callout, items };\n }\n}\n"],"mappings":";;;;;;AAAA,IAAAA,WAAA,GAAAC,OAAA;AAcA,IAAAC,gBAAA,GAAAD,OAAA;AAEA;AACA;AACA;AACA;AACA,MAAME,sBAAsB,GAAG,YAAY;;AAE3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAMC,iCAAiC,CAE9C;EAAAC,YAAA;IAAA,IAAAC,gBAAA,CAAAC,OAAA,uBACgB,kBAAkB;IAChC;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;IAlBE,IAAAD,gBAAA,CAAAC,OAAA,oBAmBW,CACT,6HAA6H,CAC9H;IAAA,IAAAD,gBAAA,CAAAC,OAAA,oBAE2B;MAC1BC,KAAK,EAAE,aAAa;MACpBC,KAAK,EAAE,CACL;QACEC,QAAQ,EAAE,WAAW;QACrBC,UAAU,EAAER,sBAAsB;QAClCS,SAAS,EAAE,oCAAoC;QAC/CC,QAAQ,EAAE;MACZ,CAAC;IAEL,CAAC;IAAA,IAAAP,gBAAA,CAAAC,OAAA,oBAE6C,CAC5C;MACEO,QAAQ,EACN,oPAAoP;MACtPC,QAAQ,EAAE;QACRP,KAAK,EAAE,sBAAsB;QAC7BQ,WAAW,EAAE,+BAA+B;QAC5CP,KAAK,EAAE,CACL;UACEC,QAAQ,EAAE,wBAAwB;UAClCC,UAAU,EAAE,YAAY;UACxBC,SAAS,EAAE,iDAAiD;UAC5DC,QAAQ,EAAE,SAAS;UACnBG,WAAW,EAAE;QACf,CAAC,EACD;UACEN,QAAQ,EAAE,wBAAwB;UAClCC,UAAU,EAAE,YAAY;UACxBC,SAAS,EAAE,iDAAiD;UAC5DC,QAAQ,EAAE,OAAO;UACjBG,WAAW,EAAE;QACf,CAAC;MAEL;IACF,CAAC,EACD;MACE;MACA;MACAF,QAAQ,EACN,iUAAiU;MACnUC,QAAQ,EAAE;QACRP,KAAK,EAAE,8BAA8B;QACrCC,KAAK,EAAE,CACL;UACEC,QAAQ,EAAE,uCAAuC;UACjDC,UAAU,EAAE,YAAY;UACxBC,SAAS,EACP,gEAAgE;UAClEI,WAAW,EAAE;QACf,CAAC,EACD;UACEN,QAAQ,EAAE,uCAAuC;UACjDC,UAAU,EAAE,YAAY;UACxBC,SAAS,EACP,gEAAgE;UAClE;UACAI,WAAW,EAAE;QACf,CAAC;MAEL;IACF,CAAC,EACD;MACE;MACAF,QAAQ,EACN,qHAAqH;MACvHC,QAAQ,EAAE;QACRP,KAAK,EAAE,mBAAmB;QAC1BC,KAAK,EAAE,CACL;UACEC,QAAQ,EAAE,wBAAwB;UAClCC,UAAU,EAAE,YAAY;UACxBC,SAAS,EAAE,iDAAiD;UAC5DC,QAAQ,EAAE,aAAa;UACvBG,WAAW,EAAE;QACf,CAAC;MAEL;IACF,CAAC,CACF;EAAA;EAEDC,KAAKA,CAACC,KAAa,EAAEC,OAAsB,EAA0B;IACnE,MAAMC,UAAU,GAAG,IAAAC,6BAAiB,EAACH,KAAK,CAAC;IAE3C,IAAIE,UAAU,CAACE,MAAM,KAAK,CAAC,EAAE;MAC3BH,OAAO,YAAPA,OAAO,CAAEI,gBAAgB,YAAzBJ,OAAO,CAAEI,gBAAgB,CACvBC,iCAAgB,CAACC,gBAAgB,EACjC,yCACF,CAAC;MACD,OAAO,IAAI;IACb;;IAEA;IACA;IACA,IAAIL,UAAU,CAACM,IAAI,CAAEC,CAAC,IAAKA,CAAC,CAAChB,UAAU,KAAKR,sBAAsB,CAAC,EAAE;MACnEgB,OAAO,YAAPA,OAAO,CAAEI,gBAAgB,YAAzBJ,OAAO,CAAEI,gBAAgB,CACvBC,iCAAgB,CAACC,gBAAgB,EACjC,mEACF,CAAC;MACD,OAAO,IAAI;IACb;IAEA,MAAMjB,KAAK,GAAG,IAAAoB,uBAAW,EAACV,KAAK,EAAE,CAAC,CAAC,IAAI,aAAa;IACpD,MAAMF,WAAW,GAAG,IAAAa,iCAAqB,EAACX,KAAK,CAAC,IAAIY,SAAS;;IAE7D;IACA;IACA;IACA,MAAMC,OAAO,GAAG,IAAAC,4BAAgB,EAACd,KAAK,CAAC;IAEvC,MAAMT,KAAmB,GAAGW,UAAU,CAACa,GAAG,CAAEN,CAAC,KAAM;MACjDjB,QAAQ,EAAEiB,CAAC,CAACjB,QAAQ;MACpBC,UAAU,EAAEgB,CAAC,CAAChB,UAAU;MACxBC,SAAS,EAAEe,CAAC,CAACf,SAAS;MACtBC,QAAQ,EAAEc,CAAC,CAACd,QAAQ,IAAIiB,SAAS;MACjCd,WAAW,EAAEW,CAAC,CAACX,WAAW,IAAIc,SAAS;MACvCI,QAAQ,EAAEP,CAAC,CAACQ,gBAAgB;MAC5BJ,OAAO,EAAEJ,CAAC,CAACI;IACb,CAAC,CAAC,CAAC;IAEH,OAAO;MAAEvB,KAAK;MAAEQ,WAAW;MAAEe,OAAO;MAAEtB;IAAM,CAAC;EAC/C;AACF;AAAC2B,OAAA,CAAAhC,iCAAA,GAAAA,iCAAA","ignoreList":[]}
|
|
@@ -16,6 +16,8 @@ var _FeatureCardsSectionDefinition = require("./FeatureCardsSectionDefinition");
|
|
|
16
16
|
exports.FeatureCardsSectionDefinition = _FeatureCardsSectionDefinition.FeatureCardsSectionDefinition;
|
|
17
17
|
var _EntitySectionDefinition = require("./EntitySectionDefinition");
|
|
18
18
|
exports.EntitySectionDefinition = _EntitySectionDefinition.EntitySectionDefinition;
|
|
19
|
+
var _EntityCollectionSectionDefinition = require("./EntityCollectionSectionDefinition");
|
|
20
|
+
exports.EntityCollectionSectionDefinition = _EntityCollectionSectionDefinition.EntityCollectionSectionDefinition;
|
|
19
21
|
var _CtaBannerSectionDefinition = require("./CtaBannerSectionDefinition");
|
|
20
22
|
exports.CtaBannerSectionDefinition = _CtaBannerSectionDefinition.CtaBannerSectionDefinition;
|
|
21
23
|
var _CalloutSectionDefinition = require("./CalloutSectionDefinition");
|
|
@@ -43,6 +45,10 @@ var _registry = require("../../registry");
|
|
|
43
45
|
* Registration order determines evaluation priority — first match wins.
|
|
44
46
|
*/
|
|
45
47
|
function createSdkRegistry() {
|
|
46
|
-
return new _registry.ComponentRegistry(null).register(new _SkipNodesSectionDefinition.SkipNodesSectionDefinition()).register(new _SearchSectionDefinition.SearchSectionDefinition()).register(new _KpiSectionDefinition.KpiSectionDefinition()).register(new _NextStepsSectionDefinition.NextStepsSectionDefinition())
|
|
48
|
+
return new _registry.ComponentRegistry(null).register(new _SkipNodesSectionDefinition.SkipNodesSectionDefinition()).register(new _SearchSectionDefinition.SearchSectionDefinition()).register(new _KpiSectionDefinition.KpiSectionDefinition()).register(new _NextStepsSectionDefinition.NextStepsSectionDefinition())
|
|
49
|
+
// Collection entities are claimed by their own definition first — it is a
|
|
50
|
+
// strictly narrower match than EntitySectionDefinition, which would
|
|
51
|
+
// otherwise swallow collection, product and article blocks alike.
|
|
52
|
+
.register(new _EntityCollectionSectionDefinition.EntityCollectionSectionDefinition()).register(new _EntitySectionDefinition.EntitySectionDefinition()).register(new _HeroEntitySectionDefinition.HeroEntitySectionDefinition()).register(new _HeroSectionDefinition.HeroSectionDefinition()).register(new _FeatureCardsSectionDefinition.FeatureCardsSectionDefinition()).register(new _TextBlockSectionDefinition.TextBlockSectionDefinition()).register(new _listItemsSectionDefinition.ListItemsSectionDefinition()).register(new _FeatureSection9PlusDefinition.FeatureSection9PlusDefinition()).register(new _ComparisonSectionDefinition.ComparisonSectionDefinition()).register(new _HtmlCommentSectionDefinition.HtmlCommentSectionDefinition()).register(new _CtaBannerSectionDefinition.CtaBannerSectionDefinition()).register(new _CalloutSectionDefinition.CalloutSectionDefinition()).register(new _FallbackSectionDefinition.FallbackSectionDefinition()).register(new _ErrorSectionDefinition.ErrorSectionDefinition());
|
|
47
53
|
}
|
|
48
54
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_ComparisonSectionDefinition","require","exports","ComparisonSectionDefinition","_TextBlockSectionDefinition","TextBlockSectionDefinition","_HeroSectionDefinition","HeroSectionDefinition","_HeroEntitySectionDefinition","HeroEntitySectionDefinition","_KpiSectionDefinition","KpiSectionDefinition","_FeatureCardsSectionDefinition","FeatureCardsSectionDefinition","_EntitySectionDefinition","EntitySectionDefinition","_CtaBannerSectionDefinition","CtaBannerSectionDefinition","_CalloutSectionDefinition","CalloutSectionDefinition","_NextStepsSectionDefinition","NextStepsSectionDefinition","_FeatureSection9PlusDefinition","FeatureSection9PlusDefinition","_listItemsSectionDefinition","ListItemsSectionDefinition","_SkipNodesSectionDefinition","SkipNodesSectionDefinition","_HtmlCommentSectionDefinition","HtmlCommentSectionDefinition","_SearchSectionDefinition","SearchSectionDefinition","_ErrorSectionDefinition","ErrorSectionDefinition","_FallbackSectionDefinition","FallbackSectionDefinition","_registry","createSdkRegistry","ComponentRegistry","register"],"sources":["../../../../src/component/componentDefinitions/index.ts"],"sourcesContent":["export type { SectionDefinition } from '../section-definition';\nexport { ComparisonSectionDefinition } from './ComparisonSectionDefinition';\nexport { TextBlockSectionDefinition } from './TextBlockSectionDefinition';\nexport { HeroSectionDefinition } from './HeroSectionDefinition';\nexport { HeroEntitySectionDefinition } from './HeroEntitySectionDefinition';\nexport { KpiSectionDefinition } from './KpiSectionDefinition';\nexport { FeatureCardsSectionDefinition } from './FeatureCardsSectionDefinition';\nexport { EntitySectionDefinition } from './EntitySectionDefinition';\nexport { CtaBannerSectionDefinition } from './CtaBannerSectionDefinition';\nexport { CalloutSectionDefinition } from './CalloutSectionDefinition';\nexport { NextStepsSectionDefinition } from './NextStepsSectionDefinition';\nexport { FeatureSection9PlusDefinition } from './FeatureSection9PlusDefinition';\nexport { ListItemsSectionDefinition } from './listItemsSectionDefinition';\nexport { SkipNodesSectionDefinition } from './SkipNodesSectionDefinition';\nexport { HtmlCommentSectionDefinition } from './HtmlCommentSectionDefinition';\nexport { SearchSectionDefinition } from './SearchSectionDefinition';\nexport { ErrorSectionDefinition } from './ErrorSectionDefinition';\nexport { FallbackSectionDefinition } from './FallbackSectionDefinition';\n\nimport { ComponentRegistry } from '../../registry';\nimport { SkipNodesSectionDefinition } from './SkipNodesSectionDefinition';\nimport { SearchSectionDefinition } from './SearchSectionDefinition';\nimport { KpiSectionDefinition } from './KpiSectionDefinition';\nimport { NextStepsSectionDefinition } from './NextStepsSectionDefinition';\nimport { EntitySectionDefinition } from './EntitySectionDefinition';\nimport { HeroEntitySectionDefinition } from './HeroEntitySectionDefinition';\nimport { HeroSectionDefinition } from './HeroSectionDefinition';\nimport { FeatureCardsSectionDefinition } from './FeatureCardsSectionDefinition';\nimport { FeatureSection9PlusDefinition } from './FeatureSection9PlusDefinition';\nimport { ListItemsSectionDefinition } from './listItemsSectionDefinition';\nimport { ComparisonSectionDefinition } from './ComparisonSectionDefinition';\nimport { HtmlCommentSectionDefinition } from './HtmlCommentSectionDefinition';\nimport { CtaBannerSectionDefinition } from './CtaBannerSectionDefinition';\nimport { CalloutSectionDefinition } from './CalloutSectionDefinition';\nimport { FallbackSectionDefinition } from './FallbackSectionDefinition';\nimport { ErrorSectionDefinition } from './ErrorSectionDefinition';\nimport { TextBlockSectionDefinition } from './TextBlockSectionDefinition';\n\n/**\n * Creates an SDK registry with all section definitions registered in the\n * same priority order as the app registry (createAppRegistry.ts).\n * Registration order determines evaluation priority — first match wins.\n */\nexport function createSdkRegistry(): ComponentRegistry<null> {\n return new ComponentRegistry<null>(null)\n
|
|
1
|
+
{"version":3,"names":["_ComparisonSectionDefinition","require","exports","ComparisonSectionDefinition","_TextBlockSectionDefinition","TextBlockSectionDefinition","_HeroSectionDefinition","HeroSectionDefinition","_HeroEntitySectionDefinition","HeroEntitySectionDefinition","_KpiSectionDefinition","KpiSectionDefinition","_FeatureCardsSectionDefinition","FeatureCardsSectionDefinition","_EntitySectionDefinition","EntitySectionDefinition","_EntityCollectionSectionDefinition","EntityCollectionSectionDefinition","_CtaBannerSectionDefinition","CtaBannerSectionDefinition","_CalloutSectionDefinition","CalloutSectionDefinition","_NextStepsSectionDefinition","NextStepsSectionDefinition","_FeatureSection9PlusDefinition","FeatureSection9PlusDefinition","_listItemsSectionDefinition","ListItemsSectionDefinition","_SkipNodesSectionDefinition","SkipNodesSectionDefinition","_HtmlCommentSectionDefinition","HtmlCommentSectionDefinition","_SearchSectionDefinition","SearchSectionDefinition","_ErrorSectionDefinition","ErrorSectionDefinition","_FallbackSectionDefinition","FallbackSectionDefinition","_registry","createSdkRegistry","ComponentRegistry","register"],"sources":["../../../../src/component/componentDefinitions/index.ts"],"sourcesContent":["export type { SectionDefinition } from '../section-definition';\nexport { ComparisonSectionDefinition } from './ComparisonSectionDefinition';\nexport { TextBlockSectionDefinition } from './TextBlockSectionDefinition';\nexport { HeroSectionDefinition } from './HeroSectionDefinition';\nexport { HeroEntitySectionDefinition } from './HeroEntitySectionDefinition';\nexport { KpiSectionDefinition } from './KpiSectionDefinition';\nexport { FeatureCardsSectionDefinition } from './FeatureCardsSectionDefinition';\nexport { EntitySectionDefinition } from './EntitySectionDefinition';\nexport { EntityCollectionSectionDefinition } from './EntityCollectionSectionDefinition';\nexport { CtaBannerSectionDefinition } from './CtaBannerSectionDefinition';\nexport { CalloutSectionDefinition } from './CalloutSectionDefinition';\nexport { NextStepsSectionDefinition } from './NextStepsSectionDefinition';\nexport { FeatureSection9PlusDefinition } from './FeatureSection9PlusDefinition';\nexport { ListItemsSectionDefinition } from './listItemsSectionDefinition';\nexport { SkipNodesSectionDefinition } from './SkipNodesSectionDefinition';\nexport { HtmlCommentSectionDefinition } from './HtmlCommentSectionDefinition';\nexport { SearchSectionDefinition } from './SearchSectionDefinition';\nexport { ErrorSectionDefinition } from './ErrorSectionDefinition';\nexport { FallbackSectionDefinition } from './FallbackSectionDefinition';\n\nimport { ComponentRegistry } from '../../registry';\nimport { SkipNodesSectionDefinition } from './SkipNodesSectionDefinition';\nimport { SearchSectionDefinition } from './SearchSectionDefinition';\nimport { KpiSectionDefinition } from './KpiSectionDefinition';\nimport { NextStepsSectionDefinition } from './NextStepsSectionDefinition';\nimport { EntitySectionDefinition } from './EntitySectionDefinition';\nimport { EntityCollectionSectionDefinition } from './EntityCollectionSectionDefinition';\nimport { HeroEntitySectionDefinition } from './HeroEntitySectionDefinition';\nimport { HeroSectionDefinition } from './HeroSectionDefinition';\nimport { FeatureCardsSectionDefinition } from './FeatureCardsSectionDefinition';\nimport { FeatureSection9PlusDefinition } from './FeatureSection9PlusDefinition';\nimport { ListItemsSectionDefinition } from './listItemsSectionDefinition';\nimport { ComparisonSectionDefinition } from './ComparisonSectionDefinition';\nimport { HtmlCommentSectionDefinition } from './HtmlCommentSectionDefinition';\nimport { CtaBannerSectionDefinition } from './CtaBannerSectionDefinition';\nimport { CalloutSectionDefinition } from './CalloutSectionDefinition';\nimport { FallbackSectionDefinition } from './FallbackSectionDefinition';\nimport { ErrorSectionDefinition } from './ErrorSectionDefinition';\nimport { TextBlockSectionDefinition } from './TextBlockSectionDefinition';\n\n/**\n * Creates an SDK registry with all section definitions registered in the\n * same priority order as the app registry (createAppRegistry.ts).\n * Registration order determines evaluation priority — first match wins.\n */\nexport function createSdkRegistry(): ComponentRegistry<null> {\n return (\n new ComponentRegistry<null>(null)\n .register(new SkipNodesSectionDefinition())\n .register(new SearchSectionDefinition())\n .register(new KpiSectionDefinition())\n .register(new NextStepsSectionDefinition())\n // Collection entities are claimed by their own definition first — it is a\n // strictly narrower match than EntitySectionDefinition, which would\n // otherwise swallow collection, product and article blocks alike.\n .register(new EntityCollectionSectionDefinition())\n .register(new EntitySectionDefinition())\n .register(new HeroEntitySectionDefinition())\n .register(new HeroSectionDefinition())\n .register(new FeatureCardsSectionDefinition())\n .register(new TextBlockSectionDefinition())\n .register(new ListItemsSectionDefinition())\n .register(new FeatureSection9PlusDefinition())\n .register(new ComparisonSectionDefinition())\n .register(new HtmlCommentSectionDefinition())\n .register(new CtaBannerSectionDefinition())\n .register(new CalloutSectionDefinition())\n .register(new FallbackSectionDefinition())\n .register(new ErrorSectionDefinition())\n );\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -12,6 +12,7 @@ var _linkTypes = require("../types/link-types");
|
|
|
12
12
|
var _web5LinkValidator = require("../utils/web5LinkValidator");
|
|
13
13
|
var _diagnosticTypes = require("./diagnosticTypes");
|
|
14
14
|
var _componentTracking = require("../utils/componentTracking");
|
|
15
|
+
var _matchDebug = require("../utils/matchDebug");
|
|
15
16
|
var _diagnosticsCollector = require("../utils/diagnosticsCollector");
|
|
16
17
|
var _unifiedMarkdownParser = require("../utils/unifiedMarkdownParser");
|
|
17
18
|
var _markdownPreprocessor = require("../utils/markdownPreprocessor");
|
|
@@ -37,8 +38,17 @@ var _propsExtractor = require("../utils/propsExtractor");
|
|
|
37
38
|
function isEntityCompProps(props) {
|
|
38
39
|
return typeof props === 'object' && props !== null && Array.isArray(props.items);
|
|
39
40
|
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Section types whose props are `EntityCompProps` and therefore participate in
|
|
44
|
+
* payload enrichment. `entityCollection` is `entity` narrowed to collection
|
|
45
|
+
* links — it produces the same props and arrives under the same
|
|
46
|
+
* `semantic: items` descriptor, so leaving it out would silently strip its
|
|
47
|
+
* items of their catalog data (image, title) and render the section blank.
|
|
48
|
+
*/
|
|
49
|
+
const ENRICHABLE_ENTITY_SECTION_TYPES = new Set(['entity', 'entityCollection']);
|
|
40
50
|
function isItemsFromContentSection(sectionType, semantic, serverSectionId) {
|
|
41
|
-
if (sectionType
|
|
51
|
+
if (!ENRICHABLE_ENTITY_SECTION_TYPES.has(sectionType)) {
|
|
42
52
|
return false;
|
|
43
53
|
}
|
|
44
54
|
const normalizedSemantic = semantic == null ? void 0 : semantic.toLowerCase().replace(/_/g, '-');
|
|
@@ -268,6 +278,15 @@ function tryParseComponent(nodes, sectionIndex, context) {
|
|
|
268
278
|
setMeta: context.tracking ? (sectionType, key, value) => context.tracking.setMeta(sectionType, key, value) : undefined,
|
|
269
279
|
getMeta: context.tracking ? (sectionType, key) => context.tracking.getMeta(sectionType, key) : undefined
|
|
270
280
|
};
|
|
281
|
+
|
|
282
|
+
// Debug-only trace (`?web5DebugMatch=1`). The registry order line doubles as
|
|
283
|
+
// a "is my definition even registered?" check — a definition missing from it
|
|
284
|
+
// never reached `register()` (stale client bundle / web5-core version skew).
|
|
285
|
+
const trace = (0, _matchDebug.isMatchDebugEnabled)();
|
|
286
|
+
if (trace) {
|
|
287
|
+
(0, _matchDebug.logMatchDebug)(`block #${sectionIndex} [${nodes.map(n => n.type).join(', ')}]`);
|
|
288
|
+
(0, _matchDebug.logMatchDebug)(` registry order: ${definitions.map(d => d.sectionType).join(' > ')}`);
|
|
289
|
+
}
|
|
271
290
|
for (const {
|
|
272
291
|
sectionType,
|
|
273
292
|
definition
|
|
@@ -277,12 +296,18 @@ function tryParseComponent(nodes, sectionIndex, context) {
|
|
|
277
296
|
// render (the main app) — their markdown should fall through to the generic
|
|
278
297
|
// sections there. Skip them unless this is a placement parse.
|
|
279
298
|
if (!placement && registry.isPlacementOnly(sectionType)) {
|
|
299
|
+
if (trace) {
|
|
300
|
+
(0, _matchDebug.logMatchDebug)(` ${sectionType}: skipped (placement-only)`);
|
|
301
|
+
}
|
|
280
302
|
continue;
|
|
281
303
|
}
|
|
282
304
|
for (const pattern of definition.patterns) {
|
|
283
305
|
var _parts$find, _context$intent;
|
|
284
306
|
const result = (0, _patternValidator.validatePattern)(nodes, pattern);
|
|
285
307
|
if (!result.valid) {
|
|
308
|
+
if (trace) {
|
|
309
|
+
(0, _matchDebug.logMatchDebug)(` ${sectionType}: no match — ${result.error ?? 'pattern did not match'}\n pattern: ${pattern}`);
|
|
310
|
+
}
|
|
286
311
|
continue;
|
|
287
312
|
}
|
|
288
313
|
let parsedNodes = result.astEndIndex !== undefined && result.astEndIndex >= 0 ? result.astEndIndex + 1 : result.endIndex >= 0 ? result.endIndex + 1 : 1;
|
|
@@ -305,8 +330,14 @@ function tryParseComponent(nodes, sectionIndex, context) {
|
|
|
305
330
|
};
|
|
306
331
|
let props = definition.parse(parts, parseContext);
|
|
307
332
|
if (props === null) {
|
|
333
|
+
if (trace) {
|
|
334
|
+
(0, _matchDebug.logMatchDebug)(` ${sectionType}: pattern matched ${parsedNodes} node(s) but parse() returned null — falling through`);
|
|
335
|
+
}
|
|
308
336
|
continue;
|
|
309
337
|
}
|
|
338
|
+
if (trace) {
|
|
339
|
+
(0, _matchDebug.logMatchDebug)(` ${sectionType}: MATCHED ${parsedNodes} node(s) via ${pattern}`);
|
|
340
|
+
}
|
|
310
341
|
const leadingHtmlCommentMeta = (_parts$find = parts.find(p => p.type === 'htmlComment' && p.meta)) == null ? void 0 : _parts$find.meta;
|
|
311
342
|
const semantic = leadingHtmlCommentMeta == null ? void 0 : leadingHtmlCommentMeta.semantic;
|
|
312
343
|
const serverSectionId = leadingHtmlCommentMeta == null ? void 0 : leadingHtmlCommentMeta.id;
|
|
@@ -320,6 +351,9 @@ function tryParseComponent(nodes, sectionIndex, context) {
|
|
|
320
351
|
});
|
|
321
352
|
}
|
|
322
353
|
if (definition.singleInstance && context.tracking && context.tracking.getComponentCount(sectionType) > 0) {
|
|
354
|
+
if (trace) {
|
|
355
|
+
(0, _matchDebug.logMatchDebug)(` ${sectionType}: dropped (singleInstance, already rendered once)`);
|
|
356
|
+
}
|
|
323
357
|
continue;
|
|
324
358
|
}
|
|
325
359
|
const isNullComponent = definition.nullComponent === true;
|
|
@@ -367,6 +401,9 @@ function tryParseComponent(nodes, sectionIndex, context) {
|
|
|
367
401
|
};
|
|
368
402
|
}
|
|
369
403
|
}
|
|
404
|
+
if (trace) {
|
|
405
|
+
(0, _matchDebug.logMatchDebug)(' no definition claimed this block');
|
|
406
|
+
}
|
|
370
407
|
return {};
|
|
371
408
|
}
|
|
372
409
|
//# sourceMappingURL=componentParser.js.map
|