npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

gdc-sdk-core-ts

v2.9.10

Published

Runtime-neutral actor and capability contracts for GDC SDK convergence

Readme

gdc-sdk-core-ts

Development and releases follow the mandatory local-first TDD and release contract.

Local-first release contract

All consumers follow test -> local-network -> test-network -> network. Every affected live E2E runs against real local services; a live E2E reported as SKIP blocks the release. Complete those live E2E gates before npm publish or any container image build. Mocks are diagnostic only. Release dependencies bottom-up through their consumers. Push the branch, run npm publish from the branch, verify the registry artifact and a clean npm installation, and only then merge to main, push it, and delete the branch.

Keep each interactive npm authorization window alive for up to five minutes and retry no more than three times. After three failed attempts, downstream work may continue against an immutable npm pack tarball for local validation only. A local tarball or file: dependency never permits consumer publication, merge to main, image creation, or deployment; first install and verify the published dependency from npm.

See ARCHITECTURE.md and CONTRIBUTING.md before adding or reshaping facades, profile contracts, or high-level tests.

Short rule:

  • 101 tests must be didactic and step by step
  • gdc-common-utils-ts owns the canonical step-by-step editors/readers, shared types, and fixtures
  • gdc-sdk-core-ts starts after that shared authoring step and exposes the neutral business contracts and facades

Runtime-neutral shared contracts and helpers for GDC SDK consumers.

This package is for code that needs to understand and build GDC business flows without caring about gateway routes, host/... vs :tenantId/..., transport adapters, or application-specific runtime details.

Actor Split

The shared SDK family starts by separating actor families, because the flows are not the same:

  • organization side
    • organization controller
    • organization employee / professional member
  • individual side
    • individual controller
    • individual member / self
    • related person
    • professional with consented access

This package is the shared business-contract layer for all of those actors. It does not execute runtime calls, but it defines or normalizes the payloads and evaluations they all depend on.

Start Here

If you are new and need to see real SDK initialization and real method usage, open these documents in this order:

Important:

  • gdc-sdk-core-ts does not initialize a runtime client by itself.
  • Runtime initialization lives in gdc-sdk-node-ts and gdc-sdk-front-ts.
  • Shared payload shapes and examples live in gdc-common-utils-ts.
  • Communication/profile/device/BFF keys belong to runtime transport identity.
  • Controller publicKeyJwk belongs to business/operation identity and must stay separate from runtime communication keys.
  • FHIR-like resources in these shared flows may carry resource.meta.claims, which is a project-specific claims container and not part of base FHIR.
  • Package-boundary guidance lives in docs/101-SDK_PACKAGE_BOUNDARIES.md.
  • Onboarding rule across the repo family: common-utils authoring first, sdk-core contracts second, runtime-specific wire payloads last.

Shared example files to open while reading those guides:

Flow Families

The SDK documentation must cover these families from the start:

Organization bootstrap and activation

  • start legal-organization verification transaction
  • activate organization from ICA proof
  • confirm organization order / offer
  • prepare legal organization controller bootstrap payloads
  • always declare service capabilities during legal-organization activation
  • use orgControllerDid as the teaching name for the controller DID
  • prefer organizationActivation as the local activation builder/result name in examples

Canonical shared onboarding order:

  1. prepare/submit host Organization/_transaction
  2. consume ICA result and submit host Organization/_activate
  3. confirm host Order/_batch

The _transaction payload is runtime-neutral in this package; real fetch, polling, and JOSE/DIDComm transport execution remain runtime concerns of gdc-sdk-node-ts or gdc-sdk-front-ts.

Primary reusable examples:

Employee creation and employee invitation

  • create employee payload
  • issue employee activation / invitation path
  • employee device activation
  • employee SMART access

Primary reusable examples:

Individual organization bootstrap

  • start individual organization
  • confirm individual order / offer
  • prepare controller-owned individual bootstrap payloads

Primary reusable examples:

Related person and professional access to individual

  • create RelatedPerson
  • grant access / create consent
  • evaluate requested access
  • detect missing permissions
  • build permission-request Communication
  • invite actor and accept invitation

