gdc-common-utils-ts 1.14.15 → 1.16.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
@@ -35,6 +35,7 @@ entry types, FHIR-like resources, and `resource.meta.claims` fit together,
35
35
  read first:
36
36
 
37
37
  - [`docs/101-COMMUNICATION_LAYERING.md`](docs/101-COMMUNICATION_LAYERING.md)
38
+ - [`docs/101-BUNDLE_EDITOR_READER.md`](docs/101-BUNDLE_EDITOR_READER.md)
38
39
 
39
40
  ## Install
40
41
 
@@ -0,0 +1,134 @@
1
+ import { buildEmployeeBatchEntry, buildEmployeePurgeBundle, buildEmployeeSearchBundle, EmployeeBundleOperations, EmployeeClaims, EmployeeResourceTypes } from './employee';
2
+ export type BundleOperation = (typeof EmployeeBundleOperations)[keyof typeof EmployeeBundleOperations];
3
+ export type AllowedResourceType = (typeof EmployeeResourceTypes)[keyof typeof EmployeeResourceTypes];
4
+ export type BuiltBundleEntry = ReturnType<typeof buildEmployeeBatchEntry> & {
5
+ fullUrl?: string;
6
+ };
7
+ /**
8
+ * Generic bundle editor for FHIR-like bundle payloads assembled in memory.
9
+ *
10
+ * This class owns bundle-level concerns:
11
+ * - which business operation the bundle represents
12
+ * - which resource type the bundle allows
13
+ * - which entries belong to the bundle
14
+ * - when the final bundle is materialized through `build()`
15
+ *
16
+ * Resource-specific semantics belong to resource entry editors such as
17
+ * `EmployeeEntryEditor`.
18
+ */
19
+ export declare class BundleEditor {
20
+ private bundleOperation;
21
+ private allowedResourceType;
22
+ private readonly entries;
23
+ /** Declares which business operation this bundle is staging. */
24
+ setBundleOperation(operation: BundleOperation): this;
25
+ /** Returns the current business operation assigned to the bundle. */
26
+ getBundleOperation(): BundleOperation | null;
27
+ /**
28
+ * Restricts the bundle to one resource type.
29
+ *
30
+ * For employee batch bundles this should be fixed to
31
+ * `EmployeeResourceTypes.employee` so the editor cannot mix unrelated
32
+ * resource kinds.
33
+ */
34
+ setAllowedResourceType(resourceType: AllowedResourceType): this;
35
+ /** Returns the bundle resource type restriction when already declared. */
36
+ getAllowedResourceType(): AllowedResourceType | null;
37
+ /**
38
+ * Opens one new entry and returns a generic entry editor for that slot.
39
+ *
40
+ * The entry editor can later expose resource-specific semantics through
41
+ * methods such as `asEmployee()`.
42
+ */
43
+ newEntry(resourceId?: string): BundleEntryEditor;
44
+ /** Reopens one existing entry by `resource.id` or `fullUrl`. */
45
+ openEntry(resourceIdOrFullUrl: string): BundleEntryEditor;
46
+ /** Returns cloned staged entries for inspection or debugging. */
47
+ getEntries(): readonly BuiltBundleEntry[];
48
+ /**
49
+ * Materializes the final bundle payload from the editor state.
50
+ *
51
+ * `build()` does not send, sign, or wrap the payload. It only returns the
52
+ * final bundle object for the declared operation and staged entries.
53
+ */
54
+ build(): ReturnType<typeof buildEmployeePurgeBundle> | ReturnType<typeof buildEmployeeSearchBundle>;
55
+ /** @internal */
56
+ getMutableEntry(entryIndex: number): BuiltBundleEntry;
57
+ private createEntryDraft;
58
+ private getSingleSearchClaims;
59
+ private requireBundleOperation;
60
+ private requireAllowedResourceType;
61
+ }
62
+ /**
63
+ * Generic editor for one staged bundle entry.
64
+ *
65
+ * This class only knows generic entry concerns such as:
66
+ * - resource id
67
+ * - fullUrl
68
+ * - meta claims
69
+ * - conversion to one resource-specific entry editor
70
+ */
71
+ export declare class BundleEntryEditor {
72
+ protected readonly bundleEditor: BundleEditor;
73
+ protected readonly entryIndex: number;
74
+ constructor(bundleEditor: BundleEditor, entryIndex: number);
75
+ /** Opens the current entry as one employee-specific resource editor. */
76
+ asEmployee(): EmployeeEntryEditor;
77
+ /** Reads one claim from this entry. */
78
+ getClaim(key: string): unknown;
79
+ /** Checks whether this entry contains one claim key. */
80
+ hasClaim(key: string): boolean;
81
+ /** Writes one claim on this entry. */
82
+ setClaim(key: string, value: unknown): this;
83
+ /** Appends one claim value on this entry. */
84
+ addClaim(key: string, value: unknown): this;
85
+ /** Removes one claim from this entry. */
86
+ removeClaim(key: string): this;
87
+ /** Writes the staged entry `resource.id`. */
88
+ setResourceId(resourceId?: string | null): this;
89
+ /** Reads the staged entry `resource.id` when present. */
90
+ getResourceId(): string | undefined;
91
+ /** Writes the staged entry `fullUrl`. */
92
+ setFullUrl(fullUrl?: string | null): this;
93
+ /** Reads the staged entry `fullUrl` when present. */
94
+ getFullUrl(): string | undefined;
95
+ /** Returns control to the parent bundle editor. */
96
+ doneEntry(): BundleEditor;
97
+ protected getMutableEntry(): BuiltBundleEntry;
98
+ protected getClaims(): EmployeeClaims;
99
+ }
100
+ /**
101
+ * Employee-specific editor for one staged bundle entry.
102
+ *
103
+ * Use this class after `bundle.newEntry().asEmployee()` or
104
+ * `bundle.openEntry(...).asEmployee()`.
105
+ */
106
+ export declare class EmployeeEntryEditor extends BundleEntryEditor {
107
+ /**
108
+ * Writes the canonical employee identifier.
109
+ *
110
+ * The identifier is synchronized across:
111
+ * - `entry.fullUrl`
112
+ * - `resource.id`
113
+ * - `org.schema.Person.identifier`
114
+ */
115
+ setIdentifier(identifier?: string | null): this;
116
+ /** Reads the canonical employee identifier from claims, resource id, or fullUrl. */
117
+ getIdentifier(): string | undefined;
118
+ /** Ensures the employee entry carries one canonical `urn:uuid:*` identifier. */
119
+ ensureIdentifier(): string;
120
+ /** Writes the canonical employee email claim on this entry. */
121
+ setEmail(email: string): this;
122
+ /** Reads the canonical employee email claim from this entry. */
123
+ getEmail(): string | undefined;
124
+ /** Writes the canonical employee occupational role claim on this entry. */
125
+ setRole(role: string): this;
126
+ /** Reads the canonical employee occupational role claim from this entry. */
127
+ getRole(): string | undefined;
128
+ /** Writes the canonical employee `worksFor` claim on this entry. */
129
+ setWorksFor(worksFor: string): this;
130
+ /** Writes the canonical employee `memberOf` claim on this entry. */
131
+ setMemberOf(memberOf: string): this;
132
+ /** Writes the canonical employee organization tax id claim on this entry. */
133
+ setMemberOfOrgTaxId(taxId: string): this;
134
+ }
@@ -0,0 +1,421 @@
1
+ import { ClaimsPersonSchemaorg } from '../constants/schemaorg.js';
2
+ import { buildEmployeeBatchEntry, buildEmployeePurgeBundle, buildEmployeeSearchBundle, EmployeeBatchEntryTypes, EmployeeBundleMethods, EmployeeBundleOperations, EmployeeResourceTypes, } from './employee.js';
3
+ function cloneEntry(value) {
4
+ return JSON.parse(JSON.stringify(value));
5
+ }
6
+ function cloneClaimValue(value) {
7
+ if (Array.isArray(value)) {
8
+ return [...value];
9
+ }
10
+ return value;
11
+ }
12
+ function normalizeOptionalIdentifier(value) {
13
+ if (value === undefined || value === null) {
14
+ return undefined;
15
+ }
16
+ const normalized = String(value).trim();
17
+ return normalized ? normalized : undefined;
18
+ }
19
+ function createCanonicalIdentifierUrn() {
20
+ const cryptoLike = globalThis;
21
+ const uuid = typeof cryptoLike.crypto?.randomUUID === 'function'
22
+ ? cryptoLike.crypto.randomUUID()
23
+ : `resource-${Date.now()}-${Math.random().toString(16).slice(2)}`;
24
+ return `urn:uuid:${uuid}`;
25
+ }
26
+ function resolveRequestMethodForOperation(operation) {
27
+ switch (operation) {
28
+ case EmployeeBundleOperations.disable:
29
+ return EmployeeBundleMethods.disable;
30
+ case EmployeeBundleOperations.search:
31
+ case EmployeeBundleOperations.create:
32
+ case EmployeeBundleOperations.purge:
33
+ default:
34
+ return EmployeeBundleMethods.create;
35
+ }
36
+ }
37
+ function resolveEntryTypeForOperation(operation) {
38
+ switch (operation) {
39
+ case EmployeeBundleOperations.disable:
40
+ return EmployeeBatchEntryTypes.disable;
41
+ case EmployeeBundleOperations.purge:
42
+ return EmployeeBatchEntryTypes.purge;
43
+ case EmployeeBundleOperations.search:
44
+ return EmployeeBatchEntryTypes.search;
45
+ case EmployeeBundleOperations.create:
46
+ default:
47
+ return EmployeeBatchEntryTypes.create;
48
+ }
49
+ }
50
+ /**
51
+ * Generic bundle editor for FHIR-like bundle payloads assembled in memory.
52
+ *
53
+ * This class owns bundle-level concerns:
54
+ * - which business operation the bundle represents
55
+ * - which resource type the bundle allows
56
+ * - which entries belong to the bundle
57
+ * - when the final bundle is materialized through `build()`
58
+ *
59
+ * Resource-specific semantics belong to resource entry editors such as
60
+ * `EmployeeEntryEditor`.
61
+ */
62
+ export class BundleEditor {
63
+ bundleOperation = null;
64
+ allowedResourceType = null;
65
+ entries = [];
66
+ /** Declares which business operation this bundle is staging. */
67
+ setBundleOperation(operation) {
68
+ this.bundleOperation = operation;
69
+ return this;
70
+ }
71
+ /** Returns the current business operation assigned to the bundle. */
72
+ getBundleOperation() {
73
+ return this.bundleOperation;
74
+ }
75
+ /**
76
+ * Restricts the bundle to one resource type.
77
+ *
78
+ * For employee batch bundles this should be fixed to
79
+ * `EmployeeResourceTypes.employee` so the editor cannot mix unrelated
80
+ * resource kinds.
81
+ */
82
+ setAllowedResourceType(resourceType) {
83
+ this.allowedResourceType = resourceType;
84
+ return this;
85
+ }
86
+ /** Returns the bundle resource type restriction when already declared. */
87
+ getAllowedResourceType() {
88
+ return this.allowedResourceType;
89
+ }
90
+ /**
91
+ * Opens one new entry and returns a generic entry editor for that slot.
92
+ *
93
+ * The entry editor can later expose resource-specific semantics through
94
+ * methods such as `asEmployee()`.
95
+ */
96
+ newEntry(resourceId) {
97
+ const operation = this.requireBundleOperation();
98
+ const resourceType = this.requireAllowedResourceType();
99
+ const entry = this.createEntryDraft(operation, resourceType, resourceId);
100
+ this.entries.push(entry);
101
+ return new BundleEntryEditor(this, this.entries.length - 1);
102
+ }
103
+ /** Reopens one existing entry by `resource.id` or `fullUrl`. */
104
+ openEntry(resourceIdOrFullUrl) {
105
+ const normalizedIdentifier = normalizeOptionalIdentifier(resourceIdOrFullUrl);
106
+ if (!normalizedIdentifier) {
107
+ throw new Error('openEntry requires a non-empty resource identifier or fullUrl.');
108
+ }
109
+ const entryIndex = this.entries.findIndex((entry) => {
110
+ return normalizeOptionalIdentifier(entry.resource?.id) === normalizedIdentifier
111
+ || normalizeOptionalIdentifier(entry.fullUrl) === normalizedIdentifier;
112
+ });
113
+ if (entryIndex < 0) {
114
+ throw new Error(`openEntry could not find resource identifier or fullUrl: ${normalizedIdentifier}`);
115
+ }
116
+ return new BundleEntryEditor(this, entryIndex);
117
+ }
118
+ /** Returns cloned staged entries for inspection or debugging. */
119
+ getEntries() {
120
+ return this.entries.map((entry) => cloneEntry(entry));
121
+ }
122
+ /**
123
+ * Materializes the final bundle payload from the editor state.
124
+ *
125
+ * `build()` does not send, sign, or wrap the payload. It only returns the
126
+ * final bundle object for the declared operation and staged entries.
127
+ */
128
+ build() {
129
+ const operation = this.requireBundleOperation();
130
+ const resourceType = this.requireAllowedResourceType();
131
+ if (resourceType !== EmployeeResourceTypes.employee) {
132
+ throw new Error(`BundleEditor does not yet support build() for resource type: ${resourceType}`);
133
+ }
134
+ if (operation === EmployeeBundleOperations.search) {
135
+ return buildEmployeeSearchBundle({
136
+ claims: this.getSingleSearchClaims(),
137
+ resourceType,
138
+ });
139
+ }
140
+ if (operation === EmployeeBundleOperations.purge) {
141
+ return {
142
+ resourceType: EmployeeResourceTypes.bundle,
143
+ type: EmployeeResourceTypes.batch,
144
+ entry: this.entries.map((entry) => {
145
+ const identifier = normalizeOptionalIdentifier(entry.resource?.meta?.claims?.[ClaimsPersonSchemaorg.identifier]
146
+ || entry.resource?.id
147
+ || entry.fullUrl);
148
+ if (!identifier) {
149
+ throw new Error('Every purge entry requires one canonical employee identifier.');
150
+ }
151
+ return buildEmployeePurgeBundle({
152
+ identifier,
153
+ resourceType,
154
+ }).entry[0];
155
+ }),
156
+ };
157
+ }
158
+ return {
159
+ resourceType: EmployeeResourceTypes.bundle,
160
+ type: EmployeeResourceTypes.batch,
161
+ entry: this.entries.map((entry) => cloneEntry(entry)),
162
+ };
163
+ }
164
+ /** @internal */
165
+ getMutableEntry(entryIndex) {
166
+ if (!Number.isInteger(entryIndex) || entryIndex < 0 || entryIndex >= this.entries.length) {
167
+ throw new Error(`BundleEditor could not open entry index: ${entryIndex}`);
168
+ }
169
+ return this.entries[entryIndex];
170
+ }
171
+ createEntryDraft(operation, resourceType, resourceId) {
172
+ if (resourceType !== EmployeeResourceTypes.employee) {
173
+ throw new Error(`BundleEditor does not yet support newEntry() for resource type: ${resourceType}`);
174
+ }
175
+ const normalizedIdentifier = operation === EmployeeBundleOperations.search
176
+ ? normalizeOptionalIdentifier(resourceId)
177
+ : (normalizeOptionalIdentifier(resourceId) || createCanonicalIdentifierUrn());
178
+ const claims = {
179
+ '@context': 'org.schema',
180
+ ...(normalizedIdentifier ? { [ClaimsPersonSchemaorg.identifier]: normalizedIdentifier } : {}),
181
+ };
182
+ const entry = buildEmployeeBatchEntry({
183
+ type: resolveEntryTypeForOperation(operation),
184
+ method: resolveRequestMethodForOperation(operation),
185
+ resourceId: normalizedIdentifier,
186
+ resourceType,
187
+ claims,
188
+ });
189
+ if (normalizedIdentifier) {
190
+ entry.fullUrl = normalizedIdentifier;
191
+ }
192
+ return entry;
193
+ }
194
+ getSingleSearchClaims() {
195
+ if (this.entries.length === 0) {
196
+ return {};
197
+ }
198
+ if (this.entries.length > 1) {
199
+ throw new Error('Search bundles currently support one entry per bundle.');
200
+ }
201
+ const claims = this.entries[0].resource?.meta?.claims || {};
202
+ const searchClaims = {};
203
+ for (const [key, value] of Object.entries(claims)) {
204
+ if (value === undefined
205
+ || value === null
206
+ || typeof value === 'string'
207
+ || typeof value === 'number'
208
+ || typeof value === 'boolean') {
209
+ searchClaims[key] = value;
210
+ }
211
+ }
212
+ return searchClaims;
213
+ }
214
+ requireBundleOperation() {
215
+ if (!this.bundleOperation) {
216
+ throw new Error('BundleEditor requires setBundleOperation(...) before newEntry() or build().');
217
+ }
218
+ return this.bundleOperation;
219
+ }
220
+ requireAllowedResourceType() {
221
+ if (!this.allowedResourceType) {
222
+ throw new Error('BundleEditor requires setAllowedResourceType(...) before newEntry() or build().');
223
+ }
224
+ return this.allowedResourceType;
225
+ }
226
+ }
227
+ /**
228
+ * Generic editor for one staged bundle entry.
229
+ *
230
+ * This class only knows generic entry concerns such as:
231
+ * - resource id
232
+ * - fullUrl
233
+ * - meta claims
234
+ * - conversion to one resource-specific entry editor
235
+ */
236
+ export class BundleEntryEditor {
237
+ bundleEditor;
238
+ entryIndex;
239
+ constructor(bundleEditor, entryIndex) {
240
+ this.bundleEditor = bundleEditor;
241
+ this.entryIndex = entryIndex;
242
+ }
243
+ /** Opens the current entry as one employee-specific resource editor. */
244
+ asEmployee() {
245
+ const entry = this.getMutableEntry();
246
+ if (entry.resource?.resourceType !== EmployeeResourceTypes.employee) {
247
+ throw new Error(`BundleEntryEditor cannot open this entry as Employee: ${String(entry.resource?.resourceType || '')}`);
248
+ }
249
+ return new EmployeeEntryEditor(this.bundleEditor, this.entryIndex);
250
+ }
251
+ /** Reads one claim from this entry. */
252
+ getClaim(key) {
253
+ return cloneClaimValue(this.getClaims()[String(key).trim()]);
254
+ }
255
+ /** Checks whether this entry contains one claim key. */
256
+ hasClaim(key) {
257
+ return Object.prototype.hasOwnProperty.call(this.getClaims(), String(key).trim());
258
+ }
259
+ /** Writes one claim on this entry. */
260
+ setClaim(key, value) {
261
+ const entry = this.getMutableEntry();
262
+ entry.resource = entry.resource || {
263
+ resourceType: this.bundleEditor.getAllowedResourceType() || EmployeeResourceTypes.employee,
264
+ meta: { claims: {} },
265
+ };
266
+ entry.resource.meta = entry.resource.meta || {};
267
+ entry.resource.meta.claims = {
268
+ ...(entry.resource.meta.claims || {}),
269
+ [String(key).trim()]: cloneClaimValue(value),
270
+ };
271
+ return this;
272
+ }
273
+ /** Appends one claim value on this entry. */
274
+ addClaim(key, value) {
275
+ const normalizedKey = String(key).trim();
276
+ const current = this.getClaim(normalizedKey);
277
+ if (current === undefined) {
278
+ return this.setClaim(normalizedKey, value);
279
+ }
280
+ if (Array.isArray(current)) {
281
+ return this.setClaim(normalizedKey, [...current, cloneClaimValue(value)]);
282
+ }
283
+ return this.setClaim(normalizedKey, [current, cloneClaimValue(value)]);
284
+ }
285
+ /** Removes one claim from this entry. */
286
+ removeClaim(key) {
287
+ const entry = this.getMutableEntry();
288
+ const claims = {
289
+ ...(entry.resource?.meta?.claims || {}),
290
+ };
291
+ delete claims[String(key).trim()];
292
+ entry.resource = entry.resource || {
293
+ resourceType: this.bundleEditor.getAllowedResourceType() || EmployeeResourceTypes.employee,
294
+ meta: { claims: {} },
295
+ };
296
+ entry.resource.meta = entry.resource.meta || {};
297
+ entry.resource.meta.claims = claims;
298
+ return this;
299
+ }
300
+ /** Writes the staged entry `resource.id`. */
301
+ setResourceId(resourceId) {
302
+ const entry = this.getMutableEntry();
303
+ const normalized = normalizeOptionalIdentifier(resourceId);
304
+ if (!normalized) {
305
+ delete entry.resource?.id;
306
+ return this;
307
+ }
308
+ entry.resource = entry.resource || {
309
+ resourceType: this.bundleEditor.getAllowedResourceType() || EmployeeResourceTypes.employee,
310
+ meta: { claims: {} },
311
+ };
312
+ entry.resource.id = normalized;
313
+ return this;
314
+ }
315
+ /** Reads the staged entry `resource.id` when present. */
316
+ getResourceId() {
317
+ return normalizeOptionalIdentifier(this.getMutableEntry().resource?.id);
318
+ }
319
+ /** Writes the staged entry `fullUrl`. */
320
+ setFullUrl(fullUrl) {
321
+ const entry = this.getMutableEntry();
322
+ const normalized = normalizeOptionalIdentifier(fullUrl);
323
+ if (!normalized) {
324
+ delete entry.fullUrl;
325
+ return this;
326
+ }
327
+ entry.fullUrl = normalized;
328
+ return this;
329
+ }
330
+ /** Reads the staged entry `fullUrl` when present. */
331
+ getFullUrl() {
332
+ return normalizeOptionalIdentifier(this.getMutableEntry().fullUrl);
333
+ }
334
+ /** Returns control to the parent bundle editor. */
335
+ doneEntry() {
336
+ return this.bundleEditor;
337
+ }
338
+ getMutableEntry() {
339
+ return this.bundleEditor.getMutableEntry(this.entryIndex);
340
+ }
341
+ getClaims() {
342
+ return {
343
+ ...(this.getMutableEntry().resource?.meta?.claims || {}),
344
+ };
345
+ }
346
+ }
347
+ /**
348
+ * Employee-specific editor for one staged bundle entry.
349
+ *
350
+ * Use this class after `bundle.newEntry().asEmployee()` or
351
+ * `bundle.openEntry(...).asEmployee()`.
352
+ */
353
+ export class EmployeeEntryEditor extends BundleEntryEditor {
354
+ /**
355
+ * Writes the canonical employee identifier.
356
+ *
357
+ * The identifier is synchronized across:
358
+ * - `entry.fullUrl`
359
+ * - `resource.id`
360
+ * - `org.schema.Person.identifier`
361
+ */
362
+ setIdentifier(identifier) {
363
+ const normalized = normalizeOptionalIdentifier(identifier);
364
+ if (!normalized) {
365
+ this.removeClaim(ClaimsPersonSchemaorg.identifier);
366
+ this.setResourceId(undefined);
367
+ this.setFullUrl(undefined);
368
+ return this;
369
+ }
370
+ this.setClaim(ClaimsPersonSchemaorg.identifier, normalized);
371
+ this.setResourceId(normalized);
372
+ this.setFullUrl(normalized);
373
+ return this;
374
+ }
375
+ /** Reads the canonical employee identifier from claims, resource id, or fullUrl. */
376
+ getIdentifier() {
377
+ return normalizeOptionalIdentifier(this.getClaim(ClaimsPersonSchemaorg.identifier)
378
+ || this.getResourceId()
379
+ || this.getFullUrl());
380
+ }
381
+ /** Ensures the employee entry carries one canonical `urn:uuid:*` identifier. */
382
+ ensureIdentifier() {
383
+ const existing = this.getIdentifier();
384
+ if (existing) {
385
+ return existing;
386
+ }
387
+ const generated = createCanonicalIdentifierUrn();
388
+ this.setIdentifier(generated);
389
+ return generated;
390
+ }
391
+ /** Writes the canonical employee email claim on this entry. */
392
+ setEmail(email) {
393
+ return this.setClaim(ClaimsPersonSchemaorg.email, String(email).trim());
394
+ }
395
+ /** Reads the canonical employee email claim from this entry. */
396
+ getEmail() {
397
+ const email = this.getClaim(ClaimsPersonSchemaorg.email);
398
+ return typeof email === 'string' && email.trim() ? email.trim() : undefined;
399
+ }
400
+ /** Writes the canonical employee occupational role claim on this entry. */
401
+ setRole(role) {
402
+ return this.setClaim(ClaimsPersonSchemaorg.hasOccupationalRoleValue, String(role).trim());
403
+ }
404
+ /** Reads the canonical employee occupational role claim from this entry. */
405
+ getRole() {
406
+ const role = this.getClaim(ClaimsPersonSchemaorg.hasOccupationalRoleValue);
407
+ return typeof role === 'string' && role.trim() ? role.trim() : undefined;
408
+ }
409
+ /** Writes the canonical employee `worksFor` claim on this entry. */
410
+ setWorksFor(worksFor) {
411
+ return this.setClaim(ClaimsPersonSchemaorg.worksFor, String(worksFor).trim());
412
+ }
413
+ /** Writes the canonical employee `memberOf` claim on this entry. */
414
+ setMemberOf(memberOf) {
415
+ return this.setClaim(ClaimsPersonSchemaorg.memberOf, String(memberOf).trim());
416
+ }
417
+ /** Writes the canonical employee organization tax id claim on this entry. */
418
+ setMemberOfOrgTaxId(taxId) {
419
+ return this.setClaim(ClaimsPersonSchemaorg.memberOfOrgTaxId, String(taxId).trim());
420
+ }
421
+ }
@@ -0,0 +1,34 @@
1
+ export type BundleReaderEntry = Record<string, unknown>;
2
+ /**
3
+ * Runtime-neutral reader for built or received FHIR-like bundles.
4
+ *
5
+ * The reader does not assume one business resource. It only exposes generic
6
+ * bundle navigation, per-entry response inspection, and aggregate counters.
7
+ */
8
+ export declare class BundleReader {
9
+ private readonly bundle;
10
+ private activeEntryIndex;
11
+ constructor(bundle: Record<string, unknown>);
12
+ /** Returns the current bundle resource type when present. */
13
+ getResourceType(): string | undefined;
14
+ /** Returns the current FHIR bundle type when present. */
15
+ getBundleType(): string | undefined;
16
+ /** Returns cloned bundle entries. */
17
+ getEntries(): readonly BundleReaderEntry[];
18
+ /** Opens one entry by index. */
19
+ openEntry(index: number): this;
20
+ /** Returns the active entry response status when present. */
21
+ getEntryResponseStatus(): string | undefined;
22
+ /** Returns all active entry issue severities. */
23
+ getIssueSeverities(): string[];
24
+ /** Returns all active entry issue diagnostics strings. */
25
+ getIssueDiagnostics(): string[];
26
+ /** Returns the number of bundle entries. */
27
+ getTotalOperations(): number;
28
+ /** Returns the number of entries with one 2xx response status. */
29
+ getTotalSuccessfulOperations(): number;
30
+ /** Returns the number of entries without one 2xx response status. */
31
+ getTotalErrorOperations(): number;
32
+ private getRequiredActiveEntry;
33
+ private getActiveEntryIssues;
34
+ }
@@ -0,0 +1,88 @@
1
+ function cloneEntry(value) {
2
+ return JSON.parse(JSON.stringify(value));
3
+ }
4
+ /**
5
+ * Runtime-neutral reader for built or received FHIR-like bundles.
6
+ *
7
+ * The reader does not assume one business resource. It only exposes generic
8
+ * bundle navigation, per-entry response inspection, and aggregate counters.
9
+ */
10
+ export class BundleReader {
11
+ bundle;
12
+ activeEntryIndex = null;
13
+ constructor(bundle) {
14
+ this.bundle = cloneEntry(bundle);
15
+ }
16
+ /** Returns the current bundle resource type when present. */
17
+ getResourceType() {
18
+ const resourceType = this.bundle.resourceType;
19
+ return typeof resourceType === 'string' && resourceType.trim() ? resourceType.trim() : undefined;
20
+ }
21
+ /** Returns the current FHIR bundle type when present. */
22
+ getBundleType() {
23
+ const bundleType = this.bundle.type;
24
+ return typeof bundleType === 'string' && bundleType.trim() ? bundleType.trim() : undefined;
25
+ }
26
+ /** Returns cloned bundle entries. */
27
+ getEntries() {
28
+ const entries = this.bundle.entry;
29
+ return Array.isArray(entries) ? entries.map((entry) => cloneEntry(entry)) : [];
30
+ }
31
+ /** Opens one entry by index. */
32
+ openEntry(index) {
33
+ const entries = this.getEntries();
34
+ if (!Number.isInteger(index) || index < 0 || index >= entries.length) {
35
+ throw new Error(`BundleReader could not open entry index: ${index}`);
36
+ }
37
+ this.activeEntryIndex = index;
38
+ return this;
39
+ }
40
+ /** Returns the active entry response status when present. */
41
+ getEntryResponseStatus() {
42
+ const entry = this.getRequiredActiveEntry();
43
+ const response = entry.response;
44
+ const status = response?.status;
45
+ return typeof status === 'string' && status.trim() ? status.trim() : undefined;
46
+ }
47
+ /** Returns all active entry issue severities. */
48
+ getIssueSeverities() {
49
+ return this.getActiveEntryIssues()
50
+ .map((issue) => issue.severity)
51
+ .filter((severity) => typeof severity === 'string' && severity.trim().length > 0);
52
+ }
53
+ /** Returns all active entry issue diagnostics strings. */
54
+ getIssueDiagnostics() {
55
+ return this.getActiveEntryIssues()
56
+ .map((issue) => issue.diagnostics)
57
+ .filter((diagnostics) => typeof diagnostics === 'string' && diagnostics.trim().length > 0);
58
+ }
59
+ /** Returns the number of bundle entries. */
60
+ getTotalOperations() {
61
+ return this.getEntries().length;
62
+ }
63
+ /** Returns the number of entries with one 2xx response status. */
64
+ getTotalSuccessfulOperations() {
65
+ return this.getEntries().filter((entry) => {
66
+ const response = entry.response;
67
+ return typeof response?.status === 'string' && /^2\d\d$/.test(response.status);
68
+ }).length;
69
+ }
70
+ /** Returns the number of entries without one 2xx response status. */
71
+ getTotalErrorOperations() {
72
+ return this.getTotalOperations() - this.getTotalSuccessfulOperations();
73
+ }
74
+ getRequiredActiveEntry() {
75
+ if (this.activeEntryIndex === null) {
76
+ throw new Error('BundleReader requires one active entry. Call openEntry(...) first.');
77
+ }
78
+ const entries = this.getEntries();
79
+ return entries[this.activeEntryIndex];
80
+ }
81
+ getActiveEntryIssues() {
82
+ const entry = this.getRequiredActiveEntry();
83
+ const response = entry.response;
84
+ const outcome = response?.outcome;
85
+ const issue = outcome?.issue;
86
+ return Array.isArray(issue) ? issue.filter((value) => !!value && typeof value === 'object') : [];
87
+ }
88
+ }
@@ -38,6 +38,8 @@ export type AddContainedDocumentToActiveEntryInput = Readonly<{
38
38
  * - `Communication.content-attachment-data` is always derived from the
39
39
  * in-memory bundle after each committed update.
40
40
  * - saving can release active entry memory via `saveAndReleaseActiveEntry()`.
41
+ * - consent onboarding should prefer semantic helpers first, but this session
42
+ * also exposes direct claim-level editing on the selected active entry.
41
43
  */
42
44
  export declare class CommunicationAttachedBundleSession {
43
45
  private communicationClaims;
@@ -53,6 +55,16 @@ export declare class CommunicationAttachedBundleSession {
53
55
  getActiveEntryIndex(): number | null;
54
56
  /** Returns a deep copy of the active entry when selected. */
55
57
  getActiveEntry(): BundleEntry | null;
58
+ /** Returns one claim from the currently selected active entry. */
59
+ getActiveEntryClaim(key: string): unknown;
60
+ /** Returns whether the currently selected active entry carries one claim key. */
61
+ hasActiveEntryClaim(key: string): boolean;
62
+ /** Sets one claim on the currently selected active entry and syncs the bundle attachment. */
63
+ setActiveEntryClaim(key: string, value: unknown): this;
64
+ /** Appends one claim value on the currently selected active entry and syncs the bundle attachment. */
65
+ addActiveEntryClaim(key: string, value: unknown): this;
66
+ /** Removes one claim from the currently selected active entry and syncs the bundle attachment. */
67
+ removeActiveEntryClaim(key: string): this;
56
68
  /** Selects an active entry by index or fullUrl. */
57
69
  selectActiveEntry(selection: ActiveEntrySelection): this;
58
70
  /** Clears active entry selection from memory. */
@@ -164,6 +176,8 @@ export declare class CommunicationAttachedBundleSession {
164
176
  * Resolves the entry URL (`fullUrl`) for a given entry/resource identifier.
165
177
  */
166
178
  getEntryUrl(entryId: string): string | undefined;
179
+ private getRequiredActiveEntry;
180
+ private getRequiredActiveEntryClaims;
167
181
  private decodeBundleFromClaims;
168
182
  private syncAttachmentFromBundle;
169
183
  private resolveCurrentSubject;
@@ -18,6 +18,8 @@ import { MedicationStatementClaim, } from '../models/interoperable-claims/medica
18
18
  * - `Communication.content-attachment-data` is always derived from the
19
19
  * in-memory bundle after each committed update.
20
20
  * - saving can release active entry memory via `saveAndReleaseActiveEntry()`.
21
+ * - consent onboarding should prefer semantic helpers first, but this session
22
+ * also exposes direct claim-level editing on the selected active entry.
21
23
  */
22
24
  export class CommunicationAttachedBundleSession {
23
25
  communicationClaims;
@@ -55,6 +57,70 @@ export class CommunicationAttachedBundleSession {
55
57
  }
56
58
  return cloneEntry(this.bundleInMemory.data[this.activeEntryIndex]);
57
59
  }
60
+ /** Returns one claim from the currently selected active entry. */
61
+ getActiveEntryClaim(key) {
62
+ const claims = this.getRequiredActiveEntryClaims();
63
+ return cloneUnknownValue(claims[key]);
64
+ }
65
+ /** Returns whether the currently selected active entry carries one claim key. */
66
+ hasActiveEntryClaim(key) {
67
+ const claims = this.getRequiredActiveEntryClaims();
68
+ return Object.prototype.hasOwnProperty.call(claims, key);
69
+ }
70
+ /** Sets one claim on the currently selected active entry and syncs the bundle attachment. */
71
+ setActiveEntryClaim(key, value) {
72
+ const current = cloneEntry(this.getRequiredActiveEntry());
73
+ const resource = ensureEntryResource(current, this.mode);
74
+ resource.meta = resource.meta || {};
75
+ resource.meta.claims = {
76
+ ...(resource.meta.claims || {}),
77
+ [String(key).trim()]: cloneUnknownValue(value),
78
+ };
79
+ current.resource = resource;
80
+ this.bundleInMemory.data[this.activeEntryIndex] = current;
81
+ this.syncAttachmentFromBundle();
82
+ return this;
83
+ }
84
+ /** Appends one claim value on the currently selected active entry and syncs the bundle attachment. */
85
+ addActiveEntryClaim(key, value) {
86
+ const current = cloneEntry(this.getRequiredActiveEntry());
87
+ const resource = ensureEntryResource(current, this.mode);
88
+ resource.meta = resource.meta || {};
89
+ const claims = {
90
+ ...(resource.meta.claims || {}),
91
+ };
92
+ const normalizedKey = String(key).trim();
93
+ const currentValue = claims[normalizedKey];
94
+ if (currentValue === undefined) {
95
+ claims[normalizedKey] = cloneUnknownValue(value);
96
+ }
97
+ else if (Array.isArray(currentValue)) {
98
+ claims[normalizedKey] = [...currentValue, cloneUnknownValue(value)];
99
+ }
100
+ else {
101
+ claims[normalizedKey] = [currentValue, cloneUnknownValue(value)];
102
+ }
103
+ resource.meta.claims = claims;
104
+ current.resource = resource;
105
+ this.bundleInMemory.data[this.activeEntryIndex] = current;
106
+ this.syncAttachmentFromBundle();
107
+ return this;
108
+ }
109
+ /** Removes one claim from the currently selected active entry and syncs the bundle attachment. */
110
+ removeActiveEntryClaim(key) {
111
+ const current = cloneEntry(this.getRequiredActiveEntry());
112
+ const resource = ensureEntryResource(current, this.mode);
113
+ resource.meta = resource.meta || {};
114
+ const claims = {
115
+ ...(resource.meta.claims || {}),
116
+ };
117
+ delete claims[String(key).trim()];
118
+ resource.meta.claims = claims;
119
+ current.resource = resource;
120
+ this.bundleInMemory.data[this.activeEntryIndex] = current;
121
+ this.syncAttachmentFromBundle();
122
+ return this;
123
+ }
58
124
  /** Selects an active entry by index or fullUrl. */
59
125
  selectActiveEntry(selection) {
60
126
  if (typeof selection.index === 'number') {
@@ -297,6 +363,20 @@ export class CommunicationAttachedBundleSession {
297
363
  const query = new BundleQuery(this.bundleInMemory);
298
364
  return query.getEntryUrl(entryId);
299
365
  }
366
+ getRequiredActiveEntry() {
367
+ if (this.activeEntryIndex === null) {
368
+ throw new Error('No active entry selected.');
369
+ }
370
+ return this.bundleInMemory.data[this.activeEntryIndex];
371
+ }
372
+ getRequiredActiveEntryClaims() {
373
+ const current = cloneEntry(this.getRequiredActiveEntry());
374
+ const resource = ensureEntryResource(current, this.mode);
375
+ resource.meta = resource.meta || {};
376
+ return {
377
+ ...(resource.meta.claims || {}),
378
+ };
379
+ }
300
380
  decodeBundleFromClaims(claims) {
301
381
  const encoded = asTrimmedString(claims[CommunicationClaim.ContentAttachmentData]);
302
382
  if (!encoded) {
@@ -495,6 +575,12 @@ function cloneBundle(bundle) {
495
575
  function cloneEntry(entry) {
496
576
  return JSON.parse(JSON.stringify(entry));
497
577
  }
578
+ function cloneUnknownValue(value) {
579
+ if (value === undefined) {
580
+ return value;
581
+ }
582
+ return JSON.parse(JSON.stringify(value));
583
+ }
498
584
  function asTrimmedString(value) {
499
585
  if (value === undefined || value === null) {
500
586
  return '';
@@ -0,0 +1,24 @@
1
+ import { BundleEditor } from './bundle-editor';
2
+ /**
3
+ * High-level employee adapter on top of the shared `BundleEditor`.
4
+ *
5
+ * Use this class when the active bundle entry is known to represent one
6
+ * employee resource and callers should work with employee semantics instead of
7
+ * raw claim keys.
8
+ */
9
+ export declare class EmployeeEditor extends BundleEditor {
10
+ /** Writes the canonical employee email claim on the active entry. */
11
+ setEmail(email: string): this;
12
+ /** Reads the canonical employee email claim from the active entry. */
13
+ getEmail(): string | undefined;
14
+ /** Writes the canonical employee occupational role claim on the active entry. */
15
+ setRole(role: string): this;
16
+ /** Reads the canonical employee occupational role claim from the active entry. */
17
+ getRole(): string | undefined;
18
+ /** Writes the canonical employee `worksFor` claim on the active entry. */
19
+ setWorksFor(worksFor: string): this;
20
+ /** Writes the canonical employee `memberOf` claim on the active entry. */
21
+ setMemberOf(memberOf: string): this;
22
+ /** Writes the canonical employee organization tax id claim on the active entry. */
23
+ setMemberOfOrgTaxId(taxId: string): this;
24
+ }
@@ -0,0 +1,41 @@
1
+ import { ClaimsPersonSchemaorg } from '../constants/schemaorg.js';
2
+ import { BundleEditor } from './bundle-editor.js';
3
+ /**
4
+ * High-level employee adapter on top of the shared `BundleEditor`.
5
+ *
6
+ * Use this class when the active bundle entry is known to represent one
7
+ * employee resource and callers should work with employee semantics instead of
8
+ * raw claim keys.
9
+ */
10
+ export class EmployeeEditor extends BundleEditor {
11
+ /** Writes the canonical employee email claim on the active entry. */
12
+ setEmail(email) {
13
+ return this.setClaim(ClaimsPersonSchemaorg.email, String(email).trim());
14
+ }
15
+ /** Reads the canonical employee email claim from the active entry. */
16
+ getEmail() {
17
+ const email = this.getClaim(ClaimsPersonSchemaorg.email);
18
+ return typeof email === 'string' && email.trim() ? email.trim() : undefined;
19
+ }
20
+ /** Writes the canonical employee occupational role claim on the active entry. */
21
+ setRole(role) {
22
+ return this.setClaim(ClaimsPersonSchemaorg.hasOccupationalRoleValue, String(role).trim());
23
+ }
24
+ /** Reads the canonical employee occupational role claim from the active entry. */
25
+ getRole() {
26
+ const role = this.getClaim(ClaimsPersonSchemaorg.hasOccupationalRoleValue);
27
+ return typeof role === 'string' && role.trim() ? role.trim() : undefined;
28
+ }
29
+ /** Writes the canonical employee `worksFor` claim on the active entry. */
30
+ setWorksFor(worksFor) {
31
+ return this.setClaim(ClaimsPersonSchemaorg.worksFor, String(worksFor).trim());
32
+ }
33
+ /** Writes the canonical employee `memberOf` claim on the active entry. */
34
+ setMemberOf(memberOf) {
35
+ return this.setClaim(ClaimsPersonSchemaorg.memberOf, String(memberOf).trim());
36
+ }
37
+ /** Writes the canonical employee organization tax id claim on the active entry. */
38
+ setMemberOfOrgTaxId(taxId) {
39
+ return this.setClaim(ClaimsPersonSchemaorg.memberOfOrgTaxId, String(taxId).trim());
40
+ }
41
+ }
@@ -21,12 +21,45 @@ export type EmployeeBatchEntryInput = Readonly<{
21
21
  export type EmployeeBatchBundleInput = Readonly<{
22
22
  entries: readonly EmployeeBatchEntryInput[];
23
23
  }>;
24
+ export type EmployeePurgeBundleInput = Readonly<{
25
+ identifier: string;
26
+ resourceId?: string;
27
+ resourceType?: 'Employee';
28
+ requestType?: (typeof EmployeeBatchEntryTypes)['purge'];
29
+ }>;
24
30
  export type EmployeeSearchBundleInput = Readonly<{
25
31
  claims?: Record<string, EmployeeSearchValue | undefined>;
26
32
  method?: 'GET' | 'POST';
27
33
  encoding?: SearchRequestEncoding;
28
34
  resourceType?: 'Employee';
29
35
  }>;
36
+ export declare const EmployeeBundleOperations: Readonly<{
37
+ readonly create: "create";
38
+ readonly search: "search";
39
+ readonly disable: "disable";
40
+ readonly purge: "purge";
41
+ }>;
42
+ export declare const EmployeeBundleMethods: Readonly<{
43
+ readonly create: "POST";
44
+ readonly search: "POST";
45
+ readonly disable: "DELETE";
46
+ readonly purge: "POST";
47
+ }>;
48
+ export declare const EmployeeBundleRoutes: Readonly<{
49
+ readonly search: "Employee/_search";
50
+ }>;
51
+ export declare const EmployeeResourceTypes: Readonly<{
52
+ readonly employee: "Employee";
53
+ readonly bundle: "Bundle";
54
+ readonly batch: "batch";
55
+ readonly parameters: "Parameters";
56
+ }>;
57
+ export declare const EmployeeBatchEntryTypes: Readonly<{
58
+ readonly create: "Employee-create-request-v1.0";
59
+ readonly disable: "Employee-disable-request-v1.0";
60
+ readonly search: "Employee-search-request-v1.0";
61
+ readonly purge: "Employee-purge-request-v1.0";
62
+ }>;
30
63
  /**
31
64
  * Builds canonical `org.schema.Person.*` employee claims from semantic input.
32
65
  */
@@ -60,6 +93,19 @@ export declare function buildEmployeeBatchBundle(input: EmployeeBatchBundleInput
60
93
  type: 'batch';
61
94
  entry: Array<ReturnType<typeof buildEmployeeBatchEntry>>;
62
95
  };
96
+ /**
97
+ * Builds the canonical employee purge batch bundle.
98
+ *
99
+ * Purge is a terminal lifecycle operation routed to the explicit
100
+ * `Employee/_purge` endpoint by runtime layers. The bundle selector should be
101
+ * one concrete employee identity, therefore this helper keeps the payload
102
+ * focused on the canonical employee identifier.
103
+ */
104
+ export declare function buildEmployeePurgeBundle(input: EmployeePurgeBundleInput): {
105
+ resourceType: 'Bundle';
106
+ type: 'batch';
107
+ entry: Array<ReturnType<typeof buildEmployeeBatchEntry>>;
108
+ };
63
109
  /**
64
110
  * Builds the legacy query-string employee search target kept for compatibility
65
111
  * with older `_search` wrappers.
@@ -1,5 +1,32 @@
1
1
  import { ClaimsPersonSchemaorg } from '../constants/schemaorg.js';
2
2
  import { buildFhirParametersResourceFromSearchParams, buildSearchQueryString, } from './fhir-search.js';
3
+ export const EmployeeBundleOperations = Object.freeze({
4
+ create: 'create',
5
+ search: 'search',
6
+ disable: 'disable',
7
+ purge: 'purge',
8
+ });
9
+ export const EmployeeBundleMethods = Object.freeze({
10
+ create: 'POST',
11
+ search: 'POST',
12
+ disable: 'DELETE',
13
+ purge: 'POST',
14
+ });
15
+ export const EmployeeBundleRoutes = Object.freeze({
16
+ search: 'Employee/_search',
17
+ });
18
+ export const EmployeeResourceTypes = Object.freeze({
19
+ employee: 'Employee',
20
+ bundle: 'Bundle',
21
+ batch: 'batch',
22
+ parameters: 'Parameters',
23
+ });
24
+ export const EmployeeBatchEntryTypes = Object.freeze({
25
+ create: 'Employee-create-request-v1.0',
26
+ disable: 'Employee-disable-request-v1.0',
27
+ search: 'Employee-search-request-v1.0',
28
+ purge: 'Employee-purge-request-v1.0',
29
+ });
3
30
  function cloneClaims(claims) {
4
31
  return { ...(claims || {}) };
5
32
  }
@@ -15,15 +42,15 @@ function normalizeEmployeeSearchClaims(claims) {
15
42
  function inferEmployeeEntryType(method) {
16
43
  switch (method) {
17
44
  case 'DELETE':
18
- return 'Employee-delete-request-v1.0';
45
+ return EmployeeBatchEntryTypes.disable;
19
46
  case 'PUT':
20
47
  case 'PATCH':
21
48
  return 'Employee-update-request-v1.0';
22
49
  case 'GET':
23
- return 'Employee-search-request-v1.0';
50
+ return EmployeeBatchEntryTypes.search;
24
51
  case 'POST':
25
52
  default:
26
- return 'Employee-create-request-v1.0';
53
+ return EmployeeBatchEntryTypes.create;
27
54
  }
28
55
  }
29
56
  /**
@@ -85,6 +112,28 @@ export function buildEmployeeBatchBundle(input) {
85
112
  entry: [...input.entries].map((entry) => buildEmployeeBatchEntry(entry)),
86
113
  };
87
114
  }
115
+ /**
116
+ * Builds the canonical employee purge batch bundle.
117
+ *
118
+ * Purge is a terminal lifecycle operation routed to the explicit
119
+ * `Employee/_purge` endpoint by runtime layers. The bundle selector should be
120
+ * one concrete employee identity, therefore this helper keeps the payload
121
+ * focused on the canonical employee identifier.
122
+ */
123
+ export function buildEmployeePurgeBundle(input) {
124
+ const identifier = input.identifier.trim();
125
+ return buildEmployeeBatchBundle({
126
+ entries: [
127
+ {
128
+ type: input.requestType || EmployeeBatchEntryTypes.purge,
129
+ method: EmployeeBundleMethods.purge,
130
+ resourceId: input.resourceId || identifier,
131
+ resourceType: input.resourceType,
132
+ claims: buildEmployeeClaims({ identifier }),
133
+ },
134
+ ],
135
+ });
136
+ }
88
137
  /**
89
138
  * Builds the legacy query-string employee search target kept for compatibility
90
139
  * with older `_search` wrappers.
@@ -103,7 +152,7 @@ export function buildEmployeeSearchQuery(input = {}) {
103
152
  export function buildEmployeeSearchBundle(input = {}) {
104
153
  const resourceType = input.resourceType || 'Employee';
105
154
  const claims = normalizeEmployeeSearchClaims(input.claims);
106
- const method = input.method || (input.encoding === 'get-query' ? 'GET' : 'POST');
155
+ const method = input.method || (input.encoding === 'get-query' ? 'GET' : EmployeeBundleMethods.search);
107
156
  if (method === 'GET') {
108
157
  return {
109
158
  resourceType: 'Bundle',
@@ -124,8 +173,8 @@ export function buildEmployeeSearchBundle(input = {}) {
124
173
  entry: [
125
174
  {
126
175
  request: {
127
- method: 'POST',
128
- url: `${resourceType}/_search`,
176
+ method: EmployeeBundleMethods.search,
177
+ url: EmployeeBundleRoutes.search,
129
178
  },
130
179
  resource: buildFhirParametersResourceFromSearchParams(claims),
131
180
  },
@@ -3,6 +3,8 @@ export * from './activation-policy';
3
3
  export * from './base-convert';
4
4
  export * from './baseN';
5
5
  export * from './bundle';
6
+ export * from './bundle-editor';
7
+ export * from './bundle-reader';
6
8
  export * from './bundle-query';
7
9
  export * from '../claims';
8
10
  export * from './content';
@@ -3,6 +3,8 @@ export * from './activation-policy.js';
3
3
  export * from './base-convert.js';
4
4
  export * from './baseN.js';
5
5
  export * from './bundle.js';
6
+ export * from './bundle-editor.js';
7
+ export * from './bundle-reader.js';
6
8
  export * from './bundle-query.js';
7
9
  export * from '../claims/index.js';
8
10
  export * from './content.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gdc-common-utils-ts",
3
- "version": "1.14.15",
3
+ "version": "1.16.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },