Skip to content

Commit

Permalink
feat: oca package (openwallet-foundation#720)
Browse files Browse the repository at this point in the history
Signed-off-by: James Ebert <[email protected]>
Signed-off-by: Akiff Manji <[email protected]>
Signed-off-by: ryankoch13 <[email protected]>
Signed-off-by: KolbyRKunz <[email protected]>
Signed-off-by: Akiff Manji <[email protected]>
Signed-off-by: Jason C. Leach <[email protected]>
Signed-off-by: Mostafa <[email protected]>
Co-authored-by: James Ebert <[email protected]>
Co-authored-by: ryankoch13 <[email protected]>
Co-authored-by: KolbyRKunz <[email protected]>
Co-authored-by: Jason C. Leach <[email protected]>
  • Loading branch information
5 people authored May 23, 2023
1 parent 73eb360 commit ed03584
Show file tree
Hide file tree
Showing 44 changed files with 1,207 additions and 42 deletions.
22 changes: 22 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/typescript-node
{
"name": "Node.js & TypeScript",
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
"image": "mcr.microsoft.com/devcontainers/typescript-node:0-16"

// Features to add to the dev container. More info: https://containers.dev/features.
// "features": {},

// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],

// Use 'postCreateCommand' to run commands after the container is created.
// "postCreateCommand": "yarn install",

// Configure tool-specific properties.
// "customizations": {},

// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "root"
}
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -175,4 +175,4 @@ app/ios/Pods/*
lib/
app/android/app/src/main/assets/app.bundle
**/.yarn/cache
.yarn/install-state.gz
**/.yarn/install-state.gz
19 changes: 19 additions & 0 deletions packages/oca/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
module.exports = {
env: {
browser: true,
es2021: true,
node: true,
},
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'],
overrides: [],
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
},
plugins: ['@typescript-eslint'],
rules: {
'@typescript-eslint/ban-ts-comment': 'warn',
'@typescript-eslint/explicit-member-accessibility': 'off',
},
}
44 changes: 23 additions & 21 deletions packages/oca/package.json
Original file line number Diff line number Diff line change
@@ -1,31 +1,33 @@
{
"name": "@aries-bifold/oca",
"main": "build/index",
"types": "build/index",
"version": "0.0.1-alpha.1365+bc01e09f",
"files": [
"build"
],
"license": "Apache-2.0",
"publishConfig": {
"access": "public"
},
"homepage": "https://github.com/hyperledger/aries-mobile-agent-react-native/tree/main/packages/oca",
"repository": {
"type": "git",
"url": "https://github.com/hyperledger/aries-mobile-agent-react-native",
"directory": "packages/oca"
},
"version": "1.0.0-alpha.0",
"description": "",
"main": "build/index.js",
"types": "build/index.d.ts",
"scripts": {
"build": "yarn run clean && yarn run compile",
"clean": "rimraf ./build",
"compile": "tsc -p tsconfig.build.json",
"compile": "tsc",
"prepublishOnly": "yarn run build",
"test": "jest"
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": "git+https://github.com/hyperledger/aries-mobile-agent-react-native.git",
"license": "Apache-2.0",
"bugs": {
"url": "https://github.com/hyperledger/aries-mobile-agent-react-native/issues"
},
"homepage": "https://github.com/hyperledger/aries-mobile-agent-react-native#readme",
"devDependencies": {
"@types/ws": "^7.4.6",
"typescript": "~4.9.4"
"@typescript-eslint/parser": "^4.33.0",
"eslint": "^7.14.0",
"eslint-import-resolver-typescript": "^2.5.0",
"rimraf": "^5.0.0",
"typescript": "^5.0.4"
},
"resolutions": {
"@aries-framework/core": "0.3.3"
},
"gitHead": "bc01e09f07f0530b5230500ef07581afbe34816f"
"dependencies": {
"@aries-framework/core": "^0.3.3"
}
}
100 changes: 100 additions & 0 deletions packages/oca/src/formatters/Credential.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import {
CredentialExchangeRecord,
CredentialPreviewAttribute,
CredentialPreviewAttributeOptions,
} from '@aries-framework/core'

import { IOverlayBundleAttribute as OverlayBundleAttributeOptions } from '../interfaces/overlay'
import { OverlayBundle } from '../types'

export class LocalizedCredential {
#bundle!: OverlayBundle

issuer: string
name: string
attributes!: DisplayAttribute[]

constructor(bundle: OverlayBundle, record: CredentialExchangeRecord, language: string) {
if (!language) {
throw new Error('language is required')
}

this.#bundle = bundle

this.issuer = bundle.metadata.issuer?.[language]
this.name = bundle.metadata.name?.[language]

// If no record attributes are present then grab default attributes from the bundle
const credentialAttributes = record.credentialAttributes?.length
? record.credentialAttributes
: bundle.attributes.map((attribute) => {
return new CredentialPreviewAttribute({ ...attribute, value: '' })
})

this.attributes =
credentialAttributes
?.filter((attribute) => bundle.getFlaggedAttribute(attribute.name))
.map((attribute) => {
const overlayOptions = bundle.getAttribute(attribute.name) ?? { name: attribute.name, type: '' }
return new DisplayAttribute(attribute, overlayOptions, language)
}) ?? []
}

get primaryAttribute(): DisplayAttribute | undefined {
const name = this.#bundle.branding?.primaryAttribute
return this.getAttribute(name)
}

get secondaryAttribute(): DisplayAttribute | undefined {
const name = this.#bundle.branding?.secondaryAttribute
return this.getAttribute(name)
}

getAttribute(attributeName?: string): DisplayAttribute | undefined {
if (!attributeName) {
return undefined
}
return this.attributes.find((attribute) => attribute.name === attributeName)
}
}

export class DisplayAttribute extends CredentialPreviewAttribute {
characterEncoding: string | undefined
standard: string | undefined
format: string | undefined
information: string | undefined
label: string | undefined

constructor(
options: CredentialPreviewAttributeOptions,
overlayOptions: OverlayBundleAttributeOptions,
language: string
) {
super(options)

this.characterEncoding = overlayOptions.characterEncoding
this.standard = overlayOptions.standard
this.format = overlayOptions.format
this.information = overlayOptions.information?.[language]
this.label = overlayOptions.label?.[language]
}

toJSON(): Record<string, unknown> {
return { ...super.toJSON(), format: this.format, information: this.information, label: this.label }
}
}

export class CredentialFormatter {
#credentials!: Record<string, LocalizedCredential>

constructor(bundle: OverlayBundle, record: CredentialExchangeRecord) {
this.#credentials = bundle.languages.reduce((credentials, language) => {
credentials[language] = new LocalizedCredential(bundle, record, language)
return credentials
}, {} as Record<string, LocalizedCredential>)
}

localizedCredential(language: string): LocalizedCredential | undefined {
return this.#credentials[language]
}
}
1 change: 1 addition & 0 deletions packages/oca/src/formatters/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { CredentialFormatter } from './Credential'
7 changes: 4 additions & 3 deletions packages/oca/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export function multiply(a: number, b: number): number {
return a * b
}
export * as interfaces from './interfaces'
export * as types from './types'
export * as utils from './utils'
export * as formatters from './formatters'
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export default interface IBaseOverlayData {
type: string
capture_base: string
digest?: string
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import IBaseOverlayData from '../base/BaseOverlayData.interface'

export default interface IBrandingOverlayData extends IBaseOverlayData {
logo: string
background_image: string
background_image_slice: string
primary_background_color: string
secondary_background_color: string
primary_attribute: string
secondary_attribute: string
issued_date_attribute: string
expiry_date_attribute: string
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import IBaseOverlayData from '../base/BaseOverlayData.interface'
import ICaptureBaseData from '../capture-base/CaptureBaseData.interface'

export default interface IOverlayBundleData {
capture_base: ICaptureBaseData
overlays: IBaseOverlayData[]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export default interface ICaptureBaseData {
type: string
classification: string
attributes: Record<string, string>
flagged_attributes: string[]
digest?: string
}
23 changes: 23 additions & 0 deletions packages/oca/src/interfaces/data/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import IBaseOverlayData from './base/BaseOverlayData.interface'
import IBrandingOverlayData from './branding/BrandingOverlayData.interface'
import IOverlayBundleData from './bundle/OverlayBundleData.interface'
import ICaptureBaseData from './capture-base/CaptureBaseData.interface'
import ICharacterEncodingOverlayData from './semantic/CharacterEncodingOverlayData.interface'
import IFormatOverlayData from './semantic/FormatOverlayData.interface'
import IInformationOverlayData from './semantic/InformationOverlayData.interface'
import ILabelOverlayData from './semantic/LabelOverlayData.interface'
import IMetaOverlayData from './semantic/MetaOverlayData.interface'
import IStandardOverlayData from './semantic/StandardOverlayData.interface'

export {
IBaseOverlayData,
ICaptureBaseData,
IOverlayBundleData,
IBrandingOverlayData,
ICharacterEncodingOverlayData,
IFormatOverlayData,
IInformationOverlayData,
ILabelOverlayData,
IMetaOverlayData,
IStandardOverlayData,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import IBaseOverlayData from '../base/BaseOverlayData.interface'

export default interface ICharacterEncodingOverlayData extends IBaseOverlayData {
default_character_encoding: string
// DEPRECATED - Use attribute_character_encoding instead
attr_character_encoding: Record<string, string>
attribute_character_encoding: Record<string, string>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import IBaseOverlayData from '../base/BaseOverlayData.interface'

export default interface IFormatOverlayData extends IBaseOverlayData {
attribute_formats: Record<string, string>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import IBaseOverlayData from '../base/BaseOverlayData.interface'

export default interface IInformationOverlayData extends IBaseOverlayData {
language: string
attribute_information: Record<string, string>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import IBaseOverlayData from '../base/BaseOverlayData.interface'

export default interface ILabelOverlayData extends IBaseOverlayData {
language: string
attribute_labels: Record<string, string>
attribute_categories: string[]
category_labels: Record<string, string>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import IBaseOverlayData from '../base/BaseOverlayData.interface'

export default interface IMetaOverlayData extends IBaseOverlayData {
language: string
name: string
description: string
credential_help_text: string
credential_support_url: string
issuer: string
issuer_description: string
issuer_url: string
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import IBaseOverlayData from '../base/BaseOverlayData.interface'

export default interface IStandardOverlayData extends IBaseOverlayData {
// DEPRECATED - Use attribute_standards instead
attr_standards: Record<string, string>
attribute_standards: Record<string, string>
}
4 changes: 4 additions & 0 deletions packages/oca/src/interfaces/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import * as data from '../interfaces/data'
import * as overlay from '../interfaces/overlay'

export { data, overlay }
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export default interface IOverlayBundleAttribute {
name: string
type: string
information?: Record<string, string>
label?: Record<string, string>
format?: string
characterEncoding?: string
standard?: string
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export default interface IOverlayBundleMetadata {
name: Record<string, string>
description: Record<string, string>
credentialHelpText?: Record<string, string>
credentialSupportUrl?: Record<string, string>
issuer: Record<string, string>
issuerDescription?: Record<string, string>
issuerUrl?: Record<string, string>
}
4 changes: 4 additions & 0 deletions packages/oca/src/interfaces/overlay/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import IOverlayBundleAttribute from './OverlayBundleAttribute.interface'
import IOverlayBundleMetadata from './OverlayBundleMetadata.interface'

export { IOverlayBundleAttribute, IOverlayBundleMetadata }
22 changes: 22 additions & 0 deletions packages/oca/src/types/OverlayTypeMap.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import BaseOverlay from './base/BaseOverlay'
import BrandingOverlay from './branding/BrandingOverlay'
import CharacterEncodingOverlay from './semantic/CharacterEncodingOverlay'
import FormatOverlay from './semantic/FormatOverlay'
import InformationOverlay from './semantic/InformationOverlay'
import LabelOverlay from './semantic/LabelOverlay'
import MetaOverlay from './semantic/MetaOverlay'
import StandardOverlay from './semantic/StandardOverlay'

const OverlayTypeMap: Map<string, typeof BaseOverlay | typeof BrandingOverlay> = new Map(
Object.entries({
'spec/overlays/character_encoding/1.0': CharacterEncodingOverlay,
'spec/overlays/label/1.0': LabelOverlay,
'spec/overlays/information/1.0': InformationOverlay,
'spec/overlays/format/1.0': FormatOverlay,
'spec/overlays/standard/1.0': StandardOverlay,
'spec/overlays/meta/1.0': MetaOverlay,
'aries/overlays/branding/1.0': BrandingOverlay,
})
)

export default OverlayTypeMap
18 changes: 18 additions & 0 deletions packages/oca/src/types/base/BaseOverlay.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { IBaseOverlayData } from '../../interfaces/data'

export default class BaseOverlay {
#capture_base: string

type: string
digest: string

constructor(overlay: IBaseOverlayData) {
this.type = overlay.type
this.#capture_base = overlay.capture_base
this.digest = overlay.digest ?? ''
}

get captureBase(): string {
return this.#capture_base
}
}
Loading

0 comments on commit ed03584

Please sign in to comment.