A permission request is not a new resource type. The reusable constructor authors one auditable FHIR Communication whose attachment is a batch Bundle of Consent.status = draft resources. Draft Consent records requested scope but never grants access; the controller must later author an active Consent.

Primary reusable examples:

Permission lifecycle

  • create/grant permissions
  • edit or replace permissions
  • enable / disable / delete permissions
  • grouped permission views for controller UX
  • permission-request notifications and lookup

Canonical lifecycle naming for all SDK-facing docs and examples:

  • enable
  • disable
  • delete

Do not teach new integrations with mixed public naming such as revoke, suspend, or purge when the intended API concept is the common lifecycle.

Clinical data contribution and retrieval

  • ingest Communication
  • import documents/resources into the subject index
  • search clinical bundles
  • search latest IPS
  • request SMART token for subject-scoped access

These flows may be executed by:

  • professional
  • individual controller
  • related person with write permission
  • caregiver or other actor with explicit allowed sections/actions

Main Flows

1. Consent access evaluation

Use this when an app or backend needs to answer:

  • can this professional or related person access this subject now?
  • what permissions are missing?
  • how do I build the canonical permission-request Communication?

Main helpers:

  • groupConsentsForControllerView(...)
  • evaluateRequestedAccess(...)
  • getMissingPermissions(...)
  • buildPermissionRequestCommunication(...)
  • buildPermissionRequestCommunicationLookupQuery(...)

The constructor uses only registered Communication.* and Consent.* claims. Do not add AccessRequest, AccessRequest.*, product names, or notification transport details to this shared contract.

Reference:

2. Relationship invitation and acceptance

Use this when a controller invites a related person or professional to connect with an individual or other subject.

The shared flow is:

  1. controller creates invitation payload
  2. invitee starts OTP challenge
  3. invitee confirms OTP
  4. invitee sets relationship PIN if required
  5. relationship channel becomes active

Main helpers:

  • createRelationshipChannelInvitationInput(...)
  • createRelationshipChannelInvitationSummary(...)
  • createRelationshipChannelOtpStartInput(...)
  • createRelationshipChannelOtpConfirmInput(...)
  • createRelationshipChannelOtpChallengeSummary(...)
  • createRelationshipPinPolicy(...)
  • createRelationshipPinSetInput(...)
  • createRelationshipPinVerifyInput(...)
  • createRelationshipLocalKeyEnvelope(...)

What this package does:

  • validates and normalizes the shared payloads
  • keeps the contract stable across portal, app, and phone-channel consumers

What this package does not do:

  • call GW endpoints
  • manage OTP providers
  • store PIN hashes
  • know anything about an application's reminder Task runtime

3. Communication and document handling

Use this when an app needs to build or read canonical Communication payloads carrying an attached document bundle.

The read path is:

document Bundle with Composition first entry -> Communication -> DIDComm/plain

Backend search remains a separate FHIR search-param story, for example with Composition.section.

For an attached batch or collection, the exact clinical section belongs in the outer Communication.topic claim and its native FHIR topic CodeableConcept. Composition.section remains inside a document Bundle; do not place it on the outer Communication and do not infer the section from payload.contentCodeableConcept.

Main helpers:

  • createCommunicationResource(...)
  • buildCommunicationBatchMessage(...)
  • addFhirResourceToCommunication(...)
  • addClaimsResourceToCommunication(...)
  • createCommunicationDraft(...)
  • createOutboxJobFromDraft(...)
  • createCommunicationFacade()

Who Should Use This Package

  • gdc-sdk-node-ts
  • gdc-sdk-front-ts
  • portal/backend orchestration layers
  • frontend/mobile code that needs stable contracts before runtime wiring

If you need HTTP/GW runtime behavior, use gdc-sdk-node-ts or a future runtime adapter, not this package directly.

Minimal Examples

Consent check

