@cooperation/vc-storage 1.0.44 → 1.0.45

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/index.js CHANGED
@@ -8,3 +8,4 @@ export * from './models/WASZcapStorage.js';
8
8
  export * from './models/StorageContext.js';
9
9
  export * from './utils/createWASSpace.js';
10
10
  export * from './utils/getOrCreateAppDID.js';
11
+ export * from './utils/context.js';
@@ -8,3 +8,4 @@ export * from './models/WASZcapStorage.js';
8
8
  export * from './models/StorageContext.js';
9
9
  export * from './utils/createWASSpace.js';
10
10
  export * from './utils/getOrCreateAppDID.js';
11
+ export * from './utils/context.js';
@@ -14,7 +14,7 @@ export declare class LCWStorage {
14
14
  ok: boolean;
15
15
  headers: [string, string][];
16
16
  status: number;
17
- blob(): Promise<import("buffer").Blob>;
17
+ blob(): Promise<import("node:buffer").Blob>;
18
18
  json(): Promise<unknown>;
19
19
  }>;
20
20
  read(key: string): Promise<unknown>;
@@ -22,7 +22,7 @@ export declare class LCWStorage {
22
22
  ok: boolean;
23
23
  headers: [string, string][];
24
24
  status: number;
25
- blob(): Promise<import("buffer").Blob>;
25
+ blob(): Promise<import("node:buffer").Blob>;
26
26
  json(): Promise<unknown>;
27
27
  }>;
28
28
  delete(key: string): Promise<boolean>;
@@ -148,6 +148,36 @@ export declare const volunteeringCredentialContext: {
148
148
  evidenceDescription: string;
149
149
  };
150
150
  };
