gdc-common-utils-ts 1.6.0 → 1.7.0

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.
Files changed (47) hide show
  1. package/dist/constants/index.d.ts +2 -0
  2. package/dist/constants/index.js +2 -0
  3. package/dist/constants/service-capabilities.d.ts +53 -0
  4. package/dist/constants/service-capabilities.js +72 -0
  5. package/dist/constants/verifiable-credentials.d.ts +34 -0
  6. package/dist/constants/verifiable-credentials.js +42 -0
  7. package/dist/examples/api-flow-examples.d.ts +1 -0
  8. package/dist/examples/api-flow-examples.js +1 -0
  9. package/dist/examples/consent-access.d.ts +12 -128
  10. package/dist/examples/consent-access.js +27 -18
  11. package/dist/examples/contract-examples.d.ts +1 -0
  12. package/dist/examples/contract-examples.js +1 -0
  13. package/dist/examples/frontend-session.d.ts +0 -4
  14. package/dist/examples/frontend-session.js +13 -7
  15. package/dist/examples/ica-activation-proof.d.ts +55 -0
  16. package/dist/examples/ica-activation-proof.js +67 -0
  17. package/dist/examples/index.d.ts +1 -0
  18. package/dist/examples/index.js +1 -0
  19. package/dist/examples/individual-controller.d.ts +19 -15
  20. package/dist/examples/individual-controller.js +16 -31
  21. package/dist/examples/lifecycle.d.ts +6 -4
  22. package/dist/examples/lifecycle.js +9 -7
  23. package/dist/examples/organization-controller.d.ts +5 -0
  24. package/dist/examples/organization-controller.js +17 -8
  25. package/dist/examples/professional.js +8 -7
  26. package/dist/examples/relationship-access.js +2 -2
  27. package/dist/examples/shared.d.ts +61 -7
  28. package/dist/examples/shared.js +55 -7
  29. package/dist/models/consent-rule.d.ts +1 -0
  30. package/dist/models/consent-rule.js +1 -0
  31. package/dist/models/interoperable-claims/allergy-intolerance-claims.js +1 -0
  32. package/dist/models/interoperable-claims/communication-claims.d.ts +14 -0
  33. package/dist/models/interoperable-claims/communication-claims.js +15 -0
  34. package/dist/models/interoperable-claims/condition-claims.js +1 -0
  35. package/dist/models/interoperable-claims/device-use-statement-claims.js +1 -0
  36. package/dist/models/interoperable-claims/document-reference-claims.js +1 -0
  37. package/dist/models/interoperable-claims/medication-statement-claims.d.ts +17 -0
  38. package/dist/models/interoperable-claims/medication-statement-claims.js +18 -0
  39. package/dist/utils/activation-policy.d.ts +8 -3
  40. package/dist/utils/activation-policy.js +26 -12
  41. package/dist/utils/clinical-resource-converters.js +70 -64
  42. package/dist/utils/communication-document-reference.js +10 -4
  43. package/dist/utils/communication-fhir-r4.js +40 -34
  44. package/dist/utils/consent.d.ts +1 -1
  45. package/dist/utils/consent.js +21 -20
  46. package/dist/utils/vp-token.js +8 -6
  47. package/package.json +1 -1
@@ -1,4 +1,5 @@
1
1
  // Copyright 2026 Antifraud Services Inc. under the Apache License, Version 2.0.
2
+ import { ClaimConsent } from '../models/consent-rule.js';
2
3
  import { assignCidToClaimsId } from './fhir-cid.js';
3
4
  /**
4
5
  * Normalizes a phone string into a compact token form.
@@ -160,16 +161,16 @@ export function buildConsentClaimsSimple(input, options = {}) {
160
161
  subjectIdentifier,
161
162
  consentClaims: {
162
163
  '@context': 'org.hl7.fhir.api',
163
- 'Consent.decision': input.decision || 'permit',
164
- 'Consent.subject': subjectIdentifier,
165
- 'Consent.identifier': consentIdentifier,
166
- 'Consent.date': consentDate,
167
- 'Consent.purpose': input.purpose,
168
- 'Consent.action': (input.actions || []).join(','),
169
- 'Consent.actor-identifier': actorIdentifier,
170
- 'Consent.actor-role': input.actorRole,
171
- 'Consent.attachment-contentType': input.attachmentContentType || 'application/odrl+json',
172
- 'Consent.attachment-data': input.attachmentBase64 || 'e30=',
164
+ [ClaimConsent.decision]: input.decision || 'permit',
165
+ [ClaimConsent.subject]: subjectIdentifier,
166
+ [ClaimConsent.identifier]: consentIdentifier,
167
+ [ClaimConsent.date]: consentDate,
168
+ [ClaimConsent.purpose]: input.purpose,
169
+ [ClaimConsent.action]: (input.actions || []).join(','),
170
+ [ClaimConsent.actorIdentifier]: actorIdentifier,
171
+ [ClaimConsent.actorRole]: input.actorRole,
172
+ [ClaimConsent.attachmentContentType]: input.attachmentContentType || 'application/odrl+json',
173
+ [ClaimConsent.attachmentData]: input.attachmentBase64 || 'e30=',
173
174
  },
174
175
  };
175
176
  }
@@ -441,7 +442,7 @@ export function resolveConsentActor(actor) {
441
442
  * @param options.now Optional evaluation timestamp.
442
443
  */
