gdc-common-utils-ts 1.24.1 → 2.0.1

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 (54) hide show
  1. package/README.md +39 -0
  2. package/dist/constants/index.d.ts +1 -0
  3. package/dist/constants/index.js +1 -0
  4. package/dist/constants/profile-runtime.d.ts +33 -0
  5. package/dist/constants/profile-runtime.js +30 -0
  6. package/dist/examples/frontend-session.js +2 -1
  7. package/dist/examples/ica-activation-proof.d.ts +11 -4
  8. package/dist/examples/ica-activation-proof.js +11 -4
  9. package/dist/examples/index.d.ts +1 -0
  10. package/dist/examples/index.js +1 -0
  11. package/dist/examples/lifecycle.js +5 -5
  12. package/dist/examples/organization-controller.d.ts +0 -1
  13. package/dist/examples/organization-controller.js +0 -1
  14. package/dist/examples/profile-runtime.d.ts +16 -0
  15. package/dist/examples/profile-runtime.js +18 -0
  16. package/dist/examples/shared.d.ts +9 -0
  17. package/dist/examples/shared.js +9 -0
  18. package/dist/interfaces/Cryptography.types.d.ts +15 -0
  19. package/dist/models/identity-bootstrap.d.ts +9 -0
  20. package/dist/utils/activation-policy.d.ts +45 -1
  21. package/dist/utils/activation-policy.js +65 -7
  22. package/dist/utils/activation-request.d.ts +63 -2
  23. package/dist/utils/activation-request.js +82 -0
  24. package/dist/utils/communication-participant-search-test-data.d.ts +17 -0
  25. package/dist/utils/communication-participant-search-test-data.js +39 -0
  26. package/dist/utils/communication-participant-search.d.ts +108 -0
  27. package/dist/utils/communication-participant-search.js +425 -0
  28. package/dist/utils/communication-retention-policy.d.ts +32 -0
  29. package/dist/utils/communication-retention-policy.js +41 -0
  30. package/dist/utils/communication-search-editor.d.ts +54 -0
  31. package/dist/utils/communication-search-editor.js +156 -0
  32. package/dist/utils/fhir-search.d.ts +32 -0
  33. package/dist/utils/fhir-search.js +45 -0
  34. package/dist/utils/index.d.ts +8 -0
  35. package/dist/utils/index.js +8 -0
  36. package/dist/utils/individual-organization-lifecycle.d.ts +15 -5
  37. package/dist/utils/individual-organization-lifecycle.js +53 -6
  38. package/dist/utils/interoperable-resource-operation.d.ts +4 -4
  39. package/dist/utils/interoperable-resource-operation.js +22 -22
  40. package/dist/utils/jwk-thumbprint.d.ts +40 -0
  41. package/dist/utils/jwk-thumbprint.js +57 -0
  42. package/dist/utils/legal-organization-onboarding.d.ts +97 -0
  43. package/dist/utils/legal-organization-onboarding.js +128 -0
  44. package/dist/utils/license-commercial-search.d.ts +6 -6
  45. package/dist/utils/license-commercial-search.js +2 -2
  46. package/dist/utils/license-list-search.d.ts +7 -7
  47. package/dist/utils/license-list-search.js +23 -23
  48. package/dist/utils/license-offer-order.d.ts +19 -19
  49. package/dist/utils/license-offer-order.js +68 -68
  50. package/dist/utils/organization-lifecycle.d.ts +59 -0
  51. package/dist/utils/organization-lifecycle.js +155 -0
  52. package/dist/utils/same-as.d.ts +41 -0
  53. package/dist/utils/same-as.js +83 -0
  54. package/package.json +2 -2
@@ -1,4 +1,4 @@
1
- import { ControllerBindingInput, IdentityBootstrapValidationResult, OrganizationActivationRequest, OrganizationBindingInput } from '../models/identity-bootstrap';
1
+ import { ControllerBindingInput, DidcommPlaintextTransportMetadata, IdentityBootstrapValidationResult, OrganizationActivationRequest, OrganizationBindingInput } from '../models/identity-bootstrap';
2
2
  import { JwkSet } from '../models/jwk';
3
3
  /**
4
4
  * Builder input for the canonical organization/service activation payload.
@@ -22,7 +22,18 @@ export interface BuildOrganizationActivationRequestInput {
22
22
  export interface BuildControllerBindingInputInput {
23
23
  /** Public DID to publish or bind for the controller/person. */
24
24
  did?: string;
25
- /** Additional public alias such as `mailto:`. */
25
+ /**
26
+ * Additional public alias for the controller/person.
27
+ *
28
+ * Canonical examples:
29
+ * - `urn:multibase:z...` for an email-derived ICA/GW binding
30
+ * - `tel:+34600111222` for a phone identifier
31
+ * - `did:web:...` or another stable public identifier
32
+ *
33
+ * Do not use `mailto:` when the source value is an email for ICA/GW
34
+ * interoperability. Start from the plain email and normalize it first with
35
+ * `normalizeSameAsHash(...)`.
36
+ */
26
37
  sameAs?: string;
27
38
  /** Primary controller signing key. */
28
39
  publicSignKey?: Record<string, unknown>;
@@ -43,6 +54,23 @@ export interface BuildOrganizationBindingInputInput {
43
54
  keys: Array<Record<string, unknown>>;
44
55
  } | Array<Record<string, unknown>>;
45
56
  }
57
+ export interface BuildDidcommPlaintextTransportMetadataInput {
58
+ /**
59
+ * Explicit controller/person binding used by `_activate`.
60
+ *
61
+ * In demo/plaintext flows this is the preferred source for mirroring the
62
+ * technical communication key metadata into `meta.jws.protected` /
63
+ * `meta.jwe.header`.
64
+ */
65
+ controller?: ControllerBindingInput;
66
+ /**
67
+ * Optional explicit content type copied into the mirrored technical JWS
68
+ * header.
69
+ *
70
+ * Defaults to `application/didcomm-plaintext+json`.
71
+ */
72
+ contentType?: string;
73
+ }
46
74
  /**
47
75
  * Builds the canonical controller/person binding from semantic variables.
48
76
  *
@@ -54,18 +82,51 @@ export interface BuildOrganizationBindingInputInput {
54
82
  *
55
83
  * so the caller does not have to manually shape `controller.publicKeyJwk` and
56
84
  * `controller.jwks`.
85
+ *
86
+ * ICA/GW interoperability note:
87
+ * - callers that start from a raw email should first normalize it with
88
+ * `normalizeSameAsHash(...)` before assigning `sameAs`
89
+ * - keep the raw email separately in activation claims when GW still needs it
90
+ * for internal admin/bootstrap records
91
+ * - do not send `mailto:` as the canonical controller alias when the binding
92
+ * source is an email address
57
93
  */
58
94
  export declare function buildControllerBindingInput(input: BuildControllerBindingInputInput): ControllerBindingInput;
59
95
  /**
60
96
  * Builds the canonical organization/provider binding from semantic variables.
61
97
  */
62
98
  export declare function buildOrganizationBindingInput(input: BuildOrganizationBindingInputInput): OrganizationBindingInput;
99
+ /**
100
+ * Builds the technical plaintext transport metadata expected by GW-compatible
101
+ * demo flows.
102
+ *
103
+ * Transport rule:
104
+ * - in secure JOSE transport, these values belong in the protected JWS/JWE
105
+ * headers of the real envelope
106
+ * - in `application/didcomm-plaintext+json`, there is no signed outer
107
+ * envelope on the wire, so high-level SDK/BFF helpers may mirror the same
108
+ * technical key identifiers and public JWKs into `meta.jws.protected` and
109
+ * `meta.jwe.header`
110
+ *
111
+ * This is technical compatibility fallback only. The canonical activation
112
+ * contract remains `controller.publicKeyJwk` / `controller.jwks`.
113
+ */
114
+ export declare function buildDidcommPlaintextTransportMetadata(input: BuildDidcommPlaintextTransportMetadataInput): DidcommPlaintextTransportMetadata | undefined;
63
115
  /**
64
116
  * Builds the canonical `_activate` request payload shared by SDK and GW helpers.
65
117
  *
66
118
  * The resulting object intentionally preserves deprecated compatibility fields
67
119
  * when supplied, so callers can keep legacy flows alive while validators and
68
120
  * runtime layers flag that debt explicitly.
121
+ *
122
+ * Transport note:
123
+ * - secure JOSE submission should place technical signing/encryption metadata
124
+ * in the protected headers of the real JWS/JWE envelope
125
+ * - demo `application/didcomm-plaintext+json` flows may mirror those same
126
+ * values into plaintext `meta.jws.protected` / `meta.jwe.header` as a
127
+ * technical fallback expected by GW-compatible backends
128
+ * - that plaintext transport metadata must not replace the canonical
129
+ * `controller.publicKeyJwk` / `controller.jwks` activation contract
69
130
  */