151
+ export declare const VC_V2_CONTEXT = "https://www.w3.org/ns/credentials/v2";
152
+ export declare const OB_V3_CONTEXT = "https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json";
153
+ export declare const HR_V1_CONTEXT = "https://w3id.org/hr/v1";
154
+ export declare const ED25519_2020_CONTEXT = "https://w3id.org/security/suites/ed25519-2020/v1";
155
+ /** @context array for SkillClaimCredential signing (single source of truth). */
156
+ export declare const skillClaimCredentialContexts: string[];
157
+ /** JSON-LD terms for RecommendationCredential (schema.org + VC v2). */
158
+ export declare const recommendationCredentialContext: {
159
+ '@context': {
160
+ recipientName: string;
161
+ howKnow: string;
162
+ recommendationText: string;
163
+ qualifications: string;
164
+ explainAnswer: string;
165
+ portfolio: string;
166
+ skillsEndorsed: string;
167
+ };
168
+ };
169
+ /** @context array for RecommendationCredential signing (single source of truth). */
170
+ export declare const recommendationCredentialContexts: (string | {
171
+ '@context': {
172
+ recipientName: string;
173
+ howKnow: string;
174
+ recommendationText: string;
175
+ qualifications: string;
176
+ explainAnswer: string;
177
+ portfolio: string;
178
+ skillsEndorsed: string;
179
+ };
180
+ })[];
151
181
  export declare const performanceReviewCredentialContext: {
152
182
  '@context': {
153
183
  '@vocab': string;
@@ -1,4 +1,4 @@
1
- import { KeyPair, DidDocument, FormDataI, RecommendationFormDataI, EmploymentFormDataI, VolunteeringFormDataI, PerformanceReviewFormDataI } from '../../types';
1
+ import { KeyPair, DidDocument, FormDataI, RecommendationFormDataI, EvidenceItem, EmploymentFormDataI, VolunteeringFormDataI, PerformanceReviewFormDataI } from '../../types';
2
2
  import type { ISkillClaimCredential } from 'hr-context';
3
3
  import { IVerifiableCredential } from '@digitalcredentials/ssi';
4
4
  /**
@@ -22,19 +22,14 @@ export declare function generateUnsignedVC({ formData, issuerDid }: {
22
22
  issuerDid: string;
23
23
  }): IVerifiableCredential;
24
24
  /**
25
- * Generate an unsigned Recommendation Credential.
26
- * Uses the hash of the VC to set the `id` for consistency.
27
- * @param {object} params
28
- * @param {IVerifiableCredential} params.vc - The Verifiable Credential to base the recommendation on.
29
- * @param {RecommendationFormDataI} params.recommendation - The recommendation form data.
30
- * @param {string} params.issuerDid - The DID of the issuer.
31
- * @returns {IVerifiableCredential} The created unsigned Recommendation Credential.
32
- * @throws Will throw an error if the recommendation creation fails or if issuance date exceeds expiration date.
25
+ * Generate an unsigned Recommendation Credential (VC Data Model v2).
26
+ * Uses the target skill-claim VC id on credentialSubject.id.
33
27
  */
34
- export declare function generateUnsignedRecommendation({ vcId, recommendation, issuerDid, }: {
28
+ export declare function generateUnsignedRecommendation({ vcId, recommendation, issuerDid, evidence, }: {
35
29
  vcId: string;
36
30
  recommendation: RecommendationFormDataI;
37
31
  issuerDid: string;
32
+ evidence?: EvidenceItem[];
38
33
  }): IVerifiableCredential;
39
34
  /**
40
35
  * Generate an unsigned Employment Credential.
@@ -166,6 +166,37 @@ export const volunteeringCredentialContext = {
166
166
  evidenceDescription: 'https://schema.org/description'
167
167
  }
168
168
  };
169
+ export const VC_V2_CONTEXT = 'https://www.w3.org/ns/credentials/v2';
170
+ export const OB_V3_CONTEXT = 'https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json';
171
+ export const HR_V1_CONTEXT = 'https://w3id.org/hr/v1';
172
+ export const ED25519_2020_CONTEXT = 'https://w3id.org/security/suites/ed25519-2020/v1';
173
+ /** @context array for SkillClaimCredential signing (single source of truth). */
174
+ export const skillClaimCredentialContexts = [
175
+ VC_V2_CONTEXT,
176
+ OB_V3_CONTEXT,
177
+ HR_V1_CONTEXT,
178
+ ED25519_2020_CONTEXT,
179
+ ];
180
+ /** JSON-LD terms for RecommendationCredential (schema.org + VC v2). */
181
+ export const recommendationCredentialContext = {
182
+ '@context': {
183
+ recipientName: 'https://schema.org/name',
184
+ howKnow: 'https://schema.org/howKnow',
185
+ recommendationText: 'https://schema.org/recommendationText',
186
+ qualifications: 'https://schema.org/qualifications',
187
+ explainAnswer: 'https://schema.org/explainAnswer',
188
+ portfolio: 'https://schema.org/portfolio',
189
+ skillsEndorsed: 'https://schema.org/skillsEndorsed',
190
+ },
191
+ };
192
+ /** @context array for RecommendationCredential signing (single source of truth). */
193
+ export const recommendationCredentialContexts = [
194
+ VC_V2_CONTEXT,
195
+ OB_V3_CONTEXT,
196
+ HR_V1_CONTEXT,
197
+ recommendationCredentialContext,
198
+ ED25519_2020_CONTEXT,
199
+ ];
169
200
  // 3. Performance Review Credential Context
170
201
  export const performanceReviewCredentialContext = {
171
202
  '@context': {
@@ -1,7 +1,7 @@
1
1
  import { Ed25519VerificationKey2020 } from '@digitalcredentials/ed25519-verification-key-2020';
2
2
  import { v4 as uuidv4 } from 'uuid';
3
3
  import CryptoJS from 'crypto-js';
4
- import { employmentCredentialContext, volunteeringCredentialContext, performanceReviewCredentialContext } from './context.js';
4
+ import { employmentCredentialContext, volunteeringCredentialContext, performanceReviewCredentialContext, recommendationCredentialContexts, skillClaimCredentialContexts, } from './context.js';
5
5
  /**
6
6
  * Utility function to generate a hashed ID for a credential.
7
7
  * Excludes the `id` field when hashing.
@@ -123,54 +123,38 @@ export function generateUnsignedVC({ formData, issuerDid }) {
123
123
  return unsignedCredential;
124
124
  }
125
125
  /**
126
- * Generate an unsigned Recommendation Credential.
127
- * Uses the hash of the VC to set the `id` for consistency.
128
- * @param {object} params
129
- * @param {IVerifiableCredential} params.vc - The Verifiable Credential to base the recommendation on.
130
- * @param {RecommendationFormDataI} params.recommendation - The recommendation form data.
131
- * @param {string} params.issuerDid - The DID of the issuer.
132
- * @returns {IVerifiableCredential} The created unsigned Recommendation Credential.
133
- * @throws Will throw an error if the recommendation creation fails or if issuance date exceeds expiration date.
126
+ * Generate an unsigned Recommendation Credential (VC Data Model v2).
127
+ * Uses the target skill-claim VC id on credentialSubject.id.
134
128
  */
135
- export function generateUnsignedRecommendation({ vcId, recommendation, issuerDid, }) {
136
- const issuanceDate = new Date().toISOString();
137
- if (issuanceDate > recommendation.expirationDate)
138
- throw new Error('issuanceDate cannot be after expirationDate');
129
+ export function generateUnsignedRecommendation({ vcId, recommendation, issuerDid, evidence = [], }) {
139
130
  const unsignedRecommendation = {
140
- '@context': [
141
- 'https://www.w3.org/2018/credentials/v1',
142
- 'https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json',
143
- {
144
- howKnow: 'https://schema.org/howKnow',
145
- recommendationText: 'https://schema.org/recommendationText',
146
- qualifications: 'https://schema.org/qualifications',
147
- explainAnswer: 'https://schema.org/explainAnswer',
148
- portfolio: 'https://schema.org/portfolio',
149
- },
150
- ],
151
- id: ``,
131
+ '@context': recommendationCredentialContexts,
132
+ id: `urn:uuid:${uuidv4()}`,
152
133
  type: ['VerifiableCredential', 'https://schema.org/RecommendationCredential'],
153
- issuer: {
154
- id: issuerDid,
155
- type: ['Profile'],
156
- },
157
- issuanceDate,
158
- expirationDate: recommendation.expirationDate,
134
+ issuer: { id: issuerDid, type: ['Profile'] },
135
+ validFrom: new Date().toISOString(),
159
136
  credentialSubject: {
160
137
  id: vcId,
161
138
  name: recommendation.fullName,
139
+ ...(recommendation.recipientName ? { recipientName: recommendation.recipientName } : {}),
162
140
  howKnow: recommendation.howKnow,
163
141
  recommendationText: recommendation.recommendationText,
164
- qualifications: recommendation.qualifications,
165
- explainAnswer: recommendation.explainAnswer,
166
- portfolio: recommendation.portfolio.map((item) => ({
167
- name: item.name,
168
- url: item.url,
169
- })),
142
+ ...(recommendation.qualifications ? { qualifications: recommendation.qualifications } : {}),
143
+ ...(recommendation.explainAnswer ? { explainAnswer: recommendation.explainAnswer } : {}),
144
+ ...(recommendation.portfolio?.length ? { portfolio: recommendation.portfolio } : {}),
145
+ ...(recommendation.skillsEndorsed?.length ? { skillsEndorsed: recommendation.skillsEndorsed } : {}),
170
146
  },
147
+ ...(evidence.length
148
+ ? {
149
+ evidence: evidence.map((e) => ({
150
+ id: e.id,
151
+ type: Array.isArray(e.type) ? e.type[0] : e.type || 'Evidence',
152
+ name: e.name,
153
+ description: e.description || '',
154
+ })),
155
+ }
156
+ : {}),
171
157
  };
172
- // Generate the hashed ID
173
- unsignedRecommendation.id = 'urn:' + generateHashedId(unsignedRecommendation);
174
158
  return unsignedRecommendation;
175
159
  }
176
160
  /**
@@ -280,12 +264,7 @@ export function generateUnsignedPerformanceReview({ formData, issuerDid }) {
280
264
  */
281
265
  export function generateUnsignedSkillClaim({ formData, issuerDid, }) {
282
266
  const unsignedCredential = {
283
- '@context': [
284
- 'https://www.w3.org/ns/credentials/v2',
285
- 'https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json',
286
- 'https://w3id.org/hr/v1',
287
- 'https://w3id.org/security/suites/ed25519-2020/v1',
288
- ],
267
+ '@context': skillClaimCredentialContexts,
289
268
  id: `urn:uuid:${uuidv4()}`,
290
269
  type: ['VerifiableCredential', 'SkillClaimCredential'],
291
270
  issuer: issuerDid,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cooperation/vc-storage",
3
3
  "type": "module",
4
- "version": "1.0.44",
4
+ "version": "1.0.45",
5
5
  "description": "Sign and store your verifiable credentials.",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/types/index.d.ts",
@@ -43,6 +43,7 @@
43
43
  "devDependencies": {
44
44
  "@types/fs-extra": "^11.0.4",
45
45
  "@types/jest": "^29.5.14",
46
+ "@types/node": "^25.9.0",
46
47
  "@types/uuid": "^10.0.0",
47
48
  "babel-jest": "^29.7.0",
48
49
  "typescript": "^5.8.3",