@certrev/cert-block 0.5.5 → 1.0.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.
Files changed (190) hide show
  1. package/CHANGELOG.md +164 -26
  2. package/LICENSE +21 -0
  3. package/README.md +415 -54
  4. package/dist/builder/cert-chrome-data.d.ts +26 -8
  5. package/dist/builder/cert-chrome-data.d.ts.map +1 -1
  6. package/dist/builder/cert-chrome-data.js +5 -5
  7. package/dist/builder/cert-chrome-data.js.map +1 -1
  8. package/dist/builder/cert-review-card.d.ts +35 -5
  9. package/dist/builder/cert-review-card.d.ts.map +1 -1
  10. package/dist/builder/cert-review-card.js +115 -34
  11. package/dist/builder/cert-review-card.js.map +1 -1
  12. package/dist/builder/index.d.ts +33 -16
  13. package/dist/builder/index.d.ts.map +1 -1
  14. package/dist/builder/index.js +33 -16
  15. package/dist/builder/index.js.map +1 -1
  16. package/dist/components/CertBadge.d.ts +2 -2
  17. package/dist/components/CertBadge.d.ts.map +1 -1
  18. package/dist/components/CertBadge.js +11 -5
  19. package/dist/components/CertBadge.js.map +1 -1
  20. package/dist/components/CertJsonLd.d.ts.map +1 -1
  21. package/dist/components/CertJsonLd.js.map +1 -1
  22. package/dist/components/CertRevBacklink.d.ts.map +1 -1
  23. package/dist/components/CertRevBacklink.js +3 -2
  24. package/dist/components/CertRevBacklink.js.map +1 -1
  25. package/dist/components/CertReview.d.ts +1 -1
  26. package/dist/components/ExpertBio.d.ts.map +1 -1
  27. package/dist/components/ExpertBio.js +12 -4
  28. package/dist/components/ExpertBio.js.map +1 -1
  29. package/dist/components/escape.d.ts +28 -1
  30. package/dist/components/escape.d.ts.map +1 -1
  31. package/dist/components/escape.js +37 -8
  32. package/dist/components/escape.js.map +1 -1
  33. package/dist/components/format.d.ts +51 -2
  34. package/dist/components/format.d.ts.map +1 -1
  35. package/dist/components/format.js +103 -6
  36. package/dist/components/format.js.map +1 -1
  37. package/dist/components/preview-block.d.ts +1 -1
  38. package/dist/components/preview-block.js +3 -3
  39. package/dist/components/preview-block.js.map +1 -1
  40. package/dist/components/rel.d.ts +24 -0
  41. package/dist/components/rel.d.ts.map +1 -0
  42. package/dist/components/rel.js +24 -0
  43. package/dist/components/rel.js.map +1 -0
  44. package/dist/components/render-cert-block.d.ts +50 -22
  45. package/dist/components/render-cert-block.d.ts.map +1 -1
  46. package/dist/components/render-cert-block.js +146 -80
  47. package/dist/components/render-cert-block.js.map +1 -1
  48. package/dist/components/render-def.d.ts +13 -14
  49. package/dist/components/render-def.d.ts.map +1 -1
  50. package/dist/components/render-def.js +14 -15
  51. package/dist/components/render-def.js.map +1 -1
  52. package/dist/index.d.ts +1 -0
  53. package/dist/index.d.ts.map +1 -1
  54. package/dist/index.js +4 -2
  55. package/dist/index.js.map +1 -1
  56. package/dist/jsonld/project.d.ts +46 -13
  57. package/dist/jsonld/project.d.ts.map +1 -1
  58. package/dist/jsonld/project.js +139 -56
  59. package/dist/jsonld/project.js.map +1 -1
  60. package/dist/modal/avatar-resize.d.ts +10 -10
  61. package/dist/modal/avatar-resize.js +14 -14
  62. package/dist/modal/avatar-resize.js.map +1 -1
  63. package/dist/modal/cert-modal-view.d.ts +27 -7
  64. package/dist/modal/cert-modal-view.d.ts.map +1 -1
  65. package/dist/modal/cert-modal-view.js +49 -25
  66. package/dist/modal/cert-modal-view.js.map +1 -1
  67. package/dist/modal/certrev-cert-modal.d.ts +5 -5
  68. package/dist/modal/certrev-cert-modal.js +9 -9
  69. package/dist/modal/certrev-cert-modal.js.map +1 -1
  70. package/dist/modal/certrev-cert-modal.styles.d.ts +6 -6
  71. package/dist/modal/certrev-cert-modal.styles.d.ts.map +1 -1
  72. package/dist/modal/certrev-cert-modal.styles.js +8 -8
  73. package/dist/modal/certrev-cert-modal.styles.js.map +1 -1
  74. package/dist/modal/certrev-cert.entry.d.ts +8 -6
  75. package/dist/modal/certrev-cert.entry.d.ts.map +1 -1
  76. package/dist/modal/certrev-cert.entry.js +9 -7
  77. package/dist/modal/certrev-cert.entry.js.map +1 -1
  78. package/dist/modal/certrev-cert.js +6 -6
  79. package/dist/modal/display-strings.d.ts +25 -5
  80. package/dist/modal/display-strings.d.ts.map +1 -1
  81. package/dist/modal/display-strings.js +27 -5
  82. package/dist/modal/display-strings.js.map +1 -1
  83. package/dist/modal/escape.d.ts +26 -3
  84. package/dist/modal/escape.d.ts.map +1 -1
  85. package/dist/modal/escape.js +32 -3
  86. package/dist/modal/escape.js.map +1 -1
  87. package/dist/modal/font-face.d.ts.map +1 -1
  88. package/dist/modal/font-face.js +8 -11
  89. package/dist/modal/font-face.js.map +1 -1
  90. package/dist/modal/ftc-disclosure.d.ts +2 -2
  91. package/dist/modal/ftc-disclosure.js +2 -2
  92. package/dist/modal/ftc-guard.d.ts +44 -9
  93. package/dist/modal/ftc-guard.d.ts.map +1 -1
  94. package/dist/modal/ftc-guard.js +50 -17
  95. package/dist/modal/ftc-guard.js.map +1 -1
  96. package/dist/modal/index.d.ts +1 -1
  97. package/dist/modal/index.js +1 -1
  98. package/dist/modal/interactions.d.ts +2 -2
  99. package/dist/modal/interactions.js +2 -2
  100. package/dist/modal/logo-paths.js +2 -2
  101. package/dist/modal/logo-paths.js.map +1 -1
  102. package/dist/modal/placement.d.ts +4 -3
  103. package/dist/modal/placement.d.ts.map +1 -1
  104. package/dist/modal/placement.js +7 -6
  105. package/dist/modal/placement.js.map +1 -1
  106. package/dist/modal/revalidate.d.ts +2 -3
  107. package/dist/modal/revalidate.d.ts.map +1 -1
  108. package/dist/modal/revalidate.js +2 -3
  109. package/dist/modal/revalidate.js.map +1 -1
  110. package/dist/modal/verify-client.d.ts +2 -2
  111. package/dist/modal/verify-client.js +2 -2
  112. package/dist/verify/cache.d.ts +21 -6
  113. package/dist/verify/cache.d.ts.map +1 -1
  114. package/dist/verify/cache.js +29 -8
  115. package/dist/verify/cache.js.map +1 -1
  116. package/dist/verify/fetch-with-deadline.d.ts +35 -0
  117. package/dist/verify/fetch-with-deadline.d.ts.map +1 -0
  118. package/dist/verify/fetch-with-deadline.js +55 -0
  119. package/dist/verify/fetch-with-deadline.js.map +1 -0
  120. package/dist/verify/get-verified-envelope.d.ts +23 -9
  121. package/dist/verify/get-verified-envelope.d.ts.map +1 -1
  122. package/dist/verify/get-verified-envelope.js +89 -40
  123. package/dist/verify/get-verified-envelope.js.map +1 -1
  124. package/dist/verify/resolve-kid.d.ts +3 -0
  125. package/dist/verify/resolve-kid.d.ts.map +1 -1
  126. package/dist/verify/resolve-kid.js +17 -8
  127. package/dist/verify/resolve-kid.js.map +1 -1
  128. package/dist/webcomponent/certrev-badge.d.ts.map +1 -1
  129. package/dist/webcomponent/certrev-badge.js +24 -2
  130. package/dist/webcomponent/certrev-badge.js.map +1 -1
  131. package/dist/webcomponent/render-badge-html.d.ts +1 -1
  132. package/dist/webcomponent/render-badge-html.d.ts.map +1 -1
  133. package/dist/webcomponent/render-badge-html.js +36 -17
  134. package/dist/webcomponent/render-badge-html.js.map +1 -1
  135. package/package.json +5 -2
  136. package/src/builder/cert-chrome-data.ts +26 -8
  137. package/src/builder/cert-review-card.tsx +147 -38
  138. package/src/builder/index.tsx +34 -17
  139. package/src/components/CertBadge.tsx +14 -9
  140. package/src/components/CertJsonLd.tsx +1 -1
  141. package/src/components/CertRevBacklink.tsx +10 -3
  142. package/src/components/CertReview.tsx +1 -1
  143. package/src/components/ExpertBio.tsx +12 -7
  144. package/src/components/escape.ts +37 -7
  145. package/src/components/format.ts +102 -6
  146. package/src/components/preview-block.ts +3 -3
  147. package/src/components/rel.ts +23 -0
  148. package/src/components/render-cert-block.ts +192 -109
  149. package/src/components/render-def.ts +14 -15
  150. package/src/index.ts +4 -2
  151. package/src/jsonld/project.ts +155 -59
  152. package/src/modal/avatar-resize.ts +14 -14
  153. package/src/modal/cert-modal-view.ts +52 -27
  154. package/src/modal/certrev-cert-modal.styles.ts +8 -8
  155. package/src/modal/certrev-cert-modal.ts +9 -9
  156. package/src/modal/certrev-cert.entry.ts +9 -7
  157. package/src/modal/display-strings.ts +26 -5
  158. package/src/modal/escape.ts +32 -4
  159. package/src/modal/font-face.ts +8 -11
  160. package/src/modal/ftc-disclosure.ts +2 -2
  161. package/src/modal/ftc-guard.ts +73 -18
  162. package/src/modal/index.ts +1 -1
  163. package/src/modal/interactions.ts +2 -2
  164. package/src/modal/logo-paths.ts +2 -2
  165. package/src/modal/placement.ts +7 -6
  166. package/src/modal/revalidate.ts +2 -3
  167. package/src/modal/verify-client.ts +2 -2
  168. package/src/verify/cache.ts +34 -8
  169. package/src/verify/fetch-with-deadline.ts +60 -0
  170. package/src/verify/get-verified-envelope.ts +131 -48
  171. package/src/verify/resolve-kid.ts +22 -6
  172. package/src/webcomponent/certrev-badge.ts +24 -2
  173. package/src/webcomponent/render-badge-html.ts +66 -19
  174. package/src/__tests__/__snapshots__/render-cert-block.test.ts.snap +0 -17
  175. package/src/__tests__/components.test.tsx +0 -206
  176. package/src/__tests__/preview-block.test.ts +0 -84
  177. package/src/__tests__/project.test.ts +0 -128
  178. package/src/__tests__/readme-version.test.ts +0 -51
  179. package/src/__tests__/render-cert-block.test.ts +0 -657
  180. package/src/__tests__/render-def.test.tsx +0 -295
  181. package/src/__tests__/verify.test.ts +0 -239
  182. package/src/__tests__/webcomponent.test.tsx +0 -116
  183. package/src/builder/__tests__/builder.test.tsx +0 -158
  184. package/src/modal/cert-modal-view.test.ts +0 -175
  185. package/src/modal/certrev-cert-modal.test.ts +0 -125
  186. package/src/modal/ftc-guard.test.ts +0 -153
  187. package/src/modal/interactions.test.ts +0 -250
  188. package/src/modal/placement.test.ts +0 -398
  189. package/src/modal/revalidate.test.ts +0 -111
  190. package/src/modal/verify-client.test.ts +0 -164
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * `renderPreviewBlock` — a STATIC, NON-DELIVERY preview of the cert block for pre-sales
3
- * look-demos (POR-10743, from the Builder demo).
3
+ * look-demos (lifted from the Builder demo).
4
4
  *
