@learncard/linked-claims-plugin 0.1.2 → 0.1.3

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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,OAAO,KAAK,EAAE,kBAAkB,EAAsB,kCAAkC,EAAE,MAAM,SAAS,CAAC;AAE1G,cAAc,SAAS,CAAC;AA8BxB,eAAO,MAAM,qBAAqB,cACnB,SAAS,CAAC,GAAG,EAAE,IAAI,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,EAAE,kCAAkC,CAAC,KACjG,kBAmHD,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,OAAO,KAAK,EAAE,kBAAkB,EAAE,kCAAkC,EAAE,MAAM,SAAS,CAAC;AAEtF,cAAc,SAAS,CAAC;AA8BxB,eAAO,MAAM,qBAAqB,cACnB,SAAS,CAAC,GAAG,EAAE,IAAI,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,EAAE,kCAAkC,CAAC,KACjG,kBAgJD,CAAC"}
@@ -80,7 +80,8 @@ var getLinkedClaimsPlugin = /* @__PURE__ */ __name((learnCard) => ({
80
80
  ...details.endorsementComment ? { endorsementComment: details.endorsementComment } : {}
81
81
  },
82
82
  ...details.name ? { name: details.name } : { name: `Endorsement of ${targetId}` },
83
- ...details.description ? { description: details.description } : {}
83
+ ...details.description ? { description: details.description } : {},
84
+ ...details.evidence && { evidence: details.evidence }
84
85
  };
85
86
  return learnCard.invoke.issueCredential(unsigned);
86
87
  },
