gdc-common-utils-ts 1.8.0 → 1.10.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.
package/README.md CHANGED
@@ -142,6 +142,8 @@ The canonical API contract should live in JSDoc on exported code. The README act
142
142
  - This is the preferred first scope to teach when the backend only needs subject-scoped read access.
143
143
  - [`getOrganizationCredentialFromVpToken(...)`, `getLegalRepresentativeCredentialFromVpToken(...)`](src/utils/vp-token.ts)
144
144
  - Extract typed VC objects from a VP token when GW/SDK flows carry canonical proof only in `vp_token`.
145
+ - [`docs/VP_TOKEN_101.md`](docs/VP_TOKEN_101.md)
146
+ - Step-by-step guide for building the canonical compact `vp_token` string from organization and representative VCs.
145
147
  - [`validateCommunicationResourceFhirR4(...)`](src/utils/communication-fhir-r4.ts)
146
148
  - Validates FHIR R4 `Communication` resources.
147
149
  - [`transformCommunicationClaimsToResourceFhirR4(...)`](src/utils/communication-fhir-r4.ts)
@@ -14,9 +14,25 @@ export type ServiceCapabilityFamilyValue = typeof ServiceCapabilityFamily[keyof
14
14
  * `.rs` and `.cruds` can evolve independently across runtimes.
15
15
  */
16
16
  export declare const ServiceCapabilityToken: {
17
+ readonly IndexReader: "indexing.rs";
18
+ readonly IndexProvider: "indexing.cruds";
19
+ readonly DigitalTwinReader: "digitaltwin.rs";
20
+ readonly DigitalTwinProvider: "digitaltwin.cruds";
21
+ /**
22
+ * @deprecated Prefer `IndexReader`.
23
+ */
17
24
  readonly IndexingReadSearch: "indexing.rs";
25
+ /**
26
+ * @deprecated Prefer `IndexProvider`.
27
+ */
18
28
  readonly IndexingCruds: "indexing.cruds";
29
+ /**
30
+ * @deprecated Prefer `DigitalTwinReader`.
31
+ */
19
32
  readonly DigitalTwinReadSearch: "digitaltwin.rs";
33
+ /**
34
+ * @deprecated Prefer `DigitalTwinProvider`.
35
+ */
20
36
  readonly DigitalTwinCruds: "digitaltwin.cruds";
21
37
  };
22
38
  export type ServiceCapabilityTokenValue = typeof ServiceCapabilityToken[keyof typeof ServiceCapabilityToken];
@@ -28,10 +44,18 @@ export type ServiceCapabilityTokenValue = typeof ServiceCapabilityToken[keyof ty
28
44
  * - `Reader` maps to read/search capability (`*.rs`)
29
45
  */
30
46
  export declare const ServiceCapability: {
31
- readonly IndexingProvider: "indexing.cruds";
32
- readonly IndexingReader: "indexing.rs";
47
+ readonly IndexProvider: "indexing.cruds";
48
+ readonly IndexReader: "indexing.rs";
33
49
  readonly DigitalTwinProvider: "digitaltwin.cruds";
34
50
  readonly DigitalTwinReader: "digitaltwin.rs";
51
+ /**
52
+ * @deprecated Prefer `IndexProvider`.
53
+ */
54
+ readonly IndexingProvider: "indexing.cruds";
55
+ /**
56
+ * @deprecated Prefer `IndexReader`.
57
+ */
58
+ readonly IndexingReader: "indexing.rs";
35
59
  };
36
60
  export type ServiceCapabilityValue = typeof ServiceCapability[keyof typeof ServiceCapability];
37
61
  /**
@@ -15,9 +15,25 @@ export const ServiceCapabilityFamily = {
15
15
  * `.rs` and `.cruds` can evolve independently across runtimes.
16
16
  */
17
17
  export const ServiceCapabilityToken = {
18
+ IndexReader: 'indexing.rs',
19
+ IndexProvider: 'indexing.cruds',
20
+ DigitalTwinReader: 'digitaltwin.rs',
21
+ DigitalTwinProvider: 'digitaltwin.cruds',
22
+ /**
23
+ * @deprecated Prefer `IndexReader`.
24
+ */
18
25
  IndexingReadSearch: 'indexing.rs',
26
+ /**
27
+ * @deprecated Prefer `IndexProvider`.
28
+ */
19
29
  IndexingCruds: 'indexing.cruds',
30
+ /**
31
+ * @deprecated Prefer `DigitalTwinReader`.
32
+ */
20
33
  DigitalTwinReadSearch: 'digitaltwin.rs',
34
+ /**
35
+ * @deprecated Prefer `DigitalTwinProvider`.
36
+ */
21
37
  DigitalTwinCruds: 'digitaltwin.cruds',
22
38
  };
23
39
  /**
@@ -28,10 +44,18 @@ export const ServiceCapabilityToken = {
28
44
  * - `Reader` maps to read/search capability (`*.rs`)
29
45
  */
30
46
  export const ServiceCapability = {
31
- IndexingProvider: ServiceCapabilityToken.IndexingCruds,
32
- IndexingReader: ServiceCapabilityToken.IndexingReadSearch,
33
- DigitalTwinProvider: ServiceCapabilityToken.DigitalTwinCruds,
34
- DigitalTwinReader: ServiceCapabilityToken.DigitalTwinReadSearch,
47
+ IndexProvider: ServiceCapabilityToken.IndexProvider,
48
+ IndexReader: ServiceCapabilityToken.IndexReader,
49
+ DigitalTwinProvider: ServiceCapabilityToken.DigitalTwinProvider,
50
+ DigitalTwinReader: ServiceCapabilityToken.DigitalTwinReader,
51
+ /**
52
+ * @deprecated Prefer `IndexProvider`.
53
+ */
54
+ IndexingProvider: ServiceCapabilityToken.IndexProvider,
55
+ /**
56
+ * @deprecated Prefer `IndexReader`.
57
+ */
58
+ IndexingReader: ServiceCapabilityToken.IndexReader,
35
59
  };
36
60
  /**
37
61
  * Parses the CSV stored in `org.schema.Service.serviceType`.
@@ -26,8 +26,8 @@ export const EXAMPLE_ACTIVATE_ORGANIZATION_FROM_ICA_PROOF_INPUT = {
26
26
  [ClaimsServiceSchemaorg.identifier]: EXAMPLE_SERVICE_PUBLIC_DID,
27
27
  [ClaimsServiceSchemaorg.url]: `https://operator.example.net/acme/cds-${String(EXAMPLE_JURISDICTION).toLowerCase()}/v1/${EXAMPLE_SECTOR}`,
28
28
  [ClaimsServiceSchemaorg.serviceType]: serializeServiceCapabilityTokens([
29
- ServiceCapabilityToken.IndexingCruds,
30
- ServiceCapabilityToken.DigitalTwinReadSearch,
29
+ ServiceCapabilityToken.IndexProvider,
30
+ ServiceCapabilityToken.DigitalTwinReader,
31
31
  ]),
32
32
  },
33
33
  };
@@ -0,0 +1,61 @@
1
+ /**
2
+ * @fileoverview Canonical flat-claim constants for FHIR `RelatedPerson`.
3
+ *
4
+ * @architecture 101
5
+ * - Use exported constants instead of inline claim-name literals.
6
+ * - `ClaimsContextFhirRelatedPerson` models the stable business/search contract.
7
+ * - `RelatedPerson.patient` is kept as a transport/storage compatibility alias for
8
+ * existing R4 payloads, while `RelatedPerson.subject` remains the shared SDK name.
9
+ */
10
+ import type { SearchParameterCatalog } from './params';
11
+ /**
12
+ * Canonical interoperable claims for `RelatedPerson`.
13
+ *
14
+ * The enum follows the established `ResourceType.parameter` shape used by the
15
+ * rest of the flat FHIR claims model.
16
+ */
17
+ export declare enum ClaimsContextFhirRelatedPerson {
18
+ Identifier = "RelatedPerson.identifier",
19
+ Subject = "RelatedPerson.subject",
20
+ Relationship = "RelatedPerson.relationship",
21
+ Name = "RelatedPerson.name",
22
+ Email = "RelatedPerson.email",
23
+ Phone = "RelatedPerson.phone"
24
+ }
25
+ /**
26
+ * Legacy FHIR R4 field name still present in examples and existing stored data.
27
+ *
28
+ * New shared code should normalize from this alias into
29
+ * `ClaimsContextFhirRelatedPerson.Subject` when projecting business DTOs.
30
+ */
31
+ export declare const FHIR_RELATED_PERSON_PATIENT_CLAIM: "RelatedPerson.patient";
32
+ /**
33
+ * Legacy telecom alias preserved for older ingestion payloads.
34
+ */
35
+ export declare const FHIR_RELATED_PERSON_TELECOM_CLAIM: "RelatedPerson.telecom";
36
+ /**
37
+ * Optional lifecycle/status claim used by projections when present.
38
+ */
39
+ export declare const FHIR_RELATED_PERSON_STATUS_CLAIM: "RelatedPerson.status";
40
+ /**
41
+ * Public search parameter names exposed for `RelatedPerson`.
42
+ *
43
+ * These names are independent from the underlying flat claim keys and are the
44
+ * right source for client-side search UIs and future `CapabilityStatement`
45
+ * generation.
46
+ */
47
+ export declare enum RelatedPersonSearchParameterName {
48
+ Identifier = "identifier",
49
+ Subject = "subject",
50
+ Relationship = "relationship",
51
+ Name = "name",
52
+ Email = "email",
53
+ Phone = "phone"
54
+ }
55
+ /**
56
+ * Shared searchable/indexable parameter catalog for `RelatedPerson`.
57
+ *
58
+ * `name` is the canonical flat claim key to index/query. The record key is the
59
+ * public search-attribute name.
60
+ */
61
+ export declare const relatedPersonSearchParameterCatalog: SearchParameterCatalog<RelatedPersonSearchParameterName>;
@@ -0,0 +1,108 @@
1
+ // Copyright 2026 Antifraud Services Inc. under the Apache License, Version 2.0.
2
+ /**
3
+ * @fileoverview Canonical flat-claim constants for FHIR `RelatedPerson`.
4
+ *
5
+ * @architecture 101
6
+ * - Use exported constants instead of inline claim-name literals.
7
+ * - `ClaimsContextFhirRelatedPerson` models the stable business/search contract.
8
+ * - `RelatedPerson.patient` is kept as a transport/storage compatibility alias for
9
+ * existing R4 payloads, while `RelatedPerson.subject` remains the shared SDK name.
10
+ */
11
+ /**
12
+ * Canonical interoperable claims for `RelatedPerson`.
13
+ *
14
+ * The enum follows the established `ResourceType.parameter` shape used by the
15
+ * rest of the flat FHIR claims model.
16
+ */
17
+ export var ClaimsContextFhirRelatedPerson;
18
+ (function (ClaimsContextFhirRelatedPerson) {
19
+ ClaimsContextFhirRelatedPerson["Identifier"] = "RelatedPerson.identifier";
20
+ ClaimsContextFhirRelatedPerson["Subject"] = "RelatedPerson.subject";
21
+ ClaimsContextFhirRelatedPerson["Relationship"] = "RelatedPerson.relationship";
22
+ ClaimsContextFhirRelatedPerson["Name"] = "RelatedPerson.name";
23
+ ClaimsContextFhirRelatedPerson["Email"] = "RelatedPerson.email";
24
+ ClaimsContextFhirRelatedPerson["Phone"] = "RelatedPerson.phone";
25
+ })(ClaimsContextFhirRelatedPerson || (ClaimsContextFhirRelatedPerson = {}));
26
+ /**
27
+ * Legacy FHIR R4 field name still present in examples and existing stored data.
28
+ *
29
+ * New shared code should normalize from this alias into
30
+ * `ClaimsContextFhirRelatedPerson.Subject` when projecting business DTOs.
31
+ */
32
+ export const FHIR_RELATED_PERSON_PATIENT_CLAIM = 'RelatedPerson.patient';
33
+ /**
34
+ * Legacy telecom alias preserved for older ingestion payloads.
35
+ */
36
+ export const FHIR_RELATED_PERSON_TELECOM_CLAIM = 'RelatedPerson.telecom';
37
+ /**
38
+ * Optional lifecycle/status claim used by projections when present.
39
+ */
40
+ export const FHIR_RELATED_PERSON_STATUS_CLAIM = 'RelatedPerson.status';
41
+ /**
42
+ * Public search parameter names exposed for `RelatedPerson`.
43
+ *
44
+ * These names are independent from the underlying flat claim keys and are the
45
+ * right source for client-side search UIs and future `CapabilityStatement`
46
+ * generation.
47
+ */
48
+ export var RelatedPersonSearchParameterName;
49
+ (function (RelatedPersonSearchParameterName) {
50
+ RelatedPersonSearchParameterName["Identifier"] = "identifier";
51
+ RelatedPersonSearchParameterName["Subject"] = "subject";
52
+ RelatedPersonSearchParameterName["Relationship"] = "relationship";
53
+ RelatedPersonSearchParameterName["Name"] = "name";
54
+ RelatedPersonSearchParameterName["Email"] = "email";
55
+ RelatedPersonSearchParameterName["Phone"] = "phone";
56
+ })(RelatedPersonSearchParameterName || (RelatedPersonSearchParameterName = {}));
57
+ /**
58
+ * Shared searchable/indexable parameter catalog for `RelatedPerson`.
59
+ *
60
+ * `name` is the canonical flat claim key to index/query. The record key is the
61
+ * public search-attribute name.
62
+ */
63
+ export const relatedPersonSearchParameterCatalog = {
64
+ [RelatedPersonSearchParameterName.Identifier]: {
65
+ name: ClaimsContextFhirRelatedPerson.Identifier,
66
+ type: 'token',
67
+ value: undefined,
68
+ indexed: true,
69
+ appliesTo: ['RelatedPerson'],
70
+ },
71
+ [RelatedPersonSearchParameterName.Subject]: {
72
+ name: ClaimsContextFhirRelatedPerson.Subject,
73
+ type: 'reference',
74
+ value: undefined,
75
+ indexed: true,
76
+ claimAliases: [FHIR_RELATED_PERSON_PATIENT_CLAIM],
77
+ appliesTo: ['RelatedPerson'],
78
+ },
79
+ [RelatedPersonSearchParameterName.Relationship]: {
80
+ name: ClaimsContextFhirRelatedPerson.Relationship,
81
+ type: 'token',
82
+ value: undefined,
83
+ indexed: true,
84
+ appliesTo: ['RelatedPerson'],
85
+ },
86
+ [RelatedPersonSearchParameterName.Name]: {
87
+ name: ClaimsContextFhirRelatedPerson.Name,
88
+ type: 'string',
89
+ value: undefined,
90
+ indexed: true,
91
+ appliesTo: ['RelatedPerson'],
92
+ },
93
+ [RelatedPersonSearchParameterName.Email]: {
94
+ name: ClaimsContextFhirRelatedPerson.Email,
95
+ type: 'token',
96
+ value: undefined,
97
+ indexed: true,
98
+ appliesTo: ['RelatedPerson'],
99
+ },
100
+ [RelatedPersonSearchParameterName.Phone]: {
101
+ name: ClaimsContextFhirRelatedPerson.Phone,
102
+ type: 'token',
103
+ value: undefined,
104
+ indexed: true,
105
+ claimAliases: [FHIR_RELATED_PERSON_TELECOM_CLAIM],
106
+ appliesTo: ['RelatedPerson'],
107
+ },
108
+ };
@@ -0,0 +1,42 @@
1
+ /**
2
+ * @fileoverview Shared DTOs for portal/BFF `related profiles` projections.
3
+ *
4
+ * @architecture 101
5
+ * - These DTOs are frontend-facing projections, not raw FHIR payloads.
6
+ * - Raw search/index semantics stay in `ClaimsContextFhirRelatedPerson`.
7
+ * - Use exported constants for repeated source and parameter names.
8
+ */
9
+ export type RelatedProfileStatus = 'active' | 'pending' | 'inactive' | 'revoked';
10
+ export type RelatedProfileRole = 'controller' | 'caregiver' | 'related-person' | 'professional' | 'member' | 'unknown';
11
+ export type RelatedProfileSource = 'relatedperson';
12
+ export declare const RELATED_PROFILE_SOURCE_RELATED_PERSON: "relatedperson";
13
+ export declare const RELATED_PROFILE_SEARCH_PARAM_ACTOR_IDENTIFIER: "actorIdentifier";
14
+ export declare const RELATED_PROFILE_SEARCH_PARAM_SUBJECT_ID: "subjectId";
15
+ export declare const RELATED_PROFILE_SEARCH_PARAM_RELATIONSHIP: "relationship";
16
+ export declare const RELATED_PROFILE_SEARCH_PARAM_INCLUDE_INACTIVE: "includeInactive";
17
+ export type RelatedProfileSearchInput = Readonly<{
18
+ actorIdentifier: string;
19
+ subjectId?: string;
20
+ relationship?: string;
21
+ includeInactive?: boolean;
22
+ }>;
23
+ export type RelatedProfileSummary = Readonly<{
24
+ relationshipId: string;
25
+ source: RelatedProfileSource;
26
+ subjectId: string;
27
+ actorIdentifier?: string;
28
+ actorDisplayName?: string;
29
+ actorTelecom?: string;
30
+ relationship?: string;
31
+ role: RelatedProfileRole;
32
+ isController: boolean;
33
+ status: RelatedProfileStatus;
34
+ claims: Record<string, unknown>;
35
+ }>;
36
+ export type RelatedProfileSearchResult = Readonly<{
37
+ actorIdentifier: string;
38
+ total: number;
39
+ data: RelatedProfileSummary[];
40
+ }>;
41
+ export declare const DEFAULT_INDIVIDUAL_MEMBER_BASELINE_SEATS = 2;
42
+ export declare const DEFAULT_INDIVIDUAL_MEMBER_BASELINE_PRICE_EUR = "0.00";
@@ -0,0 +1,16 @@
1
+ // Copyright 2026 Antifraud Services Inc. under the Apache License, Version 2.0.
2
+ /**
3
+ * @fileoverview Shared DTOs for portal/BFF `related profiles` projections.
4
+ *
5
+ * @architecture 101
6
+ * - These DTOs are frontend-facing projections, not raw FHIR payloads.
7
+ * - Raw search/index semantics stay in `ClaimsContextFhirRelatedPerson`.
8
+ * - Use exported constants for repeated source and parameter names.
9
+ */
10
+ export const RELATED_PROFILE_SOURCE_RELATED_PERSON = 'relatedperson';
11
+ export const RELATED_PROFILE_SEARCH_PARAM_ACTOR_IDENTIFIER = 'actorIdentifier';
12
+ export const RELATED_PROFILE_SEARCH_PARAM_SUBJECT_ID = 'subjectId';
13
+ export const RELATED_PROFILE_SEARCH_PARAM_RELATIONSHIP = 'relationship';
14
+ export const RELATED_PROFILE_SEARCH_PARAM_INCLUDE_INACTIVE = 'includeInactive';
15
+ export const DEFAULT_INDIVIDUAL_MEMBER_BASELINE_SEATS = 2;
16
+ export const DEFAULT_INDIVIDUAL_MEMBER_BASELINE_PRICE_EUR = '0.00';
@@ -0,0 +1,44 @@
1
+ /**
2
+ * @fileoverview Shared internal index-parameter builders used by GW managers.
3
+ *
4
+ * @architecture 101
5
+ * These helpers are not public FHIR search catalogs. They encapsulate internal
6
+ * blind-query index shapes already shared across multiple GW managers.
7
+ */
8
+ import type { ParameterData } from '../models/params';
9
+ import type { ClaimsRecord } from '../models/resource-document';
10
+ /**
11
+ * Internal blind-query attribute names shared by employee/controller records.
12
+ */
13
+ export declare enum GatewayEmployeeIndexAttributeName {
14
+ Email = "email",
15
+ Role = "role",
16
+ Kid = "kid"
17
+ }
18
+ type EmployeeIdentityIndexInput = Readonly<{
19
+ email?: string;
20
+ roleCode?: string;
21
+ kidValues?: readonly string[];
22
+ }>;
23
+ /**
24
+ * Builds the canonical blind-query index set for employee/controller records.
25
+ *
26
+ * `roleCode` is expected to be already normalized by the caller.
27
+ *
28
+ * @param input - Concrete employee/controller identity values.
29
+ * @returns Concrete `ParameterData[]` entries ready for HMAC protection.
30
+ */
31
+ export declare function buildEmployeeIdentityIndexParameters(input: EmployeeIdentityIndexInput): ParameterData[];
32
+ /**
33
+ * Materializes concrete index parameters from a shared flat-claim definition list.
34
+ *
35
+ * The returned entries keep the original definition metadata (`type`, `unique`)
36
+ * and only replace `value` with the concrete scalar from the claims object when
37
+ * present.
38
+ *
39
+ * @param claims - Flat claims object to read from.
40
+ * @param definitions - Shared parameter definitions.
41
+ * @returns Concrete entries with populated values only.
42
+ */
43
+ export declare function buildClaimIndexParametersFromDefinitionList(claims: ClaimsRecord, definitions: readonly ParameterData[]): ParameterData[];
44
+ export {};
@@ -0,0 +1,80 @@
1
+ // Copyright 2026 Antifraud Services Inc. under the Apache License, Version 2.0.
2
+ /**
3
+ * @fileoverview Shared internal index-parameter builders used by GW managers.
4
+ *
5
+ * @architecture 101
6
+ * These helpers are not public FHIR search catalogs. They encapsulate internal
7
+ * blind-query index shapes already shared across multiple GW managers.
8
+ */
9
+ /**
10
+ * Internal blind-query attribute names shared by employee/controller records.
11
+ */
12
+ export var GatewayEmployeeIndexAttributeName;
13
+ (function (GatewayEmployeeIndexAttributeName) {
14
+ GatewayEmployeeIndexAttributeName["Email"] = "email";
15
+ GatewayEmployeeIndexAttributeName["Role"] = "role";
16
+ GatewayEmployeeIndexAttributeName["Kid"] = "kid";
17
+ })(GatewayEmployeeIndexAttributeName || (GatewayEmployeeIndexAttributeName = {}));
18
+ /**
19
+ * Builds the canonical blind-query index set for employee/controller records.
20
+ *
21
+ * `roleCode` is expected to be already normalized by the caller.
22
+ *
23
+ * @param input - Concrete employee/controller identity values.
24
+ * @returns Concrete `ParameterData[]` entries ready for HMAC protection.
25
+ */
26
+ export function buildEmployeeIdentityIndexParameters(input) {
27
+ const parameters = [];
28
+ if (typeof input.email === 'string' && input.email.trim().length > 0) {
29
+ parameters.push({
30
+ name: GatewayEmployeeIndexAttributeName.Email,
31
+ value: input.email.trim(),
32
+ unique: true,
33
+ type: 'string',
34
+ });
35
+ }
36
+ if (typeof input.roleCode === 'string' && input.roleCode.trim().length > 0) {
37
+ parameters.push({
38
+ name: GatewayEmployeeIndexAttributeName.Role,
39
+ value: input.roleCode.trim(),
40
+ unique: false,
41
+ type: 'token',
42
+ });
43
+ }
44
+ for (const kid of input.kidValues || []) {
45
+ if (typeof kid !== 'string' || kid.trim().length === 0)
46
+ continue;
47
+ parameters.push({
48
+ name: GatewayEmployeeIndexAttributeName.Kid,
49
+ value: kid.trim(),
50
+ unique: false,
51
+ type: 'string',
52
+ });
53
+ }
54
+ return parameters;
55
+ }
56
+ /**
57
+ * Materializes concrete index parameters from a shared flat-claim definition list.
58
+ *
59
+ * The returned entries keep the original definition metadata (`type`, `unique`)
60
+ * and only replace `value` with the concrete scalar from the claims object when
61
+ * present.
62
+ *
63
+ * @param claims - Flat claims object to read from.
64
+ * @param definitions - Shared parameter definitions.
65
+ * @returns Concrete entries with populated values only.
66
+ */
67
+ export function buildClaimIndexParametersFromDefinitionList(claims, definitions) {
68
+ const parameters = [];
69
+ for (const definition of definitions) {
70
+ const rawValue = claims[definition.name];
71
+ if (typeof rawValue !== 'string' && typeof rawValue !== 'number') {
72
+ continue;
73
+ }
74
+ parameters.push({
75
+ ...definition,
76
+ value: rawValue,
77
+ });
78
+ }
79
+ return parameters;
80
+ }
@@ -0,0 +1,31 @@
1
+ /**
2
+ * @fileoverview Helpers for shared search-parameter catalogs.
3
+ *
4
+ * @architecture 101
5
+ * - Search catalogs define the public search surface by resource type.
6
+ * - These helpers resolve canonical contextualized claim names plus aliases.
7
+ * - GW managers can use the same catalog both for indexing and for future
8
+ * `CapabilityStatement.searchParam` generation.
9
+ */
10
+ import type { ClaimsRecord } from '../models/resource-document';
11
+ import type { ParameterData, SearchParameterCatalog, SearchParameterDefinition } from '../models/params';
12
+ /**
13
+ * Resolves the first populated value for a search parameter definition using its
14
+ * canonical claim name followed by any configured aliases.
15
+ *
16
+ * @param claims - Flat claims object.
17
+ * @param definition - Search parameter definition.
18
+ * @returns First populated scalar value, if any.
19
+ */
20
+ export declare function resolveSearchParameterValueFromClaims(claims: ClaimsRecord, definition: SearchParameterDefinition): string | undefined;
21
+ /**
22
+ * Builds index/query-ready `ParameterData` entries from a shared search catalog.
23
+ *
24
+ * Only catalog entries marked as indexable, and with a populated value in the
25
+ * claims object, are returned.
26
+ *
27
+ * @param claims - Flat claims object.
28
+ * @param catalog - Shared search parameter catalog for a resource type.
29
+ * @returns Concrete parameter entries with resolved values.
30
+ */
31
+ export declare function buildIndexParametersFromSearchCatalog<TSearchName extends string>(claims: ClaimsRecord, catalog: SearchParameterCatalog<TSearchName>): ParameterData[];
@@ -0,0 +1,81 @@
1
+ // Copyright 2026 Antifraud Services Inc. under the Apache License, Version 2.0.
2
+ /**
3
+ * @fileoverview Helpers for shared search-parameter catalogs.
4
+ *
5
+ * @architecture 101
6
+ * - Search catalogs define the public search surface by resource type.
7
+ * - These helpers resolve canonical contextualized claim names plus aliases.
8
+ * - GW managers can use the same catalog both for indexing and for future
9
+ * `CapabilityStatement.searchParam` generation.
10
+ */
11
+ /**
12
+ * Trims a scalar value into a canonical optional string.
13
+ *
14
+ * @param value - Raw claim value.
15
+ * @returns Trimmed text or `undefined` when empty.
16
+ */
17
+ function normalizeOptionalText(value) {
18
+ const normalized = String(value ?? '').trim();
19
+ return normalized || undefined;
20
+ }
21
+ /**
22
+ * Resolves a flat claim using exact match first and `@context`-prefixed lookup
23
+ * as compatibility fallback for contextualized storage mode.
24
+ *
25
+ * @param claims - Flat claims object.
26
+ * @param claimName - Canonical or alias claim key.
27
+ * @returns Scalar value when present.
28
+ */
29
+ function getContextualizedClaimValue(claims, claimName) {
30
+ const directValue = normalizeOptionalText(claims[claimName]);
31
+ if (directValue)
32
+ return directValue;
33
+ const context = normalizeOptionalText(claims['@context']);
34
+ if (!context)
35
+ return undefined;
36
+ const prefixedName = context.endsWith('.') ? `${context}${claimName}` : `${context}.${claimName}`;
37
+ return normalizeOptionalText(claims[prefixedName]);
38
+ }
39
+ /**
40
+ * Resolves the first populated value for a search parameter definition using its
41
+ * canonical claim name followed by any configured aliases.
42
+ *
43
+ * @param claims - Flat claims object.
44
+ * @param definition - Search parameter definition.
45
+ * @returns First populated scalar value, if any.
46
+ */
47
+ export function resolveSearchParameterValueFromClaims(claims, definition) {
48
+ const claimNames = [definition.name, ...(definition.claimAliases || [])];
49
+ for (const claimName of claimNames) {
50
+ const normalized = getContextualizedClaimValue(claims, claimName);
51
+ if (normalized)
52
+ return normalized;
53
+ }
54
+ return undefined;
55
+ }
56
+ /**
57
+ * Builds index/query-ready `ParameterData` entries from a shared search catalog.
58
+ *
59
+ * Only catalog entries marked as indexable, and with a populated value in the
60
+ * claims object, are returned.
61
+ *
62
+ * @param claims - Flat claims object.
63
+ * @param catalog - Shared search parameter catalog for a resource type.
64
+ * @returns Concrete parameter entries with resolved values.
65
+ */
66
+ export function buildIndexParametersFromSearchCatalog(claims, catalog) {
67
+ const parameters = [];
68
+ for (const definition of Object.values(catalog)) {
69
+ if (definition.indexed === false)
70
+ continue;
71
+ const value = resolveSearchParameterValueFromClaims(claims, definition);
72
+ if (!value)
73
+ continue;
74
+ parameters.push({
75
+ ...definition,
76
+ name: definition.name,
77
+ value,
78
+ });
79
+ }
80
+ return parameters;
81
+ }
@@ -16,20 +16,47 @@ export type VpTokenPayload = {
16
16
  '@context'?: unknown;
17
17
  type?: unknown;
18
18
  holder?: string;
19
- verifiableCredential: string[];
19
+ verifiableCredential: Array<string | Record<string, unknown>>;
20
20
  [key: string]: unknown;
21
21
  };
22
22
  [key: string]: unknown;
23
23
  };
24
24
  export type VpCredential = Record<string, unknown>;
25
+ export type VpCredentialInput = string | Record<string, unknown>;
25
26
  export declare function generateUuidLike(): string;
26
27
  export declare function buildEpochWindow(ttlSeconds?: number): {
27
28
  iat: number;
28
29
  exp: number;
29
30
  };
30
31
  export declare function createVP(input?: Partial<VpTokenPayload>): VpTokenPayload;
31
- export declare function addVC(vpPayload: VpTokenPayload, vcJwt: string): VpTokenPayload;
32
- export declare function addVCs(vpPayload: VpTokenPayload, vcs: string[]): VpTokenPayload;
32
+ /**
33
+ * Appends one VC entry to the VP payload.
34
+ *
35
+ * Accepted input forms:
36
+ *
37
+ * - compact VC JWT/JWS string
38
+ * - raw JSON VC string
39
+ * - direct VC JSON object
40
+ *
41
+ * Storage rule:
42
+ *
43
+ * - string inputs are stored as strings
44
+ * - object inputs are stored as objects
45
+ *
46
+ * This keeps the builder compatible with existing compact-token flows while
47
+ * also supporting app/runtime code that already holds the VC as parsed JSON.
48
+ */
49
+ export declare function addVC(vpPayload: VpTokenPayload, vcInput: VpCredentialInput): VpTokenPayload;
50
+ /**
51
+ * Appends many VC entries to the VP payload.
52
+ *
53
+ * Each entry may be:
54
+ *
55
+ * - compact VC JWT/JWS string
56
+ * - raw JSON VC string
57
+ * - direct VC JSON object
58
+ */
59
+ export declare function addVCs(vpPayload: VpTokenPayload, vcs: VpCredentialInput[]): VpTokenPayload;
33
60
  /**
34
61
  * Decodes a compact VP token payload into a JSON object.
35
62
  *
@@ -67,8 +94,19 @@ export declare function getOrganizationCredentialFromVpToken(vpToken: string): V
67
94
  * @param vpToken Compact VP token or raw JSON string.
68
95
  */
69
96
  export declare function getLegalRepresentativeCredentialFromVpToken(vpToken: string): VpCredential | undefined;
70
- export declare function addOrganizationCredential(vpPayload: VpTokenPayload, vc: string): VpTokenPayload;
71
- export declare function addLegalRepresentativeCredential(vpPayload: VpTokenPayload, vc: string): VpTokenPayload;
97
+ /**
98
+ * Appends an organization activation credential after validating its VC type.
99
+ *
100
+ * Accepts compact VC strings, raw JSON VC strings, or VC JSON objects.
101
+ */
102
+ export declare function addOrganizationCredential(vpPayload: VpTokenPayload, vc: VpCredentialInput): VpTokenPayload;
103
+ /**
104
+ * Appends a legal-representative activation credential after validating its VC
105
+ * type.
106
+ *
107
+ * Accepts compact VC strings, raw JSON VC strings, or VC JSON objects.
108
+ */
109
+ export declare function addLegalRepresentativeCredential(vpPayload: VpTokenPayload, vc: VpCredentialInput): VpTokenPayload;
72
110
  export declare function prepareForSignature(header: VpTokenHeader, payload: VpTokenPayload): {
73
111
  encodedHeader: string;
74
112
  encodedPayload: string;
@@ -37,19 +37,52 @@ export function createVP(input) {
37
37
  };
38
38
  return base;
39
39
  }
40
- export function addVC(vpPayload, vcJwt) {
41
- const v = String(vcJwt || '').trim();
40
+ /**
41
+ * Appends one VC entry to the VP payload.
42
+ *
43
+ * Accepted input forms:
44
+ *
45
+ * - compact VC JWT/JWS string
46
+ * - raw JSON VC string
47
+ * - direct VC JSON object
48
+ *
49
+ * Storage rule:
50
+ *
51
+ * - string inputs are stored as strings
52
+ * - object inputs are stored as objects
53
+ *
54
+ * This keeps the builder compatible with existing compact-token flows while
55
+ * also supporting app/runtime code that already holds the VC as parsed JSON.
56
+ */
57
+ export function addVC(vpPayload, vcInput) {
58
+ if (vcInput && typeof vcInput === 'object') {
59
+ vpPayload.vp.verifiableCredential.push({ ...vcInput });
60
+ return vpPayload;
61
+ }
62
+ const v = String(vcInput || '').trim();
42
63
  if (!v)
43
64
  return vpPayload;
44
65
  vpPayload.vp.verifiableCredential.push(v);
45
66
  return vpPayload;
46
67
  }
68
+ /**
69
+ * Appends many VC entries to the VP payload.
70
+ *
71
+ * Each entry may be:
72
+ *
73
+ * - compact VC JWT/JWS string
74
+ * - raw JSON VC string
75
+ * - direct VC JSON object
76
+ */
47
77
  export function addVCs(vpPayload, vcs) {
48
78
  for (const vc of vcs || [])
49
79
  addVC(vpPayload, vc);
50
80
  return vpPayload;
51
81
  }
52
82
  function decodeVcPayload(vc) {
83
+ if (vc && typeof vc === 'object') {
84
+ return vc;
85
+ }
53
86
  const raw = String(vc || '').trim();
54
87
  if (!raw)
55
88
  return undefined;
@@ -173,9 +206,20 @@ function addTypedVC(vpPayload, vc, acceptedTypes, label) {
173
206
  }
174
207
  return addVC(vpPayload, vc);
175
208
  }
209
+ /**
210
+ * Appends an organization activation credential after validating its VC type.
211
+ *
212
+ * Accepts compact VC strings, raw JSON VC strings, or VC JSON objects.
213
+ */
176
214
  export function addOrganizationCredential(vpPayload, vc) {
177
215
  return addTypedVC(vpPayload, vc, [...ORGANIZATION_ACTIVATION_VC_TYPES], 'Organization');
178
216
  }
217
+ /**
218
+ * Appends a legal-representative activation credential after validating its VC
219
+ * type.
220
+ *
221
+ * Accepts compact VC strings, raw JSON VC strings, or VC JSON objects.
222
+ */
179
223
  export function addLegalRepresentativeCredential(vpPayload, vc) {
180
224
  return addTypedVC(vpPayload, vc, [...REPRESENTATIVE_ACTIVATION_VC_TYPES], 'LegalRepresentative');
181
225
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gdc-common-utils-ts",
3
- "version": "1.8.0",
3
+ "version": "1.10.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },