@certrev/cert-block 1.1.1 → 1.2.0-canary.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +71 -0
- package/README.md +66 -4
- package/dist/builder/cert-chrome-data.d.ts +10 -0
- package/dist/builder/cert-chrome-data.d.ts.map +1 -1
- package/dist/builder/cert-chrome-data.js.map +1 -1
- package/dist/builder/cert-review-card.d.ts.map +1 -1
- package/dist/builder/cert-review-card.js +22 -2
- package/dist/builder/cert-review-card.js.map +1 -1
- package/dist/builder/envelope-face.d.ts +25 -1
- package/dist/builder/envelope-face.d.ts.map +1 -1
- package/dist/builder/envelope-face.js +40 -0
- package/dist/builder/envelope-face.js.map +1 -1
- package/dist/builder/index.d.ts +1 -1
- package/dist/builder/index.d.ts.map +1 -1
- package/dist/builder/index.js +1 -1
- package/dist/builder/index.js.map +1 -1
- package/dist/reader/face.d.ts +12 -0
- package/dist/reader/face.d.ts.map +1 -0
- package/dist/reader/face.js +19 -0
- package/dist/reader/face.js.map +1 -0
- package/dist/reader/helpers.d.ts +48 -0
- package/dist/reader/helpers.d.ts.map +1 -0
- package/dist/reader/helpers.js +166 -0
- package/dist/reader/helpers.js.map +1 -0
- package/dist/reader/index.d.ts +10 -0
- package/dist/reader/index.d.ts.map +1 -0
- package/dist/reader/index.js +10 -0
- package/dist/reader/index.js.map +1 -0
- package/dist/reader/logo.d.ts +4 -0
- package/dist/reader/logo.d.ts.map +1 -0
- package/dist/reader/logo.js +23 -0
- package/dist/reader/logo.js.map +1 -0
- package/dist/reader/reader-css.generated.d.ts +2 -0
- package/dist/reader/reader-css.generated.d.ts.map +1 -0
- package/dist/reader/reader-css.generated.js +6 -0
- package/dist/reader/reader-css.generated.js.map +1 -0
- package/dist/reader/render.d.ts +26 -0
- package/dist/reader/render.d.ts.map +1 -0
- package/dist/reader/render.js +238 -0
- package/dist/reader/render.js.map +1 -0
- package/dist/reader/tokens.d.ts +8 -0
- package/dist/reader/tokens.d.ts.map +1 -0
- package/dist/reader/tokens.js +80 -0
- package/dist/reader/tokens.js.map +1 -0
- package/dist/verify/get-verified-delivery.d.ts.map +1 -1
- package/dist/verify/get-verified-delivery.js +5 -1
- package/dist/verify/get-verified-delivery.js.map +1 -1
- package/package.json +7 -1
- package/src/builder/cert-chrome-data.ts +10 -0
- package/src/builder/cert-review-card.tsx +31 -2
- package/src/builder/envelope-face.ts +54 -5
- package/src/builder/index.tsx +3 -0
- package/src/reader/face.ts +35 -0
- package/src/reader/helpers.ts +178 -0
- package/src/reader/index.ts +14 -0
- package/src/reader/logo.ts +28 -0
- package/src/reader/reader-css.generated.ts +5 -0
- package/src/reader/reader.css +550 -0
- package/src/reader/render.ts +326 -0
- package/src/reader/tokens.ts +93 -0
- package/src/verify/get-verified-delivery.ts +5 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../src/reader/render.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AACvD,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAA;AAE3G,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AACtC,OAAO,EACN,OAAO,EACP,QAAQ,EACR,GAAG,EACH,SAAS,EACT,OAAO,EACP,SAAS,EACT,QAAQ,EACR,QAAQ,EAER,GAAG,EACH,OAAO,EACP,MAAM,GACN,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAkD1C,SAAS,SAAS,CAAC,KAAsB;IACxC,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IAClC,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;IAClC,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;IACjC,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAA;IACrB,MAAM,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,CAAA;IAEnB,MAAM,UAAU,GAAG,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,eAAe,CAAC,CAAA;IACvD,MAAM,SAAS,GAAG,IAAI,CAAC,eAAe,KAAK,KAAK,IAAI,CAAC,UAAU,CAAA;IAE/D,+GAA+G;IAC/G,MAAM,MAAM,GAAa,EAAE,CAAA;IAC3B,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC;QACvC,KAAK,MAAM,UAAU,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;YAC7C,MAAM,EAAE,GAAG,GAAG,CAAC,UAAU,CAAC,CAAA;YAC1B,MAAM,KAAK,GAAG,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,YAAY,CAAC,CAAA;YAC9E,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;gBAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACxC,CAAC;IACF,CAAC;IAED,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,eAAe,CAAC,CAAA;IAChD,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,YAAY,CAAC,GAAG,CAAC,CAAA;IACvC,OAAO;QACN,OAAO;QACP,MAAM;QACN,IAAI;QACJ,GAAG;QACH,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC;QAC5B,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC;QACjC,UAAU;QACV,SAAS;QACT,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;QACxB,MAAM;QACN,KAAK,EAAE,KAAK,CAAC,YAAY,KAAK,IAAI,IAAI,CAAC,MAAM;QAC7C,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC;QAC7B,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QACzC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QACzC,KAAK;QACL,EAAE;KACF,CAAA;AACF,CAAC;AAED,yHAAyH;AACzH,SAAS,WAAW,CAAC,CAAQ,EAAE,KAAc,EAAE,IAAY;IAC1D,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,8BAA8B,CAAC,CAAC,CAAC,gBAAgB,CAAA;IACrE,mEAAmE;IACnE,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,8BAA8B,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAA;IACzF,OAAO,CACN,mBAAmB,GAAG,YAAY,CAAC,CAAC,KAAK,IAAI,OAAO,kCAAkC,oBAAoB,IAAI;QAC9G,yBAAyB,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,iBAAiB,GAAG,CAAC,IAAI,CAAC,IAAI,CACpE,CAAA;AACF,CAAC;AAED,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,KAAa,EAAE,KAAa,EAAU,EAAE,CACrE,YAAY,GAAG,CAAC,IAAI,CAAC,0BAA0B,gBAAgB,4BAA4B,KAAK,IAAI,KAAK,MAAM,CAAA;AAEhH,qFAAqF;AACrF,SAAS,YAAY,CAAC,CAAQ;IAC7B,MAAM,KAAK,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAA;IACzC,OAAO,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC,cAAc,CAAA;AAC5E,CAAC;AAED,MAAM,cAAc,GAAG,CAAC,CAAQ,EAAU,EAAE,CAAC,uBAAuB,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAA;AAEpH,wFAAwF;AACxF,SAAS,SAAS,CAAC,CAAQ;IAC1B,IAAI,CAAC,CAAC,MAAM;QAAE,OAAO,OAAO,sBAAsB,UAAU,CAAA;IAC5D,IAAI,CAAC,CAAC,KAAK;QAAE,OAAO,kCAAkC,CAAA;IACtD,OAAO,EAAE,CAAA;AACV,CAAC;AAED,MAAM,KAAK,GAAG,uBAAuB,eAAe,SAAS,CAAA;AAE7D;;;;;;;GAOG;AACH,SAAS,YAAY,CAAC,CAAQ,EAAE,eAAwB;IACvD,IAAI,CAAC,CAAC,KAAK,KAAK,EAAE;QAAE,OAAO,EAAE,CAAA;IAC7B,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,CAAA;IAC3G,MAAM,EAAE,GAAG,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;IAChD,IAAI,CAAC,eAAe;QAAE,OAAO,qCAAqC,EAAE,OAAO,CAAA;IAC3E,OAAO,aAAa,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,iDAAiD,EAAE,cAAc,CAAA;AAClG,CAAC;AAED,gFAAgF;AAChF,sFAAsF;AACtF,gFAAgF;AAEhF,SAAS,UAAU,CAAC,CAAQ;IAC3B,IAAI,CAAC,CAAC,KAAK,KAAK,EAAE;QAAE,OAAO,EAAE,CAAA;IAC7B,MAAM,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;IACpC,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IACtC,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IACxC,MAAM,SAAS,GAAG,CAAC,CAAC,IAAI,CAAC,UAAU,KAAK,KAAK,IAAI,UAAU,KAAK,EAAE,IAAI,UAAU,KAAK,CAAC,CAAC,KAAK,CAAA;IAC5F,MAAM,MAAM,GAAG,CAAC,KAAc,EAAE,IAAe,EAAU,EAAE,CAC1D,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAA;IAE9E,MAAM,QAAQ,GAAG,SAAS;QACzB,CAAC,CAAC,6BAA6B,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,2BAA2B,GAAG,CAAC,UAAU,CAAC,MAAM;YAC3G,GAAG,WAAW,KAAK,EAAE,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,sFAAsF;QAClJ,CAAC,CAAC,EAAE,CAAA;IACL,MAAM,QAAQ,GACb,6BAA6B,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC,yBAAyB,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM;QACrG,GAAG,YAAY,CAAC,CAAC,EAAE,IAAI,CAAC,sFAAsF,CAAA;IAE/G,MAAM,WAAW,GAAG,CAAC,CAAC,OAAO,CAAC,WAAW,CAAA;IACzC,MAAM,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAA;IAE5E,gGAAgG;IAChG,IAAI,KAAK,GAAG,EAAE,CAAA;IACd,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,IAAI,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,EAAE,CAAC;QAClD,KAAK;YACJ,+BAA+B;gBAC/B,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,WAAW,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBACnE,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,kBAAkB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC7D,QAAQ,CAAA;IACV,CAAC;IAED,MAAM,OAAO,GAAG,SAAS,KAAK,EAAE,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,KAAK,CAAA;IACvD,MAAM,IAAI,GAAG,OAAO,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,oCAAoC,CAAC,CAAC,CAAC,EAAE,CAAA;IAE5E,IAAI,IAAI,GAAG,EAAE,CAAA;IACb,IAAI,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,GACT,SAAS,KAAK,EAAE;YACf,CAAC,CAAC,2CAA2C,GAAG,CAAC,WAAW,CAAC,KAAK,GAAG,CAAC,SAAS,CAAC,gBAAgB;YAChG,CAAC,CAAC,eAAe,CAAA;QACnB,IAAI,GAAG,GAAG,EAAE,CAAA;QACZ,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;YACd,GAAG,GAAG,qBAAqB,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,SAAS,CAAA;QACrG,CAAC;aAAM,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;YACpB,GAAG,GAAG,mCAAmC,CAAA;QAC1C,CAAC;QACD,IAAI,GAAG,+BAA+B,IAAI,GAAG,GAAG,QAAQ,CAAA;IACzD,CAAC;IAED,mHAAmH;IACnH,MAAM,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,oDAAoD,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAA;IAE/F,OAAO,CACN,GAAG,WAAW,CAAC,CAAC,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC,oCAAoC;QAC9E,kCAAkC,UAAU,CAAC,CAAC,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,EAAE,SAAS,CAAC,yCAAyC;QAC3I,wEAAwE,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,QAAQ,GAAG,QAAQ,gBAAgB;QACxI,GAAG,KAAK,GAAG,IAAI,GAAG,IAAI,GAAG,KAAK,8BAA8B,CAC5D,CAAA;AACF,CAAC;AAED,SAAS,UAAU,CAAC,CAAQ;IAC3B,IAAI,CAAC,CAAC,KAAK,KAAK,EAAE,IAAI,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,CAAA;IACxD,MAAM,KAAK,GACV,CAAC,CAAC,IAAI,KAAK,EAAE,IAAI,CAAC,CAAC,IAAI,KAAK,EAAE;QAC7B,CAAC,CAAC,+BAA+B;YAChC,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,WAAW,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACnE,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,kBAAkB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7D,QAAQ;QACT,CAAC,CAAC,EAAE,CAAA;IACN,MAAM,MAAM,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAA;IACtH,OAAO,CACN,GAAG,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,kBAAkB,CAAC,CAAC,KAAK,EAAE,CAAC,wCAAwC;QAC7F,qDAAqD;QACrD,mCAAmC,MAAM,SAAS;QAClD,+CAA+C,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU;QACrH,uBAAuB,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,gBAAgB,KAAK,sBAAsB;QACrF,6EAA6E;QAC7E,0CAA0C,UAAU,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,CAAC,qCAAqC;QACzG,2DAA2D,SAAS,CAAC,CAAC,CAAC,GAAG,KAAK,2CAA2C,CAC1H,CAAA;AACF,CAAC;AAED,gFAAgF;AAChF,4BAA4B;AAC5B,gFAAgF;AAEhF,SAAS,OAAO,CAAC,CAAQ;IACxB,IAAI,CAAC,CAAC,KAAK,KAAK,EAAE;QAAE,OAAO,EAAE,CAAA;IAC7B,MAAM,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC,OAAO,KAAK,KAAK,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IAC1F,MAAM,MAAM,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAA;IACtH,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,KAAK,EAAE,IAAI,CAAC,CAAC,IAAI,KAAK,EAAE,CAAA;IAC3C,MAAM,KAAK,GACV,CAAC,CAAC,IAAI,KAAK,EAAE,IAAI,CAAC,CAAC,IAAI,KAAK,EAAE;QAC7B,CAAC,CAAC,mCAAmC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,IAAI;YAC7D,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,WAAW,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAClE,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,kBAAkB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7D,QAAQ;QACT,CAAC,CAAC,EAAE,CAAA;IACN,OAAO,CACN,GAAG,WAAW,CAAC,CAAC,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC,oCAAoC;QAC9E,yCAAyC,UAAU,CAAC,CAAC,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,EAAE,SAAS,CAAC,yBAAyB;QAClI,0EAA0E,MAAM,SAAS;QACzF,gBAAgB,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,YAAY,CAAC,CAAC,EAAE,KAAK,CAAC,sBAAsB;QAC3H,GAAG,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;QAC3C,GAAG,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,eAAe,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,eAAe,EAAE;QACrF,oDAAoD,SAAS,CAAC,CAAC,CAAC,GAAG,KAAK,oBAAoB;QAC5F,GAAG,KAAK,oBAAoB,CAC5B,CAAA;AACF,CAAC;AAED,SAAS,IAAI,CAAC,CAAQ;IACrB,IAAI,CAAC,CAAC,IAAI,KAAK,EAAE;QAAE,OAAO,EAAE,CAAA;IAC5B,MAAM,OAAO,GAAG,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,WAAW,EAAE,SAAS,CAAC,6BAA6B,CAAC,CAAC,CAAC,EAAE,CAAA;IAC3G,OAAO,CACN,GAAG,WAAW,CAAC,CAAC,EAAE,IAAI,EAAE,iBAAiB,CAAC,qEAAqE;QAC/G,GAAG,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,aAAa,CAAC,wBAAwB,CACtE,CAAA;AACF,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAsB;IACtD,MAAM,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,CAAA;IAC1B,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS;QAAE,OAAO,OAAO,CAAC,CAAC,CAAC,CAAA;IACjD,IAAI,KAAK,CAAC,MAAM,KAAK,UAAU;QAAE,OAAO,IAAI,CAAC,CAAC,CAAC,CAAA;IAC/C,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,MAAM,CAAA;IACjC,IAAI,IAAI,KAAK,QAAQ;QAAE,OAAO,UAAU,CAAC,CAAC,CAAC,CAAA;IAC3C,IAAI,IAAI,KAAK,MAAM;QAAE,OAAO,UAAU,CAAC,CAAC,CAAC,CAAA;IACzC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACjF,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface ReaderTokens {
|
|
2
|
+
/** The value of the section's `style` attribute. */
|
|
3
|
+
readonly style: string;
|
|
4
|
+
/** The ink on the accent: `#ffffff` or `#141414`. The logo is white on the first and mono on the second. */
|
|
5
|
+
readonly fg: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function readerTokens(def: unknown): ReaderTokens;
|
|
8
|
+
//# sourceMappingURL=tokens.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../../src/reader/tokens.ts"],"names":[],"mappings":"AAiEA,MAAM,WAAW,YAAY;IAC5B,oDAAoD;IACpD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,4GAA4G;IAC5G,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,YAAY,CAoBvD"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `certrev-reader-tokens`: the four CSS custom properties a reader section carries on its root, from the render def.
|
|
3
|
+
*
|
|
4
|
+
* --cr-ba the accent the card cap and pill paint: the def's `barInk`, else its `accentColor`, else navy
|
|
5
|
+
* --cr-ba-fg the ink on that accent: white, or `#141414` when the def baked it for the colour that painted
|
|
6
|
+
* --cr-br the corner radius
|
|
7
|
+
* --cr-bf the font stack for the brand's `fontSlot`
|
|
8
|
+
*
|
|
9
|
+
* The values land inside a double-quoted `style` attribute, and they are held to the allow-list the Liquid snippet and
|
|
10
|
+
* the PHP twin's def parser hold them to: a colour is `#RGB` or `#RRGGBB`, a radius one non-negative px / rem / em / %
|
|
11
|
+
* length or a bare `0`, and anything else paints the default (navy, 14px). A denylist of characters is not enough: a
|
|
12
|
+
* quote, a backslash, a comment opener or a bracket left in a value hides the `;` that ends it and swallows the
|
|
13
|
+
* declarations after it. The variable names are the reader stylesheet's (`reader.css`), which `.certrev-reader`
|
|
14
|
+
* declares defaults for.
|
|
15
|
+
*/
|
|
16
|
+
import { asText } from '../components/escape.js';
|
|
17
|
+
import { esc, rec, textOr } from './helpers.js';
|
|
18
|
+
/** The accent when the def has none: CertREV navy. */
|
|
19
|
+
const DEFAULT_ACCENT = '#0A1B3F';
|
|
20
|
+
const DEFAULT_RADIUS = '14px';
|
|
21
|
+
/** The foreground the def bakes for a light accent; anything else is the white default. */
|
|
22
|
+
const DARK_INK = '#141414';
|
|
23
|
+
/**
|
|
24
|
+
* The font stack per `fontSlot`, in one table so the Liquid `certrev-reader-tokens` snippet and this one are compared
|
|
25
|
+
* on a single list. An unknown or missing slot is the sans stack, as in the snippet. The serif and grotesk stacks name
|
|
26
|
+
* the reader's own `@font-face` aliases first ("CertREV Reader Serif" / "CertREV Reader Grotesk", declared in
|
|
27
|
+
* `reader.css`), then the legacy family and the generic fallbacks, as the snippet's `--cr-bf` does.
|
|
28
|
+
*/
|
|
29
|
+
function fontStack(slot) {
|
|
30
|
+
switch (slot) {
|
|
31
|
+
case 'serif':
|
|
32
|
+
return "'CertREV Reader Serif', 'Playfair Display', ui-serif, Georgia, serif";
|
|
33
|
+
case 'grotesk':
|
|
34
|
+
return "'CertREV Reader Grotesk', 'Plus Jakarta Sans', ui-sans-serif, system-ui, sans-serif";
|
|
35
|
+
case 'mono':
|
|
36
|
+
return "'JetBrains Mono', ui-monospace, monospace";
|
|
37
|
+
case 'system':
|
|
38
|
+
return "system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif";
|
|
39
|
+
default:
|
|
40
|
+
return "'DM Sans', ui-sans-serif, system-ui, sans-serif";
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/** A colour is `#` and then 3 or 6 hex digits (ASCII only, no trailing newline), else '' (which the caller defaults). */
|
|
44
|
+
const HEX = /^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;
|
|
45
|
+
/**
|
|
46
|
+
* A radius is a bare `0`, or digits with at most one `.` (not trailing) and then px, rem, em or %, else ''. `\d` is
|
|
47
|
+
* ASCII here (no `u` flag), as the snippet's `0123456789.` is; the unit is case-sensitive.
|
|
48
|
+
*/
|
|
49
|
+
const LENGTH = /^(?:\d+|\d+\.\d+|\.\d+)(?:px|rem|em|%)$/;
|
|
50
|
+
/** A colour token that is a hex colour, or '' (which the caller defaults). */
|
|
51
|
+
function hexColour(value) {
|
|
52
|
+
const text = textOr(value);
|
|
53
|
+
return HEX.test(text) ? text : '';
|
|
54
|
+
}
|
|
55
|
+
/** A radius token that is a bare 0 or a non-negative length, or '' (which the caller defaults). */
|
|
56
|
+
function radius(value) {
|
|
57
|
+
const text = textOr(value);
|
|
58
|
+
return text === '0' || LENGTH.test(text) ? text : '';
|
|
59
|
+
}
|
|
60
|
+
export function readerTokens(def) {
|
|
61
|
+
const rd = rec(def);
|
|
62
|
+
const tokens = rec(rd.tokens);
|
|
63
|
+
const barInk = hexColour(tokens.barInk);
|
|
64
|
+
const accent = hexColour(tokens.accentColor);
|
|
65
|
+
const ba = barInk || accent || DEFAULT_ACCENT;
|
|
66
|
+
// The ink follows the value that painted the accent: a def with a bar ink takes the foreground baked for it
|
|
67
|
+
// (barInkFg); one that paints its accent colour takes the one baked for that colour (accentFg).
|
|
68
|
+
let fg = '#ffffff';
|
|
69
|
+
if (barInk !== '') {
|
|
70
|
+
if (rd.barInkFg === DARK_INK)
|
|
71
|
+
fg = DARK_INK;
|
|
72
|
+
}
|
|
73
|
+
else if (accent !== '' && rd.accentFg === DARK_INK) {
|
|
74
|
+
fg = DARK_INK;
|
|
75
|
+
}
|
|
76
|
+
const br = radius(tokens.cornerRadius) || DEFAULT_RADIUS;
|
|
77
|
+
const bf = fontStack(asText(tokens.fontSlot));
|
|
78
|
+
return { style: `--cr-ba:${esc(ba)};--cr-ba-fg:${fg};--cr-br:${esc(br)};--cr-bf:${bf}`, fg };
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=tokens.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokens.js","sourceRoot":"","sources":["../../src/reader/tokens.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAChD,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAE/C,sDAAsD;AACtD,MAAM,cAAc,GAAG,SAAS,CAAA;AAChC,MAAM,cAAc,GAAG,MAAM,CAAA;AAC7B,2FAA2F;AAC3F,MAAM,QAAQ,GAAG,SAAS,CAAA;AAE1B;;;;;GAKG;AACH,SAAS,SAAS,CAAC,IAAY;IAC9B,QAAQ,IAAI,EAAE,CAAC;QACd,KAAK,OAAO;YACX,OAAO,sEAAsE,CAAA;QAC9E,KAAK,SAAS;YACb,OAAO,qFAAqF,CAAA;QAC7F,KAAK,MAAM;YACV,OAAO,2CAA2C,CAAA;QACnD,KAAK,QAAQ;YACZ,OAAO,8EAA8E,CAAA;QACtF;YACC,OAAO,iDAAiD,CAAA;IAC1D,CAAC;AACF,CAAC;AAED,yHAAyH;AACzH,MAAM,GAAG,GAAG,sCAAsC,CAAA;AAClD;;;GAGG;AACH,MAAM,MAAM,GAAG,yCAAyC,CAAA;AAExD,8EAA8E;AAC9E,SAAS,SAAS,CAAC,KAAc;IAChC,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAA;IAC1B,OAAO,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAA;AAClC,CAAC;AAED,mGAAmG;AACnG,SAAS,MAAM,CAAC,KAAc;IAC7B,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAA;IAC1B,OAAO,IAAI,KAAK,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAA;AACrD,CAAC;AASD,MAAM,UAAU,YAAY,CAAC,GAAY;IACxC,MAAM,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC,CAAA;IACnB,MAAM,MAAM,GAAG,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,CAAA;IAE7B,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;IACvC,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,WAAW,CAAC,CAAA;IAC5C,MAAM,EAAE,GAAG,MAAM,IAAI,MAAM,IAAI,cAAc,CAAA;IAE7C,4GAA4G;IAC5G,gGAAgG;IAChG,IAAI,EAAE,GAAG,SAAS,CAAA;IAClB,IAAI,MAAM,KAAK,EAAE,EAAE,CAAC;QACnB,IAAI,EAAE,CAAC,QAAQ,KAAK,QAAQ;YAAE,EAAE,GAAG,QAAQ,CAAA;IAC5C,CAAC;SAAM,IAAI,MAAM,KAAK,EAAE,IAAI,EAAE,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACtD,EAAE,GAAG,QAAQ,CAAA;IACd,CAAC;IAED,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,cAAc,CAAA;IACxD,MAAM,EAAE,GAAG,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAA;IAC7C,OAAO,EAAE,KAAK,EAAE,WAAW,GAAG,CAAC,EAAE,CAAC,eAAe,EAAE,YAAY,GAAG,CAAC,EAAE,CAAC,YAAY,EAAE,EAAE,EAAE,EAAE,EAAE,CAAA;AAC7F,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-verified-delivery.d.ts","sourceRoot":"","sources":["../../src/verify/get-verified-delivery.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAA;AACzE,OAAO,KAAK,EAEX,WAAW,EACX,kBAAkB,EAClB,WAAW,EACX,aAAa,EACb,qBAAqB,EACrB,MAAM,uBAAuB,CAAA;AAE9B,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAGrC,qGAAqG;AACrG,MAAM,MAAM,cAAc,GACvB;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,mBAAmB,GAAG,IAAI,CAAA;CAAE,GAC5G;IAAE,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAA;CAAE,CAAA;AAEvE,mGAAmG;AACnG,MAAM,WAAW,gBAAgB;IAChC,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAA;IAC7B,iGAAiG;IACjG,QAAQ,CAAC,SAAS,EAAE,mBAAmB,GAAG,IAAI,CAAA;CAC9C;AAED,MAAM,WAAW,0BAA0B;IAC1C,mGAAmG;IACnG,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,mEAAmE;IACnE,QAAQ,CAAC,UAAU,EAAE,qBAAqB,CAAA;IAC1C,8FAA8F;IAC9F,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAA;IAC/B,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;IACjC,0EAA0E;IAC1E,QAAQ,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC,cAAc,CAAC,CAAA;IACzC,mGAAmG;IACnG,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,6EAA6E;IAC7E,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAC3B;AAED,kFAAkF;AAClF,QAAA,MAAM,mBAAmB,0BAAwE,CAAA;AAMjG,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAGzF;AAED,wGAAwG;AACxG,wBAAgB,gBAAgB,CAC/B,IAAI,EAAE,IAAI,CAAC,0BAA0B,EAAE,SAAS,GAAG,UAAU,GAAG,YAAY,GAAG,SAAS,CAAC,GACvF,MAAM,CAER;AAKD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,mBAAmB,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"get-verified-delivery.d.ts","sourceRoot":"","sources":["../../src/verify/get-verified-delivery.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAA;AACzE,OAAO,KAAK,EAEX,WAAW,EACX,kBAAkB,EAClB,WAAW,EACX,aAAa,EACb,qBAAqB,EACrB,MAAM,uBAAuB,CAAA;AAE9B,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAGrC,qGAAqG;AACrG,MAAM,MAAM,cAAc,GACvB;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,mBAAmB,GAAG,IAAI,CAAA;CAAE,GAC5G;IAAE,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAA;CAAE,CAAA;AAEvE,mGAAmG;AACnG,MAAM,WAAW,gBAAgB;IAChC,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAA;IAC7B,iGAAiG;IACjG,QAAQ,CAAC,SAAS,EAAE,mBAAmB,GAAG,IAAI,CAAA;CAC9C;AAED,MAAM,WAAW,0BAA0B;IAC1C,mGAAmG;IACnG,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,mEAAmE;IACnE,QAAQ,CAAC,UAAU,EAAE,qBAAqB,CAAA;IAC1C,8FAA8F;IAC9F,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAA;IAC/B,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;IACjC,0EAA0E;IAC1E,QAAQ,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC,cAAc,CAAC,CAAA;IACzC,mGAAmG;IACnG,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,6EAA6E;IAC7E,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAC3B;AAED,kFAAkF;AAClF,QAAA,MAAM,mBAAmB,0BAAwE,CAAA;AAMjG,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAGzF;AAED,wGAAwG;AACxG,wBAAgB,gBAAgB,CAC/B,IAAI,EAAE,IAAI,CAAC,0BAA0B,EAAE,SAAS,GAAG,UAAU,GAAG,YAAY,GAAG,SAAS,CAAC,GACvF,MAAM,CAER;AAKD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,mBAAmB,GAAG,IAAI,CAgCzE;AAyCD,iGAAiG;AACjG,wBAAgB,cAAc,CAAC,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,aAAa,GAAG,gBAAgB,CAI/F;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,0BAA0B,GAAG,OAAO,CAAC,gBAAgB,CAAC,CASrG;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CACnC,IAAI,EAAE,IAAI,CAAC,0BAA0B,EAAE,SAAS,GAAG,UAAU,GAAG,YAAY,GAAG,SAAS,GAAG,OAAO,CAAC,GACjG,gBAAgB,GAAG,SAAS,CAG9B;AAED,iFAAiF;AACjF,wBAAgB,kBAAkB,CACjC,IAAI,EAAE,IAAI,CAAC,0BAA0B,EAAE,SAAS,GAAG,UAAU,GAAG,YAAY,GAAG,SAAS,CAAC,EACzF,KAAK,GAAE,QAAQ,CAAC,cAAc,CAAuB,GACnD,IAAI,CAEN;AAED,OAAO,EAAE,mBAAmB,EAAE,CAAA"}
|
|
@@ -52,7 +52,7 @@ const isRecord = (v) => typeof v === 'object' && v !== null && !Array.isArray(v)
|
|
|
52
52
|
export function parseRenderDef(value) {
|
|
53
53
|
if (!isRecord(value))
|
|
54
54
|
return null;
|
|
55
|
-
const { v, preset, rung, tokens, hidden, barInkFg, layout, customFace } = value;
|
|
55
|
+
const { v, preset, rung, tokens, hidden, barInkFg, accentFg, face: faceName, layout, customFace } = value;
|
|
56
56
|
if (typeof v !== 'number' || !Number.isFinite(v))
|
|
57
57
|
return null;
|
|
58
58
|
if (!isString(preset) || !isString(rung) || !isRecord(tokens))
|
|
@@ -79,6 +79,10 @@ export function parseRenderDef(value) {
|
|
|
79
79
|
rung,
|
|
80
80
|
tokens: tokenOut,
|
|
81
81
|
...(barInkFg === '#141414' || barInkFg === '#ffffff' ? { barInkFg } : {}),
|
|
82
|
+
// 1.2.0: the reader face's two keys. 1.1.x dropped both; they are kept only when well-formed, so a def that
|
|
83
|
+
// carries neither parses to exactly the object 1.1.1 returned for it.
|
|
84
|
+
...(accentFg === '#141414' || accentFg === '#ffffff' ? { accentFg } : {}),
|
|
85
|
+
...(isString(faceName) ? { face: faceName } : {}),
|
|
82
86
|
hidden: [...hidden],
|
|
83
87
|
...(layout !== undefined ? { layout } : {}),
|
|
84
88
|
...(face ? { customFace: face } : {}),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-verified-delivery.js","sourceRoot":"","sources":["../../src/verify/get-verified-delivery.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAWH,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACrE,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AACrC,OAAO,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAgCtF,kFAAkF;AAClF,MAAM,mBAAmB,GAAG,IAAI,QAAQ,CAAiB,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC,CAAA;AAEjG,SAAS,UAAU,CAAC,MAA0B;IAC7C,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,CAAA;AACtC,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,OAAe,EAAE,QAAgB,EAAE,UAAkB;IAChF,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;IACxC,OAAO,GAAG,IAAI,yBAAyB,kBAAkB,CAAC,QAAQ,CAAC,IAAI,kBAAkB,CAAC,UAAU,CAAC,EAAE,CAAA;AACxG,CAAC;AAED,wGAAwG;AACxG,MAAM,UAAU,gBAAgB,CAC/B,IAAyF;IAEzF,OAAO,YAAY,WAAW,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,UAAU,CAAC,IAAI,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAA;AAC3K,CAAC;AAED,MAAM,QAAQ,GAAG,CAAC,CAAU,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAA;AACnE,MAAM,QAAQ,GAAG,CAAC,CAAU,EAAgC,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;AAEvH;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,KAAc;IAC5C,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IACjC,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,KAAK,CAAA;
|
|
1
|
+
{"version":3,"file":"get-verified-delivery.js","sourceRoot":"","sources":["../../src/verify/get-verified-delivery.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@certrev/cert-block",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0-canary.1",
|
|
4
4
|
"description": "Headless render edge for the CertREV CertDeliveryEnvelope: SSR-safe React cert components, a framework-agnostic <certrev-badge> Web Component, a schema.org JSON-LD projector, and a fail-closed verify layer over the shared VerdictKernel.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -27,6 +27,11 @@
|
|
|
27
27
|
"types": "./dist/builder/envelope-face.d.ts",
|
|
28
28
|
"default": "./dist/builder/envelope-face.js"
|
|
29
29
|
},
|
|
30
|
+
"./reader": {
|
|
31
|
+
"types": "./dist/reader/index.d.ts",
|
|
32
|
+
"default": "./dist/reader/index.js"
|
|
33
|
+
},
|
|
34
|
+
"./reader.css": "./src/reader/reader.css",
|
|
30
35
|
"./webcomponent": {
|
|
31
36
|
"types": "./dist/webcomponent/certrev-badge.d.ts",
|
|
32
37
|
"default": "./dist/webcomponent/certrev-badge.js"
|
|
@@ -65,6 +70,7 @@
|
|
|
65
70
|
"scripts": {
|
|
66
71
|
"build": "tsc && pnpm build:modal-bundle",
|
|
67
72
|
"build:modal-bundle": "pnpm dlx esbuild@0.27.7 src/modal/certrev-cert.entry.ts --bundle --minify --target=es2020 --format=iife --legal-comments=none --tsconfig-raw='{\"compilerOptions\":{\"target\":\"ES2017\",\"module\":\"esnext\",\"strict\":true}}' --banner:js='/* biome-ignore-all format: generated cert-badge bundle, see @certrev/cert-block src/modal/ */ /* biome-ignore-all lint: generated cert-badge bundle, see @certrev/cert-block src/modal/ */' --outfile=dist/modal/certrev-cert.js",
|
|
73
|
+
"refresh:reader": "node scripts/refresh-reader.mjs",
|
|
68
74
|
"typecheck": "tsc --noEmit",
|
|
69
75
|
"test": "vitest run"
|
|
70
76
|
},
|
|
@@ -47,6 +47,16 @@ export interface CertChromeRenderDef {
|
|
|
47
47
|
}
|
|
48
48
|
/** The auto-contrast bar foreground — present only on a barInk-themed face (v2). */
|
|
49
49
|
readonly barInkFg?: '#141414' | '#ffffff'
|
|
50
|
+
/**
|
|
51
|
+
* The ink painted over the ACCENT fill, as the portal derived it (1.2.0, reader face). Only the reader face reads
|
|
52
|
+
* it: the legacy face re-derives its own accent ink from `tokens.accentColor` and ignores this.
|
|
53
|
+
*/
|
|
54
|
+
readonly accentFg?: '#141414' | '#ffffff'
|
|
55
|
+
/**
|
|
56
|
+
* The face the brand chose (1.2.0). `'reader'` selects the certrev.com reader face; absent, or any other value,
|
|
57
|
+
* paints the face 1.1.1 paints (unknown faces degrade to the legacy face, never to nothing).
|
|
58
|
+
*/
|
|
59
|
+
readonly face?: string
|
|
50
60
|
/** The subtractive field-visibility hide-set. */
|
|
51
61
|
readonly hidden: readonly string[]
|
|
52
62
|
/**
|
|
@@ -23,11 +23,12 @@ import { Suspense } from 'react'
|
|
|
23
23
|
import { memoToggleFor, toggleMemo } from '../components/memo-toggle.js'
|
|
24
24
|
import { type CertBlockMode, renderCertBlock } from '../components/render-cert-block.js'
|
|
25
25
|
import { CERT_STRINGS_VERSION, type ResolvedBlockTheme } from '../components/render-def.js'
|
|
26
|
+
import { READER_CSS } from '../reader/reader-css.generated.js'
|
|
26
27
|
import { getVerifiedDelivery, peekVerifiedDelivery, type VerifiedDelivery } from '../verify/get-verified-delivery.js'
|
|
27
28
|
import type { BuilderCertChromeData } from './cert-chrome-data.js'
|
|
28
29
|
import { BUILDER_CERT_CHROME_KEYS } from './cert-chrome-data.js'
|
|
29
30
|
import { cardDeliveryRuntime } from './delivery-runtime.js'
|
|
30
|
-
import { envelopeCardInput } from './envelope-face.js'
|
|
31
|
+
import { envelopeCardHtml, envelopeCardInput, isReaderFaceDef } from './envelope-face.js'
|
|
31
32
|
|
|
32
33
|
/**
|
|
33
34
|
* The canonical Builder block name. A brand's registration + the portal
|
|
@@ -147,8 +148,17 @@ function suspendOn(key: string, start: () => Promise<VerifiedDelivery>): Verifie
|
|
|
147
148
|
* in; the button is native, so Enter and Space reach it as clicks. Bound after hydration only: the
|
|
148
149
|
* server HTML is the collapsed face, which is also what a reader without JS keeps (the whole memo
|
|
149
150
|
* is still in the text for a screen reader, and the desktop never clamps it).
|
|
151
|
+
*
|
|
152
|
+
* `reader` (1.2.0) is true ONLY for a def whose `face` is `'reader'`; it adds two things to the wrapper and nothing to
|
|
153
|
+
* any other face: `data-certrev-face="reader"` and `display: flow-root`. The reader sidebar card is a right float, and
|
|
154
|
+
* on a Shopify page the placement script and its wrapper contain it; a Builder block has no such ancestor, so the
|
|
155
|
+
* wrapper contains the float itself and the block keeps its own box in the page.
|
|
150
156
|
*/
|
|
151
|
-
function EnvelopeFace(props: {
|
|
157
|
+
function EnvelopeFace(props: {
|
|
158
|
+
readonly html: string
|
|
159
|
+
readonly defVersion: number | undefined
|
|
160
|
+
readonly reader?: boolean
|
|
161
|
+
}) {
|
|
152
162
|
const ref = React.useRef<HTMLDivElement>(null)
|
|
153
163
|
React.useEffect(() => {
|
|
154
164
|
const el = ref.current
|
|
@@ -169,6 +179,7 @@ function EnvelopeFace(props: { readonly html: string; readonly defVersion: numbe
|
|
|
169
179
|
data-certrev-delivery=""
|
|
170
180
|
data-certrev-strings-version={CERT_STRINGS_VERSION}
|
|
171
181
|
data-certrev-def-version={props.defVersion}
|
|
182
|
+
{...(props.reader ? { 'data-certrev-face': 'reader', style: { display: 'flow-root' } } : {})}
|
|
172
183
|
// biome-ignore lint/security/noDangerouslySetInnerHtml: renderCertBlock is the escaping-safe SSR string renderer
|
|
173
184
|
dangerouslySetInnerHTML={{ __html: props.html }}
|
|
174
185
|
/>
|
|
@@ -192,6 +203,24 @@ function EnvelopeCertReviewCard(props: {
|
|
|
192
203
|
)
|
|
193
204
|
// Revoked, expired, unverifiable, for another entry, or unreachable: nothing at all.
|
|
194
205
|
if (settled.verdict.decision !== 'render') return null
|
|
206
|
+
// The reader face is opt-in by the def's own `face` and is chosen HERE and nowhere else on this path; every other
|
|
207
|
+
// def (no face, an unknown face) falls through to the legacy lines below, untouched since 1.1.1.
|
|
208
|
+
if (isReaderFaceDef(settled.renderDef)) {
|
|
209
|
+
const reader = envelopeCardHtml(settled.verdict.payload.content, settled.renderDef, {
|
|
210
|
+
mode: props.mode,
|
|
211
|
+
part: props.part,
|
|
212
|
+
certId: settled.verdict.payload.certId,
|
|
213
|
+
})
|
|
214
|
+
if (!reader) return null
|
|
215
|
+
return (
|
|
216
|
+
<EnvelopeFace
|
|
217
|
+
reader
|
|
218
|
+
// The stylesheet rides inside the face, once per card; it is the portal's reader CSS byte for byte.
|
|
219
|
+
html={`<style data-certrev-reader-css>${READER_CSS}</style>${reader}`}
|
|
220
|
+
defVersion={settled.renderDef ? settled.renderDef.v : undefined}
|
|
221
|
+
/>
|
|
222
|
+
)
|
|
223
|
+
}
|
|
195
224
|
const input = envelopeCardInput(settled.verdict.payload.content, settled.renderDef, {
|
|
196
225
|
mode: props.mode,
|
|
197
226
|
part: props.part,
|
|
@@ -26,14 +26,16 @@
|
|
|
26
26
|
* it only returns null when the verified content cannot make a face (no reviewer, no verify URL).
|
|
27
27
|
*/
|
|
28
28
|
|
|
29
|
-
import
|
|
30
|
-
CertBlockFace,
|
|
31
|
-
CertBlockLayout,
|
|
32
|
-
CertBlockMode,
|
|
33
|
-
RenderCertBlockInput,
|
|
29
|
+
import {
|
|
30
|
+
type CertBlockFace,
|
|
31
|
+
type CertBlockLayout,
|
|
32
|
+
type CertBlockMode,
|
|
33
|
+
type RenderCertBlockInput,
|
|
34
|
+
renderCertBlock,
|
|
34
35
|
} from '../components/render-cert-block.js'
|
|
35
36
|
import { accentFg, HIDEABLE_FIELDS, isOpaqueHexColor, type ResolvedBlockTheme } from '../components/render-def.js'
|
|
36
37
|
import type { CertContent } from '../contract/kernel.js'
|
|
38
|
+
import { type ReaderLayout, renderReaderFace } from '../reader/render.js'
|
|
37
39
|
import type { CertChromeRenderDef } from './cert-chrome-data.js'
|
|
38
40
|
|
|
39
41
|
/**
|
|
@@ -74,6 +76,10 @@ export interface EnvelopeCardOptions {
|
|
|
74
76
|
readonly mode?: unknown
|
|
75
77
|
/** Banner memo placement, passed through as on the options path. */
|
|
76
78
|
readonly part?: unknown
|
|
79
|
+
/** The verified payload's `certId`: stamped on the reader face (`data-certrev-cert-id`). The legacy face ignores it. */
|
|
80
|
+
readonly certId?: unknown
|
|
81
|
+
/** A CertREV preview, never a live page: the reader face words the cue's empty slot as the demo does. Only `true` counts. */
|
|
82
|
+
readonly illustrative?: unknown
|
|
77
83
|
}
|
|
78
84
|
|
|
79
85
|
/** The def's theme tokens as `renderCertBlock` theme input, with the accent ink derived. */
|
|
@@ -171,3 +177,46 @@ export function envelopeCardInput(
|
|
|
171
177
|
},
|
|
172
178
|
}
|
|
173
179
|
}
|
|
180
|
+
|
|
181
|
+
/** The def `face` that selects the certrev.com reader face (1.2.0). Nothing else does. */
|
|
182
|
+
export const READER_FACE = 'reader'
|
|
183
|
+
|
|
184
|
+
/** Whether a def asks for the reader face: `face === 'reader'`, exactly. Absent or any other value is the legacy face. */
|
|
185
|
+
export function isReaderFaceDef(def: CertChromeRenderDef | null | undefined): boolean {
|
|
186
|
+
return def?.face === READER_FACE
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* The card's HTML for a verified envelope's content and the brand's def, or '' when nothing paints.
|
|
191
|
+
*
|
|
192
|
+
* THE ONE SELECTION POINT between the two faces, react-free so the portal's preview reaches it too:
|
|
193
|
+
* - `renderDef.face === 'reader'` paints the reader face (`renderReaderFace`), the same bytes as the Shopify reader
|
|
194
|
+
* snippets for the same facts;
|
|
195
|
+
* - EVERY other def (no `face`, `face: 'legacy'`, a face this version has never heard of, no def at all) paints
|
|
196
|
+
* exactly `renderCertBlock(envelopeCardInput(...))`, byte for byte what 1.1.1 paints. An unknown face degrades to
|
|
197
|
+
* the face the page had before, never to nothing and never to the reader.
|
|
198
|
+
* The reader branch sits BESIDE the legacy one; `envelopeCardInput` and `renderCertBlock` are not touched.
|
|
199
|
+
*
|
|
200
|
+
* Both faces keep the one gate they share: a content with no reviewer name or no certificate URL cannot make a face.
|
|
201
|
+
* The reader's layout is `layoutFor` (an editor mode wins, then the def's own layout, else banner); the legacy-only
|
|
202
|
+
* `custom` composition has no reader twin and paints the reader banner.
|
|
203
|
+
*/
|
|
204
|
+
export function envelopeCardHtml(
|
|
205
|
+
content: CertContent,
|
|
206
|
+
renderDef: CertChromeRenderDef | null,
|
|
207
|
+
options: EnvelopeCardOptions = {},
|
|
208
|
+
): string {
|
|
209
|
+
const input = envelopeCardInput(content, renderDef, options)
|
|
210
|
+
if (!input) return ''
|
|
211
|
+
if (!isReaderFaceDef(renderDef)) return renderCertBlock(input)
|
|
212
|
+
const chosen = layoutFor(renderDef, options.mode)
|
|
213
|
+
const layout: ReaderLayout = chosen === 'custom' ? 'banner' : chosen
|
|
214
|
+
return renderReaderFace({
|
|
215
|
+
content,
|
|
216
|
+
def: renderDef,
|
|
217
|
+
layout,
|
|
218
|
+
part: input.part,
|
|
219
|
+
certId: typeof options.certId === 'string' ? options.certId : undefined,
|
|
220
|
+
illustrative: options.illustrative === true,
|
|
221
|
+
})
|
|
222
|
+
}
|
package/src/builder/index.tsx
CHANGED
|
@@ -174,8 +174,11 @@ export {
|
|
|
174
174
|
CERT_FACE_FIELDS,
|
|
175
175
|
credentialLabel,
|
|
176
176
|
type EnvelopeCardOptions,
|
|
177
|
+
envelopeCardHtml,
|
|
177
178
|
envelopeCardInput,
|
|
178
179
|
faceFromDef,
|
|
180
|
+
isReaderFaceDef,
|
|
179
181
|
layoutFor,
|
|
182
|
+
READER_FACE,
|
|
180
183
|
themeFromDef,
|
|
181
184
|
} from './envelope-face.js'
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `certrev-reader-face`: the round avatar on a reader byline: the person's photo when there is one to show, the
|
|
3
|
+
* silhouette when there is not. The span carries a size class (`sm` for the author, none for the banner reviewer,
|
|
4
|
+
* `lg` for the memo and sidebar reviewer); the image is requested at `width` square through the asset resizer.
|
|
5
|
+
*/
|
|
6
|
+
import { avatarUrl, cleaned, esc, safeUrl } from './helpers.js'
|
|
7
|
+
|
|
8
|
+
export type ReaderFaceSize = '' | 'sm' | 'lg'
|
|
9
|
+
|
|
10
|
+
export interface ReaderFaceInput {
|
|
11
|
+
/** The photo URL on the envelope. */
|
|
12
|
+
readonly photo: unknown
|
|
13
|
+
/** Whether to ATTEMPT the photo: false never reads the URL (the silhouette shows). */
|
|
14
|
+
readonly show: boolean
|
|
15
|
+
readonly size: ReaderFaceSize
|
|
16
|
+
/** The pixel width the resizer is asked for. */
|
|
17
|
+
readonly width: number
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const SILHOUETTE =
|
|
21
|
+
'<svg viewBox="0 0 40 40" aria-hidden="true" focusable="false"><circle cx="20" cy="14.8" r="7"/><path d="M20 23.4c-6.9 0-12.6 4.8-13.8 11.2a20 20 0 0 0 27.6 0C32.6 28.2 26.9 23.4 20 23.4Z"/></svg>'
|
|
22
|
+
|
|
23
|
+
const DIMENSION: Readonly<Record<ReaderFaceSize, number>> = { '': 42, sm: 36, lg: 46 }
|
|
24
|
+
|
|
25
|
+
export function readerFace({ photo, show, size, width }: ReaderFaceInput): string {
|
|
26
|
+
const safe = show ? cleaned(safeUrl(photo)) : ''
|
|
27
|
+
const src = cleaned(avatarUrl(safe, width))
|
|
28
|
+
const dim = DIMENSION[size]
|
|
29
|
+
const cls = size === '' ? 'certrev-r-face' : `certrev-r-face ${esc(size)}`
|
|
30
|
+
const inner =
|
|
31
|
+
src !== ''
|
|
32
|
+
? `<img src="${esc(src)}" alt="" width="${dim}" height="${dim}" loading="lazy" decoding="async">`
|
|
33
|
+
: SILHOUETTE
|
|
34
|
+
return `<span class="${cls}">${inner}</span>`
|
|
35
|
+
}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Liquid semantics the reader snippets lean on, as small pure functions.
|
|
3
|
+
*
|
|
4
|
+
* The reader face is a byte-for-byte twin of the Shopify `certrev-reader-*` snippets, so the helpers below are not
|
|
5
|
+
* "what a TypeScript author would write": each one reproduces what the Liquid filter or tag does with the same input
|
|
6
|
+
* (which value counts as `blank`, which `default` replaces, how `contains` reads a string, what `strip_html` removes).
|
|
7
|
+
* Where the snippets call another snippet (`certrev-safe-url`, `certrev-avatar-url`, `certrev-reader-first-name`,
|
|
8
|
+
* `certrev-reader-date`) the port is named for it.
|
|
9
|
+
*
|
|
10
|
+
* Like every helper in this package they NEVER throw on a hostile type: the envelope is verified for its signature,
|
|
11
|
+
* not its shape, so a number or an object can arrive where the contract promised a string. Values are read through
|
|
12
|
+
* `rec` and `asText`, never dereferenced bare.
|
|
13
|
+
*/
|
|
14
|
+
import { asText, escapeHtml } from '../components/escape.js'
|
|
15
|
+
|
|
16
|
+
export type Rec = Readonly<Record<string, unknown>>
|
|
17
|
+
|
|
18
|
+
const NO_FIELDS: Rec = Object.freeze({})
|
|
19
|
+
|
|
20
|
+
/** An object's fields, or none: Liquid reads a missing field as nil, never an error. */
|
|
21
|
+
export function rec(value: unknown): Rec {
|
|
22
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value) ? (value as Rec) : NO_FIELDS
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** Liquid `escape` as Shopify (and this package) spell it: `& < > " '`. */
|
|
26
|
+
export const esc = (value: unknown): string => escapeHtml(asText(value))
|
|
27
|
+
|
|
28
|
+
/** Liquid `default: fallback`: replaces nil, false and the empty string only (whitespace stays). */
|
|
29
|
+
export function orDefault(value: unknown, fallback: string): unknown {
|
|
30
|
+
return value === undefined || value === null || value === false || value === '' ? fallback : value
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** `value | default: ''` read as text. */
|
|
34
|
+
export const textOr = (value: unknown, fallback = ''): string => asText(orDefault(value, fallback))
|
|
35
|
+
|
|
36
|
+
/** Liquid's `== blank` for the string-ish values the envelope carries: nil, false, empty or whitespace only. */
|
|
37
|
+
export const isBlank = (value: unknown): boolean => asText(value).trim() === ''
|
|
38
|
+
|
|
39
|
+
/** `{% if x %}` for a value read as a flag: Liquid treats only nil and false as false (the empty string is true). */
|
|
40
|
+
export const isTruthy = (value: unknown): boolean => value !== undefined && value !== null && value !== false
|
|
41
|
+
|
|
42
|
+
/** Whether a field carries a value after `| default: ''` (so `!= ''` in the snippet). */
|
|
43
|
+
export const isPresent = (value: unknown): boolean =>
|
|
44
|
+
!(value === undefined || value === null || value === false || value === '')
|
|
45
|
+
|
|
46
|
+
/** Liquid `contains`: an array holds the needle, a string includes it, anything else does not. */
|
|
47
|
+
export function contains(container: unknown, needle: string): boolean {
|
|
48
|
+
if (Array.isArray(container)) return container.some((item) => item === needle)
|
|
49
|
+
if (typeof container === 'string') return container.includes(needle)
|
|
50
|
+
return false
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Liquid `strip_html` as the portal's liquidjs harness runs it: raw-text blocks (`<script…</script>`, `<style…</style>`,
|
|
55
|
+
* `<!-- … -->`) and then any `<…>` tag are dropped; an opener with no closer is not a block, and once no opener fits
|
|
56
|
+
* the rest of the string is kept as it is. The snippets use it on every captured value because Shopify wraps each
|
|
57
|
+
* `{% render %}` of an app snippet in `<!-- BEGIN/END app snippet -->` comments that would corrupt an attribute.
|
|
58
|
+
*/
|
|
59
|
+
export function stripHtml(input: string): string {
|
|
60
|
+
const blocks = new Map<string, string>([
|
|
61
|
+
['<script', '</script>'],
|
|
62
|
+
['<style', '</style>'],
|
|
63
|
+
['<!--', '-->'],
|
|
64
|
+
['<', '>'],
|
|
65
|
+
])
|
|
66
|
+
let out = ''
|
|
67
|
+
let i = 0
|
|
68
|
+
while (i < input.length) {
|
|
69
|
+
const lt = input.indexOf('<', i)
|
|
70
|
+
if (lt < 0) return out + input.slice(i)
|
|
71
|
+
out += input.slice(i, lt)
|
|
72
|
+
for (const [opener, closer] of blocks) {
|
|
73
|
+
if (!input.startsWith(opener, lt)) continue
|
|
74
|
+
const end = input.indexOf(closer, lt + opener.length)
|
|
75
|
+
if (end >= 0) {
|
|
76
|
+
i = end + closer.length
|
|
77
|
+
break
|
|
78
|
+
}
|
|
79
|
+
blocks.delete(opener)
|
|
80
|
+
}
|
|
81
|
+
if (i <= lt) return out + input.slice(lt)
|
|
82
|
+
}
|
|
83
|
+
return out
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** `{% capture x %}…{% endcapture %}` then `x | strip_html | strip`, which every snippet applies to a captured value. */
|
|
87
|
+
export const cleaned = (value: string): string => stripHtml(value).trim()
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* `certrev-safe-url`: the trimmed URL when it is http(s), protocol-relative or site-relative (`/…`, `#…`), else ''.
|
|
91
|
+
* A `javascript:`, `data:` or other scheme collapses to '' so the caller's `!= ''` guard drops the link or the photo.
|
|
92
|
+
*/
|
|
93
|
+
export function safeUrl(url: unknown): string {
|
|
94
|
+
const u = textOr(url).trim()
|
|
95
|
+
if (u === '') return ''
|
|
96
|
+
const lower = u.toLowerCase()
|
|
97
|
+
if (
|
|
98
|
+
lower.startsWith('https://') ||
|
|
99
|
+
lower.startsWith('http://') ||
|
|
100
|
+
u.startsWith('//') ||
|
|
101
|
+
u.startsWith('/') ||
|
|
102
|
+
u.startsWith('#')
|
|
103
|
+
)
|
|
104
|
+
return u
|
|
105
|
+
return ''
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const ASSET_HOSTS: readonly string[] = ['assets.certrev.com', 'staging-assets.certrev.com']
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* `certrev-avatar-url`: a CertREV asset-host photo is requested through the host's `cdn-cgi/image` resizer at
|
|
112
|
+
* `width` square (the query string dropped, which the WAF allowlist pins to empty); any other URL, a lookalike host,
|
|
113
|
+
* an `http://` or `//` form, or a URL already carrying `cdn-cgi/image/`, is returned as it is.
|
|
114
|
+
*/
|
|
115
|
+
export function avatarUrl(url: string, width: number): string {
|
|
116
|
+
const u = url.trim()
|
|
117
|
+
if (!u.includes('assets.certrev.com/')) return u
|
|
118
|
+
const after = u.replace('https://', '')
|
|
119
|
+
const host = after.split('/')[0] ?? ''
|
|
120
|
+
if (!ASSET_HOSTS.includes(host)) return u
|
|
121
|
+
const path = after.replace(host, '').replace('/', '').split('?')[0] ?? ''
|
|
122
|
+
if (path.includes('cdn-cgi/image/')) return u
|
|
123
|
+
return `https://${host}/cdn-cgi/image/width=${width},height=${width},fit=cover,format=auto,onerror=redirect/${path}`
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const HONORIFICS: readonly string[] = [
|
|
127
|
+
'dr.',
|
|
128
|
+
'dr',
|
|
129
|
+
'mr.',
|
|
130
|
+
'mr',
|
|
131
|
+
'mrs.',
|
|
132
|
+
'mrs',
|
|
133
|
+
'ms.',
|
|
134
|
+
'ms',
|
|
135
|
+
'prof.',
|
|
136
|
+
'prof',
|
|
137
|
+
'mx.',
|
|
138
|
+
'mx',
|
|
139
|
+
]
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* `certrev-reader-first-name`: the name's first word with a leading honorific (Dr., Mr., Mrs., Ms., Prof., Mx.,
|
|
143
|
+
* any case) dropped; '' when nothing is left, which the caller words as "View profile".
|
|
144
|
+
*/
|
|
145
|
+
export function firstName(name: string): string {
|
|
146
|
+
let clean = name.trim()
|
|
147
|
+
const firstWord = (clean.split(' ')[0] ?? '').toLowerCase()
|
|
148
|
+
if (HONORIFICS.includes(firstWord)) {
|
|
149
|
+
const honorific = clean.split(' ')[0] ?? ''
|
|
150
|
+
clean = clean.replace(honorific, '').trim()
|
|
151
|
+
}
|
|
152
|
+
return clean.split(' ')[0] ?? ''
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const MONTHS: readonly string[] = [
|
|
156
|
+
'January',
|
|
157
|
+
'February',
|
|
158
|
+
'March',
|
|
159
|
+
'April',
|
|
160
|
+
'May',
|
|
161
|
+
'June',
|
|
162
|
+
'July',
|
|
163
|
+
'August',
|
|
164
|
+
'September',
|
|
165
|
+
'October',
|
|
166
|
+
'November',
|
|
167
|
+
'December',
|
|
168
|
+
]
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* `certrev-reader-date`: "June 20, 2026" for an ISO timestamp, read in UTC (the portal harness's `date` filter does
|
|
172
|
+
* the same). A value that is not a date prints nothing, so the caller's `!= ''` guard falls to the undated wording.
|
|
173
|
+
*/
|
|
174
|
+
export function longDate(iso: unknown): string {
|
|
175
|
+
const parsed = new Date(asText(iso))
|
|
176
|
+
if (Number.isNaN(parsed.getTime())) return ''
|
|
177
|
+
return `${MONTHS[parsed.getUTCMonth()]} ${parsed.getUTCDate()}, ${parsed.getUTCFullYear()}`
|
|
178
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The reader face, react-free: `@certrev/cert-block/reader`.
|
|
3
|
+
*
|
|
4
|
+
* Importing this loads no React, so a server bundle that cannot load `./builder` (it creates a React context at import)
|
|
5
|
+
* can still render, and a stylesheet pipeline can still read the CSS. The Builder card reaches the same function
|
|
6
|
+
* through `envelopeCardHtml` (`./builder/face`); the stylesheet is also the package asset `./reader.css`.
|
|
7
|
+
*/
|
|
8
|
+
export { READER_CSS } from './reader-css.generated.js'
|
|
9
|
+
export {
|
|
10
|
+
type ReaderFaceInput,
|
|
11
|
+
type ReaderLayout,
|
|
12
|
+
type ReaderPart,
|
|
13
|
+
renderReaderFace,
|
|
14
|
+
} from './render.js'
|