{"version":3,"file":"W3cCredentialRecord.mjs","names":[],"sources":["../../../../src/modules/vc/repository/W3cCredentialRecord.ts"],"sourcesContent":["import { BaseRecord, type Tags } from '../../../storage/BaseRecord'\nimport type { NonEmptyArray } from '../../../types'\nimport { JsonTransformer } from '../../../utils'\nimport { CredentialMultiInstanceState } from '../../../utils/credentialUseTypes'\nimport type { Constructable } from '../../../utils/mixins'\nimport { uuid } from '../../../utils/uuid'\nimport { W3cJwtVerifiableCredential } from '../jwt-vc'\nimport { W3cJsonLdVerifiableCredential } from '../linked-data-proofs/models/W3cJsonLdVerifiableCredential'\nimport { ClaimFormat, type W3cVerifiableCredential } from '../models'\nimport type { W3cJsonCredential } from '../models/credential/W3cJsonCredential'\n\nexport interface W3cCredentialRecordOptions {\n  id?: string\n  createdAt?: Date\n  tags?: CustomW3cCredentialTags\n\n  /**\n   * The W3C credential instances to store on the record.\n   *\n   * NOTE that all instances should contain roughly the same data (e.g. exp can differ slighty), as they should be usable\n   * interchangeably for presentations (allowing single-use credentials and batch issuance).\n   */\n  credentialInstances: W3cCredentialRecordInstances\n}\n\nexport type W3cCredentialRecordInstances = NonEmptyArray<{\n  credential: string | W3cJsonCredential\n\n  // no kmsKeyId for w3c credential record, since all credentials are bound to a DID\n}>\n\nexport type CustomW3cCredentialTags = {\n  /**\n   * Expanded types are used for JSON-LD credentials to allow for filtering on the expanded type.\n   */\n  expandedTypes?: Array<string>\n}\n\nexport type DefaultW3cCredentialTags = {\n  issuerId: string\n  subjectIds: Array<string>\n  schemaIds: Array<string>\n  contexts: Array<string>\n  givenId?: string\n\n  // Can be any of the values for claimFormat\n  claimFormat: W3cVerifiableCredential['claimFormat']\n\n  proofTypes?: Array<string>\n  cryptosuites?: Array<string>\n  types: Array<string>\n  algs?: Array<string>\n\n  /**\n   * @since 0.6 - tag was not defined before 0.6\n   */\n  multiInstanceState?: CredentialMultiInstanceState\n}\n\nexport class W3cCredentialRecord extends BaseRecord<DefaultW3cCredentialTags, CustomW3cCredentialTags> {\n  public static readonly type = 'W3cCredentialRecord'\n  public readonly type = W3cCredentialRecord.type\n\n  public credentialInstances!: W3cCredentialRecordInstances\n\n  /**\n   * Tracks the state of credential instances on this record.\n   *\n   * NOTE: This defaults to `CredentialMultiInstanceState.SingleInstanceUsed` for records that\n   * don't have a value set from before 0.6. We assume the credential has already been used.\n   */\n  public multiInstanceState = CredentialMultiInstanceState.SingleInstanceUsed\n\n  public constructor(props: W3cCredentialRecordOptions) {\n    super()\n    if (props) {\n      this.id = props.id ?? uuid()\n      this.createdAt = props.createdAt ?? new Date()\n      this._tags = props.tags ?? {}\n      this.credentialInstances = props.credentialInstances\n\n      // Set multiInstanceState based on the number of initial instances. We\n      // assume the instance is unused when the record is created.\n      this.multiInstanceState =\n        this.credentialInstances.length === 1\n          ? CredentialMultiInstanceState.SingleInstanceUnused\n          : CredentialMultiInstanceState.MultiInstanceFirstUnused\n    }\n  }\n\n  /**\n   * Only here for class transformation. If credential is set we transform\n   * it to the new credentialInstances array format\n   */\n  private set credential(credential: W3cVerifiableCredential) {\n    this.credentialInstances = [\n      {\n        // NOTE: we have to type the `set` method the same as the `get`. Previously\n        // we had a transformer that would transform. Now the set is private and will\n        // only be called by class transformer, and is the raw type.\n        credential: credential as unknown as string | W3cJsonCredential,\n      },\n    ]\n  }\n\n  public get firstCredential(): W3cVerifiableCredential {\n    const credential = this.credentialInstances[0].credential\n    return typeof credential === 'string'\n      ? W3cJwtVerifiableCredential.fromSerializedJwt(credential)\n      : W3cJsonLdVerifiableCredential.fromJson(credential)\n  }\n\n  public static fromCredential(credential: W3cVerifiableCredential) {\n    return new W3cCredentialRecord({\n      credentialInstances: [\n        {\n          credential: credential.encoded as string | W3cJsonCredential,\n        },\n      ],\n      tags: {},\n    })\n  }\n\n  public getTags(): Tags<DefaultW3cCredentialTags, CustomW3cCredentialTags> {\n    const credential = this.firstCredential\n    // Contexts are usually strings, but can sometimes be objects. We're unable to use objects as tags,\n    // so we filter out the objects before setting the tags.\n    const stringContexts = credential.contexts.filter((ctx): ctx is string => typeof ctx === 'string')\n\n    const tags: Tags<DefaultW3cCredentialTags, CustomW3cCredentialTags> = {\n      ...this._tags,\n      issuerId: credential.issuerId,\n      subjectIds: credential.credentialSubjectIds,\n      schemaIds: credential.credentialSchemaIds,\n      contexts: stringContexts,\n      givenId: credential.id,\n      claimFormat: credential.claimFormat,\n      types: credential.type,\n      multiInstanceState: this.multiInstanceState,\n    }\n\n    // Proof types is used for ldp_vc credentials\n    if (credential.claimFormat === ClaimFormat.LdpVc) {\n      tags.proofTypes = credential.proofTypes\n      tags.cryptosuites = credential.anonCredsW3cCredentialCryptosuites\n    }\n\n    // Algs is used for jwt_vc credentials\n    else if (credential.claimFormat === ClaimFormat.JwtVc) {\n      tags.algs = [credential.jwt.header.alg]\n    }\n\n    return tags\n  }\n\n  /**\n   * This overwrites the default clone method for records\n   * as the W3cRecord has issues with the default clone method\n   * due to how W3cJwtVerifiableCredential is implemented. This is\n   * a temporary way to make sure the clone still works, but ideally\n   * we find an alternative.\n   */\n  public clone(): this {\n    return JsonTransformer.fromJSON(JsonTransformer.toJSON(this), this.constructor as Constructable<this>)\n  }\n\n  /**\n   * encoded is convenience method added to all credential records\n   */\n  public get encoded() {\n    return this.credentialInstances[0].credential\n  }\n}\n"],"mappings":";;;;;;;;;;;AA2DA,IAAa,sBAAb,MAAa,4BAA4B,WAA8D;CAcrG,YAAmB,OAAmC;EACpD,MAAM;EAbR,KAAgB,OAAO,oBAAoB;EAU3C,KAAO,qBAAA;EAIL,IAAI,OAAO;GACT,KAAK,KAAK,MAAM,MAAM,KAAK;GAC3B,KAAK,YAAY,MAAM,6BAAa,IAAI,KAAK;GAC7C,KAAK,QAAQ,MAAM,QAAQ,CAAC;GAC5B,KAAK,sBAAsB,MAAM;GAIjC,KAAK,qBACH,KAAK,oBAAoB,WAAW,IAAA,yBAAA;EAGxC;CACF;;;;;CAMA,IAAY,WAAW,YAAqC;EAC1D,KAAK,sBAAsB,CACzB,EAIc,WACd,CACF;CACF;CAEA,IAAW,kBAA2C;EACpD,MAAM,aAAa,KAAK,oBAAoB,EAAE,CAAC;EAC/C,OAAO,OAAO,eAAe,WACzB,2BAA2B,kBAAkB,UAAU,IACvD,8BAA8B,SAAS,UAAU;CACvD;CAEA,OAAc,eAAe,YAAqC;EAChE,OAAO,IAAI,oBAAoB;GAC7B,qBAAqB,CACnB,EACE,YAAY,WAAW,QACzB,CACF;GACA,MAAM,CAAC;EACT,CAAC;CACH;CAEA,UAA0E;EACxE,MAAM,aAAa,KAAK;EAGxB,MAAM,iBAAiB,WAAW,SAAS,QAAQ,QAAuB,OAAO,QAAQ,QAAQ;EAEjG,MAAM,OAAgE;GACpE,GAAG,KAAK;GACR,UAAU,WAAW;GACrB,YAAY,WAAW;GACvB,WAAW,WAAW;GACtB,UAAU;GACV,SAAS,WAAW;GACpB,aAAa,WAAW;GACxB,OAAO,WAAW;GAClB,oBAAoB,KAAK;EAC3B;EAGA,IAAI,WAAW,gBAAA,UAAmC;GAChD,KAAK,aAAa,WAAW;GAC7B,KAAK,eAAe,WAAW;EACjC,OAGK,IAAI,WAAW,gBAAA,UAClB,KAAK,OAAO,CAAC,WAAW,IAAI,OAAO,GAAG;EAGxC,OAAO;CACT;;;;;;;;CASA,QAAqB;EACnB,OAAO,gBAAgB,SAAS,gBAAgB,OAAO,IAAI,GAAG,KAAK,WAAkC;CACvG;;;;CAKA,IAAW,UAAU;EACnB,OAAO,KAAK,oBAAoB,EAAE,CAAC;CACrC;AACF;AAhHE,oBAAuB,OAAO"}