Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: implement renderer 2024 provider #177

Merged
merged 47 commits into from
Jun 13, 2024
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
61ed51f
feat: add compute hash utils
ldhyen99 Apr 26, 2024
034f537
feat: add prefix in compute hash function
ldhyen99 May 2, 2024
ca1e3f4
feat: create plugin that contain hash
ldhyen99 May 3, 2024
14fc4b8
test: add unit test for compute hash
ldhyen99 May 3, 2024
a49ee9c
feat: implement renderer 2024 provider
ducpm511 May 3, 2024
f02873d
feat: add plugin to agent.yml
ldhyen99 May 3, 2024
b572e1d
refactor: delete compute hash function in tools package
ldhyen99 May 3, 2024
fdac6c1
chore: update ts config file
ldhyen99 May 3, 2024
ec3746f
Merge branch 'feat/add_compute_hash_utils' into renderer2024
ducpm511 May 6, 2024
9a033de
feat: implement new UI for renderer on demo explorer
ducpm511 May 7, 2024
713e011
Merge branch 'next' into renderer2024
ducpm511 May 7, 2024
5afd5ab
feat: updated unit tests
ducpm511 May 7, 2024
caef6c5
feat: handled error
ducpm511 May 7, 2024
4001ef1
Merge branch 'next' into renderer2024
ducpm511 May 14, 2024
d3581cc
feat: updated according to feedback
ducpm511 May 14, 2024
2f05cca
feat: updated renderer to be able to use extractRendererMethod function
ducpm511 May 14, 2024
85b33a0
refactor: clean up renderer
ducpm511 May 17, 2024
7b4ac12
Merge branch 'next' into renderer2024
ducpm511 May 17, 2024
65b9a24
refactor: adding missing template
ducpm511 May 17, 2024
c55545e
Merge branch 'next' into renderer2024
ducpm511 May 17, 2024
fec182d
refactor: renamed provider name; replace context url
ducpm511 May 17, 2024
8891f63
Merge branch 'next' into renderer2024
ducpm511 May 17, 2024
edcfcc0
refactor: updated provider according to computeHash function changes
ducpm511 May 17, 2024
2e6ec77
refactor: implement to support mediaQuery and refactor code
ducpm511 May 21, 2024
360f777
refactor: enhance the performance by set documentLoader
namhoang1604 May 21, 2024
ac6094c
refactor: updated response type and rename test file
ducpm511 May 21, 2024
e3e78cc
refactor: updated default contexts for renderer
ducpm511 May 21, 2024
ac71f0b
fix: display rendered template on UI and return renderedTemplate fiel…
ldhyen99 May 24, 2024
607a359
refactor: update render template 2024
ducpm511 May 29, 2024
78445c2
feat: update demo-explorer to support render template 2024
ducpm511 Jun 4, 2024
e035b72
Merge branch 'next' into renderer2024
ducpm511 Jun 4, 2024
ab74283
chore: updated unit test corresponding to changes of render provider
ducpm511 Jun 6, 2024
d3bcc29
chore: fix renderer to address unit test
ducpm511 Jun 6, 2024
2080de3
Merge branch 'next' into renderer2024
ducpm511 Jun 6, 2024
ebca386
Merge branch 'next' into renderer2024
ducpm511 Jun 7, 2024
cce6eb6
chore: added more test case to increase the coverage
ducpm511 Jun 7, 2024
1d602ad
chore: added more unit test cases
ducpm511 Jun 7, 2024
5fbca74
Merge branch 'next' into renderer2024
ducpm511 Jun 7, 2024
46f7bcf
chore: reduced uncovered count for statement
ducpm511 Jun 10, 2024
c370dea
Merge branch 'next' into renderer2024
namhoang1604 Jun 12, 2024
a65aae1
chore: removed duplicate test case
ducpm511 Jun 12, 2024
d4e31b1
refactor: use the inline template if failed to fetch it from url.
ducpm511 Jun 12, 2024
75c4d42
fix: removed duplicate test case and implement mock fetch to simulate…
ducpm511 Jun 12, 2024
aa46d60
fix: wrong expected result
ducpm511 Jun 13, 2024
50c45c4
chore: removed meanless comment
ducpm511 Jun 13, 2024
ed4ec10
refactor: enhance the render template 2024
namhoang1604 Jun 13, 2024
25ff963
test: adjust to update the unit test of renderer plugin
namhoang1604 Jun 13, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion packages/core-types/src/plugin.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -6183,12 +6183,36 @@
"documents": {
"type": "array",
"items": {
"type": "string"
"$ref": "#/components/schemas/IRenderDocument"
}
}
},
"required": [
"documents"
]
},
"IRenderDocument": {
"type": "object",
"properties": {
"type": {
"type": "string"
},
"renderedTemplate": {
"type": "string"
},
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"mediaType": {
"type": "string"
}
},
"required": [
"type",
"renderedTemplate"
],
"description": "Result of rendering a verifiable credential."
}
Expand Down
10 changes: 9 additions & 1 deletion packages/core-types/src/types/IRender.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,16 @@ export type IRendererContext = IAgentContext<
* Result of rendering a verifiable credential.
* @beta
*/
export interface IRenderDocument{
type: string;
renderedTemplate: string;
id: string | undefined;
name: string | undefined;
mediaType: string | undefined;

}
export interface IRenderResult {
documents: string[];
documents: IRenderDocument[];
}

