@certrev/cert-block 0.5.4 → 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 (189) hide show
  1. package/CHANGELOG.md +195 -12
  2. package/LICENSE +21 -0
  3. package/README.md +422 -50
  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 +14 -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__/render-cert-block.test.ts +0 -657
  179. package/src/__tests__/render-def.test.tsx +0 -295
  180. package/src/__tests__/verify.test.ts +0 -239
  181. package/src/__tests__/webcomponent.test.tsx +0 -116
  182. package/src/builder/__tests__/builder.test.tsx +0 -158
  183. package/src/modal/cert-modal-view.test.ts +0 -175
  184. package/src/modal/certrev-cert-modal.test.ts +0 -125
  185. package/src/modal/ftc-guard.test.ts +0 -153
  186. package/src/modal/interactions.test.ts +0 -250
  187. package/src/modal/placement.test.ts +0 -398
  188. package/src/modal/revalidate.test.ts +0 -111
  189. package/src/modal/verify-client.test.ts +0 -164
@@ -3,14 +3,14 @@
3
3
  * `BuilderCertChromeData` — the CANONICAL headless cert-chrome wire type
4
4
  * ─────────────────────────────────────────────────────────────────────────────
5
5
  *
6
- * The brand-render projection of the cert envelope (portal POR-10091) — the OPTIONS
6
+ * The brand-render projection of the cert envelope — the OPTIONS
7
7
  * of a brand's native cert component (the registered `CertReviewCard`) on
8
8
  * a headless blocks-mode entry (Builder.io). CertREV serves the data + the ready-made
9
9
  * strings; the brand renders it within the design-guide ladder (enforced live by the
10
10
  * crawl monitor + the MSA anti-stripping teeth).
11
11
  *
12
- * SINGLE SOURCE (POR-10721 W1): this type is HOMED HERE so the portal exporter
13
- * (`src/lib/builder/cert-chrome.ts`) and the kit component (`CertReviewCard`) +
12
+ * SINGLE SOURCE: this type is HOMED HERE so the portal's cert-chrome exporter,
13
+ * the kit component (`CertReviewCard`) and
14
14
  * `BUILDER_REGISTRATION.inputs` all reference ONE definition — killing the drift the
15
15
  * hand-rolled Hydrogen-replica component suffered (it carried a stale separate
16
16
  * `credential`/`credentialVerifiedAt` shape from before the fused-pair projection).
@@ -48,7 +48,12 @@ export interface CertChromeRenderDef {
48
48
  readonly barInkFg?: '#141414' | '#ffffff';
49
49
  /** The subtractive field-visibility hide-set. */
50
50
  readonly hidden: readonly string[];
51
- /** v2 layout axis. Omitted ⇒ 'banner'. */
51
+ /**
52
+ * v2 layout axis. This is the DEF's own axis (what the brand baked), NOT the placement the
53
+ * component renders — the entry/editor picks that via `mode`, and its default lives in
54
+ * `renderCertBlock` alone (`sidebar`). This comment used to claim the default was 'banner',
55
+ * which made it the third place a placement default was written down and the second one wrong.
56
+ */
52
57
  readonly layout?: string;
53
58
  /** Custom-face composition — present only when layout === 'custom'. */
54
59
  readonly customFace?: {
@@ -89,9 +94,22 @@ export interface BuilderCertChromeData {
89
94
  background: string | null;
90
95
  /** The QA-SCREENED `verifiedExpertMemo` (never the raw in-flight `expertMemo`), or null. */
91
96
  memo: string | null;
92
- /** The compensation cue (`Compensated expert`). Null for a pro-bono reviewer. */
97
+ /**
98
+ * The compensation cue (`Compensated expert`). Null for a pro-bono reviewer.
99
+ *
100
+ * COPY IS NOT CARRIED BY THIS FIELD — only the BOOLEAN it implies is. The face renders the
101
+ * locked `COMPENSATED_EXPERT_CUE` constant when the cue is present and NOTHING when it is
102
+ * null; a rewritten string here changes no pixel. Kept on the wire type because the
103
+ * pro-bono `null` is real signal, and because a brand's exporter payload already carries it.
104
+ */
93
105
  compensationCue: string | null;
94
- /** The verbatim FTC scope disclaimer. Always present. */
106
+ /**
107
+ * The verbatim FTC scope disclaimer. Always present.
108
+ *
109
+ * Delivered for the brand's own records / non-CertREV surfaces. The face does NOT read it:
110
+ * it renders the locked `CERT_SCOPE_LINE` constant, whose curly apostrophe is pinned to
111
+ * MSA §3, so an edited copy here can never reach a rendered disclosure.
112
+ */
95
113
  scopeLine: string;
96
114
  /** Reviewer photo URL (cert-frozen override ?? live), or null. */
97
115
  reviewerPhoto: string | null;
@@ -119,8 +137,8 @@ export interface BuilderCertChromeData {
119
137
  }
120
138
  /**
121
139
  * The ordered keys of `BuilderCertChromeData` — the SINGLE SOURCE the Builder
122
- * `inputs` array and the W3 exporter⇄inputs⇄wire-type parity lock derive from, so
123
- * the three can never silently drift again (POR-10721 W3). Adding a field to the
140
+ * `inputs` array and the exporter⇄inputs⇄wire-type parity lock derive from, so
141
+ * the three can never silently drift again. Adding a field to the
124
142
  * interface without adding it here (or vice-versa) fails the `keyof` exhaustiveness
125
143
  * check in `assertChromeKeysExhaustive` below.
126
144
  */
@@ -1 +1 @@
1
- {"version":3,"file":"cert-chrome-data.d.ts","sourceRoot":"","sources":["../../src/builder/cert-chrome-data.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH;;;;;;GAMG;AACH,MAAM,WAAW,mBAAmB;IACnC,8EAA8E;IAC9E,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE;QAChB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;QAC7B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;QACzB,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;QAC9B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;QAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;QACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAC1B,CAAA;IACD,oFAAoF;IACpF,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,GAAG,SAAS,CAAA;IACzC,iDAAiD;IACjD,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAA;IAClC,0CAA0C;IAC1C,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,uEAAuE;IACvE,QAAQ,CAAC,UAAU,CAAC,EAAE;QAAE,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAA;KAAE,CAAA;CAClE;AAED;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACrC;;;;OAIG;IACH,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC;;;;;;;;OAQG;IACH,sBAAsB,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAA;IACzE,2EAA2E;IAC3E,WAAW,EAAE,MAAM,CAAA;IACnB,wFAAwF;IACxF,YAAY,EAAE,MAAM,CAAA;IACpB,8DAA8D;IAC9D,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IAClB,sEAAsE;IACtE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,4FAA4F;IAC5F,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,iFAAiF;IACjF,eAAe,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,yDAAyD;IACzD,SAAS,EAAE,MAAM,CAAA;IACjB,kEAAkE;IAClE,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,mFAAmF;IACnF,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC,gEAAgE;IAChE,SAAS,EAAE,MAAM,CAAA;IACjB,wFAAwF;IACxF,WAAW,EAAE,MAAM,CAAA;IACnB,4EAA4E;IAC5E,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAA;IAChC,kGAAkG;IAClG,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,0DAA0D;IAC1D,OAAO,EAAE;QACR,eAAe,EAAE,OAAO,CAAA;QACxB,kGAAkG;QAClG,eAAe,EAAE,OAAO,CAAA;KACxB,CAAA;IACD,qFAAqF;IACrF,SAAS,EAAE,mBAAmB,GAAG,IAAI,CAAA;IACrC,kGAAkG;IAClG,cAAc,EAAE,MAAM,CAAA;CACtB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,sTAoB3B,CAAA;AAEV,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,wBAAwB,CAAC,CAAC,MAAM,CAAC,CAAA"}
1
+ {"version":3,"file":"cert-chrome-data.d.ts","sourceRoot":"","sources":["../../src/builder/cert-chrome-data.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH;;;;;;GAMG;AACH,MAAM,WAAW,mBAAmB;IACnC,8EAA8E;IAC9E,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE;QAChB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;QAC7B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;QACzB,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;QAC9B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;QAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;QACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAC1B,CAAA;IACD,oFAAoF;IACpF,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,GAAG,SAAS,CAAA;IACzC,iDAAiD;IACjD,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAA;IAClC;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,uEAAuE;IACvE,QAAQ,CAAC,UAAU,CAAC,EAAE;QAAE,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAA;KAAE,CAAA;CAClE;AAED;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACrC;;;;OAIG;IACH,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC;;;;;;;;OAQG;IACH,sBAAsB,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAA;IACzE,2EAA2E;IAC3E,WAAW,EAAE,MAAM,CAAA;IACnB,wFAAwF;IACxF,YAAY,EAAE,MAAM,CAAA;IACpB,8DAA8D;IAC9D,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;IAClB,sEAAsE;IACtE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,4FAA4F;IAC5F,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB;;;;;;;OAOG;IACH,eAAe,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B;;;;;;OAMG;IACH,SAAS,EAAE,MAAM,CAAA;IACjB,kEAAkE;IAClE,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,mFAAmF;IACnF,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC,gEAAgE;IAChE,SAAS,EAAE,MAAM,CAAA;IACjB,wFAAwF;IACxF,WAAW,EAAE,MAAM,CAAA;IACnB,4EAA4E;IAC5E,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAA;IAChC,kGAAkG;IAClG,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,0DAA0D;IAC1D,OAAO,EAAE;QACR,eAAe,EAAE,OAAO,CAAA;QACxB,kGAAkG;QAClG,eAAe,EAAE,OAAO,CAAA;KACxB,CAAA;IACD,qFAAqF;IACrF,SAAS,EAAE,mBAAmB,GAAG,IAAI,CAAA;IACrC,kGAAkG;IAClG,cAAc,EAAE,MAAM,CAAA;CACtB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,sTAoB3B,CAAA;AAEV,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,wBAAwB,CAAC,CAAC,MAAM,CAAC,CAAA"}
@@ -3,14 +3,14 @@
3
3
  * `BuilderCertChromeData` — the CANONICAL headless cert-chrome wire type
4
4
  * ─────────────────────────────────────────────────────────────────────────────
5
5
  *
6
- * The brand-render projection of the cert envelope (portal POR-10091) — the OPTIONS
6
+ * The brand-render projection of the cert envelope — the OPTIONS
7
7
  * of a brand's native cert component (the registered `CertReviewCard`) on
8
8
  * a headless blocks-mode entry (Builder.io). CertREV serves the data + the ready-made
9
9
  * strings; the brand renders it within the design-guide ladder (enforced live by the
10
10
  * crawl monitor + the MSA anti-stripping teeth).
11
11
  *
12
- * SINGLE SOURCE (POR-10721 W1): this type is HOMED HERE so the portal exporter
13
- * (`src/lib/builder/cert-chrome.ts`) and the kit component (`CertReviewCard`) +
12
+ * SINGLE SOURCE: this type is HOMED HERE so the portal's cert-chrome exporter,
13
+ * the kit component (`CertReviewCard`) and
14
14
  * `BUILDER_REGISTRATION.inputs` all reference ONE definition — killing the drift the
15
15
  * hand-rolled Hydrogen-replica component suffered (it carried a stale separate
16
16
  * `credential`/`credentialVerifiedAt` shape from before the fused-pair projection).
@@ -21,8 +21,8 @@
21
21
  */
22
22
  /**
23
23
  * The ordered keys of `BuilderCertChromeData` — the SINGLE SOURCE the Builder
24
- * `inputs` array and the W3 exporter⇄inputs⇄wire-type parity lock derive from, so
25
- * the three can never silently drift again (POR-10721 W3). Adding a field to the
24
+ * `inputs` array and the exporter⇄inputs⇄wire-type parity lock derive from, so
25
+ * the three can never silently drift again. Adding a field to the
26
26
  * interface without adding it here (or vice-versa) fails the `keyof` exhaustiveness
27
27
  * check in `assertChromeKeysExhaustive` below.
28
28
  */
@@ -1 +1 @@
1
- {"version":3,"file":"cert-chrome-data.js","sourceRoot":"","sources":["../../src/builder/cert-chrome-data.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAiGH;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACvC,oBAAoB;IACpB,wBAAwB;IACxB,aAAa;IACb,cAAc;IACd,KAAK;IACL,YAAY;IACZ,MAAM;IACN,iBAAiB;IACjB,WAAW;IACX,eAAe;IACf,oBAAoB;IACpB,WAAW;IACX,aAAa;IACb,mBAAmB;IACnB,YAAY;IACZ,aAAa;IACb,SAAS;IACT,WAAW;IACX,gBAAgB;CACP,CAAA;AAIV;;;;;GAKG;AACH,MAAM,cAAc,GAA8C,MAAM,CAAC,WAAW,CACnF,wBAAwB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CACR,CAAA;AACvC,MAAM,eAAe,GAAuC,cAAc,CAAA;AAC1E,KAAK,eAAe,CAAA"}
1
+ {"version":3,"file":"cert-chrome-data.js","sourceRoot":"","sources":["../../src/builder/cert-chrome-data.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAmHH;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACvC,oBAAoB;IACpB,wBAAwB;IACxB,aAAa;IACb,cAAc;IACd,KAAK;IACL,YAAY;IACZ,MAAM;IACN,iBAAiB;IACjB,WAAW;IACX,eAAe;IACf,oBAAoB;IACpB,WAAW;IACX,aAAa;IACb,mBAAmB;IACnB,YAAY;IACZ,aAAa;IACb,SAAS;IACT,WAAW;IACX,gBAAgB;CACP,CAAA;AAIV;;;;;GAKG;AACH,MAAM,cAAc,GAA8C,MAAM,CAAC,WAAW,CACnF,wBAAwB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CACR,CAAA;AACvC,MAAM,eAAe,GAAuC,cAAc,CAAA;AAC1E,KAAK,eAAe,CAAA"}
@@ -8,7 +8,7 @@
8
8
  * `BuilderCertChromeData` projection — so the visible cert chrome renders itself,
9
9
  * design-identical to the Shopify Liquid + WordPress PHP faces (same `renderCertBlock`
10
10
  * string renderer). This REPLACES the ~200-line hand-rolled component every headless
11
- * brand copied from the demo (POR-10721 W1).
11
+ * brand copied from the demo.
12
12
  *
13
13
  * Improvements over the canary demo's hand-rolled version:
14
14
  * - consumes the CANONICAL `BuilderCertChromeData` (the fused `credentialVerification`
@@ -26,11 +26,15 @@ import type { BuilderCertChromeData } from './cert-chrome-data.js';
26
26
  */
27
27
  export declare const CERT_COMPONENT_NAME = "CertREV Cert";
28
28
  export interface CertReviewCardProps extends Partial<BuilderCertChromeData> {
29
- /** Placement face — the ENTRY/editor chooses this, NOT the exporter (not a wire-type field). */
29
+ /**
30
+ * Placement face — the ENTRY/editor chooses this, NOT the exporter (not a wire-type field).
31
+ * Absent ⇒ whatever `renderCertBlock` defaults to (`sidebar`); this component names no
32
+ * fallback of its own, so there is exactly ONE place the default is written down.
33
+ */
30
34
  mode?: CertBlockMode | null;
31
35
  /**
32
36
  * Banner memo placement (not a wire-type field — the ENTRY/editor chooses it). Passed
33
- * straight through to `renderCertBlock`'s first-class `part` (POR-10741): `'full'`
37
+ * straight through to `renderCertBlock`'s first-class `part`: `'full'`
34
38
  * (default) renders header + memo in one block; `'header'`/`'memo'` render only that
35
39
  * card so the memo can be placed as its own block under the article body. The old
36
40
  * string-splitting shim is gone — `renderCertBlock` composes each part directly.
@@ -38,12 +42,31 @@ export interface CertReviewCardProps extends Partial<BuilderCertChromeData> {
38
42
  part?: 'full' | 'header' | 'memo' | null;
39
43
  }
40
44
  export declare function CertReviewCard(props: CertReviewCardProps): import("react").JSX.Element | null;
41
- /** The subset of the Builder.io input schema this kit emits. */
45
+ /**
46
+ * The subset of the Builder.io input schema this kit emits. Every field below is verified
47
+ * against `@builder.io/sdk-react`'s own `Input` declaration (`types/types/input.d.ts`, 5.2.7) —
48
+ * a field the SDK ignores would be worse than none, because it READS as configured.
49
+ */
42
50
  export interface BuilderInput {
43
51
  readonly name: string;
44
52
  readonly type: 'string' | 'longText' | 'object' | 'boolean' | 'number';
45
53
  readonly friendlyName?: string;
46
54
  readonly helperText?: string;
55
+ /** The value Builder pre-fills a freshly-dropped block with (`Input.defaultValue`). */
56
+ readonly defaultValue?: string;
57
+ /**
58
+ * Turns a `string` input into a DROPDOWN of exactly these choices (`Input.enum`). The SDK
59
+ * accepts bare strings or `{label, value}` pairs; the kit uses pairs so the editor reads a
60
+ * capitalised label while the component still receives its lowercase mode/part literal.
61
+ * The ARRAY is deliberately mutable (the entries are not): the SDK types `Input.enum` as a
62
+ * mutable array, and a `readonly` one here makes the whole registration un-assignable to
63
+ * `RegisteredComponent` — the same reason `inputs` itself is mutable below (verified by
64
+ * compiling this shape against the installed SDK's `RegisteredComponent`).
65
+ */
66
+ readonly enum?: {
67
+ readonly label: string;
68
+ readonly value: string;
69
+ }[];
47
70
  /** Tucks the input under the editor's "Advanced" reveal (Builder's `Input.advanced`). */
48
71
  readonly advanced?: boolean;
49
72
  }
@@ -53,7 +76,14 @@ export interface BuilderInput {
53
76
  * kills the demo's hand-maintained 17-entry array.
54
77
  */
55
78
  export declare const WIRE_INPUTS: readonly BuilderInput[];
56
- /** Placement inputs — chosen by the entry/editor, NOT emitted by the exporter (not wire-type keys). */
79
+ /**
80
+ * Placement inputs — chosen by the entry/editor, NOT emitted by the exporter (not wire-type keys).
81
+ *
82
+ * `defaultValue` + `enum` are what make these two REAL choices in the editor: a dropdown of the
83
+ * faces that exist, pre-filled with the same default the renderer applies. They were free-text
84
+ * with no default before, so the only description of the default was the helper text — which had
85
+ * drifted from the code (it advertised `banner`; the renderer's default is `sidebar`).
86
+ */
57
87
  export declare const PLACEMENT_INPUTS: readonly BuilderInput[];
58
88
  /** A Builder.io custom-component registration (the general shape; the anchor uses the same). */
59
89
  export interface CertBlockBuilderRegistration {
@@ -1 +1 @@
1
- {"version":3,"file":"cert-review-card.d.ts","sourceRoot":"","sources":["../../src/builder/cert-review-card.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,KAAK,aAAa,EAAmB,MAAM,oCAAoC,CAAA;AAExF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;AAGlE;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,iBAAiB,CAAA;AAEjD,MAAM,WAAW,mBAAoB,SAAQ,OAAO,CAAC,qBAAqB,CAAC;IAC1E,gGAAgG;IAChG,IAAI,CAAC,EAAE,aAAa,GAAG,IAAI,CAAA;IAC3B;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,MAAM,GAAG,IAAI,CAAA;CACxC;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,sCAyDxD;AAMD,gEAAgE;AAChE,MAAM,WAAW,YAAY;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,UAAU,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAA;IACtE,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;IAC5B,yFAAyF;IACzF,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAC3B;AAyBD;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAAE,SAAS,YAAY,EAM5C,CAAA;AAEH,uGAAuG;AACvG,eAAO,MAAM,gBAAgB,EAAE,SAAS,YAAY,EAQnD,CAAA;AAED,gGAAgG;AAChG,MAAM,WAAW,4BAA4B;IAC5C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,SAAS,EAAE,OAAO,cAAc,CAAA;IACzC,QAAQ,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,CAAA;CACxC;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,EAAE,4BAIlC,CAAA;AAED;;;;;GAKG;AACH,MAAM,WAAW,iCAAiC;IACjD,SAAS,EAAE,OAAO,cAAc,CAAA;IAChC,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,MAAM,EAAE,YAAY,EAAE,CAAA;CACtB;AAED;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,EAAE,iCAMlC,CAAA"}
1
+ {"version":3,"file":"cert-review-card.d.ts","sourceRoot":"","sources":["../../src/builder/cert-review-card.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,KAAK,aAAa,EAAmB,MAAM,oCAAoC,CAAA;AAExF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;AAGlE;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,iBAAiB,CAAA;AAEjD,MAAM,WAAW,mBAAoB,SAAQ,OAAO,CAAC,qBAAqB,CAAC;IAC1E;;;;OAIG;IACH,IAAI,CAAC,EAAE,aAAa,GAAG,IAAI,CAAA;IAC3B;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,MAAM,GAAG,IAAI,CAAA;CACxC;AAsCD,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,sCAoExD;AAMD;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,UAAU,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAA;IACtE,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;IAC5B,uFAAuF;IACvF,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAA;IAC9B;;;;;;;;OAQG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IACpE,yFAAyF;IACzF,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAC3B;AA0CD;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAAE,SAAS,YAAY,EAO5C,CAAA;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,EAAE,SAAS,YAAY,EAyBnD,CAAA;AAED,gGAAgG;AAChG,MAAM,WAAW,4BAA4B;IAC5C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,SAAS,EAAE,OAAO,cAAc,CAAA;IACzC,QAAQ,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,CAAA;CACxC;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,EAAE,4BAIlC,CAAA;AAED;;;;;GAKG;AACH,MAAM,WAAW,iCAAiC;IACjD,SAAS,EAAE,OAAO,cAAc,CAAA;IAChC,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,MAAM,EAAE,YAAY,EAAE,CAAA;CACtB;AAED;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,EAAE,iCAMlC,CAAA"}
@@ -9,7 +9,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
9
9
  * `BuilderCertChromeData` projection — so the visible cert chrome renders itself,
10
10
  * design-identical to the Shopify Liquid + WordPress PHP faces (same `renderCertBlock`
11
11
  * string renderer). This REPLACES the ~200-line hand-rolled component every headless
12
- * brand copied from the demo (POR-10721 W1).
12
+ * brand copied from the demo.
13
13
  *
14
14
  * Improvements over the canary demo's hand-rolled version:
15
15
  * - consumes the CANONICAL `BuilderCertChromeData` (the fused `credentialVerification`
@@ -26,52 +26,94 @@ import { BUILDER_CERT_CHROME_KEYS } from './cert-chrome-data.js';
26
26
  * deviation (portal `client-for-brand.ts` gains the default in a follow-up).
27
27
  */
28
28
  export const CERT_COMPONENT_NAME = 'CertREV Cert';
29
+ /**
30
+ * Coerce ONE untyped option to renderable text.
31
+ *
32
+ * `CertReviewCardProps` is erased at runtime and these options are authored in a VISUAL
33
+ * EDITOR — a number, an object or an array can sit in any field, and `??` does nothing about
34
+ * it (`props.memo ?? ''` forwards the number 42 happily). `renderCertBlock` reads its facts as
35
+ * strings (`.trim()`, `.split()`), so a mistyped option threw INSIDE the SSR render; under
36
+ * `renderToReadableStream` that aborts the whole article route with zero HTML. A value that is
37
+ * not text is not copy, so it renders as nothing.
38
+ */
39
+ function text(value) {
40
+ return typeof value === 'string' ? value : '';
41
+ }
42
+ /** The same rule where ABSENT and EMPTY are different renders (`authorTitle`, `bio`). */
43
+ function optionalText(value) {
44
+ return text(value) || undefined;
45
+ }
46
+ /**
47
+ * The fused credential pair — accepted ONLY when both halves are present AND both are strings.
48
+ *
49
+ * The R1 gate ("a credential never displays without its dated verification") is THIS FUNCTION,
50
+ * not the type: the pair arrives as untyped CMS JSON, and the old truthiness check keyed the
51
+ * whole pair off the OBJECT, so `{credential:'MD'}` forwarded `verifiedAt: undefined` into the
52
+ * renderer and crashed. Anything malformed — a half pair, a bare string, an array, a number
53
+ * where a date belongs — degrades to the name-only face, which is the honest render of a
54
+ * delivery whose verification cannot be read.
55
+ */
56
+ function fusedCredential(pair) {
57
+ if (!pair || typeof pair !== 'object')
58
+ return null;
59
+ const credential = text(pair.credential);
60
+ const verifiedAt = text(pair.verifiedAt);
61
+ return credential && verifiedAt ? { credential, verifiedAt } : null;
62
+ }
29
63
  export function CertReviewCard(props) {
30
- const { reviewerName, verifyUrl } = props;
64
+ const reviewerName = text(props.reviewerName);
65
+ const verifyUrl = text(props.verifyUrl);
31
66
  if (!reviewerName || !verifyUrl)
32
- return null; // no chrome pre-cert
33
- // The credential + its verification date arrive ONLY as the fused pair, so we can
34
- // never obtain one without the other (name-only face when the pair is null, or when
35
- // the brand set showCredentials:false). This IS the R1 gate, enforced by the type.
36
- const cv = props.credentialVerification ?? null;
67
+ return null; // no chrome pre-cert (or an unreadable delivery)
68
+ // Name-only face when the pair is unreadable, or when the brand set showCredentials:false.
37
69
  const showCred = props.display?.showCredentials !== false;
38
- const withCred = cv && showCred ? cv : null;
70
+ const withCred = showCred ? fusedCredential(props.credentialVerification) : null;
39
71
  const tokens = props.renderDef?.tokens;
40
72
  const theme = tokens
41
73
  ? {
42
- accentColor: tokens.accentColor,
43
- surface: tokens.surface,
44
- cornerRadius: tokens.cornerRadius,
45
- fontSlot: tokens.fontSlot,
74
+ accentColor: optionalText(tokens.accentColor),
75
+ surface: optionalText(tokens.surface),
76
+ cornerRadius: optionalText(tokens.cornerRadius),
77
+ fontSlot: optionalText(tokens.fontSlot),
46
78
  // v2 brand-ink (post-demo): the bar + free-content ink follow the def.
47
- barInk: tokens.barInk,
48
- inkColor: tokens.inkColor,
79
+ barInk: optionalText(tokens.barInk),
80
+ inkColor: optionalText(tokens.inkColor),
49
81
  }
50
82
  : undefined;
51
83
  const html = renderCertBlock({
52
- mode: props.mode ?? 'banner',
84
+ // NO fallback here, deliberately: `renderCertBlock` owns the ONE placement default
85
+ // (absent or unrecognised ⇒ sidebar). This line used to say `?? 'banner'`, and it was
86
+ // one of THREE layers each naming a default — here, the registered input's helper text,
87
+ // and the wire type's own doc comment — while the renderer, the only place that actually
88
+ // paints a face, named none. Three copies of a default is three chances to disagree.
89
+ mode: props.mode ?? undefined,
53
90
  theme,
54
- // First-class banner memo split (POR-10741) — renderCertBlock composes the requested
55
- // part directly; no string-splitting. Ignored outside banner mode.
91
+ // First-class banner memo split — renderCertBlock composes the requested
92
+ // part directly; no string-splitting. Ignored outside banner mode, and an unrecognised
93
+ // value is normalised to 'full' there, same as `mode` — not here.
56
94
  ...(props.part ? { part: props.part } : {}),
57
95
  facts: {
58
- authorName: props.authorName ?? 'Editorial',
59
- authorTitle: props.authorTitle ?? undefined,
96
+ authorName: optionalText(props.authorName) ?? 'Editorial',
97
+ authorTitle: optionalText(props.authorTitle),
60
98
  reviewerName,
61
- credential: withCred ? withCred.credential : '',
62
- credentialVerifiedAt: withCred ? withCred.verifiedAt : '',
63
- certifiedAt: props.certifiedAt ?? '',
64
- memo: props.memo ?? '',
65
- bio: props.bio ?? undefined,
66
- profileUrl: props.reviewerProfileUrl ?? '',
99
+ credential: withCred?.credential ?? '',
100
+ credentialVerifiedAt: withCred?.verifiedAt ?? '',
101
+ certifiedAt: text(props.certifiedAt),
102
+ memo: text(props.memo),
103
+ bio: optionalText(props.bio),
104
+ profileUrl: text(props.reviewerProfileUrl),
67
105
  certificateUrl: verifyUrl,
68
- // Locked strings default byte-verbatim inside renderCertBlock; pass the
69
- // delivered cue/scope through so a pro-bono (null-cue) delivery is honored.
70
- ...(props.compensationCue ? { compensationCue: props.compensationCue } : {}),
71
- ...(props.scopeLine ? { scopeLine: props.scopeLine } : {}),
106
+ // The compliance disclosures are CONSTANTS the renderer owns — a delivered cue is
107
+ // IGNORED (an editor cannot retype the FTC copy into something friendlier), and the
108
+ // scope line is not forwarded at all. The ONE thing honored is an explicit `null`:
109
+ // the pro-bono reviewer has no compensation to disclose, so the cue is omitted
110
+ // rather than replaced by the compensated constant (the modal already gets this
111
+ // right — a card claiming "Compensated expert" over a volunteer is an FTC-facing
112
+ // falsehood, not a cosmetic default).
113
+ compensationCue: props.compensationCue === null ? null : undefined,
72
114
  },
73
115
  });
74
- return (_jsx("div", { "data-certrev-cert-chrome": "", "data-certrev-strings-version": props.stringsVersion ?? undefined, "data-certrev-def-version": props.renderDef?.v ?? undefined,
116
+ return (_jsx("div", { "data-certrev-cert-chrome": "", "data-certrev-strings-version": optionalText(props.stringsVersion), "data-certrev-def-version": typeof props.renderDef?.v === 'number' ? props.renderDef.v : undefined,
75
117
  // biome-ignore lint/security/noDangerouslySetInnerHtml: renderCertBlock is the escaping-safe SSR string renderer
76
118
  dangerouslySetInnerHTML: { __html: html } }));
77
119
  }
@@ -97,6 +139,20 @@ const WIRE_INPUT_TYPE = {
97
139
  renderDef: 'object',
98
140
  stringsVersion: 'string',
99
141
  };
142
+ /**
143
+ * The COMPLIANCE-COPY inputs, called what they are.
144
+ *
145
+ * `advanced: true` is only a UI fold, so an editor who opens "Advanced" sees these two beside
146
+ * the rest and reads them as theirs to type in. They are NOT: the renderer paints the locked
147
+ * `COMPENSATED_EXPERT_CUE` / `CERT_SCOPE_LINE` constants and ignores whatever is here. They
148
+ * stay REGISTERED because they are wire-type keys — dropping them would change the contract
149
+ * the portal exporter writes, and would strand the `null` that signals a pro-bono reviewer.
150
+ * So the fix is truthful labelling, not removal.
151
+ */
152
+ const WIRE_INPUT_HELPER_TEXT = {
153
+ compensationCue: 'System-populated by CertREV. Only its PRESENCE is read (absent = a pro-bono reviewer, so no cue renders); the cue itself is a locked constant, so editing this text changes nothing on the page — and clearing it does not remove the disclosure.',
154
+ scopeLine: 'System-populated by CertREV. The FTC scope line renders byte-verbatim from a locked constant — editing this text changes nothing on the page.',
155
+ };
100
156
  /**
101
157
  * The wire-type inputs — DERIVED from `BUILDER_CERT_CHROME_KEYS`, so the 19-field
102
158
  * option set can never drift from the type (the W3 lock asserts name-parity). This
@@ -105,19 +161,44 @@ const WIRE_INPUT_TYPE = {
105
161
  export const WIRE_INPUTS = BUILDER_CERT_CHROME_KEYS.map((name) => ({
106
162
  name,
107
163
  type: WIRE_INPUT_TYPE[name],
164
+ ...(WIRE_INPUT_HELPER_TEXT[name] ? { helperText: WIRE_INPUT_HELPER_TEXT[name] } : {}),
108
165
  // Exporter-populated wire fields: collapsed under the editor's "Advanced" reveal so the
109
166
  // Options tab leads with the two placement choices an editor actually makes (mode/part).
110
167
  advanced: true,
111
168
  }));
112
- /** Placement inputs — chosen by the entry/editor, NOT emitted by the exporter (not wire-type keys). */
169
+ /**
170
+ * Placement inputs — chosen by the entry/editor, NOT emitted by the exporter (not wire-type keys).
171
+ *
172
+ * `defaultValue` + `enum` are what make these two REAL choices in the editor: a dropdown of the
173
+ * faces that exist, pre-filled with the same default the renderer applies. They were free-text
174
+ * with no default before, so the only description of the default was the helper text — which had
175
+ * drifted from the code (it advertised `banner`; the renderer's default is `sidebar`).
176
+ */
113
177
  export const PLACEMENT_INPUTS = [
114
178
  {
115
179
  name: 'mode',
116
180
  type: 'string',
117
181
  friendlyName: 'Placement',
118
- helperText: 'banner (default) · sidebar · floating',
182
+ helperText: 'sidebar (default) · banner · floating',
183
+ defaultValue: 'sidebar',
184
+ enum: [
185
+ { label: 'Sidebar', value: 'sidebar' },
186
+ { label: 'Banner', value: 'banner' },
187
+ { label: 'Floating', value: 'floating' },
188
+ ],
189
+ },
190
+ {
191
+ name: 'part',
192
+ type: 'string',
193
+ friendlyName: 'Banner part',
194
+ helperText: 'full (default) · header · memo — banner placement only',
195
+ defaultValue: 'full',
196
+ enum: [
197
+ { label: 'Full (header + memo)', value: 'full' },
198
+ { label: 'Header only', value: 'header' },
199
+ { label: 'Memo only', value: 'memo' },
200
+ ],
119
201
  },
120
- { name: 'part', type: 'string', friendlyName: 'Banner part', helperText: 'full (default) · header · memo' },
121
202
  ];
122
203
  /**
123
204
  * The canonical registration data (readonly view). Most consumers want
@@ -141,7 +222,7 @@ export const BUILDER_REGISTRATION = {
141
222
  export const certRevCertComponent = {
142
223
  name: CERT_COMPONENT_NAME,
143
224
  component: CertReviewCard,
144
- description: 'CertREV expert-review cert card. Options are populated by the CertREV exporter — editors choose placement (mode/part) only.',
225
+ description: 'CertREV expert-review cert card. Options are populated by the CertREV exporter; editors choose placement (mode/part) only.',
145
226
  inputs: [...PLACEMENT_INPUTS, ...WIRE_INPUTS],
146
227
  };
147
228
  //# sourceMappingURL=cert-review-card.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cert-review-card.js","sourceRoot":"","sources":["../../src/builder/cert-review-card.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cert-review-card.js","sourceRoot":"","sources":["../../src/builder/cert-review-card.tsx"],"names":[],"mappings":"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"}
@@ -1,32 +1,49 @@
1
1
  /**
2
2
  * @certrev/cert-block/builder — Builder.io adapter, "ambient-URL anchor" model.
3
3
  *
4
- * Validated by an independent architecture panel (Codex gpt-5.5 + Gemini, blind): a visual
5
- * page builder must NOT choose WHICH credential renders — that invites cross-article misuse and
6
- * re-opens the wrong-subject surface. Instead:
4
+ * A visual page builder must NOT choose WHICH credential renders — that invites cross-article
5
+ * misuse and re-opens the wrong-subject surface. The ANCHOR path splits the two concerns:
7
6
  * • the CMS controls LAYOUT — an editor drags a ZERO-INPUT <CertRevAnchor/> to position the
8
7
  * badge on the page;
9
8
  * • the SYSTEM controls TRUTH — the headless loader resolves THIS page's credential from its
10
- * own URL (Track-1 delivery), crypto-verifies it (fail-closed VerdictKernel), and supplies
11
- * the verdict via context.
9
+ * own URL, crypto-verifies it (fail-closed VerdictKernel), and supplies the verdict via
10
+ * context.
12
11
  * The anchor renders the current page's verified badge or NOTHING. It cannot be pointed at
13
12
  * another article, and there is no `placementId` input to forge or mis-select.
14
13
  *
15
- * JSON-LD is DECOUPLED (panel finding): the anchor renders the BADGE only (`omitJsonLd`). The
16
- * article template emits the schema.org JSON-LD server-side from the same verified verdict, so a
17
- * page builder can't duplicate, move, or omit structured data. (See the route example.)
14
+ * THE PUSH KIT DOES NOT INHERIT THAT PROPERTY, and this module exports it too. `CertReviewCard` /
15
+ * `certRevCertComponent` register the 19 wire-type fields — `reviewerName`,
16
+ * `credentialVerification`, `verifyUrl`, `memo` — as Builder INPUTS, and the card renders what
17
+ * those inputs hold; it runs no signature check and consults no verdict. `advanced: true` folds
18
+ * them out of the editor's default view, which is a UI reveal and not a lock, and `safeHttpUrl`
19
+ * bounds `verifyUrl` to the http(s) SCHEME rather than to a CertREV origin. So to the card a
20
+ * hand-typed option and an exporter-written one are the same string: the trust boundary on the
21
+ * PUSH path is WRITE ACCESS TO THE CMS SPACE, not a signature, and nothing in this package
22
+ * narrows it. See "PUSH trust model" in the package README for the full statement — including
23
+ * what a revocation upstream does and does not reach.
18
24
  *
19
- * EDGE-CACHE DISCIPLINE (panel finding): the consumer's loader MUST verify per request as a
20
- * dynamic edge subrequest and must NOT long-cache the rendered badge HTML — a revoked/expired
21
- * credential sitting in a stale edge cache would defeat fail-closed. Bound any positive-verdict
22
- * cache by min(expiry, revocation-TTL, content-version).
25
+ * Three things the card DOES enforce, and they are the limit of it: no chrome at all without a
26
+ * `reviewerName` and a `verifyUrl`; a credential renders only welded to its dated verification
27
+ * (the fused pair); and the FTC disclosures render from locked constants, so rewriting the
28
+ * `compensationCue` / `scopeLine` options changes no pixel. Use the anchor when the page itself
29
+ * must not be able to state a credential.
30
+ *
31
+ * JSON-LD is DECOUPLED: the anchor renders the BADGE only (`omitJsonLd`). The article template
32
+ * emits the schema.org JSON-LD server-side from the same verified verdict, so a page builder
33
+ * can't duplicate, move, or omit structured data. See "The article route example" in the package
34
+ * README for the route both halves meet in.
35
+ *
36
+ * EDGE-CACHE DISCIPLINE: the consumer's loader MUST verify per request as a dynamic edge
37
+ * subrequest and must NOT long-cache the rendered badge HTML — a revoked/expired credential
38
+ * sitting in a stale edge cache would defeat fail-closed. Bound any positive-verdict cache by
39
+ * min(expiry, revocation-TTL, content-version).
23
40
  *
24
41
  * cert-block carries no Builder dependency: the registration shape is declared structurally, and
25
42
  * `isEditing` is a passed-in flag (the consumer supplies Builder's `isPreviewing()`).
26
43
  */
27
44
  import { type ReactNode } from 'react';
28
45
  import type { CertVerdict } from '../contract/kernel.js';
29
- /** The current page's credential, resolved + verified by the loader (Track-1 delivery). */
46
+ /** The current page's credential, resolved + verified by the consumer's loader. */
30
47
  export interface CurrentCredential {
31
48
  readonly verdict: CertVerdict;
32
49
  /** Canonical page URL for JSON-LD @id alignment (used by the server-side JSON-LD, not the anchor). */
@@ -52,8 +69,8 @@ export declare function CertRevEditorPlaceholder(): import("react").JSX.Element;
52
69
  /**
53
70
  * The Builder block. ZERO inputs — a layout anchor only. Renders the current page's VERIFIED
54
71
  * badge (badge only; JSON-LD is emitted server-side), the editor placeholder in design mode, or
55
- * NOTHING in production (fail-closed). The credential is whatever Track-1 delivered + verified for
56
- * THIS page; the editor can neither choose nor forge it.
72
+ * NOTHING in production (fail-closed). The credential is whatever the loader delivered + verified
73
+ * for THIS page; the editor can neither choose nor forge it.
57
74
  */
58
75
  export declare function CertRevAnchor(): import("react").JSX.Element | null;
59
76
  /**
@@ -73,5 +90,5 @@ export interface CertRevBuilderRegistration {
73
90
  */
74
91
  export declare const certRevAnchorComponent: CertRevBuilderRegistration;
75
92
  export { BUILDER_CERT_CHROME_KEYS, type BuilderCertChromeData, type BuilderCertChromeKey, type CertChromeRenderDef, } from './cert-chrome-data.js';
76
- export { BUILDER_REGISTRATION, type BuilderInput, CERT_COMPONENT_NAME, type CertBlockBuilderRegistration, certRevCertComponent, CertReviewCard, type CertReviewCardProps, type CertReviewCardRegisteredComponent, PLACEMENT_INPUTS, WIRE_INPUTS, } from './cert-review-card.js';
93
+ export { BUILDER_REGISTRATION, type BuilderInput, CERT_COMPONENT_NAME, type CertBlockBuilderRegistration, CertReviewCard, type CertReviewCardProps, type CertReviewCardRegisteredComponent, certRevCertComponent, PLACEMENT_INPUTS, WIRE_INPUTS, } from './cert-review-card.js';
77
94
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/builder/index.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,EAAiB,KAAK,SAAS,EAAc,MAAM,OAAO,CAAA;AAEjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAExD,2FAA2F;AAC3F,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAA;IAC7B,sGAAsG;IACtG,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CACzB;AASD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,EAC/B,OAAO,EACP,SAAiB,EACjB,QAAQ,GACR,EAAE;IACF,QAAQ,CAAC,OAAO,EAAE,iBAAiB,GAAG,IAAI,CAAA;IAC1C,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAA;IAC5B,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAA;CAC5B,+BAEA;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,gCAiBvC;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,uCAO5B;AAED;;;;GAIG;AACH,MAAM,WAAW,0BAA0B;IAC1C,SAAS,EAAE,OAAO,aAAa,CAAA;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,KAAK,EAAE,CAAA;CACf;AAED;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,EAAE,0BAIpC,CAAA;AAGD,OAAO,EACN,wBAAwB,EACxB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,GACxB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACN,oBAAoB,EACpB,KAAK,YAAY,EACjB,mBAAmB,EACnB,KAAK,4BAA4B,EACjC,oBAAoB,EACpB,cAAc,EACd,KAAK,mBAAmB,EACxB,KAAK,iCAAiC,EACtC,gBAAgB,EAChB,WAAW,GACX,MAAM,uBAAuB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/builder/index.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,OAAO,EAAiB,KAAK,SAAS,EAAc,MAAM,OAAO,CAAA;AAEjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAExD,mFAAmF;AACnF,MAAM,WAAW,iBAAiB;IACjC,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAA;IAC7B,sGAAsG;IACtG,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CACzB;AASD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,EAC/B,OAAO,EACP,SAAiB,EACjB,QAAQ,GACR,EAAE;IACF,QAAQ,CAAC,OAAO,EAAE,iBAAiB,GAAG,IAAI,CAAA;IAC1C,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAA;IAC5B,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAA;CAC5B,+BAEA;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,gCAiBvC;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,uCAO5B;AAED;;;;GAIG;AACH,MAAM,WAAW,0BAA0B;IAC1C,SAAS,EAAE,OAAO,aAAa,CAAA;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,KAAK,EAAE,CAAA;CACf;AAED;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,EAAE,0BAIpC,CAAA;AAGD,OAAO,EACN,wBAAwB,EACxB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,GACxB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACN,oBAAoB,EACpB,KAAK,YAAY,EACjB,mBAAmB,EACnB,KAAK,4BAA4B,EACjC,cAAc,EACd,KAAK,mBAAmB,EACxB,KAAK,iCAAiC,EACtC,oBAAoB,EACpB,gBAAgB,EAChB,WAAW,GACX,MAAM,uBAAuB,CAAA"}
@@ -2,25 +2,42 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  /**
3
3
  * @certrev/cert-block/builder — Builder.io adapter, "ambient-URL anchor" model.
4
4
  *
5
- * Validated by an independent architecture panel (Codex gpt-5.5 + Gemini, blind): a visual
6
- * page builder must NOT choose WHICH credential renders — that invites cross-article misuse and
7
- * re-opens the wrong-subject surface. Instead:
5
+ * A visual page builder must NOT choose WHICH credential renders — that invites cross-article
6
+ * misuse and re-opens the wrong-subject surface. The ANCHOR path splits the two concerns:
8
7
  * • the CMS controls LAYOUT — an editor drags a ZERO-INPUT <CertRevAnchor/> to position the
9
8
  * badge on the page;
10
9
  * • the SYSTEM controls TRUTH — the headless loader resolves THIS page's credential from its
11
- * own URL (Track-1 delivery), crypto-verifies it (fail-closed VerdictKernel), and supplies
12
- * the verdict via context.
10
+ * own URL, crypto-verifies it (fail-closed VerdictKernel), and supplies the verdict via
11
+ * context.
13
12
  * The anchor renders the current page's verified badge or NOTHING. It cannot be pointed at
14
13
  * another article, and there is no `placementId` input to forge or mis-select.
15
14
  *
16
- * JSON-LD is DECOUPLED (panel finding): the anchor renders the BADGE only (`omitJsonLd`). The
17
- * article template emits the schema.org JSON-LD server-side from the same verified verdict, so a
18
- * page builder can't duplicate, move, or omit structured data. (See the route example.)
15
+ * THE PUSH KIT DOES NOT INHERIT THAT PROPERTY, and this module exports it too. `CertReviewCard` /
16
+ * `certRevCertComponent` register the 19 wire-type fields — `reviewerName`,
17
+ * `credentialVerification`, `verifyUrl`, `memo` — as Builder INPUTS, and the card renders what
18
+ * those inputs hold; it runs no signature check and consults no verdict. `advanced: true` folds
19
+ * them out of the editor's default view, which is a UI reveal and not a lock, and `safeHttpUrl`
20
+ * bounds `verifyUrl` to the http(s) SCHEME rather than to a CertREV origin. So to the card a
21
+ * hand-typed option and an exporter-written one are the same string: the trust boundary on the
22
+ * PUSH path is WRITE ACCESS TO THE CMS SPACE, not a signature, and nothing in this package
23
+ * narrows it. See "PUSH trust model" in the package README for the full statement — including
24
+ * what a revocation upstream does and does not reach.
19
25
  *
20
- * EDGE-CACHE DISCIPLINE (panel finding): the consumer's loader MUST verify per request as a
21
- * dynamic edge subrequest and must NOT long-cache the rendered badge HTML — a revoked/expired
22
- * credential sitting in a stale edge cache would defeat fail-closed. Bound any positive-verdict
23
- * cache by min(expiry, revocation-TTL, content-version).
26
+ * Three things the card DOES enforce, and they are the limit of it: no chrome at all without a
27
+ * `reviewerName` and a `verifyUrl`; a credential renders only welded to its dated verification
28
+ * (the fused pair); and the FTC disclosures render from locked constants, so rewriting the
29
+ * `compensationCue` / `scopeLine` options changes no pixel. Use the anchor when the page itself
30
+ * must not be able to state a credential.
31
+ *
32
+ * JSON-LD is DECOUPLED: the anchor renders the BADGE only (`omitJsonLd`). The article template
33
+ * emits the schema.org JSON-LD server-side from the same verified verdict, so a page builder
34
+ * can't duplicate, move, or omit structured data. See "The article route example" in the package
35
+ * README for the route both halves meet in.
36
+ *
37
+ * EDGE-CACHE DISCIPLINE: the consumer's loader MUST verify per request as a dynamic edge
38
+ * subrequest and must NOT long-cache the rendered badge HTML — a revoked/expired credential
39
+ * sitting in a stale edge cache would defeat fail-closed. Bound any positive-verdict cache by
40
+ * min(expiry, revocation-TTL, content-version).
24
41
  *
25
42
  * cert-block carries no Builder dependency: the registration shape is declared structurally, and
26
43
  * `isEditing` is a passed-in flag (the consumer supplies Builder's `isPreviewing()`).
@@ -55,8 +72,8 @@ export function CertRevEditorPlaceholder() {
55
72
  /**
56
73
  * The Builder block. ZERO inputs — a layout anchor only. Renders the current page's VERIFIED
57
74
  * badge (badge only; JSON-LD is emitted server-side), the editor placeholder in design mode, or
58
- * NOTHING in production (fail-closed). The credential is whatever Track-1 delivered + verified for
59
- * THIS page; the editor can neither choose nor forge it.
75
+ * NOTHING in production (fail-closed). The credential is whatever the loader delivered + verified
76
+ * for THIS page; the editor can neither choose nor forge it.
60
77
  */
61
78
  export function CertRevAnchor() {
62
79
  const { current, isEditing } = useContext(CertRevContext);
@@ -77,7 +94,7 @@ export const certRevAnchorComponent = {
77
94
  name: 'CertREV Review',
78
95
  inputs: [],
79
96
  };
80
- // ── POR-10721 W1/W3: the Builder.io PUSH kit (CertReviewCard) + single-sourced wire type ──
97
+ // ── The Builder.io PUSH kit (CertReviewCard) + the single-sourced wire type ──
81
98
  export { BUILDER_CERT_CHROME_KEYS, } from './cert-chrome-data.js';
82
- export { BUILDER_REGISTRATION, CERT_COMPONENT_NAME, certRevCertComponent, CertReviewCard, PLACEMENT_INPUTS, WIRE_INPUTS, } from './cert-review-card.js';
99
+ export { BUILDER_REGISTRATION, CERT_COMPONENT_NAME, CertReviewCard, certRevCertComponent, PLACEMENT_INPUTS, WIRE_INPUTS, } from './cert-review-card.js';
83
100
  //# sourceMappingURL=index.js.map