gdc-common-utils-ts 2.7.1 → 2.7.3
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/dist/examples/license.d.ts +1 -0
- package/dist/examples/license.js +1 -0
- package/dist/models/consent-rule.d.ts +18 -0
- package/dist/models/consent-rule.js +15 -0
- package/dist/utils/consent-entry-editor.d.ts +3 -1
- package/dist/utils/consent-entry-editor.js +2 -0
- package/dist/utils/consent.d.ts +1 -0
- package/dist/utils/consent.js +5 -1
- package/dist/utils/license.d.ts +3 -0
- package/dist/utils/license.js +3 -0
- package/package.json +1 -1
|
@@ -44,6 +44,7 @@ export declare const EXAMPLE_LICENSE_ISSUE_INPUT: Readonly<{
|
|
|
44
44
|
readonly role: "ISCO-08|2211";
|
|
45
45
|
readonly userClass: "employee";
|
|
46
46
|
readonly type: "mobile";
|
|
47
|
+
readonly subjectId: "urn:uuid:employee-controller-active-001";
|
|
47
48
|
}>;
|
|
48
49
|
export declare const EXAMPLE_LICENSE_PURCHASE_INPUT: Readonly<{
|
|
49
50
|
readonly quantity: 2;
|
package/dist/examples/license.js
CHANGED
|
@@ -41,6 +41,7 @@ export const EXAMPLE_LICENSE_ISSUE_INPUT = Object.freeze({
|
|
|
41
41
|
role: EXAMPLE_HEALTHCARE_ACTOR_ROLE_GENERALIST_MEDICAL_PRACTITIONER,
|
|
42
42
|
userClass: DeviceUserClasses.Employee,
|
|
43
43
|
type: DeviceAppTypes.Mobile,
|
|
44
|
+
subjectId: EXAMPLE_LICENSE_SUBJECT_ID_ACTIVE,
|
|
44
45
|
});
|
|
45
46
|
export const EXAMPLE_LICENSE_PURCHASE_INPUT = Object.freeze({
|
|
46
47
|
quantity: EXAMPLE_LICENSE_SEAT_UUIDS.length,
|
|
@@ -47,6 +47,22 @@ export declare const ConsentDecisions: Readonly<{
|
|
|
47
47
|
readonly Deny: "deny";
|
|
48
48
|
}>;
|
|
49
49
|
export type ConsentDecision = typeof ConsentDecisions[keyof typeof ConsentDecisions];
|
|
50
|
+
/**
|
|
51
|
+
* Canonical FHIR R5 Consent lifecycle states.
|
|
52
|
+
*
|
|
53
|
+
* `draft` is the only state used for a professional permission request. A
|
|
54
|
+
* draft is carried to the controller for review and must never participate in
|
|
55
|
+
* authorization evaluation. Only `active` consent rules can grant access.
|
|
56
|
+
*/
|
|
57
|
+
export declare const ConsentStatuses: Readonly<{
|
|
58
|
+
readonly Draft: "draft";
|
|
59
|
+
readonly Active: "active";
|
|
60
|
+
readonly Inactive: "inactive";
|
|
61
|
+
readonly NotDone: "not-done";
|
|
62
|
+
readonly EnteredInError: "entered-in-error";
|
|
63
|
+
readonly Unknown: "unknown";
|
|
64
|
+
}>;
|
|
65
|
+
export type ConsentStatus = typeof ConsentStatuses[keyof typeof ConsentStatuses];
|
|
50
66
|
/**
|
|
51
67
|
* Defines the structured, query-optimized format for storing a single, atomic consent rule
|
|
52
68
|
* in the vault (e.g., Firestore, CouchDB).
|
|
@@ -67,6 +83,8 @@ export interface ConsentRule {
|
|
|
67
83
|
* Value MUST be "org.hl7.fhir.api".
|
|
68
84
|
*/
|
|
69
85
|
'@context': 'org.hl7.fhir.api';
|
|
86
|
+
/** FHIR Consent lifecycle state; authorization evaluators accept only `active`. */
|
|
87
|
+
'Consent.status'?: ConsentStatus;
|
|
70
88
|
/**
|
|
71
89
|
* The decision of the rule: permit or deny.
|
|
72
90
|
* Derived from the `org.hl7.fhir.api.Consent.decision` claim.
|
|
@@ -48,3 +48,18 @@ export const ConsentDecisions = Object.freeze({
|
|
|
48
48
|
Permit: 'permit',
|
|
49
49
|
Deny: 'deny',
|
|
50
50
|
});
|
|
51
|
+
/**
|
|
52
|
+
* Canonical FHIR R5 Consent lifecycle states.
|
|
53
|
+
*
|
|
54
|
+
* `draft` is the only state used for a professional permission request. A
|
|
55
|
+
* draft is carried to the controller for review and must never participate in
|
|
56
|
+
* authorization evaluation. Only `active` consent rules can grant access.
|
|
57
|
+
*/
|
|
58
|
+
export const ConsentStatuses = Object.freeze({
|
|
59
|
+
Draft: 'draft',
|
|
60
|
+
Active: 'active',
|
|
61
|
+
Inactive: 'inactive',
|
|
62
|
+
NotDone: 'not-done',
|
|
63
|
+
EnteredInError: 'entered-in-error',
|
|
64
|
+
Unknown: 'unknown',
|
|
65
|
+
});
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* - Read `ARCHITECTURE.md` and `CONTRIBUTING.md` before changing this module.
|
|
4
4
|
* - This file owns only the typed editor for one staged Consent entry.
|
|
5
5
|
*/
|
|
6
|
-
import { type ConsentDecision } from '../models/consent-rule';
|
|
6
|
+
import { type ConsentDecision, type ConsentStatus } from '../models/consent-rule';
|
|
7
7
|
import { BundleEntryEditor } from './bundle-entry-editor';
|
|
8
8
|
/**
|
|
9
9
|
* Typed editor for one Consent permission staged inside a Bundle.
|
|
@@ -17,6 +17,8 @@ export declare class ConsentEntryEditor extends BundleEntryEditor {
|
|
|
17
17
|
ensureIdentifier(): string;
|
|
18
18
|
setSubject(value?: string | null): this;
|
|
19
19
|
getSubject(): string | undefined;
|
|
20
|
+
setStatus(value?: ConsentStatus | null): this;
|
|
21
|
+
getStatus(): string | undefined;
|
|
20
22
|
setDecision(value?: ConsentDecision | null): this;
|
|
21
23
|
getDecision(): string | undefined;
|
|
22
24
|
setActorIdentifierList(values: readonly string[]): this;
|
|
@@ -43,6 +43,8 @@ export class ConsentEntryEditor extends BundleEntryEditor {
|
|
|
43
43
|
}
|
|
44
44
|
setSubject(value) { return this.setOptionalText(ClaimConsent.subject, value); }
|
|
45
45
|
getSubject() { return this.getOptionalText(ClaimConsent.subject); }
|
|
46
|
+
setStatus(value) { return this.setOptionalText(ClaimConsent.status, value); }
|
|
47
|
+
getStatus() { return this.getOptionalText(ClaimConsent.status); }
|
|
46
48
|
setDecision(value) { return this.setOptionalText(ClaimConsent.decision, value); }
|
|
47
49
|
getDecision() { return this.getOptionalText(ClaimConsent.decision); }
|
|
48
50
|
setActorIdentifierList(values) { return this.setList(ClaimConsent.actorIdentifier, values); }
|
package/dist/utils/consent.d.ts
CHANGED
|
@@ -197,6 +197,7 @@ export declare function resolveConsentActor(actor: ConsentActorDescriptor): Reso
|
|
|
197
197
|
*
|
|
198
198
|
* A rule is active when:
|
|
199
199
|
* - it matches the requested subject when one is provided
|
|
200
|
+
* - `Consent.status` is absent for legacy compatibility or is exactly `active`
|
|
200
201
|
* - `Consent.period-start` is absent or already effective
|
|
201
202
|
* - `Consent.period-end` is absent or still in the future
|
|
202
203
|
*
|
package/dist/utils/consent.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Copyright 2026 Antifraud Services Inc. under the Apache License, Version 2.0.
|
|
2
|
-
import { ClaimConsent } from '../models/consent-rule.js';
|
|
2
|
+
import { ClaimConsent, ConsentStatuses } from '../models/consent-rule.js';
|
|
3
3
|
import { assignCidToClaimsId } from './fhir-cid.js';
|
|
4
4
|
/**
|
|
5
5
|
* Normalizes a phone string into a compact token form.
|
|
@@ -512,6 +512,7 @@ export function resolveConsentActor(actor) {
|
|
|
512
512
|
*
|
|
513
513
|
* A rule is active when:
|
|
514
514
|
* - it matches the requested subject when one is provided
|
|
515
|
+
* - `Consent.status` is absent for legacy compatibility or is exactly `active`
|
|
515
516
|
* - `Consent.period-start` is absent or already effective
|
|
516
517
|
* - `Consent.period-end` is absent or still in the future
|
|
517
518
|
*
|
|
@@ -523,6 +524,9 @@ export function isConsentRuleActive(rule, options = {}) {
|
|
|
523
524
|
if (options.subject && String(readConsentRuleClaim(rule, ClaimConsent.subject) || '').trim() !== String(options.subject || '').trim()) {
|
|
524
525
|
return false;
|
|
525
526
|
}
|
|
527
|
+
const status = String(readConsentRuleClaim(rule, ClaimConsent.status) || '').trim();
|
|
528
|
+
if (status && status !== ConsentStatuses.Active)
|
|
529
|
+
return false;
|
|
526
530
|
const now = options.now instanceof Date
|
|
527
531
|
? options.now.getTime()
|
|
528
532
|
: options.now
|
package/dist/utils/license.d.ts
CHANGED
|
@@ -100,6 +100,8 @@ export type LicenseIssueInput = Readonly<{
|
|
|
100
100
|
ownerOrganizationId?: string;
|
|
101
101
|
/** Card/individual DID granted by the invitation after acceptance. */
|
|
102
102
|
subjectDid?: string;
|
|
103
|
+
/** Technical resource id of the employee/member that consumes the seat. */
|
|
104
|
+
subjectId?: string;
|
|
103
105
|
/** Existing RelatedPerson/contact selected before the invitation. */
|
|
104
106
|
relatedPersonId?: string;
|
|
105
107
|
/** Stable invitation workflow identifier; not the license id or code. */
|
|
@@ -158,6 +160,7 @@ export declare function buildLicenseIssueEntry(input: LicenseIssueInput): {
|
|
|
158
160
|
claims: LicenseClaims;
|
|
159
161
|
ownerOrganizationId?: string;
|
|
160
162
|
subjectDid?: string;
|
|
163
|
+
subjectId?: string;
|
|
161
164
|
relatedPersonId?: string;
|
|
162
165
|
invitationId?: string;
|
|
163
166
|
};
|
package/dist/utils/license.js
CHANGED
|
@@ -205,6 +205,9 @@ export function buildLicenseIssueEntry(input) {
|
|
|
205
205
|
...(String(input.subjectDid || '').trim()
|
|
206
206
|
? { subjectDid: String(input.subjectDid).trim() }
|
|
207
207
|
: {}),
|
|
208
|
+
...(String(input.subjectId || '').trim()
|
|
209
|
+
? { subjectId: String(input.subjectId).trim() }
|
|
210
|
+
: {}),
|
|
208
211
|
...(String(input.relatedPersonId || '').trim()
|
|
209
212
|
? { relatedPersonId: String(input.relatedPersonId).trim() }
|
|
210
213
|
: {}),
|