443
444
  export function isConsentRuleActive(rule, options = {}) {
444
- if (options.subject && String(rule['Consent.subject'] || '').trim() !== String(options.subject || '').trim()) {
445
+ if (options.subject && String(rule[ClaimConsent.subject] || '').trim() !== String(options.subject || '').trim()) {
445
446
  return false;
446
447
  }
447
448
  const now = options.now instanceof Date
@@ -449,8 +450,8 @@ export function isConsentRuleActive(rule, options = {}) {
449
450
  : options.now
450
451
  ? new Date(options.now).getTime()
451
452
  : Date.now();
452
- const periodStart = String(rule['Consent.period-start'] || '').trim();
453
- const periodEnd = String(rule['Consent.period-end'] || '').trim();
453
+ const periodStart = String(rule[ClaimConsent.periodStart] || '').trim();
454
+ const periodEnd = String(rule[ClaimConsent.periodEnd] || '').trim();
454
455
  if (periodStart && !Number.isNaN(Date.parse(periodStart)) && Date.parse(periodStart) > now)
455
456
  return false;
456
457
  if (periodEnd && !Number.isNaN(Date.parse(periodEnd)) && Date.parse(periodEnd) < now)
@@ -460,7 +461,7 @@ export function isConsentRuleActive(rule, options = {}) {
460
461
  function groupRulesBy(rules, predicate) {
461
462
  const groups = {};
462
463
  for (const rule of rules) {
463
- for (const token of splitCsv(rule['Consent.actor-identifier'])) {
464
+ for (const token of splitCsv(rule[ClaimConsent.actorIdentifier])) {
464
465
  const normalized = normalizeConsentTarget(token, { preferOrganizationDid: true });
465
466
  if (!predicate(normalized))
466
467
  continue;
@@ -493,7 +494,7 @@ function normalizeRequestedList(values, wildcard = '*') {
493
494
  }
494
495
  function extractRuleResourceTypes(rule) {
495
496
  const candidates = [
496
- rule['Consent.resourceType'],
497
+ rule[ClaimConsent.resourceType],
497
498
  rule['Consent.resource-type'],
498
499
  rule['Consent.resource'],
499
500
  rule['Consent.data-type'],
@@ -506,14 +507,14 @@ function extractRuleResourceTypes(rule) {
506
507
  return [];
507
508
  }
508
509
  function ruleMatchesRole(rule, actorRole) {
509
- const ruleRoles = splitCsv(rule['Consent.actor-role']).map(normalizeConsentRoleValue).filter(Boolean);
510
+ const ruleRoles = splitCsv(rule[ClaimConsent.actorRole]).map(normalizeConsentRoleValue).filter(Boolean);
510
511
  if (ruleRoles.length === 0 || ruleRoles.includes('*'))
511
512
  return true;
512
513
  const requestedRole = normalizeConsentRoleValue(String(actorRole || ''));
513
514
  return !!requestedRole && ruleRoles.includes(requestedRole);
514
515
  }
515
516
  function ruleMatchesPurpose(rule, purpose) {
516
- const rulePurpose = String(rule['Consent.purpose'] || '').trim();
517
+ const rulePurpose = String(rule[ClaimConsent.purpose] || '').trim();
517
518
  if (!purpose || !rulePurpose)
518
519
  return true;
519
520
  return rulePurpose === purpose;
@@ -522,7 +523,7 @@ function ruleMatchesSection(rule, section) {
522
523
  if (!section || section === '*')
523
524
  return true;
524
525
  const requestedSection = normalizeSectionToken(section);
525
- const actions = splitCsv(rule['Consent.action']).map(normalizeSectionToken);
526
+ const actions = splitCsv(rule[ClaimConsent.action]).map(normalizeSectionToken);
526
527
  if (actions.length === 0)
527
528
  return false;
528
529
  return actions.includes(requestedSection) || actions.includes('*');
@@ -536,7 +537,7 @@ function ruleMatchesResourceType(rule, resourceType) {
536
537
  return resourceTypes.includes(resourceType) || resourceTypes.includes('*');
537
538
  }
538
539
  function resolveRuleMatch(rule, actor) {
539
- for (const token of splitCsv(rule['Consent.actor-identifier'])) {
540
+ for (const token of splitCsv(rule[ClaimConsent.actorIdentifier])) {
540
541
  const normalized = normalizeConsentTarget(token, { preferOrganizationDid: true });
541
542
  if (actor.directTargets.some((target) => target.canonicalValue === normalized.canonicalValue)) {
542
543
  return { matchKind: 'direct', target: normalized, precedenceBase: 10 };
@@ -554,7 +555,7 @@ function toRuleMatch(rule, actor, section, resourceType) {
554
555
  const resolved = resolveRuleMatch(rule, actor);
555
556
  if (!resolved.target || resolved.matchKind === 'none' || resolved.precedenceBase === undefined)
556
557
  return undefined;
557
- const decision = rule['Consent.decision'];
558
+ const decision = rule[ClaimConsent.decision];
558
559
  const precedence = resolved.precedenceBase + (decision === 'deny' ? 0 : 1);
559
560
  return {
560
561
  rule,
@@ -1,4 +1,6 @@
1
+ // Always create JSDoc, do not use strings inline in keys nor values, use types instead, and reuse the data test examples.
1
2
  import { Content } from './content.js';
3
+ import { ORGANIZATION_ACTIVATION_VC_TYPES, REPRESENTATIVE_ACTIVATION_VC_TYPES, W3cCredentialContexts, W3cCredentialTypes, } from '../constants/verifiable-credentials.js';
2
4
  function fallbackId() {
3
5
  const rand = Math.random().toString(36).slice(2, 10);
4
6
  return `id-${Date.now()}-${rand}`;
@@ -26,8 +28,8 @@ export function createVP(input) {
26
28
  exp: input?.exp ?? ttl?.exp,
27
29
  nonce,
28
30
  vp: {
29
- '@context': ['https://www.w3.org/2018/credentials/v1'],
30
- type: ['VerifiablePresentation'],
31
+ '@context': [W3cCredentialContexts.V1],
32
+ type: [W3cCredentialTypes.VerifiablePresentation],
31
33
  holder: input?.vp?.holder || input?.iss || '',
32
34
  verifiableCredential: [],
33
35
  ...(input?.vp || {}),
@@ -145,7 +147,7 @@ export function getVpCredentialByAnyType(vpToken, acceptedTypes) {
145
147
  * @param vpToken Compact VP token or raw JSON string.
146
148
  */
147
149
  export function getOrganizationCredentialFromVpToken(vpToken) {
148
- return getVpCredentialByAnyType(vpToken, ['OrganizationCredential', 'LegalOrganizationCredential']);
150
+ return getVpCredentialByAnyType(vpToken, [...ORGANIZATION_ACTIVATION_VC_TYPES]);
149
151
  }
150
152
  /**
151
153
  * Extracts the legal representative credential from a VP token when present.
@@ -153,7 +155,7 @@ export function getOrganizationCredentialFromVpToken(vpToken) {
153
155
  * @param vpToken Compact VP token or raw JSON string.
154
156
  */
155
157
  export function getLegalRepresentativeCredentialFromVpToken(vpToken) {
156
- return getVpCredentialByAnyType(vpToken, ['LegalRepresentativeCredential', 'PersonCredential']);
158
+ return getVpCredentialByAnyType(vpToken, [...REPRESENTATIVE_ACTIVATION_VC_TYPES]);
157
159
  }
158
160
  function vcHasAnyType(vcPayload, acceptedTypes) {
159
161
  if (!vcPayload)
@@ -172,10 +174,10 @@ function addTypedVC(vpPayload, vc, acceptedTypes, label) {
172
174
  return addVC(vpPayload, vc);
173
175
  }
174
176
  export function addOrganizationCredential(vpPayload, vc) {
175
- return addTypedVC(vpPayload, vc, ['OrganizationCredential', 'LegalOrganizationCredential'], 'Organization');
177
+ return addTypedVC(vpPayload, vc, [...ORGANIZATION_ACTIVATION_VC_TYPES], 'Organization');
176
178
  }
177
179
  export function addLegalRepresentativeCredential(vpPayload, vc) {
178
- return addTypedVC(vpPayload, vc, ['LegalRepresentativeCredential', 'PersonCredential'], 'LegalRepresentative');
180
+ return addTypedVC(vpPayload, vc, [...REPRESENTATIVE_ACTIVATION_VC_TYPES], 'LegalRepresentative');
179
181
  }
180
182
  export function prepareForSignature(header, payload) {
181
183
  const encodedHeader = Content.objectToRawBase64UrlSafe(header);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gdc-common-utils-ts",
3
- "version": "1.6.0",
3
+ "version": "1.7.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },