Skip to content

Commit

Permalink
Merge pull request #14 from docknetwork/feat/liquid
Browse files Browse the repository at this point in the history
Support liquid embedded templates
  • Loading branch information
cykoder authored Jul 8, 2022
2 parents f69c650 + 5dea36c commit f3d61b7
Show file tree
Hide file tree
Showing 6 changed files with 259 additions and 8 deletions.
11 changes: 10 additions & 1 deletion demo/pages/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export default function Home() {
const [renderSize, setRenderSize] = useState(16);
const [selectedTemplate, setTemplate] = useState();
const [vcData, setVCData] = useState({});
const vcHTML = renderVCHTML(vcData);
const [vcHTML, setVCHTML] = useState('');
const templateKeys = Object.keys(vcTemplates);

async function generateQRImage(credential) {
Expand Down Expand Up @@ -105,10 +105,19 @@ export default function Home() {
document.body.removeChild(link);
}

async function onUpdateData() {
const html = await renderVCHTML(vcData);
setVCHTML(html);
}

useEffect(() => {
onUpdateJSON();
}, [json, selectedTemplate]);

useEffect(() => {
onUpdateData();
}, [vcData]);

return (
<div className={styles.columnWrapper}>
<div className={styles.controls}>
Expand Down
105 changes: 104 additions & 1 deletion demo/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,12 @@
to-fast-properties "^2.0.0"

"@docknetwork/prettyvc@file:..":
version "1.2.0"
version "1.2.3"
dependencies:
identicon.js "^2.3.3"
jssha "^3.2.0"
liquidjs "^9.38.0"
sanitize-html "^2.7.0"

"@eslint/eslintrc@^0.4.3":
version "0.4.3"
Expand Down Expand Up @@ -888,6 +890,11 @@ deep-is@^0.1.3:
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"
integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==

deepmerge@^4.2.2:
version "4.2.2"
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955"
integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==

define-properties@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1"
Expand Down Expand Up @@ -948,11 +955,41 @@ dom-align@^1.7.0:
resolved "https://registry.yarnpkg.com/dom-align/-/dom-align-1.12.2.tgz#0f8164ebd0c9c21b0c790310493cd855892acd4b"
integrity sha512-pHuazgqrsTFrGU2WLDdXxCFabkdQDx72ddkraZNih1KsMcN5qsRSTR9O4VJRlwTPCPb5COYg3LOfiMHHcPInHg==

dom-serializer@^1.0.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.4.1.tgz#de5d41b1aea290215dc45a6dae8adcf1d32e2d30"
integrity sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==
dependencies:
domelementtype "^2.0.1"
domhandler "^4.2.0"
entities "^2.0.0"

[email protected]:
version "4.19.0"
resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-4.19.0.tgz#1093e17c0a17dbd521182fe90d49ac1370054af1"
integrity sha512-fRA+BaAWOR/yr/t7T9E9GJztHPeFjj8U35ajyAjCDtAAnTn1Rc1f6W6VGPJrO1tkQv9zWu+JRof7z6oQtiYVFQ==

domelementtype@^2.0.1, domelementtype@^2.2.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d"
integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==

domhandler@^4.0.0, domhandler@^4.2.0:
version "4.3.1"
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.1.tgz#8d792033416f59d68bc03a5aa7b018c1ca89279c"
integrity sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==
dependencies:
domelementtype "^2.2.0"

domutils@^2.5.2:
version "2.8.0"
resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135"
integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==
dependencies:
dom-serializer "^1.0.1"
domelementtype "^2.2.0"
domhandler "^4.2.0"

electron-to-chromium@^1.3.723:
version "1.3.894"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.894.tgz#54554ecb40d40ddac7241c4a42887e86180015d8"
Expand Down Expand Up @@ -1005,6 +1042,11 @@ enquirer@^2.3.5:
dependencies:
ansi-colors "^4.1.1"

entities@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55"
integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==

es-abstract@^1.18.5, es-abstract@^1.19.0, es-abstract@^1.19.1:
version "1.19.1"
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.19.1.tgz#d4885796876916959de78edaa0df456627115ec3"
Expand Down Expand Up @@ -1575,6 +1617,16 @@ html-to-image@^1.9.0:
resolved "https://registry.yarnpkg.com/html-to-image/-/html-to-image-1.9.0.tgz#cb49bf9f4b37376771c85cfdd65863ae9420b268"
integrity sha512-9gaDCIYg62Ek07F2pBk76AHgYZ2gxq2YALU7rK3gNCqXuhu6cWzsOQqM7qGbjZiOzxGzrU1deDqZpAod2NEwbA==

htmlparser2@^6.0.0:
version "6.1.0"
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.1.0.tgz#c4d762b6c3371a05dbe65e94ae43a9f845fb8fb7"
integrity sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==
dependencies:
domelementtype "^2.0.1"
domhandler "^4.0.0"
domutils "^2.5.2"
entities "^2.0.0"

[email protected]:
version "1.7.3"
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06"
Expand Down Expand Up @@ -1765,6 +1817,11 @@ is-number@^7.0.0:
resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==

is-plain-object@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344"
integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==

is-regex@^1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958"
Expand Down Expand Up @@ -1927,6 +1984,11 @@ levn@^0.4.1:
prelude-ls "^1.2.1"
type-check "~0.4.0"

liquidjs@^9.38.0:
version "9.38.0"
resolved "https://registry.yarnpkg.com/liquidjs/-/liquidjs-9.38.0.tgz#0fb4d380007ecde00d8c43c5fd5535d6189b7778"
integrity sha512-LDGPbOfc8L9LG7ZSG0NueTcCe0AZzJAIa0BjYgMnCR+4VO0yS+AnOZjx0WOih8mtLRNSIYo9fik5exY6Cf4TOQ==

[email protected]:
version "1.2.3"
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.2.3.tgz#1ff5dc6911c9f0a062531a4c04b609406108c2c7"
Expand Down Expand Up @@ -2074,6 +2136,11 @@ nanoid@^3.1.23:
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.30.tgz#63f93cc548d2a113dc5dfbc63bfa09e2b9b64362"
integrity sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ==

nanoid@^3.3.4:
version "3.3.4"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab"
integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==

natural-compare@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
Expand Down Expand Up @@ -2328,6 +2395,11 @@ parse-asn1@^5.0.0, parse-asn1@^5.1.5:
pbkdf2 "^3.0.3"
safe-buffer "^5.1.1"

parse-srcset@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/parse-srcset/-/parse-srcset-1.0.2.tgz#f2bd221f6cc970a938d88556abc589caaaa2bde1"
integrity sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q==

[email protected]:
version "1.0.1"
resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd"
Expand Down Expand Up @@ -2374,6 +2446,11 @@ pbkdf2@^3.0.3:
safe-buffer "^5.0.1"
sha.js "^2.4.8"

picocolors@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==

picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3:
version "2.3.0"
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972"
Expand Down Expand Up @@ -2417,6 +2494,15 @@ [email protected]:
nanoid "^3.1.23"
source-map "^0.6.1"

postcss@^8.3.11:
version "8.4.14"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.14.tgz#ee9274d5622b4858c1007a74d76e42e56fd21caf"
integrity sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==
dependencies:
nanoid "^3.3.4"
picocolors "^1.0.0"
source-map-js "^1.0.2"

prelude-ls@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
Expand Down Expand Up @@ -2724,6 +2810,18 @@ safe-buffer@~5.1.1:
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==

sanitize-html@^2.7.0:
version "2.7.0"
resolved "https://registry.yarnpkg.com/sanitize-html/-/sanitize-html-2.7.0.tgz#e106205b468aca932e2f9baf241f24660d34e279"
integrity sha512-jfQelabOn5voO7FAfnQF7v+jsA6z9zC/O4ec0z3E35XPEtHYJT/OdUziVWlKW4irCr2kXaQAyXTXDHWAibg1tA==
dependencies:
deepmerge "^4.2.2"
escape-string-regexp "^4.0.0"
htmlparser2 "^6.0.0"
is-plain-object "^5.0.0"
parse-srcset "^1.0.2"
postcss "^8.3.11"

scheduler@^0.20.2:
version "0.20.2"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91"
Expand Down Expand Up @@ -2812,6 +2910,11 @@ slice-ansi@^4.0.0:
astral-regex "^2.0.0"
is-fullwidth-code-point "^3.0.0"

source-map-js@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c"
integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==

[email protected]:
version "0.7.3"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383"
Expand Down
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@docknetwork/prettyvc",
"description": "Render pretty verifiable credentials",
"version": "1.2.3",
"version": "1.3.3",
"main": "lib/index.js",
"license": "MIT",
"repository": {
Expand Down Expand Up @@ -34,7 +34,9 @@
"author": "Sam Hellawell",
"dependencies": {
"identicon.js": "^2.3.3",
"jssha": "^3.2.0"
"jssha": "^3.2.0",
"liquidjs": "^9.38.0",
"sanitize-html": "^2.7.0"
},
"devDependencies": {
"@babel/cli": "^7.8.4",
Expand Down
36 changes: 33 additions & 3 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
import Identicon from 'identicon.js'; // THINK: should this be a peer dep or user supplied method to generate?
import { Liquid } from 'liquidjs';
import sanitizeHtml from 'sanitize-html';
import jsSHA from 'jssha';

import templates from './templates';

const liquidEngine = new Liquid();

const typeToTemplateMap = {
UniversityDegreeCredential: 'diploma',
HackathonCredential: 'hackathon',
};

export const cleanHTML = (html) => sanitizeHtml(html, {
allowedAttributes: {
'*': ['style'],
a: ['href', 'name', 'target'],
img: ['src', 'srcset', 'alt', 'title', 'width', 'height', 'loading'],
},
});

function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
Expand Down Expand Up @@ -249,6 +261,8 @@ export async function getVCData(credential, options = {}) {
const subjects = Array.isArray(credential.credentialSubject) ? credential.credentialSubject : [credential.credentialSubject];

return {
...credential,

humanizedType,
title,
subjectName,
Expand All @@ -261,7 +275,6 @@ export async function getVCData(credential, options = {}) {
qrImage,
attributes,
subjects,
issuer: credential.issuer,

// Dates
issuanceDate,
Expand All @@ -271,7 +284,24 @@ export async function getVCData(credential, options = {}) {
};
}

export function renderVCHTML(data, options = {}) {
async function renderLiquidTemplate(templateContents, data) {
const tpl = liquidEngine.parse(templateContents);
const result = await liquidEngine.render(tpl, data);
return cleanHTML(result);
}

export async function renderVCHTML(data, options = {}) {
if (data.prettyVC) {
const { type, proof } = data.prettyVC;
if (type === 'liquid') {
return {
html: await renderLiquidTemplate(proof, data),
orientation: 'landscape', // TODO: could we set this based on the type or remove it?
templateId: type,
};
}
}

const templateId = data.template || 'card';
const customTemplates = options.templates || {};
const templateFn = customTemplates[templateId] || templates[templateId];
Expand All @@ -285,5 +315,5 @@ export function renderVCHTML(data, options = {}) {

export async function getVCHTML(credential, options) {
const data = await getVCData(credential, options);
return renderVCHTML(data, options);
return await renderVCHTML(data, options);
}
13 changes: 12 additions & 1 deletion tests/index.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { guessCredentialTemplate } from '../src/index';
import { guessCredentialTemplate, renderVCHTML } from '../src/index';

describe('Index', () => {
test('guessCredentialTemplate baseline', async () => {
Expand All @@ -24,4 +24,15 @@ describe('Index', () => {
expect(template).toEqual('debugtemplate');
});

test('renderVCHTML renders liquid template', async () => {
const { html } = await renderVCHTML({
credentialSubject: { name: 'test' },
prettyVC: {
type: 'liquid',
proof: '<div style="display:flex">{{credentialSubject.name}}</div>'
}
});
expect(html).toEqual('<div style="display:flex">test</div>');
});
});

Loading

0 comments on commit f3d61b7

Please sign in to comment.