From 4bdc1f4c8e9729ec24ba04f02100ffcf1e8fd777 Mon Sep 17 00:00:00 2001 From: Mirko Mollik Date: Mon, 12 Feb 2024 11:39:09 +0100 Subject: [PATCH] generate enum of the values in the asset folder (#103) * generate enum of the values in the asset folder Signed-off-by: Mirko * fix locale Signed-off-by: Mirko * fix: validation script Signed-off-by: Mirko * add schema job to validate job Signed-off-by: Mirko * set unique fields Signed-off-by: Mirko --------- Signed-off-by: Mirko --- data/Credential-Format/JWT.json | 10 +- data/Credential-Format/LDP-VC.json | 10 +- data/Credential-Format/SD-JWT-VC.json | 10 +- data/Credential-Format/VC-(1.1).json | 2 +- schemas/Credential-Format.json | 2 +- schemas/Credential-Profile.json | 171 ++++++------------ schemas/Issuance-Protocol.json | 2 +- schemas/Key-Management.json | 2 +- schemas/Presentation-Protocol.json | 4 +- schemas/Signing-Algorithm.json | 2 +- schemas/Status-Algorithm.json | 2 +- schemas/Trust-Management.json | 2 +- schemas/defs.json | 4 +- viewer/.gitignore | 2 +- viewer/package.json | 4 +- .../credential-profile-list.component.ts | 2 +- viewer/src/assets/schemas/.gitkeep | 0 viewer/src/environments/environment.ts | 2 +- viewer/tools/merge.mjs | 18 +- viewer/tools/schema.mjs | 37 +++- viewer/tools/validate.mjs | 20 +- viewer/tools/values.mjs | 2 +- 22 files changed, 151 insertions(+), 159 deletions(-) create mode 100644 viewer/src/assets/schemas/.gitkeep diff --git a/data/Credential-Format/JWT.json b/data/Credential-Format/JWT.json index 8b0d399..55be0e4 100644 --- a/data/Credential-Format/JWT.json +++ b/data/Credential-Format/JWT.json @@ -11,5 +11,13 @@ "Selective Disclosure": false, "Predicates": false, "Compatibility with Signing Algorithms": "ECDSA, EdDSA, RSA", - "Compatibility with Key Management Methods (Issuer)": "did:key, did:web. did:ebsi, did:iota, did:jwk, did:cheqd, did:velocity" + "Compatibility with Key Management Methods (Issuer)": [ + "did:key", + "did:web", + "did:ebsi", + "did:iota", + "did:jwk", + "did:cheqd", + "did:velocity" + ] } diff --git a/data/Credential-Format/LDP-VC.json b/data/Credential-Format/LDP-VC.json index 458b9b1..a82a276 100644 --- a/data/Credential-Format/LDP-VC.json +++ b/data/Credential-Format/LDP-VC.json @@ -17,5 +17,13 @@ "Description": "depending on signature algorithm" }, "Compatibility with Signing Algorithms": "ECDSA, EdDSA, RSA", - "Compatibility with Key Management Methods (Issuer)": "did:key, did:web. did:ebsi, did:iota, did:jwk, did:cheqd, did:velocity" + "Compatibility with Key Management Methods (Issuer)": [ + "did:key", + "did:web", + "did:ebsi", + "did:iota", + "did:jwk", + "did:cheqd", + "did:velocity" + ] } diff --git a/data/Credential-Format/SD-JWT-VC.json b/data/Credential-Format/SD-JWT-VC.json index 9376d1a..15e813e 100644 --- a/data/Credential-Format/SD-JWT-VC.json +++ b/data/Credential-Format/SD-JWT-VC.json @@ -10,5 +10,13 @@ "Selective Disclosure": true, "Predicates": false, "Compatibility with Signing Algorithms": "ECDSA, EdDSA, RSA", - "Compatibility with Key Management Methods (Issuer)": "did:key, did:web. did:ebsi, did:iota, did:jwk, did:cheqd, did:velocity" + "Compatibility with Key Management Methods (Issuer)": [ + "did:key", + "did:web", + "did:ebsi", + "did:iota", + "did:jwk", + "did:cheqd", + "did:velocity" + ] } diff --git a/data/Credential-Format/VC-(1.1).json b/data/Credential-Format/VC-(1.1).json index 59b5421..b1ad039 100644 --- a/data/Credential-Format/VC-(1.1).json +++ b/data/Credential-Format/VC-(1.1).json @@ -11,5 +11,5 @@ "Selective Disclosure": true, "Predicates": false, "Compatibility with Signing Algorithms": "ECDSA, EdDSA, RSA", - "Compatibility with Key Management Methods (Issuer)": "x509, did methods" + "Compatibility with Key Management Methods (Issuer)": ["x509", "did methods"] } diff --git a/schemas/Credential-Format.json b/schemas/Credential-Format.json index 50a4766..b719069 100644 --- a/schemas/Credential-Format.json +++ b/schemas/Credential-Format.json @@ -1,6 +1,6 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "https://raw.githubusercontent.com/openwallet-foundation/credential-format-comparison-sig/main/schemas/Credential-Format.json", + "$id": "Credential-Format.json", "type": "object", "additionalProperties": false, "properties": { diff --git a/schemas/Credential-Profile.json b/schemas/Credential-Profile.json index 24da2b7..25c6e70 100644 --- a/schemas/Credential-Profile.json +++ b/schemas/Credential-Profile.json @@ -1,6 +1,6 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "https://raw.githubusercontent.com/openwallet-foundation/credential-format-comparison-sig/main/schemas/Credential-Profile.json", + "$id": "Credential-Profile.json", "type": "object", "additionalProperties": false, "properties": { @@ -16,136 +16,83 @@ "description": "A brief description of the credential profile" }, "Credential Format": { - "type": "string", - "description": "The used credential format", - "$comment": "The value should be one of the enum list, that can be updated by running \"npm run schema\" inside the viewer folder", - "enum": [ - "ACDC (KERI)", - "AnonCred", - "CESR/CESR Proof", - "CWT", - "Gordian Envelope", - "ICAO DTC", - "Idemix attribute-based credential", - "JWP", - "JWT-VC", - "JWT", - "LDP-VC", - "MDOC", - "SD-JWT-VC", - "SD-JWT", - "VC (1.1)", - "x509" + "allOf": [ + { + "$ref": "../viewer/src/assets/schemas/fields.json#/definitions/Credential-Format" + }, + { + "description": "The format of the credential." + } ] }, "Signing Algorithm": { - "type": "string", - "description": "The format of the signing algorithm.", - "$comment": "The value should be one of the enum list, that can be updated by running \"npm run schema\" inside the viewer folder", - "enum": [ - "BBS+ with public key binding", - "BoundBBS+", - "CL", - "ECDSA", - "EdDSA", - "RSA", - "Schnorr" + "allOf": [ + { + "$ref": "../viewer/src/assets/schemas/fields.json#/definitions/Signing-Algorithm" + }, + { + "description": "The format of the signing algorithm." + } ] }, "Status Algorithm": { - "type": "string", - "description": "The format of the status algorithm.", - "$comment": "The value should be one of the enum list, that can be updated by running \"npm run schema\" inside the viewer folder", - "enum": [ - "BBF18-cryptographic accumulator based on RSA", - "CRL - certificate revocation list", - "Indy Revocation", - "JWT/CWT status list", - "Non-Revocation Token", - "RSA-B - cryptographic accumulator based on RSA", - "SLTD database (travel and identity documents)", - "Status List 2021", - "VB20 - cryptographic accumulator based on pairings", - "Validity Credential", - "medium-term expiration", - "short-term expiration" + "allOf": [ + { + "$ref": "../viewer/src/assets/schemas/fields.json#/definitions/Status-Algorithm" + }, + { + "description": "The format of the status algorithm." + } ] }, "Key Management (Issuer)": { - "type": "string", - "description": "The format of the key management.", - "$comment": "The value should be one of the enum list, that can be updated by running \"npm run schema\" inside the viewer folder", - "enum": [ - ".well-known/jwt-issuer", - "cose key", - "credential as secret", - "did:cheqd", - "did:ebsi", - "did:indy", - "did:ion (long form)", - "did:ion (short form)", - "did:jwk", - "did:keri", - "did:key", - "did:peer", - "did:web", - "jwks_uri", - "link secrets", - "pub key in X.509 cert", - "raw public keys (jwk)", - "raw public keys (none jwk)" + "allOf": [ + { + "$ref": "../viewer/src/assets/schemas/fields.json#/definitions/Key-Management" + }, + { + "description": "The format of the key management for the issuer." + } ] }, "Key Management (Holder)": { - "type": "string", - "description": "The format of the key management.", - "$comment": "The value should be one of the enum list, that can be updated by running \"npm run schema\" inside the viewer folder", - "enum": [ - ".well-known/jwt-issuer", - "cose key", - "credential as secret", - "did:cheqd", - "did:ebsi", - "did:indy", - "did:ion (long form)", - "did:ion (short form)", - "did:jwk", - "did:keri", - "did:key", - "did:peer", - "did:web", - "jwks_uri", - "link secrets", - "pub key in X.509 cert", - "raw public keys (jwk)", - "raw public keys (none jwk)" + "allOf": [ + { + "$ref": "../viewer/src/assets/schemas/fields.json#/definitions/Key-Management" + }, + { + "description": "The format of the key management for the holder." + } ] }, "Issuance Protocol": { - "type": "string", - "description": "The format of the issuance protocol.", - "$comment": "The value should be one of the enum list, that can be updated by running \"npm run schema\" inside the viewer folder", - "enum": ["ACDC", "ISO 23220-3", "Issue Credential v2", "OpenID4VCI"] + "allOf": [ + { + "$ref": "../viewer/src/assets/schemas/fields.json#/definitions/Issuance-Protocol" + }, + { + "description": "The format of issuance protocol." + } + ] }, "Presentation Protocol": { - "type": "string", - "description": "The format of the presentation protocol.", - "$comment": "The value should be one of the enum list, that can be updated by running \"npm run schema\" inside the viewer folder", - "enum": ["OpenID4VP"] + "allOf": [ + { + "$ref": "../viewer/src/assets/schemas/fields.json#/definitions/Presentation-Protocol" + }, + { + "description": "The format of the presentation protocol." + } + ] }, "Trust Management": { - "type": "string", - "description": "The format of the trust management.", - "$comment": "The value should be one of the enum list, that can be updated by running \"npm run schema\" inside the viewer folder", - "enum": [ - "EBSI Trust Registries", - "IRMA (Yivi) Schemes", - "OpenID Connect Federation", - "TRAIN", - "Trusted Lists", - "Verified issuer certificate authority list (VICAL)", - "Verifier knows Issuers", - "X.509 certificates" + "allOf": [ + { + "$ref": "../viewer/src/assets/schemas/fields.json#/definitions/Trust-Management" + }, + { + "description": "The format of the trust management." + } ] }, "Formal Specification": { diff --git a/schemas/Issuance-Protocol.json b/schemas/Issuance-Protocol.json index 0aa8f73..c7531a0 100644 --- a/schemas/Issuance-Protocol.json +++ b/schemas/Issuance-Protocol.json @@ -1,6 +1,6 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "https://raw.githubusercontent.com/openwallet-foundation/credential-format-comparison-sig/main/schemas/Issuance-Protocol.json", + "$id": "Issuance-Protocol.json", "type": "object", "additionalProperties": false, "properties": { diff --git a/schemas/Key-Management.json b/schemas/Key-Management.json index 040dff9..f33f2ec 100644 --- a/schemas/Key-Management.json +++ b/schemas/Key-Management.json @@ -1,6 +1,6 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "https://raw.githubusercontent.com/openwallet-foundation/credential-format-comparison-sig/main/schemas/Key-Management.json", + "$id": "Key-Management.json", "type": "object", "additionalProperties": false, "properties": { diff --git a/schemas/Presentation-Protocol.json b/schemas/Presentation-Protocol.json index 5f8ef92..45f9f20 100644 --- a/schemas/Presentation-Protocol.json +++ b/schemas/Presentation-Protocol.json @@ -1,6 +1,6 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "https://raw.githubusercontent.com/openwallet-foundation/credential-format-comparison-sig/main/schemas/Presentation-Protocol.json", + "$id": "Presentation-Protocol.json", "type": "object", "additionalProperties": false, "properties": { @@ -15,6 +15,6 @@ "$ref": "defs.json#/definitions/Specification" } }, - "required": ["$schema", "Presentation Protocol"], + "required": ["$schema", "Name"], "title": "PresentationProtocol" } diff --git a/schemas/Signing-Algorithm.json b/schemas/Signing-Algorithm.json index 4131717..132ee26 100644 --- a/schemas/Signing-Algorithm.json +++ b/schemas/Signing-Algorithm.json @@ -1,6 +1,6 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "https://raw.githubusercontent.com/openwallet-foundation/credential-format-comparison-sig/main/schemas/Signing-Algorithm.json", + "$id": "Signing-Algorithm.json", "type": "object", "additionalProperties": false, "properties": { diff --git a/schemas/Status-Algorithm.json b/schemas/Status-Algorithm.json index f6b5e7f..d28f979 100644 --- a/schemas/Status-Algorithm.json +++ b/schemas/Status-Algorithm.json @@ -1,6 +1,6 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "https://raw.githubusercontent.com/openwallet-foundation/credential-format-comparison-sig/main/schemas/Status-Algorithm.json", + "$id": "Status-Algorithm.json", "type": "object", "additionalProperties": false, "properties": { diff --git a/schemas/Trust-Management.json b/schemas/Trust-Management.json index d37fbb7..60e9fc5 100644 --- a/schemas/Trust-Management.json +++ b/schemas/Trust-Management.json @@ -1,6 +1,6 @@ { "$schema": "http://json-schema.org/draft-07/schema#", - "$id": "https://raw.githubusercontent.com/openwallet-foundation/credential-format-comparison-sig/main/schemas/Trust-Management.json", + "$id": "Trust-Management.json", "type": "object", "additionalProperties": false, "properties": { diff --git a/schemas/defs.json b/schemas/defs.json index 984d23e..f0e645c 100644 --- a/schemas/defs.json +++ b/schemas/defs.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-07/schema", - "$id": "https://raw.githubusercontent.com/openwallet-foundation/credential-format-comparison-sig/main/schemas/defs.json", - "type": ["object"], + "$id": "defs.json", + "type": "object", "definitions": { "Schema": { "type": "string", diff --git a/viewer/.gitignore b/viewer/.gitignore index ce782e9..7e6ed4c 100644 --- a/viewer/.gitignore +++ b/viewer/.gitignore @@ -6,7 +6,7 @@ /out-tsc /bazel-out structure.json - +src/assets/schemas/*.json # Node /node_modules npm-debug.log diff --git a/viewer/package.json b/viewer/package.json index 3811d79..a6d77b7 100644 --- a/viewer/package.json +++ b/viewer/package.json @@ -3,14 +3,14 @@ "version": "0.0.0", "scripts": { "ng": "ng", - "prestart": "npm run merge", + "prestart": "npm run merge && npm run schema", "start": "ng serve", "prebuild": "npm run merge && npm run timestamp", "build": "ng build", "watch": "ng build --watch --configuration development", "test": "ng test", "merge": "node tools/merge.mjs", - "validate": "node tools/validate.mjs", + "validate": "npm run schema && node tools/validate.mjs", "validate:watch": "nodemon --watch ../data tools/validate.mjs", "schema": "node tools/schema.mjs", "lint": "ng lint", diff --git a/viewer/src/app/credential-profile/credential-profile-list/credential-profile-list.component.ts b/viewer/src/app/credential-profile/credential-profile-list/credential-profile-list.component.ts index 32e2e7e..6080abf 100644 --- a/viewer/src/app/credential-profile/credential-profile-list/credential-profile-list.component.ts +++ b/viewer/src/app/credential-profile/credential-profile-list/credential-profile-list.component.ts @@ -144,7 +144,7 @@ export class CredentialProfileListComponent implements OnInit, AfterViewInit { } isSticky(column: ColumnHeader) { - return column.key === 'Credential Profile is commonly called'; + return column.key === 'Name'; } hasLink(value: string, header: string) { diff --git a/viewer/src/assets/schemas/.gitkeep b/viewer/src/assets/schemas/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/viewer/src/environments/environment.ts b/viewer/src/environments/environment.ts index 3936f28..5379bec 100644 --- a/viewer/src/environments/environment.ts +++ b/viewer/src/environments/environment.ts @@ -1,3 +1,3 @@ export const environment = { - buildTime: '2024-01-23T10:58:02.535Z', + buildTime: '2024-02-11T15:33:07.572Z', }; diff --git a/viewer/tools/merge.mjs b/viewer/tools/merge.mjs index 8238260..d791042 100644 --- a/viewer/tools/merge.mjs +++ b/viewer/tools/merge.mjs @@ -1,19 +1,19 @@ -import fs from 'fs'; +import { readFileSync, writeFileSync, readdirSync } from 'fs'; import { schemaFolder, folder, mergedStructure, structureFile, defFile, githubPath } from './values.mjs'; import { join } from 'path'; // merges the json files to one json file const input = {}; // loop through all subfolders -fs.readdirSync(schemaFolder).forEach((resource) => { +readdirSync(schemaFolder).forEach((resource) => { if(resource === defFile) { - input['defs'] = JSON.parse(fs.readFileSync(join(schemaFolder, resource), 'utf8')); + input['defs'] = JSON.parse(readFileSync(join(schemaFolder, resource), 'utf8')); return; } // create a new json object for each subfolder const subFolder = resource.slice(0, -5); - let content = fs.readFileSync(join(schemaFolder, resource), 'utf8'); - content = content.replaceAll('"$ref": "defs.json', `"$ref": "${githubPath}/schemas/defs.json`); + let content = readFileSync(join(schemaFolder, resource), 'utf8'); + content = content.replaceAll('"$ref": "defs.json', `"$ref": "${githubPath}/main/schemas/defs.json`); const structure = JSON.parse(content); input[subFolder.replace(/-/g, ' ')] = { @@ -21,14 +21,14 @@ fs.readdirSync(schemaFolder).forEach((resource) => { values: {} }; // write the content of the file to the json object - fs.readdirSync(join(folder, subFolder)).filter(file => file !== structureFile).forEach((file) => { + readdirSync(join(folder, subFolder)).filter(file => file !== structureFile).forEach((file) => { // write the content of the file to the json object - const content = JSON.parse(fs.readFileSync(join(folder, subFolder, file), 'utf8')); - content['$schema'] = content['$schema'].replace('../..', githubPath); + const content = JSON.parse(readFileSync(join(folder, subFolder, file), 'utf8')); + content['$schema'] = content['$schema'].replace('../..', `/main/${githubPath}`); input[subFolder.replace(/-/g, ' ')].values[content.Name] = content; }); }); //TODO: think about to separate the structure and the values files in the future so others can query only the information they need // write the final json object to a file -fs.writeFileSync(mergedStructure, JSON.stringify(input)); +writeFileSync(mergedStructure, JSON.stringify(input)); diff --git a/viewer/tools/schema.mjs b/viewer/tools/schema.mjs index f57123a..2bb7fe7 100644 --- a/viewer/tools/schema.mjs +++ b/viewer/tools/schema.mjs @@ -1,24 +1,43 @@ -import {readFileSync, writeFileSync, lstatSync, readdirSync} from 'fs'; -import { folder, schemaFolder } from './values.mjs'; +import {readFileSync, writeFileSync, lstatSync, readdirSync, existsSync, mkdirSync} from 'fs'; +import { folder, githubPath, schemaFolder } from './values.mjs'; +import { join } from 'path'; const schemaPath = `${schemaFolder}/Credential-Profile.json`; const file = JSON.parse(readFileSync(schemaPath, 'utf8')); +const generatedFolder = "src/assets/schemas"; -Object.keys(file.properties).forEach((key) => { - const enums = getEnum(key.startsWith('Key Management') ? 'Key Management' : key); - if(enums) { - file.properties[key].enum = [...enums]; +if(!existsSync(generatedFolder)) { + mkdirSync(generatedFolder); +} +const schema = { + "$schema": "http://json-schema.org/draft-07/schema", + "$id": "fields.json", + type: "object", + definitions: {} +} + +const resources = Object.keys(file.properties); +resources.push('Credential Profile'); +resources.forEach((key) => { + key = key.startsWith('Key Management') ? 'Key Management' : key; + const enums = getEnum(key); + if(enums) { + schema.definitions[key.replace(' ', '-')] = { + description: `The used ${key}`, + type: "string", + enum: enums } + } }); -writeFileSync(schemaPath, JSON.stringify(file, null, 2)); +writeFileSync(join(generatedFolder, 'fields.json'), JSON.stringify(schema, null, 2), 'utf8'); function getEnum(subFolder) { // adds the resources to the schema file of the profile try { const info = lstatSync(`${folder}/${subFolder.replace(' ', '-')}`); if(info.isDirectory()) { - return readdirSync(`${folder}/${subFolder.replace(' ', '-')}`).map((file) => - JSON.parse(readFileSync(`${folder}/${subFolder.replace(' ', '-')}/${file}`, 'utf8'))[subFolder] + return readdirSync(`${folder}/${subFolder.replace(' ', '-')}`).map((file) => + JSON.parse(readFileSync(`${folder}/${subFolder.replace(' ', '-')}/${file}`, 'utf8')).Name ); } } catch (e) { diff --git a/viewer/tools/validate.mjs b/viewer/tools/validate.mjs index b30ff19..c615f40 100644 --- a/viewer/tools/validate.mjs +++ b/viewer/tools/validate.mjs @@ -9,30 +9,32 @@ const pattern = /^(?!^(PRN|AUX|CON|NUL|COM[1-9]|LPT[1-9])(\..*)?$)[^<>:"/\\|?*]+ let error = false; //will loop through all the files and will check if the entries match with the structure defined in the info.json file. -readdirSync(folder).forEach((subFolder) => { +readdirSync(folder).forEach((subFolder) => { const infoFile = readFileSync(`${schemaFolder}/${subFolder}.json`, 'utf8'); if(!infoFile) { console.log(`No schema file found for ${subFolder}`); - process.exit(1); + process.exit(1); } const ajv = new Ajv({allowUnionTypes: true}); + const def = JSON.parse(readFileSync("src/assets/schemas/fields.json")); + ajv.addSchema(def, 'viewer/src/assets/schemas/fields.json'); const validate = ajv.addSchema(JSON.parse(readFileSync(join(schemaFolder, defFile)))).compile(JSON.parse(infoFile)); - const uniqueNames = []; + const uniqueNames = []; readdirSync(`${folder}/${subFolder}`).filter(file => file !== structureFile).forEach((file) => { - // check path compliance + // check path compliance if(!pattern.test(file)) { console.log(`File "../data/${subFolder}/${file}" does not match the pattern: ${pattern}}`); - error = true; + error = true; } // check schema compliance const content = JSON.parse(readFileSync(`${folder}/${subFolder}/${file}`)); if(!validate(content)) { console.log(`File "../data/${subFolder}/${file}" is invalid`); console.log(JSON.stringify(validate.errors, null ,2)); - error = true; - } + error = true; + } // check duplicate names - const name = subFolder === 'Credential-Profile' ? content['Credential Profile is commonly called'] : content[subFolder.replace('-', ' ')]; + const name = content['Name'] if(uniqueNames.includes(name)) { console.log(`File "../data/${subFolder}/${file}" has a duplicate name: ${name}`); error = true; @@ -45,4 +47,4 @@ if(error) { console.error(`At least one file is invalid`); } else { console.log(`All files are valid`); -} \ No newline at end of file +} diff --git a/viewer/tools/values.mjs b/viewer/tools/values.mjs index 55bdeca..56ee521 100644 --- a/viewer/tools/values.mjs +++ b/viewer/tools/values.mjs @@ -3,4 +3,4 @@ export const schemaFolder = "../schemas"; export const defFile = "defs.json"; export const structureFile = 'schema.json'; export const mergedStructure = './src/assets/structure.json'; -export const githubPath = 'https://raw.githubusercontent.com/openwallet-foundation/credential-format-comparison-sig/main'; +export const githubPath = 'https://raw.githubusercontent.com/openwallet-foundation/credential-format-comparison-sig';