gdc-common-utils-ts 2.9.16 → 2.9.18
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
|
@@ -494,7 +494,9 @@ The canonical API contract should live in JSDoc on exported code. The README act
|
|
|
494
494
|
- Jurisdiction is mandatory so `BN`, `EIN`, `TAX` and subnational identifier
|
|
495
495
|
schemes cannot collide; `roleType` remains protected while only the compact
|
|
496
496
|
`roleValue` is serialized.
|
|
497
|
-
- [`
|
|
497
|
+
- [`buildScopeSmartCompositionAccess(...)`](src/utils/smart-scope.ts), with
|
|
498
|
+
`buildSmartCompositionReadScope(...)` retained as a deprecated compatibility
|
|
499
|
+
alias
|
|
498
500
|
- Builds the current CORE GW pinned SMART root scope for `organization/Composition...` token requests.
|
|
499
501
|
- This is the preferred first scope to teach when the backend only needs subject-scoped read access.
|
|
500
502
|
- [`getOrganizationCredentialFromVpToken(...)`, `getLegalRepresentativeCredentialFromVpToken(...)`, `getServiceControllerCredentialFromVpToken(...)`](src/utils/vp-token.ts)
|
|
@@ -162,7 +162,10 @@ export declare function toClinicalResourceCardView(entry: ClinicalResourceEntryL
|
|
|
162
162
|
* Short claims take precedence over their expanded
|
|
163
163
|
* `org.hl7.fhir.api.<ResourceType>.<search-param>` equivalent. Versioned
|
|
164
164
|
* `org.hl7.fhir.<version>.*` namespaces are rejected because they are native
|
|
165
|
-
* FHIR representation namespaces, never claims vocabularies.
|
|
165
|
+
* FHIR representation namespaces, never claims vocabularies. Native
|
|
166
|
+
* structural projections such as `<ResourceType>.meta.versionId` or array
|
|
167
|
+
* paths are ignored: they remain part of the FHIR resource, but are not API
|
|
168
|
+
* SearchParameters and must never become editable clinical fields.
|
|
166
169
|
*/
|
|
167
170
|
export declare function toClinicalResourceClaimFieldViews(claims: ClinicalViewClaims): ClinicalResourceClaimFieldView[];
|
|
168
171
|
/**
|
|
@@ -113,7 +113,10 @@ export function toClinicalResourceCardView(entry, options = {}) {
|
|
|
113
113
|
* Short claims take precedence over their expanded
|
|
114
114
|
* `org.hl7.fhir.api.<ResourceType>.<search-param>` equivalent. Versioned
|
|
115
115
|
* `org.hl7.fhir.<version>.*` namespaces are rejected because they are native
|
|
116
|
-
* FHIR representation namespaces, never claims vocabularies.
|
|
116
|
+
* FHIR representation namespaces, never claims vocabularies. Native
|
|
117
|
+
* structural projections such as `<ResourceType>.meta.versionId` or array
|
|
118
|
+
* paths are ignored: they remain part of the FHIR resource, but are not API
|
|
119
|
+
* SearchParameters and must never become editable clinical fields.
|
|
117
120
|
*/
|
|
118
121
|
export function toClinicalResourceClaimFieldViews(claims) {
|
|
119
122
|
const fields = new Map();
|
|
@@ -126,7 +129,9 @@ export function toClinicalResourceClaimFieldViews(claims) {
|
|
|
126
129
|
}
|
|
127
130
|
if (!rawClaim.startsWith('org.hl7.fhir.api.') && !/^[A-Z][A-Za-z0-9]+\./.test(rawClaim))
|
|
128
131
|
continue;
|
|
129
|
-
const claim =
|
|
132
|
+
const claim = normalizeViewClaim(rawClaim);
|
|
133
|
+
if (!claim)
|
|
134
|
+
continue;
|
|
130
135
|
const separator = claim.indexOf('.');
|
|
131
136
|
if (separator <= 0 || separator === claim.length - 1)
|
|
132
137
|
continue;
|
|
@@ -145,17 +150,28 @@ export function toClinicalResourceClaimFieldViews(claims) {
|
|
|
145
150
|
continue;
|
|
146
151
|
if (!/^[A-Z][A-Za-z0-9]+\./.test(claim))
|
|
147
152
|
continue;
|
|
148
|
-
const
|
|
149
|
-
if (
|
|
153
|
+
const normalizedClaim = normalizeViewClaim(claim);
|
|
154
|
+
if (!normalizedClaim)
|
|
155
|
+
continue;
|
|
156
|
+
const separator = normalizedClaim.indexOf('.');
|
|
157
|
+
if (separator <= 0 || separator === normalizedClaim.length - 1)
|
|
150
158
|
continue;
|
|
151
|
-
fields.set(
|
|
152
|
-
claim,
|
|
153
|
-
parameter:
|
|
159
|
+
fields.set(normalizedClaim, {
|
|
160
|
+
claim: normalizedClaim,
|
|
161
|
+
parameter: normalizedClaim.slice(separator + 1),
|
|
154
162
|
value,
|
|
155
163
|
});
|
|
156
164
|
}
|
|
157
165
|
return [...fields.values()].sort((left, right) => left.claim.localeCompare(right.claim));
|
|
158
166
|
}
|
|
167
|
+
function normalizeViewClaim(rawClaim) {
|
|
168
|
+
try {
|
|
169
|
+
return normalizeFhirApiClaimKey(rawClaim);
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
return undefined;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
159
175
|
/**
|
|
160
176
|
* Maps all entries from a Bundle into minimal card views.
|
|
161
177
|
*/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ConsentActorDescriptor, EffectiveAccessEvaluation } from '../models/consent-access.js';
|
|
2
2
|
import type { ConsentRule } from '../models/consent-rule.js';
|
|
3
|
-
export type
|
|
3
|
+
export type ScopeSmartCompositionAccessOptions = {
|
|
4
4
|
/**
|
|
5
5
|
* Subject DID pinned by the current CORE GW root scope contract.
|
|
6
6
|
*/
|
|
@@ -12,12 +12,14 @@ export type SmartCompositionReadScopeOptions = {
|
|
|
12
12
|
*/
|
|
13
13
|
sections?: string | string[];
|
|
14
14
|
/**
|
|
15
|
-
*
|
|
15
|
+
* Access suffix used in the current GW SMART root scope contract.
|
|
16
16
|
*
|
|
17
17
|
* Defaults to `rs`.
|
|
18
18
|
*/
|
|
19
19
|
accessVerb?: 'r' | 'rs' | 'cruds';
|
|
20
20
|
};
|
|
21
|
+
/** @deprecated Use {@link ScopeSmartCompositionAccessOptions}. */
|
|
22
|
+
export type SmartCompositionReadScopeOptions = ScopeSmartCompositionAccessOptions;
|
|
21
23
|
/**
|
|
22
24
|
* Builds the gateway-pinned SMART root scope required by the current CORE GW
|
|
23
25
|
* token contract:
|
|
@@ -27,6 +29,11 @@ export type SmartCompositionReadScopeOptions = {
|
|
|
27
29
|
* This is intentionally a gateway-contract helper, not a generic SMART/FHIR
|
|
28
30
|
* scope builder.
|
|
29
31
|
*/
|
|
32
|
+
export declare function buildScopeSmartCompositionAccess(options: ScopeSmartCompositionAccessOptions): string;
|
|
33
|
+
/**
|
|
34
|
+
* @deprecated Use {@link buildScopeSmartCompositionAccess}. The historical
|
|
35
|
+
* name incorrectly described a helper that also supports `cruds` access.
|
|
36
|
+
*/
|
|
30
37
|
export declare function buildSmartCompositionReadScope(options: SmartCompositionReadScopeOptions): string;
|
|
31
38
|
export type DeriveGrantedSmartScopesInput = Readonly<{
|
|
32
39
|
/** Requested SMART root scopes. Every scope must pin the same subject. */
|
|
@@ -9,10 +9,10 @@ import { evaluateConsentCoverage } from './consent.js';
|
|
|
9
9
|
* This is intentionally a gateway-contract helper, not a generic SMART/FHIR
|
|
10
10
|
* scope builder.
|
|
11
11
|
*/
|
|
12
|
-
export function
|
|
12
|
+
export function buildScopeSmartCompositionAccess(options) {
|
|
13
13
|
const subjectDid = String(options.subjectDid || '').trim();
|
|
14
14
|
if (!subjectDid) {
|
|
15
|
-
throw new Error('
|
|
15
|
+
throw new Error('buildScopeSmartCompositionAccess requires subjectDid.');
|
|
16
16
|
}
|
|
17
17
|
const sections = Array.isArray(options.sections)
|
|
18
18
|
? options.sections
|
|
@@ -28,6 +28,13 @@ export function buildSmartCompositionReadScope(options) {
|
|
|
28
28
|
}
|
|
29
29
|
return `organization/Composition.${options.accessVerb || 'rs'}?${query.toString()}`;
|
|
30
30
|
}
|
|
31
|
+
/**
|
|
32
|
+
* @deprecated Use {@link buildScopeSmartCompositionAccess}. The historical
|
|
33
|
+
* name incorrectly described a helper that also supports `cruds` access.
|
|
34
|
+
*/
|
|
35
|
+
export function buildSmartCompositionReadScope(options) {
|
|
36
|
+
return buildScopeSmartCompositionAccess(options);
|
|
37
|
+
}
|
|
31
38
|
/**
|
|
32
39
|
* Derives the exact read-only SMART scopes covered by active Consent rules.
|
|
33
40
|
*
|
|
@@ -101,7 +108,7 @@ export function deriveGrantedSmartScopes(rules, input) {
|
|
|
101
108
|
deniedScopes.push(parsed.raw);
|
|
102
109
|
continue;
|
|
103
110
|
}
|
|
104
|
-
grantedScopes.push(
|
|
111
|
+
grantedScopes.push(buildScopeSmartCompositionAccess({
|
|
105
112
|
subjectDid: subject,
|
|
106
113
|
sections: scopeGrantedSections,
|
|
107
114
|
accessVerb: parsed.accessVerb,
|