/**
Expand Down
19 changes: 18 additions & 1 deletion packages/core-types/src/types/IRendererProvider.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { IRendererContext } from "./IRender";

/**
* The document to render.
* @public
Expand All @@ -15,7 +17,22 @@ export interface IRendererProvider {
* Render a verifiable credential using the specified render methods.
* @param template - The template to render.
* @param document - The document to render.
* @param url - The url to the svg template to render.
* @param digestMultibase - The digest multibase of the svg template to verify.
* @returns A promise that resolves to the rendered document.
*/
renderCredential(template: string, document: RenderDocument): Promise<string>;
renderCredential({
template,
document,
url,
digestMultibase,
context,
}: {
template?: string;
document?: RenderDocument;
url?: string;
digestMultibase?: string;
context?: IRendererContext;
}): Promise<string>;
}

78 changes: 50 additions & 28 deletions packages/demo-explorer/src/components/CredentialRender.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import { ProCard } from '@ant-design/pro-components'
import { QrCodeDocumentWrapper } from '@vckit/react-components'
import { Renderer, WebRenderingTemplate2022 } from '@vckit/renderer'
import {
Renderer,
WebRenderingTemplate2022,
WebRenderingTemplate2024,
} from '@vckit/renderer'
import { useVeramo } from '@veramo-community/veramo-react'
import { VerifiableCredential } from '@veramo/core'
import { Button, Spin } from 'antd'
import { Button, Spin, Tabs } from 'antd'
import html2canvas from 'html2canvas'
import { CSSProperties, useCallback, useEffect, useState } from 'react'
import { useQuery } from 'react-query'
Expand All @@ -28,12 +32,20 @@ interface CredentialRenderProps {
hash: string
}

interface IRenderDocument{
type: string;
renderedTemplate: string;
id: string | undefined;
name: string | undefined;
mediaType: string | undefined;

}
const CredentialRender: React.FC<CredentialRenderProps> = ({
credential,
hash,
}) => {
const { agent } = useVeramo()
const [documents, setDocuments] = useState<string[]>([])
const [documents, setDocuments] = useState<IRenderDocument[]>([])
const [qrCodeValue, setQrCodeValue] = useState<string>('')
const [isLoading, setIsLoading] = useState<boolean>(false)
const encryptedEndpoint = process.env.REACT_APP_ENCRYPTED_ENDPOINT
Expand All @@ -60,15 +72,21 @@ const CredentialRender: React.FC<CredentialRenderProps> = ({
const renderer = new Renderer({
providers: {
WebRenderingTemplate2022: new WebRenderingTemplate2022(),
WebRenderingTemplate2024: new WebRenderingTemplate2024(),
},
defaultProvider: 'WebRenderingTemplate2022',
})

let { documents }: { documents: string[] } =
let { documents }: { documents: IRenderDocument[] } =
await renderer.renderCredential({
credential,
})
documents = documents.map((doc) => convertBase64ToString(doc))
documents = documents.map((doc) => {
return {
...doc,
renderedTemplate: convertBase64ToString(doc.renderedTemplate),
}
})
setDocuments(documents)
} catch (e) {}
setIsLoading(false)
Expand Down Expand Up @@ -113,29 +131,33 @@ const CredentialRender: React.FC<CredentialRenderProps> = ({

return (
<Spin tip="Loading..." spinning={isLoading || credentialLoading}>
<ProCard
style={proCardStyle}
title={<IdentifierProfile did={getIssuerDID(credential)} />}
>
<div id="render">
<QrCodeDocumentWrapper qrCodeValue={qrCodeValue}>
{!isLoading && !credentialLoading ? (
documents.length !== 0 ? (
documents.map((doc, i) => (
<div key={i} dangerouslySetInnerHTML={{ __html: doc }}></div>
))
) : (
<pre style={jsonStyle}>
{JSON.stringify(credential, null, 2)}
</pre>
)
) : (
<></>
)}
</QrCodeDocumentWrapper>
</div>
<Button onClick={printdiv}>Print</Button>
</ProCard>
{!isLoading && !credentialLoading ? (
documents.length !== 0 ? (
<Tabs
items={documents.map((doc, i) => ({
key: i.toString(),
label: `${doc.type}`,
children: (
<ProCard
style={proCardStyle}
title={<IdentifierProfile did={getIssuerDID(credential)} />}
>
<QrCodeDocumentWrapper qrCodeValue={qrCodeValue}>
<div
key={i}
dangerouslySetInnerHTML={{ __html: doc.renderedTemplate }}
></div>
</QrCodeDocumentWrapper>
</ProCard>
),
}))}
/>
) : (
<pre style={jsonStyle}>{JSON.stringify(credential, null, 2)}</pre>
)
) : (
<></>
)}
</Spin>
)
}
Expand Down
8 changes: 7 additions & 1 deletion packages/renderer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,13 @@ To implement a new render provider, follow these steps:

2. Save the provider file in the `packages/renderer/src/providers` folder, using a name that corresponds to the render type. For example, if you want to implement a provider for `WebRenderingTemplate2022`, name the provider file as `web-rendering-template-2022.ts`.

3. Add the provider to the agent.yml file, as shown in the following example:
3. Delete `tsconfig.tsbuildinfo` and run build the plugin by running this command
```bash
pnpm build
```
To test it locally, you need to restart your vckit server.

4. Add the provider to the agent.yml file, as shown in the following example:

```yaml
renderer:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ describe('WebRenderingTemplate2022', () => {
const template = '<p>{{name}}</p>';
const document = { name: 'John Doe' };

const renderedContent = await renderer.renderCredential(
const renderedContent = await renderer.renderCredential({
template,
document
);
document,
});

expect(renderedContent).toBe('<p>John Doe</p>');
});
Expand All @@ -24,10 +24,10 @@ describe('WebRenderingTemplate2022', () => {
const template = '';
const document = { name: 'John Doe' };

const renderedContent = await renderer.renderCredential(
const renderedContent = await renderer.renderCredential({
template,
document
);
document,
});

expect(renderedContent).toBe('');
});
Expand All @@ -36,10 +36,10 @@ describe('WebRenderingTemplate2022', () => {
const template = 'Some random text';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove if it does not use

const document = { name: 'John Doe' };

const renderedContent = await renderer.renderCredential(
const renderedContent = await renderer.renderCredential({
template,
document
);
document,
});

expect(renderedContent).toBe(template);
});
Expand All @@ -48,10 +48,10 @@ describe('WebRenderingTemplate2022', () => {
const template = ' \t\n ';
const document = { name: 'John Doe' };

const renderedContent = await renderer.renderCredential(
const renderedContent = await renderer.renderCredential({
template,
document
);
document,
});

expect(renderedContent).toBe('');
});
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { WebRenderingTemplate2024 } from '/Users/ducpm/GoSource/projects/project_vckit/project-vckit/packages/renderer/src/providers/web-rendering-template-2024';

describe('WebRenderingTemplate2024', () => {
let renderer: WebRenderingTemplate2024;

beforeEach(() => {
renderer = new WebRenderingTemplate2024();
});

it('should return an p tag with error message if the template is not provided', async () => {
const result = await renderer.renderCredential({});

expect(result).toBe(
'<p style="color: red">Error: Failed to fetch template or no template provided</p>',
);
});

it('should render the template with the credential data', async () => {
const template = '<p>{{name}}</p>';
const document = { name: 'John Doe' };

const renderedContent = await renderer.renderCredential({
template,
document,
});

expect(renderedContent).toBe('<p>John Doe</p>');
});

it('should return an p tag with error message if the template and the digestMultibase are not the same', async () => {
const template = '<p>{{name}}</p>';
const document = { name: 'John Doe' };
const digestMultibase = '123';
const result = await renderer.renderCredential({
template,
document,
digestMultibase,
});

expect(result).toBe(
'<p style="color: red">Error: Template hash does not match the provided digest</p>',
);
});

// Add more tests here for different scenarios
});
2 changes: 1 addition & 1 deletion packages/renderer/__tests__/renderer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import universityDegreeCredential from '../fixtures/university-degree-credential
describe('Renderer', () => {
// Mock renderer provider
const MockWebRenderingTemplate2022: IRendererProvider = {
async renderCredential(template: string, document: any): Promise<string> {
async renderCredential({template: string, document: any}): Promise<string> {
// Mock implementation
return 'Rendered credential successfully';
},
Expand Down
3 changes: 2 additions & 1 deletion packages/renderer/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Renderer } from './renderer.js';
import { WebRenderingTemplate2022 } from './providers/web-rendering-template-2022.js';
import { WebRenderingTemplate2024 } from './providers/web-rendering-template-2024.js';

export { Renderer, WebRenderingTemplate2022 };
export { Renderer, WebRenderingTemplate2022, WebRenderingTemplate2024 };
export { RenderDefaultContexts } from './render-default-contexts.js';
12 changes: 8 additions & 4 deletions packages/renderer/src/providers/web-rendering-template-2022.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,18 @@ import handlebars from 'handlebars';
*/
export class WebRenderingTemplate2022 implements IRendererProvider {
async renderCredential(
template: string,
document: RenderDocument
{
template,
document,
}: {
template?: string;
document?: RenderDocument;
}
): Promise<string> {
// Check if the template is empty or contains only whitespace
if (!template.trim()) {
if (!template?.trim()) {
return '';
}

const compiledTemplate = handlebars.compile(template);

// Render the template with the document data
Expand Down
Loading