import {
  evaluateRequestedAccess,
  getMissingPermissions,
  type ConsentCoverageRequest,
} from 'gdc-sdk-core-ts';
import {
  EXAMPLE_EMAIL_PROFESSIONAL,
  EXAMPLE_INDIVIDUAL_DID_WEB,
} from 'gdc-common-utils-ts/examples/consent-access';
import {
  HealthcareActorRoles,
  HealthcareBasicSections,
  HealthcareConsentPurposes,
} from 'gdc-common-utils-ts/constants/healthcare';

const request: ConsentCoverageRequest = {
  subject: EXAMPLE_INDIVIDUAL_DID_WEB,
  actor: { actorKind: 'professional', email: EXAMPLE_EMAIL_PROFESSIONAL },
  actorRole: HealthcareActorRoles.Physician,
  purpose: HealthcareConsentPurposes.Treatment,
  sections: [HealthcareBasicSections.HistoryOfMedicationUse.claim],
};

const evaluation = await evaluateRequestedAccess(provider, request);

const missing = getMissingPermissions(evaluation);

Relationship invitation

import {
  createRelationshipChannelInvitationInput,
  createRelationshipChannelOtpStartInput,
  createRelationshipPinSetInput,
  RelationshipAccessActorKinds,
  RelationshipEnrollmentChannels,
  RelationshipOtpDeliveryChannels,
  RelationshipSubjectKinds,
  type RelationshipChannelInvitationInput,
  type RelationshipChannelOtpStartInput,
  type RelationshipPinSetInput,
} from 'gdc-sdk-core-ts';
import {
  buildIndividualDidWeb,
  HealthcareActorRoles,
  HealthcareConsentPurposes,
} from 'gdc-common-utils-ts';

const tenantId = 'acme-id';
const jurisdiction = 'ES';
const sector = 'health-care';
const providerOrganizationDid = subjectProfile.organizationDid;
const subjectLocalId = subjectProfile.subjectId;
const subjectDid = buildIndividualDidWeb({
  organizationDidWeb: providerOrganizationDid,
  subjectId: subjectLocalId,
});
const emailProfessional = professionalDirectoryEntry.email;
const actorKind = RelationshipAccessActorKinds.Professional;
const actorIdentifier = emailProfessional;
const actorRole = HealthcareActorRoles.Physician;
const deliveryChannel = RelationshipEnrollmentChannels.Phone;
const deliveryTarget = professionalDirectoryEntry.phone;
const purpose = HealthcareConsentPurposes.Treatment;
const phonePinOptional = false;

const invitationInput: RelationshipChannelInvitationInput = {
  tenantId,
  jurisdiction,
  sector,
  subjectId: subjectDid,
  subjectKind: RelationshipSubjectKinds.Person,
  actorKind,
  actorIdentifier,
  actorRole,
  deliveryChannel,
  deliveryTarget,
  purpose,
  relationshipLabel: 'primary-physician',
  phonePinOptional,
};

const invitation = createRelationshipChannelInvitationInput(invitationInput);

const invitationId = 'rel-invite-001';

const otpStartInput: RelationshipChannelOtpStartInput = {
  invitationId,
  deliveryChannel: RelationshipOtpDeliveryChannels.Sms,
  locale: 'es-ES',
};

const otpStart = createRelationshipChannelOtpStartInput(otpStartInput);

const challengeId = 'otp-challenge-001';
const pin = '482915';

const pinSetInput: RelationshipPinSetInput = {
  invitationId,
  challengeId,
  channel: deliveryChannel,
  pin,
  pinConfirmation: pin,
  policy: {
    minLength: 6,
    numericOnly: true,
  },
};

const pinSet = createRelationshipPinSetInput(pinSetInput);

Where those variables come from:

  • tenantId, jurisdiction, sector come from the selected GW tenant route context
  • subjectDid should be built with buildIndividualDidWeb(...) from the provider/subject identifiers you already have
  • actorKind, actorIdentifier, actorRole come from the invited professional or related person
  • deliveryChannel, deliveryTarget come from the chosen channel for enrollment
  • invitationId, challengeId come from the backend after creating the invitation and starting OTP
  • pin comes from the invitee during channel enrollment

Local terminology fallback

