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
@@ -0,0 +1,156 @@
1
+ import { ResourceTypesFhirR4 } from '../constants/fhir-resource-types.js';
2
+ import { CommunicationClaim } from '../models/interoperable-claims/communication-claims.js';
3
+ import { buildCommunicationParticipantSearchBundle, buildCommunicationParticipantSearchParameters, normalizeCommunicationParticipantTokenList, } from './communication-participant-search.js';
4
+ export const CommunicationSearchEntryTypes = Object.freeze({
5
+ Search: 'Communication-search-request-v1.0',
6
+ });
7
+ export const CommunicationSearchOperationTypes = Object.freeze({
8
+ Search: 'search',
9
+ });
10
+ function normalizeText(value) {
11
+ const normalized = String(value ?? '').trim();
12
+ return normalized || undefined;
13
+ }
14
+ function normalizeInteger(value) {
15
+ const numeric = typeof value === 'number' ? value : Number(String(value ?? '').trim());
16
+ return Number.isInteger(numeric) && numeric > 0 ? numeric : undefined;
17
+ }
18
+ function normalizeSearchParamValue(claimKey, value) {
19
+ if (value === undefined || value === null) {
20
+ return undefined;
21
+ }
22
+ if (Array.isArray(value)) {
23
+ if (isParticipantClaimKey(claimKey)) {
24
+ return normalizeCommunicationParticipantTokenList(value);
25
+ }
26
+ const normalized = value
27
+ .map((item) => typeof item === 'string' ? item.trim() : item)
28
+ .filter((item) => item !== '' && item !== undefined && item !== null);
29
+ return normalized.length > 0 ? normalized : undefined;
30
+ }
31
+ if (typeof value === 'boolean' || typeof value === 'number') {
32
+ return value;
33
+ }
34
+ if (isParticipantClaimKey(claimKey)) {
35
+ const normalized = normalizeCommunicationParticipantTokenList(value);
36
+ return normalized.length > 0 ? normalized : undefined;
37
+ }
38
+ return normalizeText(value);
39
+ }
40
+ function cloneDraft(draft) {
41
+ const searchParams = {};
42
+ for (const [key, value] of Object.entries(draft?.searchParams || {})) {
43
+ const normalizedKey = normalizeText(key);
44
+ if (!normalizedKey) {
45
+ continue;
46
+ }
47
+ const normalizedValue = normalizeSearchParamValue(normalizedKey, value);
48
+ if (normalizedValue !== undefined) {
49
+ searchParams[normalizedKey] = normalizedValue;
50
+ }
51
+ }
52
+ return {
53
+ searchParams,
54
+ periodStart: normalizeText(draft?.periodStart),
55
+ periodEnd: normalizeText(draft?.periodEnd),
56
+ page: normalizeInteger(draft?.page),
57
+ count: normalizeInteger(draft?.count),
58
+ };
59
+ }
60
+ function isParticipantClaimKey(claimKey) {
61
+ return claimKey === CommunicationClaim.Subject
62
+ || claimKey === CommunicationClaim.Sender
63
+ || claimKey === CommunicationClaim.Recipient;
64
+ }
65
+ /**
66
+ * High-level chainable editor for `Communication/_search`.
67
+ *
68
+ * Design goals:
69
+ * - keep business filters near the caller instead of forcing ad-hoc `Parameters`
70
+ * - reuse canonical `CommunicationClaim.*` keys for search params
71
+ * - keep shared controls (`periodStart`, `periodEnd`, `page`, `count`) outside
72
+ * the claim bag because they are search controls, not resource claims
73
+ */
74
+ export class CommunicationSearchEditor {
75
+ draft;
76
+ constructor(initial) {
77
+ this.draft = cloneDraft(initial);
78
+ }
79
+ setSearchParams(value) {
80
+ this.draft = cloneDraft({ ...this.draft, searchParams: value });
81
+ return this;
82
+ }
83
+ setSearchParam(claimKey, value) {
84
+ this.draft = cloneDraft({
85
+ ...this.draft,
86
+ searchParams: {
87
+ ...this.draft.searchParams,
88
+ [claimKey]: value,
89
+ },
90
+ });
91
+ return this;
92
+ }
93
+ setSearchParamSender(value) {
94
+ return this.setSearchParam(CommunicationClaim.Sender, value);
95
+ }
96
+ setSearchParamRecipient(value) {
97
+ return this.setSearchParam(CommunicationClaim.Recipient, value);
98
+ }
99
+ setSearchParamCategory(value) {
100
+ return this.setSearchParam(CommunicationClaim.Category, value);
101
+ }
102
+ setSearchParamTopic(value) {
103
+ return this.setSearchParam(CommunicationClaim.Topic, value);
104
+ }
105
+ getSearchParams() {
106
+ return { ...this.draft.searchParams };
107
+ }
108
+ setPeriodStart(value) {
109
+ this.draft = cloneDraft({ ...this.draft, periodStart: value });
110
+ return this;
111
+ }
112
+ setPeriodEnd(value) {
113
+ this.draft = cloneDraft({ ...this.draft, periodEnd: value });
114
+ return this;
115
+ }
116
+ setPaginationCount(value) {
117
+ this.draft = cloneDraft({ ...this.draft, count: value });
118
+ return this;
119
+ }
120
+ setPageNumber(value) {
121
+ this.draft = cloneDraft({ ...this.draft, page: value });
122
+ return this;
123
+ }
124
+ getState() {
125
+ return cloneDraft(this.draft);
126
+ }
127
+ toSearchInput() {
128
+ return {
129
+ searchParams: this.draft.searchParams,
130
+ periodStart: this.draft.periodStart,
131
+ periodEnd: this.draft.periodEnd,
132
+ page: this.draft.page,
133
+ count: this.draft.count,
134
+ };
135
+ }
136
+ buildRequest() {
137
+ return buildCommunicationParticipantSearchParameters(this.toSearchInput());
138
+ }
139
+ buildEntry() {
140
+ const built = this.buildBundle().entry[0];
141
+ return {
142
+ type: CommunicationSearchEntryTypes.Search,
143
+ request: {
144
+ method: 'POST',
145
+ url: built?.request.url || `${ResourceTypesFhirR4.Communication}/_search`,
146
+ },
147
+ resource: built?.resource || this.buildRequest(),
148
+ meta: {
149
+ operationType: CommunicationSearchOperationTypes.Search,
150
+ },
151
+ };
152
+ }
153
+ buildBundle() {
154
+ return buildCommunicationParticipantSearchBundle(this.toSearchInput());
155
+ }
156
+ }
@@ -1,6 +1,19 @@
1
1
  import { ParameterData } from '../models/params';