5
5
  * The visual is BYTE-FOR-BYTE `renderCertBlock` (pixel-parity — "see it on your own site
6
6
  * today"), wrapped in a `[data-certrev-preview]` container carrying a REQUIRED expiry.
@@ -19,7 +19,7 @@
19
19
  */
20
20
  import { escapeAttribute, escapeHtml } from './escape.js';
21
21
  import { renderCertBlock } from './render-cert-block.js';
22
- const DEFAULT_LABEL = 'Preview — not a verified certification';
22
+ const DEFAULT_LABEL = 'Preview · Not a verified certification';
23
23
  /** Extract a preview block's baked expiry (ISO), or null if the HTML isn't a preview block. */
24
24
  export function previewExpiry(html) {
25
25
  const m = html.match(/data-certrev-preview-expires="([^"]*)"/);
@@ -44,7 +44,7 @@ export function renderPreviewBlock(input, options) {
44
44
  const label = showLabel
45
45
  ? `<div data-certrev-preview-label style="font:500 11px/1.4 ui-monospace,SFMono-Regular,Menlo,monospace;letter-spacing:.08em;text-transform:uppercase;color:#9a9a9a;margin-bottom:8px;">${escapeHtml(options.labelText ?? DEFAULT_LABEL)}</div>`
46
46
  : '';
47
- return (`<!-- CertREV PREVIEW — static, non-revocable, NOT a verified certification. Expires ${escapeHtml(expires)}. Never use as delivery. -->` +
47
+ return (`<!-- CertREV PREVIEW: static, non-revocable, NOT a verified certification. Expires ${escapeHtml(expires)}. Never use as delivery. -->` +
48
48
  `<div data-certrev-preview="1" data-certrev-preview-expires="${escapeAttribute(expires)}">` +
49
49
  label +
50
50
  renderCertBlock(input) +
@@ -1 +1 @@
1
- {"version":3,"file":"preview-block.js","sourceRoot":"","sources":["../../src/components/preview-block.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACzD,OAAO,EAA6B,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAkBnF,MAAM,aAAa,GAAG,wCAAwC,CAAA;AAE9D,+FAA+F;AAC/F,MAAM,UAAU,aAAa,CAAC,IAAY;IACzC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAA;IAC9D,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;AACvB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAA2B,EAAE,OAA4B;IAC3F,MAAM,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE,CAAA;IACxC,IAAI,CAAC,OAAO,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,+EAA+E,CAAC,CAAA;IACjG,CAAC;IACD,iGAAiG;IACjG,iGAAiG;IACjG,iCAAiC;IACjC,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;QAC/C,MAAM,IAAI,KAAK,CAAC,oEAAoE,OAAO,KAAK,CAAC,CAAA;IAClG,CAAC;IACD,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,KAAK,KAAK,CAAA;IAC7C,MAAM,KAAK,GAAG,SAAS;QACtB,CAAC,CAAC,wLAAwL,UAAU,CAAC,OAAO,CAAC,SAAS,IAAI,aAAa,CAAC,QAAQ;QAChP,CAAC,CAAC,EAAE,CAAA;IACL,OAAO,CACN,uFAAuF,UAAU,CAAC,OAAO,CAAC,8BAA8B;QACxI,+DAA+D,eAAe,CAAC,OAAO,CAAC,IAAI;QAC3F,KAAK;QACL,eAAe,CAAC,KAAK,CAAC;QACtB,QAAQ,CACR,CAAA;AACF,CAAC"}
1
+ {"version":3,"file":"preview-block.js","sourceRoot":"","sources":["../../src/components/preview-block.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACzD,OAAO,EAA6B,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAkBnF,MAAM,aAAa,GAAG,wCAAwC,CAAA;AAE9D,+FAA+F;AAC/F,MAAM,UAAU,aAAa,CAAC,IAAY;IACzC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAA;IAC9D,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;AACvB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAA2B,EAAE,OAA4B;IAC3F,MAAM,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC,IAAI,EAAE,CAAA;IACxC,IAAI,CAAC,OAAO,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,+EAA+E,CAAC,CAAA;IACjG,CAAC;IACD,iGAAiG;IACjG,iGAAiG;IACjG,iCAAiC;IACjC,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;QAC/C,MAAM,IAAI,KAAK,CAAC,oEAAoE,OAAO,KAAK,CAAC,CAAA;IAClG,CAAC;IACD,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,KAAK,KAAK,CAAA;IAC7C,MAAM,KAAK,GAAG,SAAS;QACtB,CAAC,CAAC,wLAAwL,UAAU,CAAC,OAAO,CAAC,SAAS,IAAI,aAAa,CAAC,QAAQ;QAChP,CAAC,CAAC,EAAE,CAAA;IACL,OAAO,CACN,sFAAsF,UAAU,CAAC,OAAO,CAAC,8BAA8B;QACvI,+DAA+D,eAAe,CAAC,OAAO,CAAC,IAAI;QAC3F,KAAK;QACL,eAAe,CAAC,KAAK,CAAC;QACtB,QAAQ,CACR,CAAA;AACF,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Link qualification for every anchor this package emits to a CertREV-owned host.
3
+ *
4
+ * The package renders links the consumer did not author and cannot edit: `CertBadgeProps`
5
+ * has no `rel` input, and the string renderers build their anchors internally. That makes
6
+ * qualification the PACKAGE's job — a consumer who wanted to qualify them has no seam to
7
+ * do it through.
8
+ *
9
+ * Google's link-spam policy treats a link a vendor requires on a customer's page as
10
+ * paid/placed unless it is qualified, and names the remedy explicitly: it is not a
11
+ * violation "as long as they are qualified with rel='nofollow' or rel='sponsored'".
12
+ * `sponsored` is the accurate token for a commercial placement; `nofollow` is carried
13
+ * alongside it because it is the token every downstream tool actually reads. `noopener`
14
+ * is unrelated to ranking and is kept for the window-handle hardening it always gave.
15
+ *
16
+ * There is NO override seam, deliberately: every anchor this package emits points at a
17
+ * CertREV-owned host (a profile URL or a verify URL, both carried on the signed payload —
18
+ * a brand cannot author either), so no consumer has a link of their own here to widen, and
19
+ * an opt-out would only be a way to un-qualify the placement the policy is about. The
20
+ * constant is exported so a consumer can READ the value and reason about it; the anchors
21
+ * themselves are not configurable.
22
+ */
23
+ export declare const CERTREV_LINK_REL = "nofollow sponsored noopener";
24
+ //# sourceMappingURL=rel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rel.d.ts","sourceRoot":"","sources":["../../src/components/rel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,gBAAgB,gCAAgC,CAAA"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Link qualification for every anchor this package emits to a CertREV-owned host.
3
+ *
4
+ * The package renders links the consumer did not author and cannot edit: `CertBadgeProps`
5
+ * has no `rel` input, and the string renderers build their anchors internally. That makes
6
+ * qualification the PACKAGE's job — a consumer who wanted to qualify them has no seam to
7
+ * do it through.
8
+ *
9
+ * Google's link-spam policy treats a link a vendor requires on a customer's page as
10
+ * paid/placed unless it is qualified, and names the remedy explicitly: it is not a
11
+ * violation "as long as they are qualified with rel='nofollow' or rel='sponsored'".
12
+ * `sponsored` is the accurate token for a commercial placement; `nofollow` is carried
13
+ * alongside it because it is the token every downstream tool actually reads. `noopener`
14
+ * is unrelated to ranking and is kept for the window-handle hardening it always gave.
15
+ *
16
+ * There is NO override seam, deliberately: every anchor this package emits points at a
17
+ * CertREV-owned host (a profile URL or a verify URL, both carried on the signed payload —
18
+ * a brand cannot author either), so no consumer has a link of their own here to widen, and
19
+ * an opt-out would only be a way to un-qualify the placement the policy is about. The
20
+ * constant is exported so a consumer can READ the value and reason about it; the anchors
21
+ * themselves are not configurable.
22
+ */
23
+ export const CERTREV_LINK_REL = 'nofollow sponsored noopener';
24
+ //# sourceMappingURL=rel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rel.js","sourceRoot":"","sources":["../../src/components/rel.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,6BAA6B,CAAA"}
@@ -4,10 +4,20 @@
4
4
  * ─────────────────────────────────────────────────────────────────────────────
5
5
  *
6
6
  * Paints the owner-approved cert render (decision 2026-07-17) in one of three
7
- * placement modes — `banner`, `sidebar`, `floating` — from RESOLVED theme tokens +
8
- * the cert facts. It returns a self-contained HTML string that renders with ZERO
9
- * JavaScript (the CertREV modal + the reviewer-bio accordion are progressive
10
- * enhancement, wired by the shared embed script via the `data-certrev-*` hooks).
7
+ * placement modes — `sidebar` (the DEFAULT), `banner`, `floating` — plus the engine's
8
+ * free-composition `custom` face, from RESOLVED theme tokens + the cert facts. It
9
+ * returns a self-contained HTML string that renders with ZERO JavaScript (the CertREV
10
+ * modal + the reviewer-bio accordion are progressive enhancement, wired by the shared
11
+ * embed script via the `data-certrev-*` hooks).
12
+ *
13
+ * THE DEFAULT PLACEMENT IS `sidebar`, AND IT IS NAMED IN EXACTLY ONE PLACE — the
14
+ * `case 'sidebar':` that falls into `default:` at the bottom of this file. Nothing
15
+ * else in the package (this renderer, the Builder card, the preview) may name a
16
+ * placement fallback of its own: the switch previously had no `default:` at all, so
17
+ * an untyped `mode` off CMS JSON returned `undefined` from a `: string` function and
18
+ * landed in `dangerouslySetInnerHTML` as an empty div — a 200 with the card silently
19
+ * gone. Declared default and runtime fallback are now physically the same line and
20
+ * cannot drift.
11
21
  *
12
22
  * WHY A STRING (not a React component): the block is emitted into storefront HTML
13
23
  * across every render surface (Shopify Liquid, WordPress PHP, the JS engine, and
@@ -70,10 +80,15 @@ export interface CertBlockFace {
70
80
  readonly placedFields: readonly string[];
71
81
  }
72
82
  /**
73
- * The cert facts + LOCKED display strings a face renders. Facts are escaped; the
74
- * three locked strings (`compensationCue`, `scopeLine`, `credentialLine`) are
75
- * byte-verbatim per the CertREV Display Guide and default to the mirrored constants
76
- * when a caller omits them — so the compliance baseline is exact even if unsupplied.
83
+ * The cert FACTS a face renders — the per-cert data, all of it escaped.
84
+ *
85
+ * The compliance copy is NOT here. The scope line and the credential attribution are
86
+ * rendered straight from `CERT_SCOPE_LINE` / `CREDENTIAL_VERIFIED_ATTRIBUTION`: they
87
+ * are locked strings per the CertREV Display Guide (the scope line's curly apostrophe
88
+ * is pinned to MSA §3 — see render-def.ts), so a caller has no legitimate reason to
89
+ * supply them and taking them as input made compliance copy rewritable from a CMS
90
+ * field. `compensationCue` survives as an input for exactly ONE decision — whether the
91
+ * reviewer was compensated at all — never for the wording.
77
92
  */
78
93
  export interface CertBlockFacts {
79
94
  /** The content author (the "Written by" column). */
@@ -88,24 +103,33 @@ export interface CertBlockFacts {
88
103
  readonly credentialVerifiedAt: string;
89
104
  /** ISO instant the article was certified (the "Certified <date>" footer). */
90
105
  readonly certifiedAt: string;
91
- /** The expert's memo (rendered as the serif blockquote). */
92
- readonly memo: string;
106
+ /**
107
+ * The expert's memo (the quote / blockquote). OPTIONAL, exactly like `bio`: a face may
108
+ * legally carry no memo, and an empty one must drop the heading + quote rather than paint
109
+ * an "Expert memo" label over an empty `<p>`.
110
+ */
111
+ readonly memo?: string;
93
112
  /** The expert's bio (banner accordion / sidebar paragraph). Omitted when absent. */
94
113
  readonly bio?: string;
95
114
  /** The expert profile URL (the "Profile" link + modal `expert` hook). */
96
115
  readonly profileUrl: string;
97
116
  /** The certificate URL (the "Certificate" link + modal hook). */
98
117
  readonly certificateUrl: string;
99
- /** LOCKED — the compensation cue. Default: `COMPENSATED_EXPERT_CUE`. */
100
- readonly compensationCue?: string;
101
- /** LOCKED — the byte-exact FTC scope line. Default: `CERT_SCOPE_LINE`. */
102
- readonly scopeLine?: string;
103
- /** LOCKED — the verification attribution. Default: `CREDENTIAL_VERIFIED_ATTRIBUTION`. */
104
- readonly credentialLine?: string;
118
+ /**
119
+ * WHETHER there is a material connection to disclose — never its WORDING.
120
+ *
121
+ * `null` ⇒ the cue is OMITTED entirely: the pro-bono reviewer, who has no compensation
122
+ * to disclose (the same contract `modal/cert-modal-view.ts` already honours). Any other
123
+ * value — absent, or a supplied string — renders the LOCKED `COMPENSATED_EXPERT_CUE`
124
+ * constant; a supplied string is IGNORED. The scope line still renders for a pro-bono
125
+ * reviewer: it makes no compensation claim, so it is true for volunteers too.
126
+ */
127
+ readonly compensationCue?: string | null;
105
128
  }
106
129
  /** The full input to `renderCertBlock`. */
107
130
  export interface RenderCertBlockInput {
108
- readonly mode: CertBlockLayout;
131
+ /** The placement face. ABSENT or UNRECOGNISED ⇒ `sidebar` (see the file header). */
132
+ readonly mode?: CertBlockLayout;
109
133
  /** RESOLVED theme tokens (the portal bakes these). Absent/invalid tokens fall back to navy. */
110
134
  readonly theme?: Partial<ResolvedBlockTheme>;
111
135
  readonly facts: CertBlockFacts;
@@ -115,8 +139,8 @@ export interface RenderCertBlockInput {
115
139
  */
116
140
  readonly face?: CertBlockFace;
117
141
  /**
118
- * BANNER memo placement (POR-10741 — first-class split, retires the CertReviewCard
119
- * string-hack). Default `'full'` = header card + memo card in ONE root, BYTE-IDENTICAL
142
+ * BANNER memo placement — the first-class split that retires the CertReviewCard
143
+ * string-hack. Default `'full'` = header card + memo card in ONE root, BYTE-IDENTICAL
120
144
  * to prior behavior. `'header'` / `'memo'` render ONLY that card in its own themed root,
121
145
  * so a headless exporter can place the memo as its OWN block under the article body
122
146
  * (the "banner → body → memo" layout) WITHOUT string-splitting the rendered HTML — and
@@ -126,9 +150,13 @@ export interface RenderCertBlockInput {
126
150
  readonly part?: 'full' | 'header' | 'memo';
127
151
  }
128
152
  /**
129
- * Render the LOCKED CertREV cert design as an SSR-safe HTML string for one of the
130
- * three placement modes. Returns a self-contained `<div class="certrev-cert …">`
131
- * that needs no JS to render (the modal + bio accordion progressively enhance).
153
+ * Render the LOCKED CertREV cert design as an SSR-safe HTML string for one placement
154
+ * face. Returns a self-contained `<div class="certrev-cert …">` that needs no JS to
155
+ * render (the modal + bio accordion progressively enhance).
156
+ *
157
+ * `mode` absent or unrecognised ⇒ `sidebar`. Each arm passes its own LITERAL to
158
+ * `root()` — never `input.mode` — so an untyped `mode` can reach neither the root class
159
+ * name nor the `data-certrev-mode` attribute.
132
160
  */
133
161
  export declare function renderCertBlock(input: RenderCertBlockInput): string;
134
162
  //# sourceMappingURL=render-cert-block.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"render-cert-block.d.ts","sourceRoot":"","sources":["../../src/components/render-cert-block.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AAIH,OAAO,EAMN,KAAK,kBAAkB,EAEvB,MAAM,iBAAiB,CAAA;AAExB,wCAAwC;AACxC,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,SAAS,GAAG,UAAU,CAAA;AAE7D,0GAA0G;AAC1G,MAAM,MAAM,eAAe,GAAG,aAAa,GAAG,QAAQ,CAAA;AAEtD;;;;;;GAMG;AACH,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAA;CACxC;AAED;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC9B,oDAAoD;IACpD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,qEAAqE;IACrE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,qFAAqF;IACrF,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,6EAA6E;IAC7E,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,iFAAiF;IACjF,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAA;IACrC,6EAA6E;IAC7E,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,4DAA4D;IAC5D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,oFAAoF;IACpF,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;IACrB,yEAAyE;IACzE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,iEAAiE;IACjE,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B,wEAAwE;IACxE,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAA;IACjC,0EAA0E;IAC1E,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B,yFAAyF;IACzF,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CAChC;AAED,2CAA2C;AAC3C,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAA;IAC9B,+FAA+F;IAC/F,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAA;IAC5C,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAA;IAC9B;;;OAGG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,aAAa,CAAA;IAC7B;;;;;;;;OAQG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAA;CAC1C;AAkhBD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,MAAM,CA+BnE"}
1
+ {"version":3,"file":"render-cert-block.d.ts","sourceRoot":"","sources":["../../src/components/render-cert-block.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgEG;AAKH,OAAO,EAMN,KAAK,kBAAkB,EAEvB,MAAM,iBAAiB,CAAA;AAExB,wCAAwC;AACxC,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,SAAS,GAAG,UAAU,CAAA;AAE7D,0GAA0G;AAC1G,MAAM,MAAM,eAAe,GAAG,aAAa,GAAG,QAAQ,CAAA;AAEtD;;;;;;GAMG;AACH,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAA;CACxC;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,cAAc;IAC9B,oDAAoD;IACpD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,qEAAqE;IACrE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,qFAAqF;IACrF,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,6EAA6E;IAC7E,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,iFAAiF;IACjF,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAA;IACrC,6EAA6E;IAC7E,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;IACtB,oFAAoF;IACpF,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;IACrB,yEAAyE;IACzE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,iEAAiE;IACjE,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B;;;;;;;;OAQG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACxC;AAED,2CAA2C;AAC3C,MAAM,WAAW,oBAAoB;IACpC,oFAAoF;IACpF,QAAQ,CAAC,IAAI,CAAC,EAAE,eAAe,CAAA;IAC/B,+FAA+F;IAC/F,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAA;IAC5C,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAA;IAC9B;;;OAGG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,aAAa,CAAA;IAC7B;;;;;;;;OAQG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAA;CAC1C;AAikBD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,MAAM,CAsCnE"}