70
131
  export declare function buildOrganizationActivationRequest(input: BuildOrganizationActivationRequestInput): OrganizationActivationRequest;
71
132
  /**
@@ -1,5 +1,6 @@
1
1
  // Copyright 2026 Antifraud Services Inc. under the Apache License, Version 2.0.
2
2
  import { IssueSeverity } from '../models/issue.js';
3
+ import { JoseContentEncryptionAlgorithms } from '../constants/cryptography.js';
3
4
  function pushIssue(issues, severity, code, message, path) {
4
5
  issues.push({ severity, code, message, ...(path ? { path } : {}) });
5
6
  }
@@ -12,6 +13,22 @@ function normalizeJwkSet(publicKeys) {
12
13
  }
13
14
  return publicKeys;
14
15
  }
16
+ function normalizeJwk(input) {
17
+ return input && typeof input === 'object'
18
+ ? input
19
+ : undefined;
20
+ }
21
+ function isEncryptionJwk(key) {
22
+ if (!key) {
23
+ return false;
24
+ }
25
+ const purposes = Array.isArray(key.purposes) ? key.purposes.map((value) => String(value)) : [];
26
+ const keyOps = Array.isArray(key.key_ops) ? key.key_ops.map((value) => String(value)) : [];
27
+ return String(key.use || '').trim() === 'enc'
28
+ || purposes.includes('didcomm-enc')
29
+ || keyOps.includes('encrypt')
30
+ || keyOps.includes('deriveKey');
31
+ }
15
32
  /**
16
33
  * Builds the canonical controller/person binding from semantic variables.
17
34
  *
@@ -23,6 +40,14 @@ function normalizeJwkSet(publicKeys) {
23
40
  *
24
41
  * so the caller does not have to manually shape `controller.publicKeyJwk` and
25
42
  * `controller.jwks`.
43
+ *
44
+ * ICA/GW interoperability note:
45
+ * - callers that start from a raw email should first normalize it with
46
+ * `normalizeSameAsHash(...)` before assigning `sameAs`
47
+ * - keep the raw email separately in activation claims when GW still needs it
48
+ * for internal admin/bootstrap records
49
+ * - do not send `mailto:` as the canonical controller alias when the binding
50
+ * source is an email address
26
51
  */
27
52
  export function buildControllerBindingInput(input) {
28
53
  const jwks = normalizeJwkSet(input.publicKeys);
@@ -45,12 +70,69 @@ export function buildOrganizationBindingInput(input) {
45
70
  ...(jwks ? { jwks } : {}),
46
71
  };
47
72
  }