2
2
  export type SearchParameterPrimitive = string | number | boolean | readonly (string | number | boolean)[];
3
3
  export type SearchRequestEncoding = 'get-query' | 'post-parameters';
4
+ /**
5
+ * Canonical business-level bundle types used by search request/response flows.
6
+ */
7
+ export declare const SearchBundleTypes: Readonly<{
8
+ readonly Search: "search";
9
+ readonly SearchResponse: "search-response";
10
+ }>;
11
+ export type SearchBundleOptions = Readonly<{
12
+ resourceType: string;
13
+ searchParams?: Readonly<Record<string, SearchParameterPrimitive | undefined>>;
14
+ encoding?: SearchRequestEncoding;
15
+ bundleType?: (typeof SearchBundleTypes)[keyof typeof SearchBundleTypes];
16
+ }>;
4
17
  export type FhirParametersParameter = {
5
18
  name: string;
6
19
  valueString?: string;
@@ -24,3 +37,22 @@ export type FhirParametersResource = {
24
37
  export declare function buildSearchQueryString(searchParams: Readonly<Record<string, SearchParameterPrimitive | undefined>>): string;
25
38
  export declare function buildFhirParametersResourceFromSearchParams(searchParams: Readonly<Record<string, SearchParameterPrimitive | undefined>>): FhirParametersResource;
26
39
  export declare function buildFhirParametersResourceFromParameterData(parameters: ReadonlyArray<ParameterData>): FhirParametersResource;
40
+ /**
41
+ * Builds one search bundle entry using either GET query parameters or POST
42
+ * `Parameters`.
43
+ */
44
+ export declare function buildSearchBundleEntry(input: SearchBundleOptions): {
45
+ request: {
46
+ method: 'GET' | 'POST';
47
+ url: string;
48
+ };
49
+ resource?: FhirParametersResource;
50
+ };
51
+ /**
52
+ * Builds a one-entry batch bundle for runtime-neutral search operations.
53
+ */
54
+ export declare function buildSearchBundle(input: SearchBundleOptions): {
55
+ resourceType: 'Bundle';
56
+ type: (typeof SearchBundleTypes)[keyof typeof SearchBundleTypes];
57
+ entry: Array<ReturnType<typeof buildSearchBundleEntry>>;
58
+ };
@@ -1,3 +1,10 @@
1
+ /**
2
+ * Canonical business-level bundle types used by search request/response flows.
3
+ */
4
+ export const SearchBundleTypes = Object.freeze({
5
+ Search: 'search',
6
+ SearchResponse: 'search-response',
7
+ });
1
8
  function normalizeSearchPrimitiveValues(value) {
2
9
  const values = Array.isArray(value) ? [...value] : [value];
3
10
  return values
@@ -82,3 +89,41 @@ export function buildFhirParametersResourceFromParameterData(parameters) {
82
89
  .filter((parameter) => Boolean(parameter)),
83
90
  };
84
91
  }
92
+ /**
93
+ * Builds one search bundle entry using either GET query parameters or POST
94
+ * `Parameters`.
95
+ */
96
+ export function buildSearchBundleEntry(input) {
97
+ const resourceType = String(input.resourceType || '').trim();
98
+ const encoding = input.encoding || 'post-parameters';
99
+ const searchParams = input.searchParams || {};
100
+ if (!resourceType) {
101
+ throw new Error('buildSearchBundleEntry requires resourceType.');
102
+ }
103
+ if (encoding === 'get-query') {
104
+ const query = buildSearchQueryString(searchParams);
105
+ return {
106
+ request: {
107
+ method: 'GET',
108
+ url: query ? `${resourceType}?${query}` : resourceType,
109
+ },
110
+ };
111
+ }
112
+ return {
113
+ request: {
114
+ method: 'POST',
115
+ url: `${resourceType}/_search`,
116
+ },
117
+ resource: buildFhirParametersResourceFromSearchParams(searchParams),
118
+ };
119
+ }
120
+ /**
121
+ * Builds a one-entry batch bundle for runtime-neutral search operations.
122
+ */
123
+ export function buildSearchBundle(input) {
124
+ return {
125
+ resourceType: 'Bundle',
126
+ type: input.bundleType || SearchBundleTypes.Search,
127
+ entry: [buildSearchBundleEntry(input)],
128
+ };
129
+ }
@@ -33,6 +33,10 @@ export * from './communication-fhir-r4';
33
33
  export * from './communication-document-reference';
34
34
  export * from './communication-bundle-document-request';
35
35
  export * from './communication-identity';
36
+ export * from './communication-search-editor';
37
+ export * from './communication-participant-search';
38
+ export * from './communication-participant-search-test-data';
39
+ export * from './communication-retention-policy';
36
40
  export * from './communication-attached-bundle-session';
37
41
  export * from './confidential-storage-persistence';
38
42
  export * from './confidential-storage-test-data';
@@ -44,6 +48,7 @@ export * from './fhir-validator';
44
48
  export * from './family-registration-test-data';
45
49
  export * from './individual-form-pdf';
46
50
  export * from './individual-organization-claims';
51
+ export * from './organization-lifecycle';
47
52
  export * from './individual-organization-lifecycle';
48
53
  export * from './individual-onboarding-editor';
49
54
  export * from './individual-onboarding-document-reference';
@@ -53,6 +58,8 @@ export * from './invoice-bundle';
53
58
  export * from './ips-bundle-claims';
54
59
  export * from './interoperable-resource-operation';
55
60
  export * from './jwt';
61
+ export * from './jwk-thumbprint';
62
+ export * from './legal-organization-onboarding';
56
63
  export * from './license';
57
64
  export * from './license-commercial-search';
58
65
  export * from './license-list-search';
@@ -69,5 +76,6 @@ export * from './object-sanitize';
69
76
  export * from './permission-templates';
70
77
  export * from './smart-scope';
71
78
  export * from './service-act-reasons';
79
+ export * from './same-as';
72
80
  export * from './activation-request';
73
81
  export * from './vp-token';
@@ -33,6 +33,10 @@ export * from './communication-fhir-r4.js';
33
33
  export * from './communication-document-reference.js';
34
34
  export * from './communication-bundle-document-request.js';
35
35
  export * from './communication-identity.js';
36
+ export * from './communication-search-editor.js';
37
+ export * from './communication-participant-search.js';
38
+ export * from './communication-participant-search-test-data.js';
39
+ export * from './communication-retention-policy.js';
36
40
  export * from './communication-attached-bundle-session.js';
37
41
  export * from './confidential-storage-persistence.js';
38
42
  export * from './confidential-storage-test-data.js';
@@ -44,6 +48,7 @@ export * from './fhir-validator.js';
44
48
  export * from './family-registration-test-data.js';
45
49
  export * from './individual-form-pdf.js';
46
50
  export * from './individual-organization-claims.js';
51
+ export * from './organization-lifecycle.js';
47
52
  export * from './individual-organization-lifecycle.js';
48
53
  export * from './individual-onboarding-editor.js';
49
54
  export * from './individual-onboarding-document-reference.js';
@@ -53,6 +58,8 @@ export * from './invoice-bundle.js';
53
58
  export * from './ips-bundle-claims.js';
54
59
  export * from './interoperable-resource-operation.js';
55
60
  export * from './jwt.js';
61
+ export * from './jwk-thumbprint.js';
62
+ export * from './legal-organization-onboarding.js';
56
63
  export * from './license.js';
57
64
  export * from './license-commercial-search.js';
58
65
  export * from './license-list-search.js';
@@ -69,5 +76,6 @@ export * from './object-sanitize.js';
69
76
  export * from './permission-templates.js';
70
77
  export * from './smart-scope.js';
71
78
  export * from './service-act-reasons.js';
79
+ export * from './same-as.js';
72
80
  export * from './activation-request.js';
73
81
  export * from './vp-token.js';
@@ -47,7 +47,7 @@ export type IndividualOrganizationLifecyclePayload = Readonly<{
47
47
  data: IndividualOrganizationLifecycleDataEntry[];
48
48
  };
49
49
  }>;
50
- export type IndividualOrganizationLifecycleDraftState = Readonly<{
50
+ export type IndividualOrganizationLifecycleEditorState = Readonly<{
51
51
  operation: IndividualOrganizationLifecycleOperation;
52
52
  claims: IndividualOrganizationLifecycleClaims;
53
53
  resourceId?: string;
@@ -76,7 +76,7 @@ export declare function buildCurrentIndividualOrganizationLifecycleDataEntry(inp
76
76
  */
77
77
  export declare function buildCurrentIndividualOrganizationLifecyclePayload(input: IndividualOrganizationLifecyclePayloadInput): IndividualOrganizationLifecyclePayload;
78
78
  /**
79
- * High-level chainable draft for hosted individual/family lifecycle work.
79
+ * High-level chainable editor for hosted individual/family lifecycle work.
80
80
  *
81
81
  * Teaching goal:
82
82
  * - authors one canonical flat `org.schema.Organization.*` claim set
@@ -84,11 +84,12 @@ export declare function buildCurrentIndividualOrganizationLifecyclePayload(input
84
84
  * - can emit either a semantic lifecycle message or the current GW CORE
85
85
  * payload shape used by `sdk-node`
86
86
  */
87
- export declare class IndividualOrganizationLifecycleDraft {
87
+ export declare class IndividualOrganizationLifecycleEditor {
88
88
  private draft;
89
- constructor(initial?: Partial<IndividualOrganizationLifecycleDraftState>);
89
+ constructor(initial?: Partial<IndividualOrganizationLifecycleEditorState>);
90
90
  mergeClaims(claims: IndividualOrganizationLifecycleClaims): this;
91
91
  setClaims(claims: IndividualOrganizationLifecycleClaims): this;
92
+ setContext(context: string): this;
92
93
  setIdentifier(identifier: string): this;
93
94
  setAlternateName(alternateName: string): this;
94
95
  setOwnerEmail(email: string): this;
@@ -96,8 +97,17 @@ export declare class IndividualOrganizationLifecycleDraft {
96
97
  setResourceId(resourceId?: string): this;
97
98
  setRequestType(requestType: string): this;
98
99
  setThreadId(thid: string): this;
100
+ getIdentifier(): string | undefined;
101
+ getContext(): string | undefined;
102
+ getAlternateName(): string | undefined;
103
+ getOwnerEmail(): string | undefined;
104
+ getOperation(): IndividualOrganizationLifecycleOperation;
105
+ getResourceId(): string | undefined;
106
+ getRequestType(): string | undefined;
107
+ getThreadId(): string | undefined;
99
108
  getClaims(): IndividualOrganizationLifecycleClaims;
100
- getDraft(): IndividualOrganizationLifecycleDraftState;
109
+ getState(): IndividualOrganizationLifecycleEditorState;
110
+ getEditorState(): IndividualOrganizationLifecycleEditorState;
101
111
  toSemanticMessage(): IndividualOrganizationLifecycleSemanticMessage;
102
112
  buildCurrentGwDataEntry(): IndividualOrganizationLifecycleDataEntry;
103
113
  buildCurrentGwPayload(): IndividualOrganizationLifecyclePayload;
@@ -17,7 +17,10 @@ function normalizeText(value) {
17
17
  function normalizeDraft(draft) {
18
18
  return {
19
19
  operation: draft?.operation || IndividualOrganizationLifecycleOperations.Disable,
20
- claims: cloneClaims(draft?.claims),
20
+ claims: {
21
+ '@context': 'org.schema',
22
+ ...cloneClaims(draft?.claims),
23
+ },
21
24
  resourceId: normalizeText(draft?.resourceId),
22
25
  requestType: normalizeText(draft?.requestType),
23
26
  thid: normalizeText(draft?.thid),
@@ -75,7 +78,7 @@ export function buildCurrentIndividualOrganizationLifecyclePayload(input) {
75
78
  };
76
79
  }
77
80
  /**
78
- * High-level chainable draft for hosted individual/family lifecycle work.
81
+ * High-level chainable editor for hosted individual/family lifecycle work.
79
82
  *
80
83
  * Teaching goal:
81
84
  * - authors one canonical flat `org.schema.Organization.*` claim set
@@ -83,7 +86,7 @@ export function buildCurrentIndividualOrganizationLifecyclePayload(input) {
83
86
  * - can emit either a semantic lifecycle message or the current GW CORE
84
87
  * payload shape used by `sdk-node`
85
88
  */
86
- export class IndividualOrganizationLifecycleDraft {
89
+ export class IndividualOrganizationLifecycleEditor {
87
90
  draft;
88
91
  constructor(initial) {
89
92
  this.draft = normalizeDraft(initial);
@@ -96,6 +99,15 @@ export class IndividualOrganizationLifecycleDraft {
96
99
  this.draft = patchDraft(this.draft, { claims });
97
100
  return this;
98
101
  }
102
+ setContext(context) {
103
+ this.draft = patchDraft(this.draft, {
104
+ claims: {
105
+ ...this.draft.claims,
106
+ '@context': String(context).trim(),
107
+ },
108
+ });
109
+ return this;
110
+ }
99
111
  setIdentifier(identifier) {
100
112
  this.draft = patchDraft(this.draft, {
101
113
  claims: {
@@ -139,12 +151,47 @@ export class IndividualOrganizationLifecycleDraft {
139
151
  this.draft = patchDraft(this.draft, { thid });
140
152
  return this;
141
153
  }
154
+ getIdentifier() {
155
+ const value = this.draft.claims[ClaimsOrganizationSchemaorg.identifier];
156
+ const normalized = normalizeText(value);
157
+ return normalized || undefined;
158
+ }
159
+ getContext() {
160
+ const value = this.draft.claims['@context'];
161
+ const normalized = normalizeText(value);
162
+ return normalized || undefined;
163
+ }
164
+ getAlternateName() {
165
+ const value = this.draft.claims[ClaimsOrganizationSchemaorg.alternateName];
166
+ const normalized = normalizeText(value);
167
+ return normalized || undefined;
168
+ }
169
+ getOwnerEmail() {
170
+ const value = this.draft.claims[ClaimsOrganizationSchemaorg.ownerEmail];
171
+ const normalized = normalizeText(value);
172
+ return normalized || undefined;
173
+ }
174
+ getOperation() {
175
+ return this.draft.operation;
176
+ }
177
+ getResourceId() {
178
+ return normalizeText(this.draft.resourceId) || undefined;
179
+ }
180
+ getRequestType() {
181
+ return normalizeText(this.draft.requestType) || undefined;
182
+ }
183
+ getThreadId() {
184
+ return normalizeText(this.draft.thid) || undefined;
185
+ }
142
186
  getClaims() {
143
187
  return cloneClaims(this.draft.claims);
144
188
  }
145
- getDraft() {
189
+ getState() {
146
190
  return normalizeDraft(this.draft);
147
191
  }
192
+ getEditorState() {
193
+ return this.getState();
194
+ }
148
195
  toSemanticMessage() {
149
196
  return {
150
197
  operation: this.draft.operation,
@@ -156,7 +203,7 @@ export class IndividualOrganizationLifecycleDraft {
156
203
  buildCurrentGwDataEntry() {
157
204
  const requestType = normalizeText(this.draft.requestType);
158
205
  if (!requestType) {
159
- throw new Error('IndividualOrganizationLifecycleDraft.buildCurrentGwDataEntry requires requestType.');
206
+ throw new Error('IndividualOrganizationLifecycleEditor.buildCurrentGwDataEntry requires requestType.');
160
207
  }
161
208
  return buildCurrentIndividualOrganizationLifecycleDataEntry({
162
209
  claims: this.getClaims(),
@@ -167,7 +214,7 @@ export class IndividualOrganizationLifecycleDraft {
167
214
  buildCurrentGwPayload() {
168
215
  const requestType = normalizeText(this.draft.requestType);
169
216
  if (!requestType) {
170
- throw new Error('IndividualOrganizationLifecycleDraft.buildCurrentGwPayload requires requestType.');
217
+ throw new Error('IndividualOrganizationLifecycleEditor.buildCurrentGwPayload requires requestType.');
171
218
  }
172
219
  return {
173
220
  thid: this.draft.thid || createLifecycleThreadId(this.draft.operation),
@@ -16,7 +16,7 @@ export declare const InteroperableLifecycleStatuses: Readonly<{
16
16
  }>;
17
17
  export type InteroperableLifecycleStatus = typeof InteroperableLifecycleStatuses[keyof typeof InteroperableLifecycleStatuses];
18
18
  export type InteroperableSearchParams = Readonly<Record<string, SearchParameterPrimitive | undefined>>;
19
- export type InteroperableResourceOperationDraft = Readonly<{
19
+ export type InteroperableResourceOperationState = Readonly<{
20
20
  resourceType: string;
21
21
  identifierClaimKey: string;
22
22
  identifierValue?: string;
@@ -45,7 +45,7 @@ export interface InteroperableResourceOperationEditor {
45
45
  mergeClaims(claims: Record<string, unknown>): InteroperableResourceOperationEditor;
46
46
  setLifecycleStatus(value: InteroperableLifecycleStatus): InteroperableResourceOperationEditor;
47
47
  importFhirResource(resource: FhirResource): InteroperableResourceOperationEditor;
48
- getDraft(): InteroperableResourceOperationDraft;
48
+ getState(): InteroperableResourceOperationState;
49
49
  getBusinessIdentifier(): string | undefined;
50
50
  getClaims(): Record<string, unknown>;
51
51
  buildLifecycleResource(): {
@@ -140,7 +140,7 @@ export declare function buildInteroperableSearchPath(resourceType: string): stri
140
140
  * - `resource.meta.status` carries lifecycle state without overloading
141
141
  * resource-specific FHIR fields such as `status` or `active`
142
142
  */
143
- export declare function buildLifecycleOperationResource(draft: InteroperableResourceOperationDraft): {
143
+ export declare function buildLifecycleOperationResource(state: InteroperableResourceOperationState): {
144
144
  resourceType: string;
145
145
  id?: string;
146
146
  identifier?: Array<{
@@ -155,4 +155,4 @@ export declare function buildLifecycleOperationResource(draft: InteroperableReso
155
155
  /**
156
156
  * Creates the shared chainable editor for search/disable/purge request shapes.
157
157
  */
158
- export declare function createInteroperableResourceOperationEditor(initial?: Partial<InteroperableResourceOperationDraft>): InteroperableResourceOperationEditor;
158
+ export declare function createInteroperableResourceOperationEditor(initial?: Partial<InteroperableResourceOperationState>): InteroperableResourceOperationEditor;
@@ -24,23 +24,23 @@ function cloneClaims(claims) {
24
24
  function resolveDefaultIdentifierClaimKey(resourceType) {
25
25
  return `${String(resourceType || '').trim()}.identifier`;
26
26
  }
27
- function normalizeDraft(draft) {
28
- const resourceType = normalizeText(draft?.resourceType) || 'Resource';
27
+ function normalizeDraft(state) {
28
+ const resourceType = normalizeText(state?.resourceType) || 'Resource';
29
29
  return {
30
30
  resourceType,
31
- identifierClaimKey: normalizeText(draft?.identifierClaimKey) || resolveDefaultIdentifierClaimKey(resourceType),
32
- identifierValue: normalizeText(draft?.identifierValue),
33
- identifierSystem: normalizeText(draft?.identifierSystem),
34
- resourceId: normalizeText(draft?.resourceId),
35
- claims: cloneClaims(draft?.claims),
36
- lifecycleStatus: draft?.lifecycleStatus,
31
+ identifierClaimKey: normalizeText(state?.identifierClaimKey) || resolveDefaultIdentifierClaimKey(resourceType),
32
+ identifierValue: normalizeText(state?.identifierValue),
33
+ identifierSystem: normalizeText(state?.identifierSystem),
34
+ resourceId: normalizeText(state?.resourceId),
35
+ claims: cloneClaims(state?.claims),
36
+ lifecycleStatus: state?.lifecycleStatus,
37
37
  };
38
38
  }
39
- function patchDraft(draft, patch) {
39
+ function patchDraft(state, patch) {
40
40
  return normalizeDraft({
41
- ...draft,
41
+ ...state,
42
42
  ...patch,
43
- claims: patch.claims ? cloneClaims(patch.claims) : cloneClaims(draft.claims),
43
+ claims: patch.claims ? cloneClaims(patch.claims) : cloneClaims(state.claims),
44
44
  });
45
45
  }
46
46
  /**
@@ -118,23 +118,23 @@ export function buildInteroperableSearchPath(resourceType) {
118
118
  * - `resource.meta.status` carries lifecycle state without overloading
119
119
  * resource-specific FHIR fields such as `status` or `active`
120
120
  */
121
- export function buildLifecycleOperationResource(draft) {
122
- const claims = cloneClaims(draft.claims);
123
- if (draft.identifierValue && !normalizeText(claims[draft.identifierClaimKey])) {
124
- claims[draft.identifierClaimKey] = draft.identifierValue;
121
+ export function buildLifecycleOperationResource(state) {
122
+ const claims = cloneClaims(state.claims);
123
+ if (state.identifierValue && !normalizeText(claims[state.identifierClaimKey])) {
124
+ claims[state.identifierClaimKey] = state.identifierValue;
125
125
  }
126
126
  return {
127
- resourceType: draft.resourceType,
128
- ...(draft.resourceId ? { id: draft.resourceId } : {}),
129
- ...(draft.identifierValue ? {
127
+ resourceType: state.resourceType,
128
+ ...(state.resourceId ? { id: state.resourceId } : {}),
129
+ ...(state.identifierValue ? {
130
130
  identifier: [{
131
- value: draft.identifierValue,
132
- ...(draft.identifierSystem ? { system: draft.identifierSystem } : {}),
131
+ value: state.identifierValue,
132
+ ...(state.identifierSystem ? { system: state.identifierSystem } : {}),
133
133
  }],
134
134
  } : {}),
135
135
  meta: {
136
136
  claims,
137
- ...(draft.lifecycleStatus ? { status: draft.lifecycleStatus } : {}),
137
+ ...(state.lifecycleStatus ? { status: state.lifecycleStatus } : {}),
138
138
  },
139
139
  };
140
140
  }
@@ -192,7 +192,7 @@ export function createInteroperableResourceOperationEditor(initial) {
192
192
  });
193
193
  return editor;
194
194
  },
195
- getDraft() {
195
+ getState() {
196
196
  return normalizeDraft(draft);
197
197
  },
198
198
  getBusinessIdentifier() {
@@ -0,0 +1,40 @@
1
+ import { PublicJwk } from '../interfaces/Cryptography.types';
2
+ /**
3
+ * Minimal RSA public JWK shape needed for RFC 7638 thumbprint derivation.
4
+ */
5
+ export type RsaPublicJwk = {
6
+ kty: 'RSA';
7
+ e: string;
8
+ n: string;
9
+ kid?: string;
10
+ alg?: string;
11
+ use?: string;
12
+ };
13
+ /**
14
+ * Public JWK shapes supported by the RFC 7638 thumbprint helpers.
15
+ *
16
+ * Notes:
17
+ * - classic EC keys are identified by `kty: 'EC'` and use `crv`, `x`, `y`
18
+ * - this includes `secp256k1`, represented as `crv: 'secp256k1'`
19
+ * - ML-DSA keys are represented in this codebase as `kty: 'AKP'` and use
20
+ * `alg` plus `pub`; they do not use `crv`
21
+ */
22
+ export type ThumbprintableJwk = PublicJwk | RsaPublicJwk;
23
+ /**
24
+ * Computes the RFC 7638 JWK thumbprint as a bare base64url string.
25
+ *
26
+ * Canonical fields per supported key family:
27
+ * - `EC`: `kty`, `crv`, `x`, `y`
28
+ * - `RSA`: `kty`, `e`, `n`
29
+ * - `OKP`: `kty`, `crv`, `x`
30
+ * - `AKP` / ML-DSA: `kty`, `alg`, `pub`
31
+ *
32
+ * For classical EC keys, the curve is taken from `crv`, so keys such as
33
+ * `secp256k1` are handled naturally through `crv: 'secp256k1'`.
34
+ */
35
+ export declare function computeRfc7638JwkThumbprint(jwk: ThumbprintableJwk): string;
36
+ /**
37
+ * Returns the RFC 9278 thumbprint URI form:
38
+ * `urn:ietf:params:oauth:jwk-thumbprint:sha-256:<base64url>`
39
+ */
40
+ export declare function toJwkThumbprintSha256Urn(jwk: ThumbprintableJwk): string;