@cooperation/vc-storage 1.0.22 → 1.0.24
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/dist/models/CredentialEngine.js +12 -19
- package/dist/models/GoogleDriveStorage.js +203 -159
- package/dist/models/ResumeVC.js +118 -12
- package/dist/types/models/CredentialEngine.d.ts +2 -2
- package/dist/types/models/GoogleDriveStorage.d.ts +12 -13
- package/dist/types/models/ResumeVC.d.ts +4 -1
- package/dist/types/utils/context.d.ts +76 -2
- package/dist/types/utils/credential.d.ts +2 -2
- package/dist/types/utils/google.d.ts +7 -5
- package/dist/utils/context.js +99 -9
- package/dist/utils/credential.js +2 -7
- package/dist/utils/google.js +25 -23
- package/package.json +8 -16
package/dist/models/ResumeVC.js
CHANGED
@@ -30,30 +30,136 @@ export class ResumeVC {
|
|
30
30
|
return unsignedCredential;
|
31
31
|
}
|
32
32
|
generateUnsignedCredential({ formData, issuerDid }) {
|
33
|
-
const
|
33
|
+
const unsignedResumeVC = {
|
34
34
|
'@context': [
|
35
|
-
'https://www.w3.org/2018/credentials/v1',
|
35
|
+
'https://www.w3.org/2018/credentials/v1',
|
36
36
|
inlineResumeContext['@context'], // Inline context
|
37
37
|
],
|
38
|
-
id: `urn:uuid:${uuidv4()}`, // Generate a
|
39
|
-
type: ['VerifiableCredential'],
|
38
|
+
id: `urn:uuid:${uuidv4()}`, // Generate a unique UUID
|
39
|
+
type: ['VerifiableCredential', 'LERRSCredential'], // LER-RS compliant credential type
|
40
40
|
issuer: issuerDid,
|
41
|
-
issuanceDate: new Date().toISOString(),
|
41
|
+
issuanceDate: new Date().toISOString(), // Current date/time in ISO format
|
42
42
|
credentialSubject: {
|
43
43
|
type: 'Resume',
|
44
44
|
person: {
|
45
45
|
name: {
|
46
|
-
formattedName: formData.
|
46
|
+
formattedName: formData.name || '',
|
47
47
|
},
|
48
|
-
primaryLanguage:
|
48
|
+
primaryLanguage: 'en',
|
49
|
+
contact: {
|
50
|
+
fullName: formData.contact.fullName || '',
|
51
|
+
email: formData.contact.email || '',
|
52
|
+
phone: formData.contact.phone || '',
|
53
|
+
location: {
|
54
|
+
street: formData.contact.location.street || '',
|
55
|
+
city: formData.contact.location.city || '',
|
56
|
+
state: formData.contact.location.state || '',
|
57
|
+
country: formData.contact.location.country || '',
|
58
|
+
postalCode: formData.contact.location.postalCode || '',
|
59
|
+
},
|
60
|
+
socialLinks: {
|
61
|
+
linkedin: formData.contact.socialLinks.linkedin || '',
|
62
|
+
github: formData.contact.socialLinks.github || '',
|
63
|
+
portfolio: formData.contact.socialLinks.portfolio || '',
|
64
|
+
twitter: formData.contact.socialLinks.twitter || '',
|
65
|
+
},
|
66
|
+
},
|
67
|
+
},
|
68
|
+
narrative: {
|
69
|
+
text: formData.summary || '',
|
49
70
|
},
|
50
|
-
|
51
|
-
employmentHistory: formData.
|
52
|
-
|
53
|
-
|
71
|
+
// Employment History
|
72
|
+
employmentHistory: formData.experience.items.map((exp) => ({
|
73
|
+
organization: {
|
74
|
+
tradeName: exp.company || '',
|
75
|
+
},
|
76
|
+
title: exp.title || '',
|
77
|
+
description: exp.description || '',
|
78
|
+
startDate: exp.startDate || '',
|
79
|
+
endDate: exp.endDate || '',
|
80
|
+
stillEmployed: exp.stillEmployed || false,
|
81
|
+
})),
|
82
|
+
// Duplicated Experience (Raw)
|
83
|
+
experience: formData.experience.items.map((exp) => ({
|
84
|
+
company: exp.company || '',
|
85
|
+
title: exp.title || '',
|
86
|
+
description: exp.description || '',
|
87
|
+
startDate: exp.startDate || '',
|
88
|
+
endDate: exp.endDate || '',
|
89
|
+
stillEmployed: exp.stillEmployed || false,
|
90
|
+
})),
|
91
|
+
// Skills
|
92
|
+
skills: formData.skills.items.map((skill) => ({
|
93
|
+
name: skill.name || '',
|
94
|
+
})),
|
95
|
+
// Education
|
96
|
+
educationAndLearning: formData.education.items.map((edu) => ({
|
97
|
+
institution: edu.institution || '',
|
98
|
+
degree: edu.degree || '',
|
99
|
+
fieldOfStudy: edu.fieldOfStudy || '',
|
100
|
+
startDate: edu.startDate || '',
|
101
|
+
endDate: edu.endDate || '',
|
102
|
+
})),
|
103
|
+
// Awards
|
104
|
+
awards: formData.awards.items.map((award) => ({
|
105
|
+
title: award.title || '',
|
106
|
+
issuer: award.issuer || '',
|
107
|
+
date: award.date || '',
|
108
|
+
description: award.description || '',
|
109
|
+
})),
|
110
|
+
// Publications
|
111
|
+
publications: formData.publications.items.map((pub) => ({
|
112
|
+
title: pub.title || '',
|
113
|
+
publisher: pub.publisher || '',
|
114
|
+
date: pub.date || '',
|
115
|
+
url: pub.url || '',
|
116
|
+
})),
|
117
|
+
// Certifications
|
118
|
+
certifications: formData.certifications.items.map((cert) => ({
|
119
|
+
name: cert.name || '',
|
120
|
+
issuer: cert.issuer || '',
|
121
|
+
date: cert.date || '',
|
122
|
+
url: cert.url || '',
|
123
|
+
})),
|
124
|
+
// Professional Affiliations
|
125
|
+
professionalAffiliations: formData.professionalAffiliations.items.map((aff) => ({
|
126
|
+
organization: aff.organization || '',
|
127
|
+
role: aff.role || '',
|
128
|
+
startDate: aff.startDate || '',
|
129
|
+
endDate: aff.endDate || '',
|
130
|
+
})),
|
131
|
+
// Volunteer Work
|
132
|
+
volunteerWork: formData.volunteerWork.items.map((vol) => ({
|
133
|
+
organization: vol.organization || '',
|
134
|
+
role: vol.role || '',
|
135
|
+
description: vol.description || '',
|
136
|
+
startDate: vol.startDate || '',
|
137
|
+
endDate: vol.endDate || '',
|
138
|
+
})),
|
139
|
+
// Hobbies and Interests
|
140
|
+
hobbiesAndInterests: formData.hobbiesAndInterests || [],
|
141
|
+
// Languages
|
142
|
+
languages: formData.languages.items.map((lang) => ({
|
143
|
+
language: lang.language || '',
|
144
|
+
proficiency: lang.proficiency || '',
|
145
|
+
})),
|
146
|
+
// Testimonials
|
147
|
+
testimonials: formData.testimonials.items.map((testi) => ({
|
148
|
+
author: testi.author || '',
|
149
|
+
text: testi.text || '',
|
150
|
+
date: testi.date || '',
|
151
|
+
})),
|
152
|
+
// Projects
|
153
|
+
projects: formData.projects.items.map((proj) => ({
|
154
|
+
name: proj.name || '',
|
155
|
+
description: proj.description || '',
|
156
|
+
url: proj.url || '',
|
157
|
+
startDate: proj.startDate || '',
|
158
|
+
endDate: proj.endDate || '',
|
159
|
+
})),
|
54
160
|
},
|
55
161
|
};
|
56
|
-
return
|
162
|
+
return unsignedResumeVC;
|
57
163
|
}
|
58
164
|
generateKeyPair = async (address) => {
|
59
165
|
// Generate the key pair using the library's method
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import { DidDocument, KeyPair, FormDataI, RecommendationFormDataI, VerifiableCredential } from '../../types/credential.js';
|
2
|
+
import { GoogleDriveStorage } from './GoogleDriveStorage.js';
|
2
3
|
interface SignPropsI {
|
3
4
|
data: FormDataI | RecommendationFormDataI;
|
4
5
|
type: 'VC' | 'RECOMMENDATION';
|
@@ -9,7 +10,6 @@ interface SignPropsI {
|
|
9
10
|
/**
|
10
11
|
* Class representing the Credential Engine.
|
11
12
|
* @class CredentialEngine
|
12
|
-
* @param {string} accessToken - The access token for the user.
|
13
13
|
* @classdesc Credential Engine class to create DIDs and VCs.
|
14
14
|
* @method createDID - Create a new DID with Digital Bazaar's Ed25519VerificationKey2020 key pair.
|
15
15
|
* @method createWalletDID - Create a new DID with user metamask address as controller.
|
@@ -21,7 +21,7 @@ interface SignPropsI {
|
|
21
21
|
export declare class CredentialEngine {
|
22
22
|
private storage;
|
23
23
|
private keyPair;
|
24
|
-
constructor(
|
24
|
+
constructor(storage: GoogleDriveStorage);
|
25
25
|
private getKeyPair;
|
26
26
|
private generateKeyPair;
|
27
27
|
private verifyCreds;
|
@@ -1,8 +1,4 @@
|
|
1
|
-
|
2
|
-
name: string;
|
3
|
-
content: any;
|
4
|
-
comments: string[];
|
5
|
-
}
|
1
|
+
type FileType = 'KEYPAIRs' | 'VCs' | 'SESSIONs' | 'DIDs' | 'RECOMMENDATIONs' | 'MEDIAs';
|
6
2
|
/**
|
7
3
|
* @class GoogleDriveStorage
|
8
4
|
* @description Class to interact with Google Drive API
|
@@ -20,6 +16,9 @@ interface FileContent {
|
|
20
16
|
*/
|
21
17
|
export declare class GoogleDriveStorage {
|
22
18
|
private accessToken;
|
19
|
+
folderCache: any;
|
20
|
+
private fileIdsCache;
|
21
|
+
private updateFileIdsJson;
|
23
22
|
constructor(accessToken: string);
|
24
23
|
private fetcher;
|
25
24
|
private getFileContent;
|
@@ -27,12 +26,11 @@ export declare class GoogleDriveStorage {
|
|
27
26
|
createFolder({ folderName, parentFolderId }: {
|
28
27
|
folderName: string;
|
29
28
|
parentFolderId: string;
|
30
|
-
}): Promise<
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
}>;
|
29
|
+
}): Promise<any>;
|
30
|
+
getMediaFolderId(): Promise<any>;
|
31
|
+
uploadBinaryFile({ file }: {
|
32
|
+
file: File;
|
33
|
+
}): Promise<any>;
|
36
34
|
saveFile({ data, folderId }: {
|
37
35
|
data: any;
|
38
36
|
folderId: string;
|
@@ -44,19 +42,20 @@ export declare class GoogleDriveStorage {
|
|
44
42
|
*/
|
45
43
|
retrieve(id: string): Promise<{
|
46
44
|
data: any;
|
45
|
+
id: string;
|
47
46
|
} | null>;
|
48
47
|
/**
|
49
48
|
* Get folder by folderId, if folderId == null you will have them all
|
50
49
|
* @param folderId [Optional]
|
51
50
|
* @returns
|
52
51
|
*/
|
53
|
-
findFolders
|
52
|
+
findFolders(folderId?: string): Promise<any[]>;
|
54
53
|
/**
|
55
54
|
* Get all files content for the specified type ('KEYPAIRs' | 'VCs' | 'SESSIONs' | 'DIDs' | 'RECOMMENDATIONs')
|
56
55
|
* @param type
|
57
56
|
* @returns
|
58
57
|
*/
|
59
|
-
getAllFilesByType(type:
|
58
|
+
getAllFilesByType(type: FileType): Promise<any[]>;
|
60
59
|
/**
|
61
60
|
* Update the name of a file in Google Drive
|
62
61
|
* @param fileId - The ID of the file to update
|
@@ -4,7 +4,10 @@ export declare class ResumeVC {
|
|
4
4
|
issuerDid: string;
|
5
5
|
keyPair: any;
|
6
6
|
}): Promise<any>;
|
7
|
-
|
7
|
+
generateUnsignedCredential({ formData, issuerDid }: {
|
8
|
+
formData: any;
|
9
|
+
issuerDid: string;
|
10
|
+
}): any;
|
8
11
|
generateKeyPair: (address?: string) => Promise<any>;
|
9
12
|
/**
|
10
13
|
* Create a new DID with Digital Bazaar's Ed25519VerificationKey2020 key pair.
|
@@ -6,23 +6,97 @@ export declare const inlineResumeContext: {
|
|
6
6
|
primaryLanguage: string;
|
7
7
|
narrative: string;
|
8
8
|
text: string;
|
9
|
+
contact: string;
|
10
|
+
email: string;
|
11
|
+
phone: string;
|
12
|
+
location: string;
|
13
|
+
street: string;
|
14
|
+
city: string;
|
15
|
+
state: string;
|
16
|
+
country: string;
|
17
|
+
postalCode: string;
|
18
|
+
socialLinks: {
|
19
|
+
'@id': string;
|
20
|
+
'@container': string;
|
21
|
+
};
|
22
|
+
linkedin: string;
|
23
|
+
github: string;
|
24
|
+
portfolio: string;
|
25
|
+
twitter: string;
|
26
|
+
experience: {
|
27
|
+
'@id': string;
|
28
|
+
'@container': string;
|
29
|
+
};
|
9
30
|
employmentHistory: {
|
10
31
|
'@id': string;
|
11
32
|
'@container': string;
|
12
33
|
};
|
13
34
|
company: string;
|
14
35
|
position: string;
|
36
|
+
description: string;
|
37
|
+
startDate: string;
|
38
|
+
endDate: string;
|
39
|
+
stillEmployed: string;
|
15
40
|
duration: string;
|
16
41
|
skills: {
|
17
42
|
'@id': string;
|
18
43
|
'@container': string;
|
19
44
|
};
|
20
|
-
educationAndLearning:
|
45
|
+
educationAndLearning: {
|
46
|
+
'@id': string;
|
47
|
+
'@container': string;
|
48
|
+
};
|
21
49
|
degree: string;
|
50
|
+
fieldOfStudy: string;
|
22
51
|
institution: string;
|
23
52
|
year: string;
|
24
|
-
|
53
|
+
awards: {
|
54
|
+
'@id': string;
|
55
|
+
'@container': string;
|
56
|
+
};
|
57
|
+
title: string;
|
25
58
|
issuer: string;
|
59
|
+
date: string;
|
60
|
+
publications: {
|
61
|
+
'@id': string;
|
62
|
+
'@container': string;
|
63
|
+
};
|
64
|
+
publisher: string;
|
65
|
+
url: string;
|
66
|
+
certifications: {
|
67
|
+
'@id': string;
|
68
|
+
'@container': string;
|
69
|
+
};
|
70
|
+
professionalAffiliations: {
|
71
|
+
'@id': string;
|
72
|
+
'@container': string;
|
73
|
+
};
|
74
|
+
organization: string;
|
75
|
+
role: string;
|
76
|
+
volunteerWork: {
|
77
|
+
'@id': string;
|
78
|
+
'@container': string;
|
79
|
+
};
|
80
|
+
hobbiesAndInterests: {
|
81
|
+
'@id': string;
|
82
|
+
'@container': string;
|
83
|
+
};
|
84
|
+
languages: {
|
85
|
+
'@id': string;
|
86
|
+
'@container': string;
|
87
|
+
};
|
88
|
+
language: string;
|
89
|
+
proficiency: string;
|
90
|
+
testimonials: {
|
91
|
+
'@id': string;
|
92
|
+
'@container': string;
|
93
|
+
};
|
94
|
+
author: string;
|
95
|
+
projects: {
|
96
|
+
'@id': string;
|
97
|
+
'@container': string;
|
98
|
+
};
|
99
|
+
issuanceDate: string;
|
26
100
|
credentialSubject: string;
|
27
101
|
person: string;
|
28
102
|
Resume: string;
|
@@ -29,8 +29,8 @@ export declare function generateUnsignedVC({ formData, issuerDid }: {
|
|
29
29
|
* @returns {RecommendationCredential} The created unsigned Recommendation Credential.
|
30
30
|
* @throws Will throw an error if the recommendation creation fails or if issuance date exceeds expiration date.
|
31
31
|
*/
|
32
|
-
export declare function generateUnsignedRecommendation({
|
33
|
-
|
32
|
+
export declare function generateUnsignedRecommendation({ vcId, recommendation, issuerDid, }: {
|
33
|
+
vcId: string;
|
34
34
|
recommendation: RecommendationFormDataI;
|
35
35
|
issuerDid: string;
|
36
36
|
}): RecommendationCredential;
|
@@ -12,8 +12,9 @@ export declare const getVCWithRecommendations: ({ vcId, storage }: {
|
|
12
12
|
}) => Promise<{
|
13
13
|
vc: {
|
14
14
|
data: any;
|
15
|
+
id: string;
|
15
16
|
};
|
16
|
-
|
17
|
+
recommendationIds: any;
|
17
18
|
relationsFileId: any;
|
18
19
|
}>;
|
19
20
|
/**
|
@@ -26,13 +27,14 @@ export declare const getVCWithRecommendations: ({ vcId, storage }: {
|
|
26
27
|
*/
|
27
28
|
export declare function saveToGoogleDrive({ storage, data, type }: SaveToGooglePropsI): Promise<any>;
|
28
29
|
/**
|
29
|
-
* Upload
|
30
|
+
* Upload any type of file to Google Drive in the Credentials/MEDIAs folder.
|
30
31
|
* @param {GoogleDriveStorage} storage - The GoogleDriveStorage instance.
|
31
|
-
* @param {File}
|
32
|
-
* @
|
32
|
+
* @param {File} file - The file to upload.
|
33
|
+
* @param {string} folderName - The name of the folder where the file will be saved (default is 'MEDIAs').
|
34
|
+
* @returns {Promise<{ id: string }>} - The uploaded file object.
|
33
35
|
* @throws Will throw an error if the upload operation fails.
|
34
36
|
*/
|
35
|
-
export declare function
|
37
|
+
export declare function uploadToGoogleDrive(storage: GoogleDriveStorage, file: File, folderName?: string): Promise<{
|
36
38
|
id: string;
|
37
39
|
}>;
|
38
40
|
export declare function generateViewLink(fileId: string): string;
|
package/dist/utils/context.js
CHANGED
@@ -1,31 +1,121 @@
|
|
1
1
|
export const inlineResumeContext = {
|
2
2
|
'@context': {
|
3
3
|
'@vocab': 'https://schema.hropenstandards.org/4.4/',
|
4
|
+
// Basic details
|
4
5
|
name: 'https://schema.org/name',
|
5
6
|
formattedName: 'https://schema.org/formattedName',
|
6
7
|
primaryLanguage: 'https://schema.org/primaryLanguage',
|
8
|
+
// Narrative
|
7
9
|
narrative: 'https://schema.org/narrative',
|
8
10
|
text: 'https://schema.org/text',
|
11
|
+
// Contact Information
|
12
|
+
contact: 'https://schema.org/ContactPoint',
|
13
|
+
email: 'https://schema.org/email',
|
14
|
+
phone: 'https://schema.org/telephone',
|
15
|
+
location: 'https://schema.org/address',
|
16
|
+
street: 'https://schema.org/streetAddress',
|
17
|
+
city: 'https://schema.org/addressLocality',
|
18
|
+
state: 'https://schema.org/addressRegion',
|
19
|
+
country: 'https://schema.org/addressCountry',
|
20
|
+
postalCode: 'https://schema.org/postalCode',
|
21
|
+
socialLinks: {
|
22
|
+
'@id': 'https://schema.org/URL',
|
23
|
+
'@container': '@set',
|
24
|
+
},
|
25
|
+
linkedin: 'https://schema.org/sameAs',
|
26
|
+
github: 'https://schema.org/sameAs',
|
27
|
+
portfolio: 'https://schema.org/url',
|
28
|
+
twitter: 'https://schema.org/sameAs',
|
29
|
+
// Experience & Employment History
|
30
|
+
experience: {
|
31
|
+
'@id': 'https://schema.org/WorkExperience',
|
32
|
+
'@container': '@list',
|
33
|
+
},
|
9
34
|
employmentHistory: {
|
10
35
|
'@id': 'https://schema.org/employmentHistory',
|
11
|
-
'@container': '@list',
|
36
|
+
'@container': '@list',
|
12
37
|
},
|
13
|
-
company: 'https://schema.org/
|
38
|
+
company: 'https://schema.org/worksFor',
|
14
39
|
position: 'https://schema.org/jobTitle',
|
40
|
+
description: 'https://schema.org/description',
|
41
|
+
startDate: 'https://schema.org/startDate',
|
42
|
+
endDate: 'https://schema.org/endDate',
|
43
|
+
stillEmployed: 'https://schema.org/Boolean',
|
15
44
|
duration: 'https://schema.org/temporalCoverage',
|
45
|
+
// Skills
|
16
46
|
skills: {
|
17
47
|
'@id': 'https://schema.org/skills',
|
18
|
-
'@container': '@list',
|
48
|
+
'@container': '@list',
|
19
49
|
},
|
20
|
-
|
21
|
-
|
22
|
-
|
50
|
+
// Education
|
51
|
+
educationAndLearning: {
|
52
|
+
'@id': 'https://schema.org/EducationalOccupationalProgram',
|
53
|
+
'@container': '@list',
|
54
|
+
},
|
55
|
+
degree: 'https://schema.org/educationalCredentialAwarded',
|
56
|
+
fieldOfStudy: 'https://schema.org/studyField',
|
57
|
+
institution: 'https://schema.org/educationalInstitution',
|
23
58
|
year: 'https://schema.org/year',
|
24
|
-
|
59
|
+
// Awards
|
60
|
+
awards: {
|
61
|
+
'@id': 'https://schema.org/Achievement',
|
62
|
+
'@container': '@list',
|
63
|
+
},
|
64
|
+
title: 'https://schema.org/name',
|
25
65
|
issuer: 'https://schema.org/issuer',
|
66
|
+
date: 'https://schema.org/dateReceived',
|
67
|
+
// Publications
|
68
|
+
publications: {
|
69
|
+
'@id': 'https://schema.org/CreativeWork',
|
70
|
+
'@container': '@list',
|
71
|
+
},
|
72
|
+
publisher: 'https://schema.org/publisher',
|
73
|
+
url: 'https://schema.org/url',
|
74
|
+
// Certifications
|
75
|
+
certifications: {
|
76
|
+
'@id': 'https://schema.org/EducationalOccupationalCredential',
|
77
|
+
'@container': '@list',
|
78
|
+
},
|
79
|
+
// Professional Affiliations
|
80
|
+
professionalAffiliations: {
|
81
|
+
'@id': 'https://schema.org/OrganizationRole',
|
82
|
+
'@container': '@list',
|
83
|
+
},
|
84
|
+
organization: 'https://schema.org/memberOf',
|
85
|
+
role: 'https://schema.org/jobTitle',
|
86
|
+
// Volunteer Work
|
87
|
+
volunteerWork: {
|
88
|
+
'@id': 'https://schema.org/VolunteerRole',
|
89
|
+
'@container': '@list',
|
90
|
+
},
|
91
|
+
// Hobbies and Interests
|
92
|
+
hobbiesAndInterests: {
|
93
|
+
'@id': 'https://schema.org/knowsAbout',
|
94
|
+
'@container': '@set',
|
95
|
+
},
|
96
|
+
// Languages
|
97
|
+
languages: {
|
98
|
+
'@id': 'https://schema.org/knowsLanguage',
|
99
|
+
'@container': '@list',
|
100
|
+
},
|
101
|
+
language: 'https://schema.org/inLanguage',
|
102
|
+
proficiency: 'https://schema.org/proficiencyLevel',
|
103
|
+
// Testimonials
|
104
|
+
testimonials: {
|
105
|
+
'@id': 'https://schema.org/Review',
|
106
|
+
'@container': '@list',
|
107
|
+
},
|
108
|
+
author: 'https://schema.org/author',
|
109
|
+
// Projects
|
110
|
+
projects: {
|
111
|
+
'@id': 'https://schema.org/Project',
|
112
|
+
'@container': '@list',
|
113
|
+
},
|
114
|
+
// Issuance Information
|
115
|
+
issuanceDate: 'https://schema.org/issuanceDate',
|
26
116
|
credentialSubject: 'https://schema.org/credentialSubject',
|
27
|
-
person: 'https://schema.org/Person', //
|
28
|
-
Resume: 'https://schema.hropenstandards.org/4.4#Resume',
|
117
|
+
person: 'https://schema.org/Person', // Map to Person schema
|
118
|
+
Resume: 'https://schema.hropenstandards.org/4.4#Resume',
|
29
119
|
},
|
30
120
|
};
|
31
121
|
let localOBContext = {
|
package/dist/utils/credential.js
CHANGED
@@ -131,10 +131,7 @@ export function generateUnsignedVC({ formData, issuerDid }) {
|
|
131
131
|
* @returns {RecommendationCredential} The created unsigned Recommendation Credential.
|
132
132
|
* @throws Will throw an error if the recommendation creation fails or if issuance date exceeds expiration date.
|
133
133
|
*/
|
134
|
-
export function generateUnsignedRecommendation({
|
135
|
-
console.log('🚀 ~ vc.id:', vc.id);
|
136
|
-
console.log('🚀 ~ vc:', vc);
|
137
|
-
console.log('🚀 ~ recommendation:', recommendation);
|
134
|
+
export function generateUnsignedRecommendation({ vcId, recommendation, issuerDid, }) {
|
138
135
|
const issuanceDate = new Date().toISOString();
|
139
136
|
if (issuanceDate > recommendation.expirationDate)
|
140
137
|
throw new Error('issuanceDate cannot be after expirationDate');
|
@@ -150,7 +147,7 @@ export function generateUnsignedRecommendation({ vc, recommendation, issuerDid,
|
|
150
147
|
portfolio: 'https://schema.org/portfolio',
|
151
148
|
},
|
152
149
|
],
|
153
|
-
id:
|
150
|
+
id: `urn:${generateHashedId({ id: vcId })}`,
|
154
151
|
type: ['VerifiableCredential', 'https://schema.org/RecommendationCredential'],
|
155
152
|
issuer: {
|
156
153
|
id: issuerDid,
|
@@ -170,8 +167,6 @@ export function generateUnsignedRecommendation({ vc, recommendation, issuerDid,
|
|
170
167
|
})),
|
171
168
|
},
|
172
169
|
};
|
173
|
-
// Use the VC's hashed ID for the Recommendation's ID
|
174
|
-
unsignedRecommendation.id = vc.data.id;
|
175
170
|
return unsignedRecommendation;
|
176
171
|
}
|
177
172
|
/**
|
package/dist/utils/google.js
CHANGED
@@ -1,16 +1,18 @@
|
|
1
1
|
export const getVCWithRecommendations = async ({ vcId, storage }) => {
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
2
|
+
try {
|
3
|
+
const vcFolderId = await storage.getFileParents(vcId);
|
4
|
+
const files = await storage.findFilesUnderFolder(vcFolderId);
|
5
|
+
const relationsFile = files.find((f) => f.name === 'RELATIONS');
|
6
|
+
const relationsContent = await storage.retrieve(relationsFile.id);
|
7
|
+
const relationsData = relationsContent.data.body ? JSON.parse(relationsContent.data.body) : relationsContent.data;
|
8
|
+
const recommendationIds = relationsData.recommendations || [];
|
9
|
+
const vc = await storage.retrieve(vcId);
|
10
|
+
return { vc: vc, recommendationIds, relationsFileId: relationsFile.id };
|
11
|
+
}
|
12
|
+
catch (error) {
|
13
|
+
console.error('Error getting VC with recommendations:', error);
|
14
|
+
throw error;
|
15
|
+
}
|
14
16
|
};
|
15
17
|
/**
|
16
18
|
* Save data to Google Drive in the specified folder type.
|
@@ -53,7 +55,6 @@ export async function saveToGoogleDrive({ storage, data, type }) {
|
|
53
55
|
}
|
54
56
|
// Save the file in the specific subfolder
|
55
57
|
const file = await storage.saveFile({ data: fileData, folderId: typeFolderId });
|
56
|
-
console.log('🚀 ~ file:', file);
|
57
58
|
return file;
|
58
59
|
}
|
59
60
|
catch (error) {
|
@@ -62,17 +63,19 @@ export async function saveToGoogleDrive({ storage, data, type }) {
|
|
62
63
|
}
|
63
64
|
}
|
64
65
|
/**
|
65
|
-
* Upload
|
66
|
+
* Upload any type of file to Google Drive in the Credentials/MEDIAs folder.
|
66
67
|
* @param {GoogleDriveStorage} storage - The GoogleDriveStorage instance.
|
67
|
-
* @param {File}
|
68
|
-
* @
|
68
|
+
* @param {File} file - The file to upload.
|
69
|
+
* @param {string} folderName - The name of the folder where the file will be saved (default is 'MEDIAs').
|
70
|
+
* @returns {Promise<{ id: string }>} - The uploaded file object.
|
69
71
|
* @throws Will throw an error if the upload operation fails.
|
70
72
|
*/
|
71
|
-
export async function
|
73
|
+
export async function uploadToGoogleDrive(storage, file, folderName = 'MEDIAs') {
|
72
74
|
try {
|
73
75
|
const rootFolders = await storage.findFolders();
|
74
76
|
let credentialsFolder = rootFolders.find((f) => f.name === 'Credentials');
|
75
77
|
if (!credentialsFolder) {
|
78
|
+
console.log('Creating Credentials folder...');
|
76
79
|
credentialsFolder = await storage.createFolder({ folderName: 'Credentials', parentFolderId: 'root' });
|
77
80
|
}
|
78
81
|
const credentialsFolderId = credentialsFolder.id;
|
@@ -83,17 +86,16 @@ export async function uploadImageToGoogleDrive(storage, imageFile) {
|
|
83
86
|
}
|
84
87
|
const mediasFolderId = mediasFolder.id;
|
85
88
|
// Prepare the image file data
|
86
|
-
const
|
87
|
-
fileName:
|
88
|
-
mimeType:
|
89
|
-
body:
|
89
|
+
const fileMetaData = {
|
90
|
+
fileName: file.name,
|
91
|
+
mimeType: file.type,
|
92
|
+
body: file,
|
90
93
|
};
|
91
94
|
// SaveFile the image in the "MEDIAs" folder
|
92
95
|
const uploadedImage = await storage.saveFile({
|
93
|
-
data:
|
96
|
+
data: fileMetaData,
|
94
97
|
folderId: mediasFolderId,
|
95
98
|
});
|
96
|
-
console.log('🚀 ~ uploadedImage:', uploadedImage);
|
97
99
|
return uploadedImage;
|
98
100
|
}
|
99
101
|
catch (error) {
|