@@ -98,7 +99,9 @@ var getLinkedClaimsPlugin = /* @__PURE__ */ __name((learnCard) => ({
98
99
  const csObj = Array.isArray(cs) ? cs[0] : cs;
99
100
  const csTypes = ensureArray(csObj?.type);
100
101
  if (!csTypes.includes("EndorsementSubject")) {
101
- check.errors.push("linked-claims error: credentialSubject.type must include EndorsementSubject");
102
+ check.errors.push(
103
+ "linked-claims error: credentialSubject.type must include EndorsementSubject"
104
+ );
102
105
  }
103
106
  if (!csObj?.id) {
104
107
  check.errors.push("linked-claims error: credentialSubject.id missing");
@@ -112,13 +115,19 @@ var getLinkedClaimsPlugin = /* @__PURE__ */ __name((learnCard) => ({
112
115
  if (!storeName)
113
116
  throw new Error("No store plane provider available");
114
117
  if (!learnCard.store[storeName].uploadEncrypted || typeof learnCard.store[storeName].uploadEncrypted !== "function") {
115
- throw new Error(`Store provider '${storeName}' does not support uploadEncrypted method`);
118
+ throw new Error(
119
+ `Store provider '${storeName}' does not support uploadEncrypted method`
120
+ );
116
121
  }
117
- const uri = await learnCard.store[storeName].uploadEncrypted(endorsement);
122
+ const uri = await learnCard.store[storeName].uploadEncrypted(
123
+ endorsement
124
+ );
118
125
  const indexName = pickIndexProvider(learnCard, options?.indexName);
119
126
  let indexed = false;
120
127
  let id = endorsement.id || `urn:uuid:${globalThis.crypto?.randomUUID?.() || (() => {
121
- throw new Error("Secure random UUID generation is not available. Please use an environment that supports crypto.randomUUID().");
128
+ throw new Error(
129
+ "Secure random UUID generation is not available. Please use an environment that supports crypto.randomUUID()."
130
+ );
122
131
  })()}`;
123
132
  if (indexName) {
124
133
  const cs = endorsement.credentialSubject;
@@ -131,7 +140,11 @@ var getLinkedClaimsPlugin = /* @__PURE__ */ __name((learnCard) => ({
131
140
  subjectId: csObj?.id,
132
141
  originalCredentialId: csObj?.id,
133
142
  issuedOn: endorsement.validFrom || endorsement.issuanceDate,
134
- category: "Endorsement"
143
+ category: "Endorsement",
144
+ credentialId: options?.credentialId,
145
+ sharedUri: options?.sharedUri,
146
+ relationship: options?.relationship,
147
+ visibility: options?.visibility ?? "public"
135
148
  };
136
149
  indexed = await learnCard.index[indexName].add(record);
137
150
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/index.ts"],
4
- "sourcesContent": ["import type { LearnCard } from '@learncard/core';\nimport type { VC, UnsignedVC } from '@learncard/types';\nimport type { LinkedClaimsPlugin, EndorsementDetails, LinkedClaimsPluginDependentMethods } from './types';\n\nexport * from './types';\n\nconst ENDORSEMENT_CONTEXT = 'https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json';\n\nconst getSubjectIds = (credential: VC): string[] => {\n const subject = credential.credentialSubject as any;\n if (Array.isArray(subject)) return subject.map(s => s?.id).filter(Boolean);\n return subject?.id ? [subject.id] : [];\n};\n\nconst pickIndexProvider = (learnCard: any, preferred?: string): string | undefined => {\n const providers = Object.keys(learnCard.index || {}).filter(\n k => !['providers', 'all'].includes(k)\n );\n if (!providers.length) return undefined;\n if (preferred && providers.includes(preferred)) return preferred;\n if (providers.includes('LearnCloud')) return 'LearnCloud';\n return providers[0];\n};\n\nconst pickStoreProvider = (learnCard: any, preferred?: string): string | undefined => {\n const providers = Object.keys(learnCard.store || {}).filter(k => k !== 'providers');\n if (!providers.length) return undefined;\n if (preferred && providers.includes(preferred)) return preferred;\n return providers[0];\n};\n\nconst ensureArray = <T>(arr: T | T[] | undefined): T[] =>\n Array.isArray(arr) ? arr : arr ? [arr] : [];\n\nexport const getLinkedClaimsPlugin = (\n learnCard: LearnCard<any, 'id' | 'store' | 'index' | 'read', LinkedClaimsPluginDependentMethods>\n): LinkedClaimsPlugin => ({\n name: 'LinkedClaims',\n displayName: 'LinkedClaims',\n description: 'Create, verify, store, and retrieve endorsement credentials linked to originals.',\n methods: {\n endorseCredential: async (_learnCard, original, details, opts) => {\n const issuer = learnCard.id.did();\n\n const originalId: string | undefined = (original as any).id;\n const subjectIds = getSubjectIds(original);\n const targetId = originalId || subjectIds[0];\n if (!targetId) throw new Error('Original credential must have either id or credentialSubject.id');\n\n const context: (string | Record<string, any>)[] = [\n 'https://www.w3.org/ns/credentials/v2',\n ENDORSEMENT_CONTEXT,\n ];\n\n const types: [string, ...string[]] = ['VerifiableCredential', 'EndorsementCredential'];\n\n const unsigned: UnsignedVC = {\n '@context': context as any,\n type: types,\n issuer,\n validFrom: new Date().toISOString(),\n credentialSubject: {\n type: ['EndorsementSubject'],\n id: targetId,\n ...(details.endorsementComment\n ? { endorsementComment: details.endorsementComment }\n : {}),\n },\n ...(details.name ? { name: details.name } : { name: `Endorsement of ${targetId}` }),\n ...(details.description ? { description: details.description } : {}),\n };\n\n return learnCard.invoke.issueCredential(unsigned);\n },\n\n verifyEndorsement: async (_learnCard, endorsement, options) => {\n const check = await learnCard.invoke.verifyCredential(endorsement, options);\n\n const ctx = ensureArray((endorsement as any)['@context']);\n const types = ensureArray((endorsement as any)['type']);\n\n if (!ctx.some((c: string) => c === 'https://www.w3.org/ns/credentials/v2') || !ctx.some((c: string) => c === ENDORSEMENT_CONTEXT)) {\n check.errors.push('linked-claims error: missing VCv2 or OBv3 context');\n }\n if (!types.includes('EndorsementCredential')) {\n check.errors.push('linked-claims error: missing EndorsementCredential type');\n }\n\n const cs: any = (endorsement as any).credentialSubject;\n const csObj = Array.isArray(cs) ? cs[0] : cs;\n const csTypes = ensureArray<string>(csObj?.type);\n if (!csTypes.includes('EndorsementSubject')) {\n check.errors.push('linked-claims error: credentialSubject.type must include EndorsementSubject');\n }\n if (!csObj?.id) {\n check.errors.push('linked-claims error: credentialSubject.id missing');\n }\n\n if (!check.errors.length) check.checks.push('linked-claims');\n return check;\n },\n\n storeEndorsement: async (_learnCard, endorsement, options) => {\n const storeName = pickStoreProvider(learnCard, options?.storeName);\n if (!storeName) throw new Error('No store plane provider available');\n if (!learnCard.store[storeName].uploadEncrypted || typeof learnCard.store[storeName].uploadEncrypted !== 'function') {\n throw new Error(`Store provider '${storeName}' does not support uploadEncrypted method`);\n }\n const uri: string = await (learnCard.store as any)[storeName].uploadEncrypted(endorsement);\n\n const indexName = pickIndexProvider(learnCard, options?.indexName);\n let indexed = false;\n let id = (endorsement as any).id || `urn:uuid:${(globalThis as any).crypto?.randomUUID?.() || (() => { throw new Error('Secure random UUID generation is not available. Please use an environment that supports crypto.randomUUID().'); })()}`;\n\n if (indexName) {\n const cs: any = (endorsement as any).credentialSubject;\n const csObj = Array.isArray(cs) ? cs[0] : cs;\n const record = {\n id,\n uri,\n type: ensureArray((endorsement as any).type),\n endorsedId: csObj?.id,\n subjectId: csObj?.id,\n originalCredentialId: csObj?.id,\n issuedOn: (endorsement as any).validFrom || (endorsement as any).issuanceDate,\n category: 'Endorsement',\n };\n indexed = await (learnCard.index as any)[indexName].add(record);\n }\n\n return { uri, indexed, id, indexName, storeName };\n },\n\n getEndorsements: async (_learnCard, original, options) => {\n const indexName = pickIndexProvider(learnCard, options?.indexName);\n if (!indexName) return [];\n\n const subjectIds = getSubjectIds(original);\n const originalId = (original as any).id;\n\n const query = originalId ? { originalCredentialId: originalId } : { endorsedId: subjectIds[0] };\n const records = await (learnCard.index as any)[indexName].get(query);\n\n const results: VC[] = [];\n for (const rec of records) {\n const vc = await learnCard.read.get(rec.uri);\n if (vc) results.push(vc as VC);\n }\n return results;\n },\n },\n});\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type { LearnCard } from '@learncard/core';\nimport type { VC, UnsignedVC } from '@learncard/types';\nimport type { LinkedClaimsPlugin, LinkedClaimsPluginDependentMethods } from './types';\n\nexport * from './types';\n\nconst ENDORSEMENT_CONTEXT = 'https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json';\n\nconst getSubjectIds = (credential: VC): string[] => {\n const subject = credential.credentialSubject as any;\n if (Array.isArray(subject)) return subject.map(s => s?.id).filter(Boolean);\n return subject?.id ? [subject.id] : [];\n};\n\nconst pickIndexProvider = (learnCard: any, preferred?: string): string | undefined => {\n const providers = Object.keys(learnCard.index || {}).filter(\n k => !['providers', 'all'].includes(k)\n );\n if (!providers.length) return undefined;\n if (preferred && providers.includes(preferred)) return preferred;\n if (providers.includes('LearnCloud')) return 'LearnCloud';\n return providers[0];\n};\n\nconst pickStoreProvider = (learnCard: any, preferred?: string): string | undefined => {\n const providers = Object.keys(learnCard.store || {}).filter(k => k !== 'providers');\n if (!providers.length) return undefined;\n if (preferred && providers.includes(preferred)) return preferred;\n return providers[0];\n};\n\nconst ensureArray = <T>(arr: T | T[] | undefined): T[] =>\n Array.isArray(arr) ? arr : arr ? [arr] : [];\n\nexport const getLinkedClaimsPlugin = (\n learnCard: LearnCard<any, 'id' | 'store' | 'index' | 'read', LinkedClaimsPluginDependentMethods>\n): LinkedClaimsPlugin => ({\n name: 'LinkedClaims',\n displayName: 'LinkedClaims',\n description: 'Create, verify, store, and retrieve endorsement credentials linked to originals.',\n methods: {\n endorseCredential: async (_learnCard, original, details, opts) => {\n const issuer = learnCard.id.did();\n\n const originalId: string | undefined = (original as any).id;\n const subjectIds = getSubjectIds(original);\n const targetId = originalId || subjectIds[0];\n if (!targetId)\n throw new Error('Original credential must have either id or credentialSubject.id');\n\n const context: (string | Record<string, any>)[] = [\n 'https://www.w3.org/ns/credentials/v2',\n ENDORSEMENT_CONTEXT,\n ];\n\n const types: [string, ...string[]] = ['VerifiableCredential', 'EndorsementCredential'];\n\n const unsigned: UnsignedVC = {\n '@context': context as any,\n type: types,\n issuer,\n validFrom: new Date().toISOString(),\n credentialSubject: {\n type: ['EndorsementSubject'],\n id: targetId,\n ...(details.endorsementComment\n ? { endorsementComment: details.endorsementComment }\n : {}),\n },\n ...(details.name ? { name: details.name } : { name: `Endorsement of ${targetId}` }),\n ...(details.description ? { description: details.description } : {}),\n ...(details.evidence && { evidence: details.evidence }),\n };\n\n return learnCard.invoke.issueCredential(unsigned);\n },\n\n verifyEndorsement: async (_learnCard, endorsement, options) => {\n const check = await learnCard.invoke.verifyCredential(endorsement, options);\n\n const ctx = ensureArray((endorsement as any)['@context']);\n const types = ensureArray((endorsement as any)['type']);\n\n if (\n !ctx.some((c: string) => c === 'https://www.w3.org/ns/credentials/v2') ||\n !ctx.some((c: string) => c === ENDORSEMENT_CONTEXT)\n ) {\n check.errors.push('linked-claims error: missing VCv2 or OBv3 context');\n }\n if (!types.includes('EndorsementCredential')) {\n check.errors.push('linked-claims error: missing EndorsementCredential type');\n }\n\n const cs: any = (endorsement as any).credentialSubject;\n const csObj = Array.isArray(cs) ? cs[0] : cs;\n const csTypes = ensureArray<string>(csObj?.type);\n if (!csTypes.includes('EndorsementSubject')) {\n check.errors.push(\n 'linked-claims error: credentialSubject.type must include EndorsementSubject'\n );\n }\n if (!csObj?.id) {\n check.errors.push('linked-claims error: credentialSubject.id missing');\n }\n\n if (!check.errors.length) check.checks.push('linked-claims');\n return check;\n },\n\n storeEndorsement: async (_learnCard, endorsement, options) => {\n const storeName = pickStoreProvider(learnCard, options?.storeName);\n if (!storeName) throw new Error('No store plane provider available');\n if (\n !learnCard.store[storeName].uploadEncrypted ||\n typeof learnCard.store[storeName].uploadEncrypted !== 'function'\n ) {\n throw new Error(\n `Store provider '${storeName}' does not support uploadEncrypted method`\n );\n }\n const uri: string = await (learnCard.store as any)[storeName].uploadEncrypted(\n endorsement\n );\n\n const indexName = pickIndexProvider(learnCard, options?.indexName);\n let indexed = false;\n let id =\n (endorsement as any).id ||\n `urn:uuid:${\n (globalThis as any).crypto?.randomUUID?.() ||\n (() => {\n throw new Error(\n 'Secure random UUID generation is not available. Please use an environment that supports crypto.randomUUID().'\n );\n })()\n }`;\n\n if (indexName) {\n const cs: any = (endorsement as any).credentialSubject;\n const csObj = Array.isArray(cs) ? cs[0] : cs;\n const record = {\n id,\n uri,\n type: ensureArray((endorsement as any).type),\n endorsedId: csObj?.id,\n subjectId: csObj?.id,\n originalCredentialId: csObj?.id,\n issuedOn: (endorsement as any).validFrom || (endorsement as any).issuanceDate,\n category: 'Endorsement',\n credentialId: options?.credentialId, // original credential id\n sharedUri: options?.sharedUri, // original credential shared uri\n relationship: options?.relationship,\n visibility: options?.visibility ?? 'public',\n };\n indexed = await (learnCard.index as any)[indexName].add(record);\n }\n\n return { uri, indexed, id, indexName, storeName };\n },\n\n getEndorsements: async (_learnCard, original, options) => {\n const indexName = pickIndexProvider(learnCard, options?.indexName);\n if (!indexName) return [];\n\n const subjectIds = getSubjectIds(original);\n const originalId = (original as any).id;\n\n const query = originalId\n ? { originalCredentialId: originalId }\n : { endorsedId: subjectIds[0] };\n const records = await (learnCard.index as any)[indexName].get(query);\n\n const results: VC[] = [];\n for (const rec of records) {\n const vc = await learnCard.read.get(rec.uri);\n if (vc) results.push(vc as VC);\n }\n return results;\n },\n },\n});\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,2 +1,2 @@
1
- "use strict";var p=Object.defineProperty;var v=Object.getOwnPropertyDescriptor;var b=Object.getOwnPropertyNames;var C=Object.prototype.hasOwnProperty;var y=(e,t)=>p(e,"name",{value:t,configurable:!0});var E=(e,t)=>{for(var n in t)p(e,n,{get:t[n],enumerable:!0})},w=(e,t,n,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of b(t))!C.call(e,r)&&r!==n&&p(e,r,{get:()=>t[r],enumerable:!(s=v(t,r))||s.enumerable});return e};var k=e=>w(p({},"__esModule",{value:!0}),e);var S={};E(S,{getLinkedClaimsPlugin:()=>x});module.exports=k(S);var g="https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json",f=y(e=>{let t=e.credentialSubject;return Array.isArray(t)?t.map(n=>n?.id).filter(Boolean):t?.id?[t.id]:[]},"getSubjectIds"),h=y((e,t)=>{let n=Object.keys(e.index||{}).filter(s=>!["providers","all"].includes(s));if(!!n.length)return t&&n.includes(t)?t:n.includes("LearnCloud")?"LearnCloud":n[0]},"pickIndexProvider"),j=y((e,t)=>{let n=Object.keys(e.store||{}).filter(s=>s!=="providers");if(!!n.length)return t&&n.includes(t)?t:n[0]},"pickStoreProvider"),m=y(e=>Array.isArray(e)?e:e?[e]:[],"ensureArray"),x=y(e=>({name:"LinkedClaims",displayName:"LinkedClaims",description:"Create, verify, store, and retrieve endorsement credentials linked to originals.",methods:{endorseCredential:async(t,n,s,r)=>{let c=e.id.did(),o=n.id,d=f(n),i=o||d[0];if(!i)throw new Error("Original credential must have either id or credentialSubject.id");let l={"@context":["https://www.w3.org/ns/credentials/v2",g],type:["VerifiableCredential","EndorsementCredential"],issuer:c,validFrom:new Date().toISOString(),credentialSubject:{type:["EndorsementSubject"],id:i,...s.endorsementComment?{endorsementComment:s.endorsementComment}:{}},...s.name?{name:s.name}:{name:`Endorsement of ${i}`},...s.description?{description:s.description}:{}};return e.invoke.issueCredential(l)},verifyEndorsement:async(t,n,s)=>{let r=await e.invoke.verifyCredential(n,s),c=m(n["@context"]),o=m(n.type);(!c.some(a=>a==="https://www.w3.org/ns/credentials/v2")||!c.some(a=>a===g))&&r.errors.push("linked-claims error: missing VCv2 or OBv3 context"),o.includes("EndorsementCredential")||r.errors.push("linked-claims error: missing EndorsementCredential type");let d=n.credentialSubject,i=Array.isArray(d)?d[0]:d;return m(i?.type).includes("EndorsementSubject")||r.errors.push("linked-claims error: credentialSubject.type must include EndorsementSubject"),i?.id||r.errors.push("linked-claims error: credentialSubject.id missing"),r.errors.length||r.checks.push("linked-claims"),r},storeEndorsement:async(t,n,s)=>{let r=j(e,s?.storeName);if(!r)throw new Error("No store plane provider available");if(!e.store[r].uploadEncrypted||typeof e.store[r].uploadEncrypted!="function")throw new Error(`Store provider '${r}' does not support uploadEncrypted method`);let c=await e.store[r].uploadEncrypted(n),o=h(e,s?.indexName),d=!1,i=n.id||`urn:uuid:${globalThis.crypto?.randomUUID?.()||(()=>{throw new Error("Secure random UUID generation is not available. Please use an environment that supports crypto.randomUUID().")})()}`;if(o){let u=n.credentialSubject,a=Array.isArray(u)?u[0]:u,l={id:i,uri:c,type:m(n.type),endorsedId:a?.id,subjectId:a?.id,originalCredentialId:a?.id,issuedOn:n.validFrom||n.issuanceDate,category:"Endorsement"};d=await e.index[o].add(l)}return{uri:c,indexed:d,id:i,indexName:o,storeName:r}},getEndorsements:async(t,n,s)=>{let r=h(e,s?.indexName);if(!r)return[];let c=f(n),o=n.id,d=o?{originalCredentialId:o}:{endorsedId:c[0]},i=await e.index[r].get(d),u=[];for(let a of i){let l=await e.read.get(a.uri);l&&u.push(l)}return u}}}),"getLinkedClaimsPlugin");
1
+ "use strict";var p=Object.defineProperty;var h=Object.getOwnPropertyDescriptor;var b=Object.getOwnPropertyNames;var C=Object.prototype.hasOwnProperty;var y=(e,t)=>p(e,"name",{value:t,configurable:!0});var E=(e,t)=>{for(var n in t)p(e,n,{get:t[n],enumerable:!0})},w=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of b(t))!C.call(e,i)&&i!==n&&p(e,i,{get:()=>t[i],enumerable:!(r=h(t,i))||r.enumerable});return e};var k=e=>w(p({},"__esModule",{value:!0}),e);var I={};E(I,{getLinkedClaimsPlugin:()=>x});module.exports=k(I);var g="https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json",f=y(e=>{let t=e.credentialSubject;return Array.isArray(t)?t.map(n=>n?.id).filter(Boolean):t?.id?[t.id]:[]},"getSubjectIds"),v=y((e,t)=>{let n=Object.keys(e.index||{}).filter(r=>!["providers","all"].includes(r));if(!!n.length)return t&&n.includes(t)?t:n.includes("LearnCloud")?"LearnCloud":n[0]},"pickIndexProvider"),j=y((e,t)=>{let n=Object.keys(e.store||{}).filter(r=>r!=="providers");if(!!n.length)return t&&n.includes(t)?t:n[0]},"pickStoreProvider"),m=y(e=>Array.isArray(e)?e:e?[e]:[],"ensureArray"),x=y(e=>({name:"LinkedClaims",displayName:"LinkedClaims",description:"Create, verify, store, and retrieve endorsement credentials linked to originals.",methods:{endorseCredential:async(t,n,r,i)=>{let c=e.id.did(),o=n.id,d=f(n),s=o||d[0];if(!s)throw new Error("Original credential must have either id or credentialSubject.id");let u={"@context":["https://www.w3.org/ns/credentials/v2",g],type:["VerifiableCredential","EndorsementCredential"],issuer:c,validFrom:new Date().toISOString(),credentialSubject:{type:["EndorsementSubject"],id:s,...r.endorsementComment?{endorsementComment:r.endorsementComment}:{}},...r.name?{name:r.name}:{name:`Endorsement of ${s}`},...r.description?{description:r.description}:{},...r.evidence&&{evidence:r.evidence}};return e.invoke.issueCredential(u)},verifyEndorsement:async(t,n,r)=>{let i=await e.invoke.verifyCredential(n,r),c=m(n["@context"]),o=m(n.type);(!c.some(a=>a==="https://www.w3.org/ns/credentials/v2")||!c.some(a=>a===g))&&i.errors.push("linked-claims error: missing VCv2 or OBv3 context"),o.includes("EndorsementCredential")||i.errors.push("linked-claims error: missing EndorsementCredential type");let d=n.credentialSubject,s=Array.isArray(d)?d[0]:d;return m(s?.type).includes("EndorsementSubject")||i.errors.push("linked-claims error: credentialSubject.type must include EndorsementSubject"),s?.id||i.errors.push("linked-claims error: credentialSubject.id missing"),i.errors.length||i.checks.push("linked-claims"),i},storeEndorsement:async(t,n,r)=>{let i=j(e,r?.storeName);if(!i)throw new Error("No store plane provider available");if(!e.store[i].uploadEncrypted||typeof e.store[i].uploadEncrypted!="function")throw new Error(`Store provider '${i}' does not support uploadEncrypted method`);let c=await e.store[i].uploadEncrypted(n),o=v(e,r?.indexName),d=!1,s=n.id||`urn:uuid:${globalThis.crypto?.randomUUID?.()||(()=>{throw new Error("Secure random UUID generation is not available. Please use an environment that supports crypto.randomUUID().")})()}`;if(o){let l=n.credentialSubject,a=Array.isArray(l)?l[0]:l,u={id:s,uri:c,type:m(n.type),endorsedId:a?.id,subjectId:a?.id,originalCredentialId:a?.id,issuedOn:n.validFrom||n.issuanceDate,category:"Endorsement",credentialId:r?.credentialId,sharedUri:r?.sharedUri,relationship:r?.relationship,visibility:r?.visibility??"public"};d=await e.index[o].add(u)}return{uri:c,indexed:d,id:s,indexName:o,storeName:i}},getEndorsements:async(t,n,r)=>{let i=v(e,r?.indexName);if(!i)return[];let c=f(n),o=n.id,d=o?{originalCredentialId:o}:{endorsedId:c[0]},s=await e.index[i].get(d),l=[];for(let a of s){let u=await e.read.get(a.uri);u&&l.push(u)}return l}}}),"getLinkedClaimsPlugin");
2
2
  //# sourceMappingURL=linked-claims-plugin.cjs.production.min.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/index.ts"],
4
- "sourcesContent": ["import type { LearnCard } from '@learncard/core';\nimport type { VC, UnsignedVC } from '@learncard/types';\nimport type { LinkedClaimsPlugin, EndorsementDetails, LinkedClaimsPluginDependentMethods } from './types';\n\nexport * from './types';\n\nconst ENDORSEMENT_CONTEXT = 'https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json';\n\nconst getSubjectIds = (credential: VC): string[] => {\n const subject = credential.credentialSubject as any;\n if (Array.isArray(subject)) return subject.map(s => s?.id).filter(Boolean);\n return subject?.id ? [subject.id] : [];\n};\n\nconst pickIndexProvider = (learnCard: any, preferred?: string): string | undefined => {\n const providers = Object.keys(learnCard.index || {}).filter(\n k => !['providers', 'all'].includes(k)\n );\n if (!providers.length) return undefined;\n if (preferred && providers.includes(preferred)) return preferred;\n if (providers.includes('LearnCloud')) return 'LearnCloud';\n return providers[0];\n};\n\nconst pickStoreProvider = (learnCard: any, preferred?: string): string | undefined => {\n const providers = Object.keys(learnCard.store || {}).filter(k => k !== 'providers');\n if (!providers.length) return undefined;\n if (preferred && providers.includes(preferred)) return preferred;\n return providers[0];\n};\n\nconst ensureArray = <T>(arr: T | T[] | undefined): T[] =>\n Array.isArray(arr) ? arr : arr ? [arr] : [];\n\nexport const getLinkedClaimsPlugin = (\n learnCard: LearnCard<any, 'id' | 'store' | 'index' | 'read', LinkedClaimsPluginDependentMethods>\n): LinkedClaimsPlugin => ({\n name: 'LinkedClaims',\n displayName: 'LinkedClaims',\n description: 'Create, verify, store, and retrieve endorsement credentials linked to originals.',\n methods: {\n endorseCredential: async (_learnCard, original, details, opts) => {\n const issuer = learnCard.id.did();\n\n const originalId: string | undefined = (original as any).id;\n const subjectIds = getSubjectIds(original);\n const targetId = originalId || subjectIds[0];\n if (!targetId) throw new Error('Original credential must have either id or credentialSubject.id');\n\n const context: (string | Record<string, any>)[] = [\n 'https://www.w3.org/ns/credentials/v2',\n ENDORSEMENT_CONTEXT,\n ];\n\n const types: [string, ...string[]] = ['VerifiableCredential', 'EndorsementCredential'];\n\n const unsigned: UnsignedVC = {\n '@context': context as any,\n type: types,\n issuer,\n validFrom: new Date().toISOString(),\n credentialSubject: {\n type: ['EndorsementSubject'],\n id: targetId,\n ...(details.endorsementComment\n ? { endorsementComment: details.endorsementComment }\n : {}),\n },\n ...(details.name ? { name: details.name } : { name: `Endorsement of ${targetId}` }),\n ...(details.description ? { description: details.description } : {}),\n };\n\n return learnCard.invoke.issueCredential(unsigned);\n },\n\n verifyEndorsement: async (_learnCard, endorsement, options) => {\n const check = await learnCard.invoke.verifyCredential(endorsement, options);\n\n const ctx = ensureArray((endorsement as any)['@context']);\n const types = ensureArray((endorsement as any)['type']);\n\n if (!ctx.some((c: string) => c === 'https://www.w3.org/ns/credentials/v2') || !ctx.some((c: string) => c === ENDORSEMENT_CONTEXT)) {\n check.errors.push('linked-claims error: missing VCv2 or OBv3 context');\n }\n if (!types.includes('EndorsementCredential')) {\n check.errors.push('linked-claims error: missing EndorsementCredential type');\n }\n\n const cs: any = (endorsement as any).credentialSubject;\n const csObj = Array.isArray(cs) ? cs[0] : cs;\n const csTypes = ensureArray<string>(csObj?.type);\n if (!csTypes.includes('EndorsementSubject')) {\n check.errors.push('linked-claims error: credentialSubject.type must include EndorsementSubject');\n }\n if (!csObj?.id) {\n check.errors.push('linked-claims error: credentialSubject.id missing');\n }\n\n if (!check.errors.length) check.checks.push('linked-claims');\n return check;\n },\n\n storeEndorsement: async (_learnCard, endorsement, options) => {\n const storeName = pickStoreProvider(learnCard, options?.storeName);\n if (!storeName) throw new Error('No store plane provider available');\n if (!learnCard.store[storeName].uploadEncrypted || typeof learnCard.store[storeName].uploadEncrypted !== 'function') {\n throw new Error(`Store provider '${storeName}' does not support uploadEncrypted method`);\n }\n const uri: string = await (learnCard.store as any)[storeName].uploadEncrypted(endorsement);\n\n const indexName = pickIndexProvider(learnCard, options?.indexName);\n let indexed = false;\n let id = (endorsement as any).id || `urn:uuid:${(globalThis as any).crypto?.randomUUID?.() || (() => { throw new Error('Secure random UUID generation is not available. Please use an environment that supports crypto.randomUUID().'); })()}`;\n\n if (indexName) {\n const cs: any = (endorsement as any).credentialSubject;\n const csObj = Array.isArray(cs) ? cs[0] : cs;\n const record = {\n id,\n uri,\n type: ensureArray((endorsement as any).type),\n endorsedId: csObj?.id,\n subjectId: csObj?.id,\n originalCredentialId: csObj?.id,\n issuedOn: (endorsement as any).validFrom || (endorsement as any).issuanceDate,\n category: 'Endorsement',\n };\n indexed = await (learnCard.index as any)[indexName].add(record);\n }\n\n return { uri, indexed, id, indexName, storeName };\n },\n\n getEndorsements: async (_learnCard, original, options) => {\n const indexName = pickIndexProvider(learnCard, options?.indexName);\n if (!indexName) return [];\n\n const subjectIds = getSubjectIds(original);\n const originalId = (original as any).id;\n\n const query = originalId ? { originalCredentialId: originalId } : { endorsedId: subjectIds[0] };\n const records = await (learnCard.index as any)[indexName].get(query);\n\n const results: VC[] = [];\n for (const rec of records) {\n const vc = await learnCard.read.get(rec.uri);\n if (vc) results.push(vc as VC);\n }\n return results;\n },\n },\n});\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type { LearnCard } from '@learncard/core';\nimport type { VC, UnsignedVC } from '@learncard/types';\nimport type { LinkedClaimsPlugin, LinkedClaimsPluginDependentMethods } from './types';\n\nexport * from './types';\n\nconst ENDORSEMENT_CONTEXT = 'https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json';\n\nconst getSubjectIds = (credential: VC): string[] => {\n const subject = credential.credentialSubject as any;\n if (Array.isArray(subject)) return subject.map(s => s?.id).filter(Boolean);\n return subject?.id ? [subject.id] : [];\n};\n\nconst pickIndexProvider = (learnCard: any, preferred?: string): string | undefined => {\n const providers = Object.keys(learnCard.index || {}).filter(\n k => !['providers', 'all'].includes(k)\n );\n if (!providers.length) return undefined;\n if (preferred && providers.includes(preferred)) return preferred;\n if (providers.includes('LearnCloud')) return 'LearnCloud';\n return providers[0];\n};\n\nconst pickStoreProvider = (learnCard: any, preferred?: string): string | undefined => {\n const providers = Object.keys(learnCard.store || {}).filter(k => k !== 'providers');\n if (!providers.length) return undefined;\n if (preferred && providers.includes(preferred)) return preferred;\n return providers[0];\n};\n\nconst ensureArray = <T>(arr: T | T[] | undefined): T[] =>\n Array.isArray(arr) ? arr : arr ? [arr] : [];\n\nexport const getLinkedClaimsPlugin = (\n learnCard: LearnCard<any, 'id' | 'store' | 'index' | 'read', LinkedClaimsPluginDependentMethods>\n): LinkedClaimsPlugin => ({\n name: 'LinkedClaims',\n displayName: 'LinkedClaims',\n description: 'Create, verify, store, and retrieve endorsement credentials linked to originals.',\n methods: {\n endorseCredential: async (_learnCard, original, details, opts) => {\n const issuer = learnCard.id.did();\n\n const originalId: string | undefined = (original as any).id;\n const subjectIds = getSubjectIds(original);\n const targetId = originalId || subjectIds[0];\n if (!targetId)\n throw new Error('Original credential must have either id or credentialSubject.id');\n\n const context: (string | Record<string, any>)[] = [\n 'https://www.w3.org/ns/credentials/v2',\n ENDORSEMENT_CONTEXT,\n ];\n\n const types: [string, ...string[]] = ['VerifiableCredential', 'EndorsementCredential'];\n\n const unsigned: UnsignedVC = {\n '@context': context as any,\n type: types,\n issuer,\n validFrom: new Date().toISOString(),\n credentialSubject: {\n type: ['EndorsementSubject'],\n id: targetId,\n ...(details.endorsementComment\n ? { endorsementComment: details.endorsementComment }\n : {}),\n },\n ...(details.name ? { name: details.name } : { name: `Endorsement of ${targetId}` }),\n ...(details.description ? { description: details.description } : {}),\n ...(details.evidence && { evidence: details.evidence }),\n };\n\n return learnCard.invoke.issueCredential(unsigned);\n },\n\n verifyEndorsement: async (_learnCard, endorsement, options) => {\n const check = await learnCard.invoke.verifyCredential(endorsement, options);\n\n const ctx = ensureArray((endorsement as any)['@context']);\n const types = ensureArray((endorsement as any)['type']);\n\n if (\n !ctx.some((c: string) => c === 'https://www.w3.org/ns/credentials/v2') ||\n !ctx.some((c: string) => c === ENDORSEMENT_CONTEXT)\n ) {\n check.errors.push('linked-claims error: missing VCv2 or OBv3 context');\n }\n if (!types.includes('EndorsementCredential')) {\n check.errors.push('linked-claims error: missing EndorsementCredential type');\n }\n\n const cs: any = (endorsement as any).credentialSubject;\n const csObj = Array.isArray(cs) ? cs[0] : cs;\n const csTypes = ensureArray<string>(csObj?.type);\n if (!csTypes.includes('EndorsementSubject')) {\n check.errors.push(\n 'linked-claims error: credentialSubject.type must include EndorsementSubject'\n );\n }\n if (!csObj?.id) {\n check.errors.push('linked-claims error: credentialSubject.id missing');\n }\n\n if (!check.errors.length) check.checks.push('linked-claims');\n return check;\n },\n\n storeEndorsement: async (_learnCard, endorsement, options) => {\n const storeName = pickStoreProvider(learnCard, options?.storeName);\n if (!storeName) throw new Error('No store plane provider available');\n if (\n !learnCard.store[storeName].uploadEncrypted ||\n typeof learnCard.store[storeName].uploadEncrypted !== 'function'\n ) {\n throw new Error(\n `Store provider '${storeName}' does not support uploadEncrypted method`\n );\n }\n const uri: string = await (learnCard.store as any)[storeName].uploadEncrypted(\n endorsement\n );\n\n const indexName = pickIndexProvider(learnCard, options?.indexName);\n let indexed = false;\n let id =\n (endorsement as any).id ||\n `urn:uuid:${\n (globalThis as any).crypto?.randomUUID?.() ||\n (() => {\n throw new Error(\n 'Secure random UUID generation is not available. Please use an environment that supports crypto.randomUUID().'\n );\n })()\n }`;\n\n if (indexName) {\n const cs: any = (endorsement as any).credentialSubject;\n const csObj = Array.isArray(cs) ? cs[0] : cs;\n const record = {\n id,\n uri,\n type: ensureArray((endorsement as any).type),\n endorsedId: csObj?.id,\n subjectId: csObj?.id,\n originalCredentialId: csObj?.id,\n issuedOn: (endorsement as any).validFrom || (endorsement as any).issuanceDate,\n category: 'Endorsement',\n credentialId: options?.credentialId, // original credential id\n sharedUri: options?.sharedUri, // original credential shared uri\n relationship: options?.relationship,\n visibility: options?.visibility ?? 'public',\n };\n indexed = await (learnCard.index as any)[indexName].add(record);\n }\n\n return { uri, indexed, id, indexName, storeName };\n },\n\n getEndorsements: async (_learnCard, original, options) => {\n const indexName = pickIndexProvider(learnCard, options?.indexName);\n if (!indexName) return [];\n\n const subjectIds = getSubjectIds(original);\n const originalId = (original as any).id;\n\n const query = originalId\n ? { originalCredentialId: originalId }\n : { endorsedId: subjectIds[0] };\n const records = await (learnCard.index as any)[indexName].get(query);\n\n const results: VC[] = [];\n for (const rec of records) {\n const vc = await learnCard.read.get(rec.uri);\n if (vc) results.push(vc as VC);\n }\n return results;\n },\n },\n});\n"],
5
+ "mappings": "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",
6
6
  "names": ["src_exports", "__export", "getLinkedClaimsPlugin", "__toCommonJS", "ENDORSEMENT_CONTEXT", "getSubjectIds", "__name", "credential", "subject", "s", "pickIndexProvider", "learnCard", "preferred", "providers", "k", "pickStoreProvider", "ensureArray", "arr", "getLinkedClaimsPlugin", "_learnCard", "original", "details", "opts", "issuer", "originalId", "subjectIds", "targetId", "unsigned", "endorsement", "options", "check", "ctx", "types", "c", "cs", "csObj", "storeName", "uri", "indexName", "indexed", "id", "record", "query", "records", "results", "rec", "vc"]
7
7
  }
@@ -58,7 +58,8 @@ var getLinkedClaimsPlugin = /* @__PURE__ */ __name((learnCard) => ({
58
58
  ...details.endorsementComment ? { endorsementComment: details.endorsementComment } : {}
59
59
  },
60
60
  ...details.name ? { name: details.name } : { name: `Endorsement of ${targetId}` },
61
- ...details.description ? { description: details.description } : {}
61
+ ...details.description ? { description: details.description } : {},
62
+ ...details.evidence && { evidence: details.evidence }
62
63
  };
63
64
  return learnCard.invoke.issueCredential(unsigned);
64
65
  },
@@ -76,7 +77,9 @@ var getLinkedClaimsPlugin = /* @__PURE__ */ __name((learnCard) => ({
76
77
  const csObj = Array.isArray(cs) ? cs[0] : cs;
77
78
  const csTypes = ensureArray(csObj?.type);
78
79
  if (!csTypes.includes("EndorsementSubject")) {
79
- check.errors.push("linked-claims error: credentialSubject.type must include EndorsementSubject");
80
+ check.errors.push(
81
+ "linked-claims error: credentialSubject.type must include EndorsementSubject"
82
+ );
80
83
  }
81
84
  if (!csObj?.id) {
82
85
  check.errors.push("linked-claims error: credentialSubject.id missing");
@@ -90,13 +93,19 @@ var getLinkedClaimsPlugin = /* @__PURE__ */ __name((learnCard) => ({
90
93
  if (!storeName)
91
94
  throw new Error("No store plane provider available");
92
95
  if (!learnCard.store[storeName].uploadEncrypted || typeof learnCard.store[storeName].uploadEncrypted !== "function") {
93
- throw new Error(`Store provider '${storeName}' does not support uploadEncrypted method`);
96
+ throw new Error(
97
+ `Store provider '${storeName}' does not support uploadEncrypted method`
98
+ );
94
99
  }
95
- const uri = await learnCard.store[storeName].uploadEncrypted(endorsement);
100
+ const uri = await learnCard.store[storeName].uploadEncrypted(
101
+ endorsement
102
+ );
96
103
  const indexName = pickIndexProvider(learnCard, options?.indexName);
97
104
  let indexed = false;
98
105
  let id = endorsement.id || `urn:uuid:${globalThis.crypto?.randomUUID?.() || (() => {
99
- throw new Error("Secure random UUID generation is not available. Please use an environment that supports crypto.randomUUID().");
106
+ throw new Error(
107
+ "Secure random UUID generation is not available. Please use an environment that supports crypto.randomUUID()."
108
+ );
100
109
  })()}`;
101
110
  if (indexName) {
102
111
  const cs = endorsement.credentialSubject;
@@ -109,7 +118,11 @@ var getLinkedClaimsPlugin = /* @__PURE__ */ __name((learnCard) => ({
109
118
  subjectId: csObj?.id,
110
119
  originalCredentialId: csObj?.id,
111
120
  issuedOn: endorsement.validFrom || endorsement.issuanceDate,
112
- category: "Endorsement"
121
+ category: "Endorsement",
122
+ credentialId: options?.credentialId,
123
+ sharedUri: options?.sharedUri,
124
+ relationship: options?.relationship,
125
+ visibility: options?.visibility ?? "public"
113
126
  };
114
127
  indexed = await learnCard.index[indexName].add(record);
115
128
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/index.ts"],
4
- "sourcesContent": ["import type { LearnCard } from '@learncard/core';\nimport type { VC, UnsignedVC } from '@learncard/types';\nimport type { LinkedClaimsPlugin, EndorsementDetails, LinkedClaimsPluginDependentMethods } from './types';\n\nexport * from './types';\n\nconst ENDORSEMENT_CONTEXT = 'https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json';\n\nconst getSubjectIds = (credential: VC): string[] => {\n const subject = credential.credentialSubject as any;\n if (Array.isArray(subject)) return subject.map(s => s?.id).filter(Boolean);\n return subject?.id ? [subject.id] : [];\n};\n\nconst pickIndexProvider = (learnCard: any, preferred?: string): string | undefined => {\n const providers = Object.keys(learnCard.index || {}).filter(\n k => !['providers', 'all'].includes(k)\n );\n if (!providers.length) return undefined;\n if (preferred && providers.includes(preferred)) return preferred;\n if (providers.includes('LearnCloud')) return 'LearnCloud';\n return providers[0];\n};\n\nconst pickStoreProvider = (learnCard: any, preferred?: string): string | undefined => {\n const providers = Object.keys(learnCard.store || {}).filter(k => k !== 'providers');\n if (!providers.length) return undefined;\n if (preferred && providers.includes(preferred)) return preferred;\n return providers[0];\n};\n\nconst ensureArray = <T>(arr: T | T[] | undefined): T[] =>\n Array.isArray(arr) ? arr : arr ? [arr] : [];\n\nexport const getLinkedClaimsPlugin = (\n learnCard: LearnCard<any, 'id' | 'store' | 'index' | 'read', LinkedClaimsPluginDependentMethods>\n): LinkedClaimsPlugin => ({\n name: 'LinkedClaims',\n displayName: 'LinkedClaims',\n description: 'Create, verify, store, and retrieve endorsement credentials linked to originals.',\n methods: {\n endorseCredential: async (_learnCard, original, details, opts) => {\n const issuer = learnCard.id.did();\n\n const originalId: string | undefined = (original as any).id;\n const subjectIds = getSubjectIds(original);\n const targetId = originalId || subjectIds[0];\n if (!targetId) throw new Error('Original credential must have either id or credentialSubject.id');\n\n const context: (string | Record<string, any>)[] = [\n 'https://www.w3.org/ns/credentials/v2',\n ENDORSEMENT_CONTEXT,\n ];\n\n const types: [string, ...string[]] = ['VerifiableCredential', 'EndorsementCredential'];\n\n const unsigned: UnsignedVC = {\n '@context': context as any,\n type: types,\n issuer,\n validFrom: new Date().toISOString(),\n credentialSubject: {\n type: ['EndorsementSubject'],\n id: targetId,\n ...(details.endorsementComment\n ? { endorsementComment: details.endorsementComment }\n : {}),\n },\n ...(details.name ? { name: details.name } : { name: `Endorsement of ${targetId}` }),\n ...(details.description ? { description: details.description } : {}),\n };\n\n return learnCard.invoke.issueCredential(unsigned);\n },\n\n verifyEndorsement: async (_learnCard, endorsement, options) => {\n const check = await learnCard.invoke.verifyCredential(endorsement, options);\n\n const ctx = ensureArray((endorsement as any)['@context']);\n const types = ensureArray((endorsement as any)['type']);\n\n if (!ctx.some((c: string) => c === 'https://www.w3.org/ns/credentials/v2') || !ctx.some((c: string) => c === ENDORSEMENT_CONTEXT)) {\n check.errors.push('linked-claims error: missing VCv2 or OBv3 context');\n }\n if (!types.includes('EndorsementCredential')) {\n check.errors.push('linked-claims error: missing EndorsementCredential type');\n }\n\n const cs: any = (endorsement as any).credentialSubject;\n const csObj = Array.isArray(cs) ? cs[0] : cs;\n const csTypes = ensureArray<string>(csObj?.type);\n if (!csTypes.includes('EndorsementSubject')) {\n check.errors.push('linked-claims error: credentialSubject.type must include EndorsementSubject');\n }\n if (!csObj?.id) {\n check.errors.push('linked-claims error: credentialSubject.id missing');\n }\n\n if (!check.errors.length) check.checks.push('linked-claims');\n return check;\n },\n\n storeEndorsement: async (_learnCard, endorsement, options) => {\n const storeName = pickStoreProvider(learnCard, options?.storeName);\n if (!storeName) throw new Error('No store plane provider available');\n if (!learnCard.store[storeName].uploadEncrypted || typeof learnCard.store[storeName].uploadEncrypted !== 'function') {\n throw new Error(`Store provider '${storeName}' does not support uploadEncrypted method`);\n }\n const uri: string = await (learnCard.store as any)[storeName].uploadEncrypted(endorsement);\n\n const indexName = pickIndexProvider(learnCard, options?.indexName);\n let indexed = false;\n let id = (endorsement as any).id || `urn:uuid:${(globalThis as any).crypto?.randomUUID?.() || (() => { throw new Error('Secure random UUID generation is not available. Please use an environment that supports crypto.randomUUID().'); })()}`;\n\n if (indexName) {\n const cs: any = (endorsement as any).credentialSubject;\n const csObj = Array.isArray(cs) ? cs[0] : cs;\n const record = {\n id,\n uri,\n type: ensureArray((endorsement as any).type),\n endorsedId: csObj?.id,\n subjectId: csObj?.id,\n originalCredentialId: csObj?.id,\n issuedOn: (endorsement as any).validFrom || (endorsement as any).issuanceDate,\n category: 'Endorsement',\n };\n indexed = await (learnCard.index as any)[indexName].add(record);\n }\n\n return { uri, indexed, id, indexName, storeName };\n },\n\n getEndorsements: async (_learnCard, original, options) => {\n const indexName = pickIndexProvider(learnCard, options?.indexName);\n if (!indexName) return [];\n\n const subjectIds = getSubjectIds(original);\n const originalId = (original as any).id;\n\n const query = originalId ? { originalCredentialId: originalId } : { endorsedId: subjectIds[0] };\n const records = await (learnCard.index as any)[indexName].get(query);\n\n const results: VC[] = [];\n for (const rec of records) {\n const vc = await learnCard.read.get(rec.uri);\n if (vc) results.push(vc as VC);\n }\n return results;\n },\n },\n});\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type { LearnCard } from '@learncard/core';\nimport type { VC, UnsignedVC } from '@learncard/types';\nimport type { LinkedClaimsPlugin, LinkedClaimsPluginDependentMethods } from './types';\n\nexport * from './types';\n\nconst ENDORSEMENT_CONTEXT = 'https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json';\n\nconst getSubjectIds = (credential: VC): string[] => {\n const subject = credential.credentialSubject as any;\n if (Array.isArray(subject)) return subject.map(s => s?.id).filter(Boolean);\n return subject?.id ? [subject.id] : [];\n};\n\nconst pickIndexProvider = (learnCard: any, preferred?: string): string | undefined => {\n const providers = Object.keys(learnCard.index || {}).filter(\n k => !['providers', 'all'].includes(k)\n );\n if (!providers.length) return undefined;\n if (preferred && providers.includes(preferred)) return preferred;\n if (providers.includes('LearnCloud')) return 'LearnCloud';\n return providers[0];\n};\n\nconst pickStoreProvider = (learnCard: any, preferred?: string): string | undefined => {\n const providers = Object.keys(learnCard.store || {}).filter(k => k !== 'providers');\n if (!providers.length) return undefined;\n if (preferred && providers.includes(preferred)) return preferred;\n return providers[0];\n};\n\nconst ensureArray = <T>(arr: T | T[] | undefined): T[] =>\n Array.isArray(arr) ? arr : arr ? [arr] : [];\n\nexport const getLinkedClaimsPlugin = (\n learnCard: LearnCard<any, 'id' | 'store' | 'index' | 'read', LinkedClaimsPluginDependentMethods>\n): LinkedClaimsPlugin => ({\n name: 'LinkedClaims',\n displayName: 'LinkedClaims',\n description: 'Create, verify, store, and retrieve endorsement credentials linked to originals.',\n methods: {\n endorseCredential: async (_learnCard, original, details, opts) => {\n const issuer = learnCard.id.did();\n\n const originalId: string | undefined = (original as any).id;\n const subjectIds = getSubjectIds(original);\n const targetId = originalId || subjectIds[0];\n if (!targetId)\n throw new Error('Original credential must have either id or credentialSubject.id');\n\n const context: (string | Record<string, any>)[] = [\n 'https://www.w3.org/ns/credentials/v2',\n ENDORSEMENT_CONTEXT,\n ];\n\n const types: [string, ...string[]] = ['VerifiableCredential', 'EndorsementCredential'];\n\n const unsigned: UnsignedVC = {\n '@context': context as any,\n type: types,\n issuer,\n validFrom: new Date().toISOString(),\n credentialSubject: {\n type: ['EndorsementSubject'],\n id: targetId,\n ...(details.endorsementComment\n ? { endorsementComment: details.endorsementComment }\n : {}),\n },\n ...(details.name ? { name: details.name } : { name: `Endorsement of ${targetId}` }),\n ...(details.description ? { description: details.description } : {}),\n ...(details.evidence && { evidence: details.evidence }),\n };\n\n return learnCard.invoke.issueCredential(unsigned);\n },\n\n verifyEndorsement: async (_learnCard, endorsement, options) => {\n const check = await learnCard.invoke.verifyCredential(endorsement, options);\n\n const ctx = ensureArray((endorsement as any)['@context']);\n const types = ensureArray((endorsement as any)['type']);\n\n if (\n !ctx.some((c: string) => c === 'https://www.w3.org/ns/credentials/v2') ||\n !ctx.some((c: string) => c === ENDORSEMENT_CONTEXT)\n ) {\n check.errors.push('linked-claims error: missing VCv2 or OBv3 context');\n }\n if (!types.includes('EndorsementCredential')) {\n check.errors.push('linked-claims error: missing EndorsementCredential type');\n }\n\n const cs: any = (endorsement as any).credentialSubject;\n const csObj = Array.isArray(cs) ? cs[0] : cs;\n const csTypes = ensureArray<string>(csObj?.type);\n if (!csTypes.includes('EndorsementSubject')) {\n check.errors.push(\n 'linked-claims error: credentialSubject.type must include EndorsementSubject'\n );\n }\n if (!csObj?.id) {\n check.errors.push('linked-claims error: credentialSubject.id missing');\n }\n\n if (!check.errors.length) check.checks.push('linked-claims');\n return check;\n },\n\n storeEndorsement: async (_learnCard, endorsement, options) => {\n const storeName = pickStoreProvider(learnCard, options?.storeName);\n if (!storeName) throw new Error('No store plane provider available');\n if (\n !learnCard.store[storeName].uploadEncrypted ||\n typeof learnCard.store[storeName].uploadEncrypted !== 'function'\n ) {\n throw new Error(\n `Store provider '${storeName}' does not support uploadEncrypted method`\n );\n }\n const uri: string = await (learnCard.store as any)[storeName].uploadEncrypted(\n endorsement\n );\n\n const indexName = pickIndexProvider(learnCard, options?.indexName);\n let indexed = false;\n let id =\n (endorsement as any).id ||\n `urn:uuid:${\n (globalThis as any).crypto?.randomUUID?.() ||\n (() => {\n throw new Error(\n 'Secure random UUID generation is not available. Please use an environment that supports crypto.randomUUID().'\n );\n })()\n }`;\n\n if (indexName) {\n const cs: any = (endorsement as any).credentialSubject;\n const csObj = Array.isArray(cs) ? cs[0] : cs;\n const record = {\n id,\n uri,\n type: ensureArray((endorsement as any).type),\n endorsedId: csObj?.id,\n subjectId: csObj?.id,\n originalCredentialId: csObj?.id,\n issuedOn: (endorsement as any).validFrom || (endorsement as any).issuanceDate,\n category: 'Endorsement',\n credentialId: options?.credentialId, // original credential id\n sharedUri: options?.sharedUri, // original credential shared uri\n relationship: options?.relationship,\n visibility: options?.visibility ?? 'public',\n };\n indexed = await (learnCard.index as any)[indexName].add(record);\n }\n\n return { uri, indexed, id, indexName, storeName };\n },\n\n getEndorsements: async (_learnCard, original, options) => {\n const indexName = pickIndexProvider(learnCard, options?.indexName);\n if (!indexName) return [];\n\n const subjectIds = getSubjectIds(original);\n const originalId = (original as any).id;\n\n const query = originalId\n ? { originalCredentialId: originalId }\n : { endorsedId: subjectIds[0] };\n const records = await (learnCard.index as any)[indexName].get(query);\n\n const results: VC[] = [];\n for (const rec of records) {\n const vc = await learnCard.read.get(rec.uri);\n if (vc) results.push(vc as VC);\n }\n return results;\n },\n },\n});\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
package/dist/types.d.ts CHANGED
@@ -2,14 +2,34 @@ import { Plugin } from '@learncard/core';
2
2
  import { VC, VerificationCheck } from '@learncard/types';
3
3
  import { VCPluginMethods } from '@learncard/vc-plugin';
4
4
  import { ProofOptions } from '@learncard/didkit-plugin';
5
+ export type EndorsementEvidence = {
6
+ id?: string;
7
+ type: string | [string, ...string[]];
8
+ name?: string;
9
+ narrative?: string;
10
+ description?: string;
11
+ genre?: string;
12
+ audience?: string;
13
+ [key: string]: any;
14
+ };
5
15
  export type EndorsementDetails = {
6
16
  endorsementComment?: string;
7
17
  name?: string;
8
18
  description?: string;
19
+ evidence?: EndorsementEvidence;
20
+ };
21
+ export type EndorsementRelationship = {
22
+ type: string;
23
+ label: string;
9
24
  };
25
+ export type EndorsementVisibility = 'public' | 'private';
10
26
  export type StoreIndexOptions = {
11
27
  storeName?: string;
12
28
  indexName?: string;
29
+ credentialId?: string;
30
+ sharedUri?: string;
31
+ relationship?: EndorsementRelationship;
32
+ visibility?: EndorsementVisibility;
13
33
  };
14
34
  export type LinkedClaimsPluginDependentMethods = VCPluginMethods;
15
35
  export type LinkedClaimsPluginMethods = {
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,EAAE,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAExD,MAAM,MAAM,kBAAkB,GAAG;IAE7B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,kCAAkC,GAAG,eAAe,CAAC;AAEjE,MAAM,MAAM,yBAAyB,GAAG;IACpC,iBAAiB,EAAE,CACf,QAAQ,EAAE,EAAE,EACZ,OAAO,EAAE,kBAAkB,EAC3B,OAAO,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,KAChC,OAAO,CAAC,EAAE,CAAC,CAAC;IAEjB,iBAAiB,EAAE,CACf,WAAW,EAAE,EAAE,EACf,OAAO,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,KAC9B,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAEhC,gBAAgB,EAAE,CACd,WAAW,EAAE,EAAE,EACf,OAAO,CAAC,EAAE,iBAAiB,KAC1B,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAEpG,eAAe,EAAE,CACb,QAAQ,EAAE,EAAE,EACZ,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,KAC/B,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,MAAM,CACnC,cAAc,EACd,GAAG,EACH,yBAAyB,EACzB,IAAI,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,EACjC,kCAAkC,CACrC,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAE,EAAE,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAExD,MAAM,MAAM,mBAAmB,GAAG;IAC9B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAE7B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,mBAAmB,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEzD,MAAM,MAAM,iBAAiB,GAAG;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,uBAAuB,CAAC;IACvC,UAAU,CAAC,EAAE,qBAAqB,CAAC;CACtC,CAAC;AAEF,MAAM,MAAM,kCAAkC,GAAG,eAAe,CAAC;AAEjE,MAAM,MAAM,yBAAyB,GAAG;IACpC,iBAAiB,EAAE,CACf,QAAQ,EAAE,EAAE,EACZ,OAAO,EAAE,kBAAkB,EAC3B,OAAO,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,KAChC,OAAO,CAAC,EAAE,CAAC,CAAC;IAEjB,iBAAiB,EAAE,CACf,WAAW,EAAE,EAAE,EACf,OAAO,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,KAC9B,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAEhC,gBAAgB,EAAE,CACd,WAAW,EAAE,EAAE,EACf,OAAO,CAAC,EAAE,iBAAiB,KAC1B,OAAO,CAAC;QACT,GAAG,EAAE,MAAM,CAAC;QACZ,OAAO,EAAE,OAAO,CAAC;QACjB,EAAE,EAAE,MAAM,CAAC;QACX,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,SAAS,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC,CAAC;IAEH,eAAe,EAAE,CAAC,QAAQ,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;CACtF,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,MAAM,CACnC,cAAc,EACd,GAAG,EACH,yBAAyB,EACzB,IAAI,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,EACjC,kCAAkC,CACrC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@learncard/linked-claims-plugin",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "LinkedClaims plugin to create, verify, store, and query endorsement credentials.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/linked-claims-plugin.esm.js",
@@ -31,9 +31,9 @@
31
31
  "types": "./dist/index.d.ts",
32
32
  "dependencies": {
33
33
  "why-is-node-running": "^2.2.2",
34
- "@learncard/core": "9.3.42",
35
- "@learncard/types": "5.9.0",
36
- "@learncard/vc-plugin": "^1.2.5"
34
+ "@learncard/core": "9.3.43",
35
+ "@learncard/types": "5.9.1",
36
+ "@learncard/vc-plugin": "^1.2.6"
37
37
  },
38
38
  "scripts": {
39
39
  "build": "node ./scripts/build.mjs && shx cp ./scripts/mixedEntypoint.js ./dist/index.js && tsc --p tsconfig.json",