Core re-exports LocalTerminologyProvider, createClinicalCodeTranslator(...) and their catalog/search contracts. The provider accepts the established legacy catalog shape data[].attributes[code] = display; it does not translate free text or make network requests.

Use the provider directly for cached/offline display and search. Node and Front add runtime-specific facades without changing this canonical contract.

API Index

The canonical contract should live in JSDoc on exported code. This README is the entrypoint, not the exhaustive reference.

Full Public Surface

The following modules define the complete public SDK surface exported by this package:

  • src/actor-model.ts
    • types: ActorKind, Capability, ActorSessionDescriptor, ActorFacadeDescriptor, ActorFlags, ActorSessionDescriptorInput
    • functions: filterCapabilitiesForActor(...), expandActorSessionDescriptorToFacades(...), buildActorSessionDescriptorFromActorFlags(...)
  • src/bootstrap-facade.ts
    • types: BootstrapValidationIssue, OrganizationActivationPayload, BootstrapFacade
    • function: createBootstrapFacade()
  • src/communication-bundle-contracts.ts
    • types: AttachmentObj, CommunicationInput, CommMsgExtendedInput, DateRange, SectionFilter, IncludedResourceType, BundleSearchQuery, CompositionSearchQuery, ProjectedResourceSummary, BundleSearchResult, CommunicationAuditRecord
    • functions: assertCommunicationInput(...), assertCommMsgExtendedInput(...), assertBundleSearchQuery(...)
  • src/consent-access.ts
    • types: PermissionRequestCommunicationInput, PermissionRequestCommunicationLookup, ActiveConsentProvider
    • functions: groupConsentsForControllerView(...), evaluateRequestedAccess(...), getMissingPermissions(...), buildPermissionRequestCommunication(...), buildPermissionRequestCommunicationLookupQuery(...)
  • src/communication-draft.ts
    • constant: CommunicationOutboxStatuses
    • types: CommunicationOutboxStatus, CommunicationDraft, CommunicationDraftCreationOptions, OutboxJob, CommunicationOutboxJob, CommunicationOutboxJobOptions
    • functions: createCommunicationDraft(...), getCommunicationFromDraft(...), isCommunicationDraftReady(...), addFhirResourceToDraft(...), addClaimsResourceToDraft(...), createOutboxJobFromDraft(...), updateOutboxJobStatus(...)
  • src/communication-document-facade.ts
    • types: ResolvedCommunicationDocument, FhirDocumentSection, FhirDocumentFacade
    • functions: getDocumentFromCommunication(...), createFhirDocumentFacade(...), createCommunicationFacade()
  • src/communication-outbox.ts
    • types/interfaces: OutboxQuery, IOutboxRepository
    • class: OutboxRepositoryMemory
  • src/communication-resource-helpers.ts
    • types: FhirResourceLike, CommunicationResourceLike, AttachmentEncodingInput, CommunicationCreationOptions, ResourceAttachmentOptions, CommunicationPayloadResolution, ObservationCodeFilter, CommunicationBatchMessageOptions
    • functions: createCommunicationResource(...), buildCommunicationBatchMessage(...), addFhirResourceToCommunication(...), addClaimsResourceToCommunication(...), resolveCommunicationPayloads(...), getFirstBundleDocumentFromCommunication(...), getBundleDocumentEntries(...), getBundleDocumentResourcesByType(...), getMedicationClaimsFromCommunicationDocument(...), sortFhirResourcesByDateDescending(...), getObservationsByCodeFromCommunicationDocument(...)
  • src/did-resolution-session.ts
    • functions: getProviderDidFromSubjectDid(...), resolveDidDocumentServices(...), resolveProviderIdentityForSubject(...)
  • src/discovery-facade.ts
    • types/interfaces: DiscoveryResolutionResult, DiscoveryFacade
    • function: createStaticDiscoveryFacade(...)
  • src/identity-model.ts
    • types: DidServiceLike, DidDocumentLike, ResolvedServiceEndpointLike, TransportIdentityState, ActorIdentityState, ProviderIdentityState
  • src/identity-store.ts
    • interfaces: DidDocumentStore, IdentityStore
    • class: MemoryIdentityStore
  • src/polling-model.ts
    • types: SubmitPayload, AsyncPollRequest, SubmitResponse, PollOptions, PollResult, SubmitAndPollResult
    • function: resolvePollOptionsFromSeconds(...)
  • src/relationship-access.ts
    • types: RelationshipEnrollmentChannel, RelationshipSubjectKind, RelationshipAccessActorKind, RelationshipInvitationStatus, RelationshipOtpDeliveryChannel, RelationshipPinKdf, RelationshipChannelInvitationInput, RelationshipChannelInvitationSummary, RelationshipChannelOtpStartInput, RelationshipChannelOtpConfirmInput, RelationshipChannelOtpChallengeSummary, RelationshipPinPolicy, RelationshipPinSetInput, RelationshipPinVerifyInput, RelationshipLocalKeyEnvelope
    • functions: createRelationshipChannelInvitationInput(...), createRelationshipChannelInvitationSummary(...), createRelationshipChannelOtpStartInput(...), createRelationshipChannelOtpConfirmInput(...), createRelationshipChannelOtpChallengeSummary(...), createRelationshipPinPolicy(...), createRelationshipPinSetInput(...), createRelationshipPinVerifyInput(...), createRelationshipLocalKeyEnvelope(...)
  • src/session-model.ts
    • types/interfaces: AppType, AppInfo, DeviceTrustLevel, PersistenceMode, DataPersistencePolicy, InitializeSessionParams, Profile, ProfileRegistryEntry, VaultQueryCondition, VaultQuery, IVaultRepository, IApiConfig, INetwork, IVerifier
  • src/smart-endpoint-resolver.ts
    • function: resolveSmartTokenEndpointForSubject(...)
  • src/vital-signs.ts
    • types: VitalSignQuantityInput, BloodPressureInput, VitalSignsDocumentBase
    • functions: createHeartRateObservation(...), createBodyTemperatureObservation(...), createBloodPressureObservation(...), createVitalSignsFacade(...)

Actor/session contracts

Identity/discovery/bootstrap

Discovery boundary rule:

  • gdc-sdk-core-ts defines runtime-neutral contracts plus reusable transport-agnostic discovery resolvers that accept injected fetch
  • host DSP resolution uses the contextualized hosting-operator entrypoint /<hosting-operator-network-context>/.well-known/dspace-version
  • frontend DTO/card mapping belongs to gdc-sdk-front-ts

Polling helpers

Communication/document contracts

Consent access

Consent precedence in the shared model:

  1. explicit deny for a concrete email
  2. explicit permit for a concrete email
  3. organization decision
  4. jurisdiction decision
  5. default deny

Relationship access

Communication/document builders and readers

Drafts and outbox

IPS search through Communication

For IPS document requests, keep the search semantics separate from the transport envelope. The frontend/web app should still create a FHIR Communication, but the actual IPS search story is documented separately as FHIR search params such as Composition.section.

Employee Contract

Employee lifecycle, search semantics, and the canonical EmployeeDraft contract live in docs/101-EMPLOYEES.md.

The shared bundle/editor mechanics for employee live in:

  • gdc-common-utils-ts/docs/101-EMPLOYEE_ENTRY_EDITOR.md

  • Communication.content-reference stores the relative request reference used by the transport envelope

  • Communication.recipient is the logical/clinical conversation recipient, not the HTTP endpoint

  • DIDComm to / aud belong to the transport envelope or runtime submitter, not to Communication.content-reference

Typical flow:

  1. build summaryOperationRequestParameters
  2. flatten them to summaryOperationRequestReferencePath
  3. create Communication claims with communication.newIpsSummarySearchCommunication(...)
  4. place the Communication in a draft
  5. freeze the draft into an outbox job
  6. let the runtime/backend resolve the provider and send the envelope

If you need the actual search semantics, read the common-utils 101 that documents the FHIR search-param story separately.

See the executable example:

High-level document facade

Vital signs

Documentation Rule

  • JSDoc on exported code is canonical.
  • README should explain the business flows first.
  • Runtime routing details belong in node/front runtime docs, not in this package.