gdc-common-utils-ts
v2.9.21
Published
Development and releases follow the mandatory [`local-first TDD and release contract`](docs/LOCAL_FIRST_RELEASE_CONTRACT.md).
Readme
gdc-common-utils-ts
Development and releases follow the mandatory
local-first TDD and release contract.
See ARCHITECTURE.md and CONTRIBUTING.md before adding new shared helpers, fixtures, or high-level tests.
Short rule:
- if a test/example can reuse a shared type or fixture, it must do so
- do not add ad hoc literals in
101tests whengdc-common-utils-tscan own the reusable value instead
Shared Workspace
Recommended local layout for the shared ICA/GDC repos and fixture PDFs:
~/GITS/gdc-workspace/
dataspace-ica-ts/
ica-client-sdk-ts/
gdc-common-utils-ts/
examples/
<example-pdf-1>.pdf
<example-pdf-2>.pdfThis is recommended because:
- cross-repo docs and fixture-based tests often refer to sibling repos
- real PDF examples are expected under
~/GITS/gdc-workspace/examples/ - keeping a single shared workspace reduces path drift between repos
Employee shared examples live in src/examples/employee.ts.
Employee pure helper functions live in src/utils/employee.ts.
The canonical employee editor note lives in
docs/101-EMPLOYEE_ENTRY_EDITOR.md.
Shared TypeScript utilities for GDC client and connector code. This package provides low-level primitives for cryptography, DID/DIDComm-related helpers, and the shared models and interfaces used across SDKs.
It is intentionally not a full backend orchestration layer.
Non-Negotiable Conventions
- FHIR SearchParameter names must use canonical FHIR naming (lowercase, with
-when defined by FHIR). - Never use invented camelCase parameter names for FHIR claims/search keys (example:
Communication.part-ofis valid,Communication.partOfis not). - FHIR claims use exactly
<ResourceType>.<concrete-parameter>and never add pseudo-path segments. For example, the section/topic claim isCommunication.topic; the native projection may containCommunication.topic.coding, butCommunication.topic.codingis not a claims key. - FHIR claims are version-independent FHIR API SearchParameter claims. Their
only context is
@context: org.hl7.fhir.api; an expanded key is thereforeorg.hl7.fhir.api.<ResourceType>.<concrete-parameter>. Never useorg.hl7.fhir.r4.*as a claim namespace: R4 identifies a native FHIR resource representation, not the claims vocabulary. - Schema.org claims are a different vocabulary and preserve the canonical Schema.org camelCase property name.
- Only define custom names when no canonical FHIR SearchParameter exists.
resource.meta.claimsis the canonical project-specific claims container and must be preserved across conversions/transports.resource.meta.claimsis not part of base FHIR; it is a claims-first extension carried by FHIR-like resources in GDC contracts.- Claims-first aggregates may intentionally mix related resource families. A
Digital Twin
ResearchSubject.meta.claimscontains bothResearchSubject.*andComposition.*; strict FHIR R4/R5 translates the Composition intoResearchSubject.contained[]. Producers never invent aResearchSubject.compositionwire property. - Native FHIR resources received from EHR systems do not need that extension:
normalize them with
normalizeClaimsFromFhirResource(...)at the processing boundary before indexed storage. Existingresource.meta.claimstake precedence so SDK-authored semantics survive transport conversion.
For a Communication whose attached Bundle is batch or collection, the
application section code belongs in Communication.topic. A LOINC section code
is serialized as native FHIR topic.coding; it is not inferred from
payload.contentCodeableConcept. A document Bundle instead remains organized
by its attached Composition.section graph.
Identity Continuity
For every Individual Organization, the initial Organization.member is the
indexed subject itself and uses the HL7 relationship ONESELF. The creating
Organization.owner is the controller by default. ONESELF describes who the
subject is; controller authority such as RESPRSN describes who may act for
that subject. Never copy the owner/controller role into the SELF member.
For ICA-backed organization activation, the representative/controller proof is intentionally split into two complementary dimensions:
credentialSubject.sameAspublic identity continuity, typically an email-derivedurn:multibase:z...credentialSubject.hasCredential.materialsigning-key continuity, ideally an RFC 9278 JWK-thumbprint URN bound to the controller key that signs the VP or was captured during ICA verification
They are not interchangeable:
sameAsdoes not prove possession of the signing keyhasCredential.materialdoes not by itself prove the expected public alias or email continuity
Production-grade flows should prefer ICA-issued representative VCs that carry both dimensions.
Legal Organization Verification Transaction
The first host-side legal-organization onboarding step now has one canonical shared payload builder in this package:
buildLegalOrganizationVerificationTransactionBundle(...)EXAMPLE_LEGAL_ORGANIZATION_VERIFICATION_TRANSACTION_BUNDLE
This builder owns the business payload only:
- signed PDF evidence attachment references
controller.publicKeyJwkas the controller business binding key- optional
organization.publicKeyJwk - legal representative payload
meta.claimsbusiness claims
It intentionally does not own:
fetch- polling
- JOSE transport execution
- BFF/frontend runtime crypto
Those runtime concerns belong in gdc-sdk-node-ts, gdc-sdk-front-ts, or GW.
Step by step:
- ICA verifies the signed PDF and emits the representative VC.
- ICA projects
credentialSubject.sameAsfrom signed email evidence when available. - ICA projects
credentialSubject.hasCredential.materialfrom the captured controller binding key. - GW/common-utils enforce key-binding continuity as the hard activation requirement.
- Higher layers may additionally compare
sameAsfor stronger identity/audit continuity.
101 Test Convention
Every 101 test in this repo is expected to be a didactic executable tutorial,
not only a behavior check.
Required shape for 101 tests:
- start with a short
Teaching goalcomment block - explain the main app/business flow, not only internal plumbing
- use explicit
Step 1.,Step 2., ... comments for the happy path - make clear what the user/app already has, what is shown, what is edited, what is saved, and what is reloaded
- if a low-level helper path is shown, mark it explicitly as an escape hatch
and not the primary
101path
The goal is that a developer can read the test top-to-bottom as tutorial material without needing chat history or private repo context.
If you need the canonical explanation of how DIDComm envelope, batch body,
entry types, FHIR-like resources, and resource.meta.claims fit together,
read first:
docs/101-ID_TOKEN.mddocs/101-DIDCOMM-IDENTITY-BOUNDARY.mddocs/101-COMMUNICATION_LAYERING.mddocs/101-BUNDLE_EDITOR_READER.mddocs/101-CLINICAL-IPS.mddocs/REFERENCE-CLINICAL-IPS-API.mddocs/101-CONSENT_PERMISSION_TEMPLATES.mddocs/101-INDIVIDUAL-MEMBER-SMART.md
Shared batch model for high-frequency clinical measurements:
- one day-level vital-sign batch is an atomic clinical artifact
- several day batches from the same actor are a collection of atomic batch artifacts
- the batch is what moves through Communication and ledger paths; the individual observations remain the facts inside it
For high-frequency clinical measurements, keep the same mental model across packages:
- one day-level vital-sign batch is an atomic clinical artifact
- several day batches from the same actor are a collection of atomic batch artifacts
- the batch is what gets moved through Communication and ledger paths; the underlying observations remain the facts inside it
Install
npm install gdc-common-utils-tsWhat It Exports
The published package exposes these entry points through package.json:
- Root:
gdc-common-utils-ts gdc-common-utils-ts/AesManagergdc-common-utils-ts/CryptographyServicegdc-common-utils-ts/hmacgdc-common-utils-ts/examplesgdc-common-utils-ts/examples/*gdc-common-utils-ts/claimsgdc-common-utils-ts/constantsgdc-common-utils-ts/convertgdc-common-utils-ts/modelsgdc-common-utils-ts/utilsgdc-common-utils-ts/interfaces- File-level subpaths under
claims/*,constants/*,models/*,utils/*, andinterfaces/*plusconvert/*
Root crypto exports
The package root re-exports the main crypto helpers:
AesManagerCryptographyServicecomputeHmacSha256computeHmacSha256Base64Url
Example:
import { AesManager, CryptographyService, computeHmacSha256Base64Url } from 'gdc-common-utils-ts';Utilities
The utils export exposes reusable helpers for DID and message handling, such as:
utils/didhelpers likegenerateServiceId,normalizeDidWeb,createHostedDidWeb,buildHostedDidDetails, andgetBaseUrlFromDidWebutils/jwtutils/contentutils/normalizeutils/unified-health-idfor provider-scoped Damm control digits over normalized provider + personal numeric sequencesutils/multibasehashforencodeMultibaseSha3(input, digestBits = 384), returning a base58btc multibase-encoded SHA3 multihashutils/multiformat-profileforbuildRawCidV1FromUtf8String(canonicalValue), returningCIDv1(raw, SHA3-384)by defaultutils/fhir-cidfor recursive FHIR canonicalization + CID generation +meta.versionIdassignmentutils/fhir-validatorfor adapter-based FHIR validation (validateFhirResource, pluggable formal validator)- conversion, formatting, and multibase helpers
These helpers support DIDComm-style message construction and related transport/data-shaping workflows.
The high-level federated SMART authorization profile
defines the two-step emergency flow: resolve the individual's index provider
from an opaque subject-identifier ledger key, then ask any available trusted
tenant to issue one token whose aud remains that resolved index provider.
The ledger value is only { indexProviderDid: 'did:web:...' }; the same opaque
hash stops at Fabric. After DID resolution, the authenticated human-facing
request uses IHE PDQm POST Patient/$match with one FHIR Parameters body;
the provider returns a FHIR search Bundle and projects private sameAs
associations as governed Patient.identifier values.
Example:
import { normalizeDidWeb, generateServiceId } from 'gdc-common-utils-ts/utils/did';
import { fhirResourceToCid, assignCidToFhirResourceVersionId } from 'gdc-common-utils-ts/utils/fhir-cid';
import { encodeMultibaseSha3 } from 'gdc-common-utils-ts/utils/multibasehash';
import { buildRawCidV1FromUtf8String } from 'gdc-common-utils-ts/utils/multiformat-profile';
const lookupMultihash = encodeMultibaseSha3('DL|US-CA|D1234567');
const blockchainAssetId = buildRawCidV1FromUtf8String('DL|US-CA|D1234567');Canonical Subject-collection lookup tokens use codingSystem|codeValue, for
example org.hl7.terminology.CodeSystem.v2-0203.NN.ES|12345678Z or
urn:iso:std:iso:11784-11785|981020000123456. Import
buildSubjectIdentifierAssetId(...) when a GW must derive the opaque SHA3-384
urn:multibase key used by the distributed subject index. The semantic
Person/Animal entry keeps the private claims and its sameAs points to the
stable public unified card; the raw identifier must never be written to the
ledger.
buildIndividualIdentifierLedgerAssetId(...) remains the older
type/jurisdiction/value compatibility helper. Do not use its former
Organization.sameAs convention for new Subject collection writes.
Both helpers hash the exact UTF-8 bytes supplied by the caller. Identifier, FHIR-token or JSON canonicalization belongs to the contract that owns the input. A multibase multihash is suitable as a deterministic lookup key; a CID is suitable when the key must identify a content-addressed record or blockchain asset.
Convert
The convert export exposes resource-specific FHIR conversion helpers such as:
medicationStatementFlatToFhirR4medicationStatementFhirR4ToFlatobservationFromFlatToFhirR4documentReferenceFlatToFhirR4compositionFlatToFhirR4consentFlatToFhirR4/consentFhirR4ToFlatconsentFlatToFhirR5/consentFhirR5ToFlat
Consent claims are version-neutral. Consent validity, data validity, grantor,
grantee, manager, enforcer, actor role, action, purpose, resource/content codes
and an optional source attachment stay in resource.meta.claims. Explicit R4
or R5 export maps only concepts supported by that version. For example, R5
exports Consent.controller, while R4 does not invent an equivalent field.
Computable policy content such as ODRL remains in sourceAttachment; its
profile must validate semantic parity before projection.
Example:
import {
medicationStatementFlatToFhirR4,
observationToFlatFhirR4,
} from 'gdc-common-utils-ts/convert';Claims
The claims export exposes resource-specific flat claim helpers such as:
setMedicationIdentifiergetMedicationCategoryListsetCommunicationCategorysetActorRoleListaddSectionList
Example:
import {
setMedicationIdentifier,
setMedicationCategoryList,
} from 'gdc-common-utils-ts/claims/claims-helpers-medication-statement';Models
The models export contains the shared data shapes used by the SDKs, including:
- cryptographic and JOSE shapes such as
aes,jwe,jws,jwt, andjwk - DID and DIDComm-related models such as
did,comm, andverifiable-credential - confidential transport and storage models
- auth, device, response, issue, and FHIR-oriented models
Example:
import { JweObject, JwtCompactParts } from 'gdc-common-utils-ts/models';Cross-Repo Task Docs
- docs/DATASPACE_DISCOVERY_ROADMAP.md
- cross-repo contract for dataspace discovery semantics, EU coverage inference, shared DTOs, and parameterized examples
- docs/101-DATASPACE_DISCOVERY_DEFAULTS.md
- portal/backend bootstrap guide for
defaults-only,default-first, andinternet-firstdiscovery seeding byjurisdiction + version + networkType
- portal/backend bootstrap guide for
- docs/consent-access-matrix-task.md
- next-step design/task document for active consent aggregation, explicit deny precedence, controller views, permission-request communications, and SMART access evaluation
- docs/101-CONSENT_PERMISSION_TEMPLATES.md
- canonical design note for role/relationship permission templates, front pickers, actor/target/purpose classification, and consent import/export planning
- docs/101-IPS_BUNDLE.md
- canonical 101 for requesting IPS, editing IPS-style bundles in
Communication.content-attachment-data, and reading resources by section
- canonical 101 for requesting IPS, editing IPS-style bundles in
- docs/101-CLINICAL-IPS.md
- shortest high-level onboarding for
ipsBundleReader, section summaries, family queries, and UI-ready narrative helpers
- shortest high-level onboarding for
- docs/REFERENCE-CLINICAL-IPS-API.md
- canonical claim/method matrix with
TODOcoverage for missing typedget.../set...helpers
- canonical claim/method matrix with
Dataspace Protocol And Discovery
Use gdc-common-utils-ts as the shared source of truth for DSP route building,
dspace-version metadata, and normalized discovery DTOs.
Main entry points:
src/utils/dataspace-protocol.ts- canonical GW CORE path builders for host-scoped and tenant-scoped DSP routes
src/utils/dataspace-discovery.ts- semantic extraction, provider filtering, default DTO builders, and the copy/paste fetcher harness used by docs/tests
src/utils/dataspace-discovery-defaults.ts- defaults registry for ICAs and hosting operators plus the backend
default-firstbootstrap plan used to unblock portal integration - includes authority-based helpers so integrators can seed from a single
domain/IP instead of manually assembling
did:weband discovery URLs
- defaults registry for ICAs and hosting operators plus the backend
src/examples/dataspace-discovery.ts- synthetic provider/operator examples that distinguish discovery URL from derived catalog artifact URL
docs/101-DATASPACE_DISCOVERY_DEFAULTS.md- copy/paste backend bootstrap guide for portal
default-firstrollout
- copy/paste backend bootstrap guide for portal
__tests__/dataspace-discovery-defaults.101.test.ts- executable defaults-registry examples for ICAs, hosting operators, and source-mode behavior
__tests__/dataspace-protocol.test.ts- executable path and
dspace-versionexamples
- executable path and
__tests__/dataspace-discovery.test.ts- executable semantic extraction and filtering examples
Copy/paste example:
import {
buildDspaceVersionMetadata,
buildGwCatalogArtifactPath,
buildGwDspaceVersionWellKnownPath,
deriveGwCatalogArtifactUrlFromDspaceVersion,
} from 'gdc-common-utils-ts/utils/dataspace-protocol';
import { HostNetworkTypes } from 'gdc-common-utils-ts/constants/network';
const hostContext = {
participantId: 'host',
hostCoverageScope: 'EU',
jurisdiction: 'ES',
version: 'v1',
hostNetwork: HostNetworkTypes.Test,
};
const discoveryPath = buildGwDspaceVersionWellKnownPath(hostContext);
const metadata = buildDspaceVersionMetadata('/host/cds-EU/v1/test/dsp');
const catalogPath = buildGwCatalogArtifactPath(hostContext);
const catalogUrl = deriveGwCatalogArtifactUrlFromDspaceVersion(
`https://host.example.org${discoveryPath}`,
metadata,
);API Index
The canonical API contract should live in JSDoc on exported code. The README acts as a navigable index.
Shared terminology constants
FhirCodeSystems- Canonical code system URLs such as
LoincandCommunicationCategory. - Use instead of inline system strings like
http://loinc.org.
- Canonical code system URLs such as
ResourceTypesFhirR4- Canonical FHIR R4
resourceTypenames such asCommunication,Bundle,DocumentReference,Observation,MedicationStatement,Consent. - Use instead of inline resource type strings.
- Canonical FHIR R4
CommunicationCategoryCodes- Canonical
Communication.categorycoding descriptors and<system>|<code>claims. - Exactly the four FHIR R4 categories; use
CommunicationTopicCodes.BreakTheGlassfor the HL7 v3 ActReasonBTGtopic and LOINC catalogs for clinical section/document topics. See Communication Layering 101.
- Canonical
ObservationCategoryCodes,VitalSignsCodes,VitalSignsUnits- Canonical Vital Signs category, code, and UCUM unit descriptors for
Observation.
- Canonical Vital Signs category, code, and UCUM unit descriptors for
HealthcareSummarySections,HealthcareCoreSections,HealthcareAllSections- One nested hierarchy: 16 official IPS sections, 22 application clinical
sections after six extensions, and the complete 82-section/classification
catalog. The IPS document type lives separately in
HealthcareDocumentTypes.
- One nested hierarchy: 16 official IPS sections, 22 application clinical
sections after six extensions, and the complete 82-section/classification
catalog. The IPS document type lives separately in
HealthcareConsentPurposes,HealthcareConsentActions,HealthcareActorRoles,HealthcareActorRoleCodes- Shared healthcare authorization and role constants, including the
health-lab,animal-lab, andonehealth-labsector catalogs. See Healthcare Roles and i18n 101.
- Shared healthcare authorization and role constants, including the
EXAMPLE_PROFESSIONAL_ACCESS_SCENARIOS- Reusable professional role/permission examples tying actor role, consent action, SMART scope, and expected FHIR resource types together.
DeviceUserClasses,DeviceAppTypes- Shared user-class and app/device-type constants used by licensing and SDK flows.
HostNetworkTypes- Shared network/environment labels for host discovery/bootstrap.
SmartGatewayScopesFhirR4- Current CORE GW SMART scope literals such as
organization/Consent.cruds. - Treat these as optional elevated scopes. Do not add them to the first read-only tutorial by default.
- Current CORE GW SMART scope literals such as
Root exports
AesManager- AES helper class exported from the package root.
CryptographyService- Main cryptography service implementation exported from the package root.
computeHmacSha256(...),computeHmacSha256Base64Url(...)- Low-level HMAC helpers for UTF-8 plaintext and raw key bytes.
Communication / document utilities
initializeCommunicationIdentity(...)- bootstraps the technical communication profile identity for a device/app/channel runtime
- do not teach its
entityIdas if it were the legal organization id - Derives the technical ML-DSA/ML-KEM communication identity for a device, portal, or app profile and returns JOSE header templates for
meta.jws.protectedandmeta.jwe.header. - Uses explicit
seedMaterialfor deterministic derivation. WithoutseedMaterial, it defaults to random generation.mode = deterministicrequiresseedMaterial.
buildOrganizationDidWeb(...),buildProfessionalDidWeb(...),buildIndividualDidWeb(...),buildIndividualMemberDidWebFromPrivateIdentifiers(...)- Build canonical data-space
did:webidentifiers for hosted organizations, professionals, and individuals/family actors.
- Build canonical data-space
buildOrganizationAuthorizationUrnCds(...),buildOrganizationMemberAuthorizationUrnCds(...)- Build host-independent legal organization/member identities such as
urn:cds-es:v1:organization:tax:ES-B00112233and its:member:<multibase-id>:<role-value>child. - Jurisdiction is mandatory so
BN,EIN,TAXand subnational identifier schemes cannot collide;roleTyperemains protected while only the compactroleValueis serialized.
- Build host-independent legal organization/member identities such as
buildScopeSmartCompositionAccess(...), withbuildSmartCompositionReadScope(...)retained as a deprecated compatibility alias- Builds the current CORE GW pinned SMART root scope for
organization/Composition...token requests. - This is the preferred first scope to teach when the backend only needs subject-scoped read access.
- Builds the current CORE GW pinned SMART root scope for
getOrganizationCredentialFromVpToken(...),getLegalRepresentativeCredentialFromVpToken(...),getServiceControllerCredentialFromVpToken(...)- Extract typed VC objects from a VP token when GW/SDK flows carry canonical proof only in
vp_token.
- Extract typed VC objects from a VP token when GW/SDK flows carry canonical proof only in
readServiceControllerCredentialsFromResponseBody(...)extractServiceControllerRoleCodes(...),extractServiceControllerOccupationCodes(...)read controller authority fromowner.additionalTypeand professional occupation fromowner.hasOccupation.occupationalCategory.- Reads every independently issued controller service VC from direct ICA or projected GW responses; companion helpers expose
owner.sameAsand its JWK-thumbprint binding without falling back to the legal representative.
- Reads every independently issued controller service VC from direct ICA or projected GW responses; companion helpers expose
docs/101-VP_TOKEN.md- Step-by-step guide for building the canonical compact
vp_tokenstring from organization and representative VCs.
- Step-by-step guide for building the canonical compact
validateCommunicationResourceFhirR4(...)- Validates FHIR R4
Communicationresources.
- Validates FHIR R4
transformCommunicationClaimsToResourceFhirR4(...)- Converts canonical communication claims into FHIR R4 resources.
extractCommunicationClaimsFromResourceFhirR4(...)- Extracts canonical claims from FHIR R4
Communication.
- Extracts canonical claims from FHIR R4
detectAttachmentKind(...)- Detects
fhir/pdf/png/jpg/binaryfrom MIME type.
- Detects
buildDocumentReferenceFromCommunicationPayload(...)- Projects a simplified
DocumentReferencefromCommunication.payload[0].contentAttachment.
- Projects a simplified
Identity bootstrap / discovery utilities
DidServiceIds,DidServiceTypes,DiscoveryCapabilities- Canonical DID service ids, service types, and capability names used to publish and resolve
service[]entries consistently across GW and SDK layers.
- Canonical DID service ids, service types, and capability names used to publish and resolve
ControllerBindingInput,OrganizationBindingInput,ActivationProofInput,OrganizationActivationRequest- Canonical bootstrap contracts that explicitly separate person/controller key binding from provider/organization key binding.
vp_tokenis the canonical proof carrier;controller.*andorganization.*carry public key binding material for DID publication.
buildControllerBindingInput(...),buildOrganizationBindingInput(...)- Build canonical
controller.*andorganization.*binding fragments from semantic variables such aspublicSignKey,publicKeys,did,sameAs, orurl.
- Build canonical
RelationshipChannelInvitationInput,RelationshipChannelInvitationSummary,RelationshipChannelOtpStartInput,RelationshipChannelOtpConfirmInput- Shared contracts for controller-driven invitation and acceptance flows between an individual/subject and a related person or professional across phone, email, and app channels.
RelationshipEnrollmentChannels,RelationshipSubjectKinds,RelationshipAccessActorKinds,RelationshipOtpDeliveryChannels- Shared constant objects for relationship flows so docs and app code do not hardcode actor kinds or channel labels inline.
RelationshipChannelOtpChallengeSummary,RelationshipPinPolicy,RelationshipPinSetInput,RelationshipPinVerifyInput,RelationshipLocalKeyEnvelope- Shared OTP, relationship PIN, and offline-first local-key envelope contracts for channel enrollment and subject-scoped local protection.
IdentityBootstrapValidationIssue,IdentityBootstrapValidationResult- Shared validation result shapes used by bootstrap builders/validators.
buildOrganizationActivationRequest(...)- Builds the canonical
_activatepayload withvp_tokenas the primary proof plus optional explicit controller/organization binding data.
- Builds the canonical
validateOrganizationActivationRequest(...)- Enforces bootstrap contract priority: canonical
vp_token, explicitcontroller.*key binding when needed, and legacy credential side-fields only as deprecated compatibility inputs.
- Enforces bootstrap contract priority: canonical
resolveDidDocumentServices(...)- Normalizes a DID Document
service[]block into capability-aware endpoint descriptors.
- Normalizes a DID Document
getDidDocumentService(...),selectServiceEndpoint(...)- Select a DID service entry or its invocable
serviceEndpointbyid,type, or logical capability.
- Select a DID service entry or its invocable
getDidDocumentEndpoint(...),getJwksServiceEndpoint(...),getSmartTokenEndpoint(...)- Resolve well-known public/operational endpoints from a DID Document instead of reconstructing them from URL conventions.
getOrganizationDidFromIndividualDid(...),getProviderDidFromSubjectDid(...)- Collapse actor/member DIDs back to their owning organization/provider DID using the current naming conventions.
getActorKindFromDid(...)- Heuristically classify current data-space actor DID patterns into actor kinds.
toDidResolutionResult(...)- Build a reusable DID resolution carrier from a raw DID Document.
normalizeIcaDiscoveryMetadata(...),normalizeNodeOperatorDiscoveryMetadata(...),normalizeServiceProviderEntry(...)- Normalize ICA, node-operator, and provider/DCAT-style discovery payloads into a shared DID/discovery shape for higher-level SDK runtime code.
Shared API flow examples
src/examples/organization-controller.ts- Host onboarding and organization-controller examples such as
_activate, legal order, employee creation, and employee device activation.
- Host onboarding and organization-controller examples such as
src/examples/individual-controller.ts- Individual-controller examples such as family/subject organization bootstrap, consent, search, communication ingestion, and digital twin flows.
- CORE canonical examples are email-first and do not require phone-only fields unless an extension layer adds them.
src/examples/professional.ts- Professional/physician runtime access examples such as SMART token and clinical access request payloads.
- The base token examples are read-only; richer scenario fixtures intentionally add
organization/Consent.cruds.
src/examples/related-person.ts- RelatedPerson/family-member examples.
buildFhirIpsCreatorProvenance(...)anddocs/101-DIDCOMM-IDENTITY-BOUNDARY.md- Keep
Composition.author,Composition.attester, DIDComm sender and signing key separate. The organization, EHR/portal or individual remains the document author; a registered PractitionerRole or RelatedPerson is the attester, including for content entered by that authenticated person.
- Keep
normalizeClinicalCreatorBinding(...)- Accept stable person, assignment and owner UUIDs plus governed bare role
codes at the BFF boundary, then add canonical UUID URNs and HL7/ISCO coding
systems before transport. Use
assignmentIdentifierfor the registeredRelatedPerson/PractitionerRole; the deprecated wire propertyauthorIdentifiernames that assignment and does not decideComposition.author.
- Accept stable person, assignment and owner UUIDs plus governed bare role
codes at the BFF boundary, then add canonical UUID URNs and HL7/ISCO coding
systems before transport. Use
src/examples/frontend-session.ts- Frontend profile/session bootstrap examples.
src/examples/lifecycle.ts- Canonical
enable/disable/deletelifecycle examples with placeholders and no personal data. - This is the source of truth for GW, Swagger, Node SDK, Front SDK, and portal examples.
- Canonical
src/examples/shared.ts- Shared route contexts, controller binding fragments, and reusable helper builders.
tenantIdis modeled as an identifier-like route token (acme-id), not as a friendly alternate name.
docs/101-LIFECYCLE.md- Copy/paste lifecycle
101guide with semantic rules and reusable placeholders.
- Copy/paste lifecycle
docs/101-HEALTHCARE_ROLES_I18N.md- Sector-aware healthcare role catalog and i18n
101(ISCO-08 + HL7) for FE/BE onboarding.
- Sector-aware healthcare role catalog and i18n
Documentation Naming Rules
Prefer these semantic names in docs and examples:
subjectDidprofessionalDidorgControllerDidindividualControllerDidemailProfessionalemailControllerOrgemailControllerIndividualemailRelatedPerson
Avoid teaching new integrations from legacy names such as individualDidWeb
when the active runtime variable is really the subject identifier.
src/examples/api-flow-examples.ts- Preferred compatibility aggregator for consumers that want one import surface without using the overloaded term
contract.
- Preferred compatibility aggregator for consumers that want one import surface without using the overloaded term
src/examples/contract-examples.ts- Legacy compatibility aggregator retained only so older imports keep working while consumers migrate to flow-specific modules or
api-flow-examples.
- Legacy compatibility aggregator retained only so older imports keep working while consumers migrate to flow-specific modules or
DID / DIDComm utilities
generateServiceId(...)normalizeDidWeb(...)createHostedDidWeb(...)buildHostedDidDetails(...)getBaseUrlFromDidWeb(...)submitDidcomm(...)DidCommMessageprepareDidCommRequest(...)includeVpTokenInMessage(...)includeFileInMessage(...)getThidFromMessage(...)getDataResults(...)
FHIR validation and conversion
registerFhirValidatorAdapter(...)clearFhirValidatorAdapters()listFhirValidatorAdapters()validateFhirResource(...)validateFhirResourceBasic(...)medicationStatementFlatToFhir(...)medicationStatementFhirToFlat(...)allergyIntoleranceFlatToFhir(...)allergyIntoleranceFhirToFlat(...)conditionFlatToFhir(...)conditionFhirToFlat(...)deviceUseStatementFlatToFhir(...)deviceUseStatementFhirToFlat(...)documentReferenceFlatToFhir(...)documentReferenceFhirToFlat(...)extractResources(...)getNextLink(...)
JWT utilities
getPartsJWT(...)decodeHeader(...)decodePayload(...)getDataJWT(...)encodeHeader(...)encodePayload(...)encodeSignature(...)compactJWT(...)
Activation / URL / base conversion utilities
extractCredentialSubject(...)normalizeTaxIdentifier(...)extractOrganizationTaxId(...)extractRepresentativeMemberOfTaxId(...)extractRepresentativeRoleCode(...)hasRoleCode(...)extractRepresentativeCredentialMaterial(...)extractDidWebFromCredential(...)buildMemberDidWeb(...)isMemberDidWebUnderOwner(...)validateActivationRepresentativePolicy(...)safelyJoinUrl(...)splitUrl(...)bytesToHexString(...)bytesToBase58(...)base58ToBytes(...)stringToStdBase64(...)base64ToBase64Url(...)stringToBase64Url(...)base64UrlToBase64(...)base64OrUrlSafeToBytes(...)bytesToBase64(...)bytesToRawBase64UrlSafe(...)
Consent utilities
normalizePhone(...)normalizeIdentifierToken(...)resolveActorIdentifier(...)resolveSubjectIdentifier(...)buildConsentClaimsSimple(...)buildConsentClaimsSimpleWithCid(...)getPurposes(...),setPurposes(...),addPurposes(...)and related claim list helpers__tests__/utils-consent-claim-helpers.test.ts
These helpers are the shared base for consent claim construction across GW and SDKs.
The canonical claim catalogue also distinguishes Consent.period-* (the
Consent's effective period) from Consent.data-period-* (the period of the
governed data).
Public module surfaces
src/constants/- Shared constants and code catalogs.
src/utils/- Shared functional helpers used by GW and SDK layers.
src/models/- Shared transport, FHIR, DID, consent, and storage models.
src/storage/- Shared vault/storage contracts and in-memory implementation.
Documentation rule
- Add or update JSDoc on exported functions, classes, and constants first.
- Keep README sections as a linked index to those exports, not as a second source of truth.
- If a function signature changes, update its JSDoc and then refresh the README link/index entry.
Current bootstrap / discovery status
- Implemented here:
- Canonical bootstrap payload models for
vp_token,controller.*, andorganization.* - Pure DID
service[]resolution helpers - Pure discovery normalization helpers for ICA, node operators, and provider entries
- Canonical bootstrap payload models for
- Intentionally not implemented here:
- Network fetch/resolution
- Runtime cache/state
- GW/SDK orchestration side effects
Interfaces
The interfaces export contains the shared low-level type contracts and cryptography types, including:
ICryptographyICryptoHelperCryptography.typesMlDsaMlKem
Wallet contracts and runtime adapters live in higher layers:
gdc-sdk-core-tsowns the runtime-neutralIWalletcontractgdc-sdk-node-tsowns concrete Node wallet/runtime adapters
Example:
import { ICryptography, MlkemPublicJwk } from 'gdc-common-utils-ts/interfaces/Cryptography.types';Auth-Flow Boundaries
This package provides primitives, not orchestration.
It supports the cryptographic and data-model building blocks needed by higher-level clients, but it does not coordinate the backend auth exchange sequence for:
/_dcr/_code/_token/_exchange
Those request/response flows belong in connector SDKs and backend orchestration layers.
Relationship To Other SDKs
gdc-sdk-client-ts and dataconv-client-sdk-ts are consumers of this package, not replacements for it.
SDK Integration Note
When integrating the converged SDKs:
use
initializeCommunicationIdentity(...)from this package for the technical communication identity bootstrapuse
gdc-sdk-core-tsfor runtime-neutral communication/document helpersuse
gdc-sdk-front-tsorgdc-sdk-node-tsfor the runtime-specific session and orchestration layerUse
gdc-common-utils-tswhen you need shared crypto primitives, DID/DIDComm helpers, and common typesUse
gdc-sdk-client-tsordataconv-client-sdk-tswhen you need higher-level client orchestration, transport, or API workflows
Notes
- The package is published as ESM.
- The
filesfield only publishesdist/, so source imports should use the documented package entry points rather than local file paths.
Roadmap and Briefing
docs/BRIEFING_DATASPACE_EN.md