73
+ /**
74
+ * Builds the technical plaintext transport metadata expected by GW-compatible
75
+ * demo flows.
76
+ *
77
+ * Transport rule:
78
+ * - in secure JOSE transport, these values belong in the protected JWS/JWE
79
+ * headers of the real envelope
80
+ * - in `application/didcomm-plaintext+json`, there is no signed outer
81
+ * envelope on the wire, so high-level SDK/BFF helpers may mirror the same
82
+ * technical key identifiers and public JWKs into `meta.jws.protected` and
83
+ * `meta.jwe.header`
84
+ *
85
+ * This is technical compatibility fallback only. The canonical activation
86
+ * contract remains `controller.publicKeyJwk` / `controller.jwks`.
87
+ */
88
+ export function buildDidcommPlaintextTransportMetadata(input) {
89
+ const signingKey = normalizeJwk(input.controller?.publicKeyJwk);
90
+ const encryptionKey = normalizeJwk(input.controller?.jwks?.keys?.find((candidate) => isEncryptionJwk(normalizeJwk(candidate))));
91
+ if (!signingKey && !encryptionKey) {
92
+ return undefined;
93
+ }
94
+ return {
95
+ ...(signingKey
96
+ ? {
97
+ jws: {
98
+ protected: {
99
+ alg: String(signingKey.alg || '').trim() || 'none',
100
+ kid: String(signingKey.kid || '').trim() || 'none',
101
+ cty: String(input.contentType || '').trim() || 'application/didcomm-plaintext+json',
102
+ jwk: signingKey,
103
+ },
104
+ },
105
+ }
106
+ : {}),
107
+ ...(encryptionKey
108
+ ? {
109
+ jwe: {
110
+ header: {
111
+ alg: String(encryptionKey.alg || encryptionKey.crv || '').trim() || 'none',
112
+ enc: JoseContentEncryptionAlgorithms.Aes256Gcm,
113
+ skid: String(encryptionKey.kid || '').trim() || 'none',
114
+ jwk: encryptionKey,
115
+ },
116
+ },
117
+ }
118
+ : {}),
119
+ };
120
+ }
48
121
  /**
49
122
  * Builds the canonical `_activate` request payload shared by SDK and GW helpers.
50
123
  *
51
124
  * The resulting object intentionally preserves deprecated compatibility fields
52
125
  * when supplied, so callers can keep legacy flows alive while validators and
53
126
  * runtime layers flag that debt explicitly.
127
+ *
128
+ * Transport note:
129
+ * - secure JOSE submission should place technical signing/encryption metadata
130
+ * in the protected headers of the real JWS/JWE envelope
131
+ * - demo `application/didcomm-plaintext+json` flows may mirror those same
132
+ * values into plaintext `meta.jws.protected` / `meta.jwe.header` as a
133
+ * technical fallback expected by GW-compatible backends
134
+ * - that plaintext transport metadata must not replace the canonical
135
+ * `controller.publicKeyJwk` / `controller.jwks` activation contract
54
136
  */
55
137
  export function buildOrganizationActivationRequest(input) {
56
138
  return {
@@ -0,0 +1,17 @@
1
+ import type { CommunicationParticipantProjection, CommunicationParticipantSearchInput } from './communication-participant-search';
2
+ /**
3
+ * Shared communication-participant search input fixture reused across GW/SDK
4
+ * tests.
5
+ */
6
+ export declare function buildExampleCommunicationParticipantSearchInput(overrides?: Partial<CommunicationParticipantSearchInput>): CommunicationParticipantSearchInput;
7
+ /**
8
+ * Shared stored projection fixture that mirrors the shape persisted by GW
9
+ * communication-channel projections.
10
+ */
11
+ export declare function buildExampleCommunicationParticipantProjection(overrides?: Partial<CommunicationParticipantProjection & {
12
+ id?: string;
13
+ thid?: string;
14
+ }>): CommunicationParticipantProjection & {
15
+ id: string;
16
+ thid: string;
17
+ };
@@ -0,0 +1,39 @@
1
+ import { EXAMPLE_COMMUNICATION_PARTICIPANT_EMAIL_RECIPIENT, EXAMPLE_COMMUNICATION_PARTICIPANT_EMAIL_USER, EXAMPLE_COMMUNICATION_SEARCH_CATEGORY, EXAMPLE_COMMUNICATION_SEARCH_TOPIC, EXAMPLE_COMMUNICATION_PARTICIPANT_SEARCH_SUBJECT_DID, EXAMPLE_COMMUNICATION_PARTICIPANT_SENDER_DID, EXAMPLE_COMMUNICATION_PARTICIPANT_TEL_RECIPIENT, EXAMPLE_COMMUNICATION_PARTICIPANT_USER_DID, EXAMPLE_COMMUNICATION_THREAD_ID, } from '../examples/shared.js';
2
+ import { CommunicationClaim } from '../models/interoperable-claims/communication-claims.js';
3
+ /**
4
+ * Shared communication-participant search input fixture reused across GW/SDK
5
+ * tests.
6
+ */
7
+ export function buildExampleCommunicationParticipantSearchInput(overrides = {}) {
8
+ return {
9
+ subject: EXAMPLE_COMMUNICATION_PARTICIPANT_SEARCH_SUBJECT_DID,
10
+ userActorId: [EXAMPLE_COMMUNICATION_PARTICIPANT_USER_DID, EXAMPLE_COMMUNICATION_PARTICIPANT_EMAIL_USER],
11
+ targetActorId: [EXAMPLE_COMMUNICATION_PARTICIPANT_EMAIL_RECIPIENT, EXAMPLE_COMMUNICATION_PARTICIPANT_TEL_RECIPIENT],
12
+ searchParams: {
13
+ [CommunicationClaim.Category]: EXAMPLE_COMMUNICATION_SEARCH_CATEGORY,
14
+ [CommunicationClaim.Topic]: EXAMPLE_COMMUNICATION_SEARCH_TOPIC,
15
+ },
16
+ ...overrides,
17
+ };
18
+ }
19
+ /**
20
+ * Shared stored projection fixture that mirrors the shape persisted by GW
21
+ * communication-channel projections.
22
+ */
23
+ export function buildExampleCommunicationParticipantProjection(overrides = {}) {
24
+ return {
25
+ id: 'communication-participant-record-001',
26
+ thid: EXAMPLE_COMMUNICATION_THREAD_ID,
27
+ subject: EXAMPLE_COMMUNICATION_PARTICIPANT_SEARCH_SUBJECT_DID,
28
+ sender: EXAMPLE_COMMUNICATION_PARTICIPANT_SENDER_DID,
29
+ sent: '2026-06-15T10:00:00Z',
30
+ category: EXAMPLE_COMMUNICATION_SEARCH_CATEGORY,
31
+ topic: EXAMPLE_COMMUNICATION_SEARCH_TOPIC,
32
+ recipients: [
33
+ EXAMPLE_COMMUNICATION_PARTICIPANT_USER_DID,
34
+ EXAMPLE_COMMUNICATION_PARTICIPANT_EMAIL_RECIPIENT,
35
+ EXAMPLE_COMMUNICATION_PARTICIPANT_TEL_RECIPIENT,
36
+ ],
37
+ ...overrides,
38
+ };
39
+ }
@@ -0,0 +1,108 @@
1
+ import { buildSearchBundle, type FhirParametersResource, type SearchParameterPrimitive } from './fhir-search.js';
2
+ /**
3
+ * Canonical participant-token prefixes used by communication search helpers.
4
+ */
5
+ export declare const CommunicationParticipantPrefixes: Readonly<{
6
+ readonly Did: "did:";
7
+ readonly Email: "email:";
8
+ readonly Mailto: "mailto:";
9
+ readonly Tel: "tel:";
10
+ readonly Phone: "phone:";
11
+ readonly Wildcard: "*";
12
+ }>;
13
+ /**
14
+ * Canonical parameter names supported by `Communication/_search`.
15
+ */
16
+ export declare const CommunicationParticipantSearchParameterNames: Readonly<{
17
+ readonly Subject: "subject";
18
+ readonly Actor: "actor";
19
+ readonly Sender: "sender";
20
+ readonly Recipient: "recipient";
21
+ readonly User: "user";
22
+ readonly Target: "target";
23
+ readonly PeriodStart: "period-start";
24
+ readonly PeriodEnd: "period-end";
25
+ readonly Page: "page";
26
+ readonly Count: "count";
27
+ }>;
28
+ /**
29
+ * Backward-compatible aliases still accepted while callers migrate to the
30
+ * canonical control names.
31
+ */
32
+ export declare const CommunicationParticipantSearchParameterAliases: Readonly<{
33
+ readonly SentFrom: "sent-from";
34
+ readonly SentTo: "sent-to";
35
+ }>;
36
+ /**
37
+ * Indexed-attribute names used by communication projections.
38
+ */
39
+ export declare const CommunicationParticipantIndexNames: Readonly<{
40
+ readonly Subject: "Communication.subject";
41
+ readonly Participant: "Communication.participant-token";
42
+ readonly Sender: "Communication.sender-token";
43
+ readonly Recipient: "Communication.recipient-token";
44
+ }>;
45
+ export type CommunicationParticipantTokenInput = string | readonly string[] | undefined | null;
46
+ export type CommunicationParticipantSearchInput = {
47
+ /**
48
+ * Canonical claims-like search parameters keyed by reusable claim constants
49
+ * such as `CommunicationClaim.Sender`, `CommunicationClaim.Recipient`,
50
+ * `CommunicationClaim.Category`, or `CommunicationClaim.Topic`.
51
+ */
52
+ searchParams?: Readonly<Record<string, SearchParameterPrimitive | undefined>>;
53
+ subject?: CommunicationParticipantTokenInput;
54
+ actorId?: CommunicationParticipantTokenInput;
55
+ senderActorId?: CommunicationParticipantTokenInput;
56
+ recipientActorId?: CommunicationParticipantTokenInput;
57
+ userActorId?: CommunicationParticipantTokenInput;
58
+ targetActorId?: CommunicationParticipantTokenInput;
59
+ periodStart?: string;
60
+ periodEnd?: string;
61
+ sentFrom?: string;
62
+ sentTo?: string;
63
+ page?: number;
64
+ count?: number;
65
+ };
66
+ export type CommunicationParticipantSearchCriteria = {
67
+ subjectActorIds: string[];
68
+ anySubject: boolean;
69
+ actorIds: string[];
70
+ anyActor: boolean;
71
+ senderActorIds: string[];
72
+ anySender: boolean;
73
+ recipientActorIds: string[];
74
+ anyRecipient: boolean;
75
+ userActorIds: string[];
76
+ anyUser: boolean;
77
+ targetActorIds: string[];
78
+ anyTarget: boolean;
79
+ claimSearchParams: Readonly<Record<string, string[]>>;
80
+ periodStart?: string;
81
+ periodEnd?: string;
82
+ page: number;
83
+ count?: number;
84
+ };
85
+ export type CommunicationParticipantProjection = {
86
+ subject?: unknown;
87
+ sender?: unknown;
88
+ recipients?: unknown;
89
+ from?: unknown;
90
+ to?: unknown;
91
+ sent?: unknown;
92
+ category?: unknown;
93
+ topic?: unknown;
94
+ };
95
+ export type CommunicationParticipantIndexedAttribute = {
96
+ name: string;
97
+ value: string;
98
+ unique?: boolean;
99
+ };
100
+ export declare function normalizeCommunicationParticipantToken(value: unknown): string;
101
+ export declare function normalizeCommunicationParticipantTokenList(value: unknown): string[];
102
+ export declare function isCommunicationParticipantWildcardToken(value: unknown): boolean;
103
+ export declare function buildCommunicationParticipantSearchParameters(input: CommunicationParticipantSearchInput): FhirParametersResource;
104
+ export declare function buildCommunicationParticipantSearchBundle(input: CommunicationParticipantSearchInput): ReturnType<typeof buildSearchBundle>;
105
+ export declare function parseCommunicationParticipantSearchCriteria(input: Record<string, unknown> | FhirParametersResource | undefined): CommunicationParticipantSearchCriteria;
106
+ export declare function buildCommunicationParticipantIndexAttributes(projection: CommunicationParticipantProjection): CommunicationParticipantIndexedAttribute[];
107
+ export declare function matchesCommunicationParticipantSearch(projection: CommunicationParticipantProjection, criteria: CommunicationParticipantSearchCriteria): boolean;
108
+ export declare function paginateCommunicationParticipantMatches<T>(records: readonly T[], criteria: Pick<CommunicationParticipantSearchCriteria, 'page' | 'count'>): T[];