@metriport/fhir-sdk 0.30.0-alpha.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 (155) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +564 -0
  3. package/dist/__tests__/careplan.test.d.ts +2 -0
  4. package/dist/__tests__/careplan.test.d.ts.map +1 -0
  5. package/dist/__tests__/careplan.test.js +544 -0
  6. package/dist/__tests__/careplan.test.js.map +1 -0
  7. package/dist/__tests__/clinical-dates.test.d.ts +2 -0
  8. package/dist/__tests__/clinical-dates.test.d.ts.map +1 -0
  9. package/dist/__tests__/clinical-dates.test.js +341 -0
  10. package/dist/__tests__/clinical-dates.test.js.map +1 -0
  11. package/dist/__tests__/coding-utilities.test.d.ts +2 -0
  12. package/dist/__tests__/coding-utilities.test.d.ts.map +1 -0
  13. package/dist/__tests__/coding-utilities.test.js +482 -0
  14. package/dist/__tests__/coding-utilities.test.js.map +1 -0
  15. package/dist/__tests__/date-range-performance.test.d.ts +2 -0
  16. package/dist/__tests__/date-range-performance.test.d.ts.map +1 -0
  17. package/dist/__tests__/date-range-performance.test.js +218 -0
  18. package/dist/__tests__/date-range-performance.test.js.map +1 -0
  19. package/dist/__tests__/date-range-search.test.d.ts +2 -0
  20. package/dist/__tests__/date-range-search.test.d.ts.map +1 -0
  21. package/dist/__tests__/date-range-search.test.js +215 -0
  22. package/dist/__tests__/date-range-search.test.js.map +1 -0
  23. package/dist/__tests__/env-setup.d.ts +2 -0
  24. package/dist/__tests__/env-setup.d.ts.map +1 -0
  25. package/dist/__tests__/env-setup.js +37 -0
  26. package/dist/__tests__/env-setup.js.map +1 -0
  27. package/dist/__tests__/fhir-bundle-sdk-basic.test.d.ts +2 -0
  28. package/dist/__tests__/fhir-bundle-sdk-basic.test.d.ts.map +1 -0
  29. package/dist/__tests__/fhir-bundle-sdk-basic.test.js +19 -0
  30. package/dist/__tests__/fhir-bundle-sdk-basic.test.js.map +1 -0
  31. package/dist/__tests__/fhir-bundle-sdk.test.d.ts +2 -0
  32. package/dist/__tests__/fhir-bundle-sdk.test.d.ts.map +1 -0
  33. package/dist/__tests__/fhir-bundle-sdk.test.js +953 -0
  34. package/dist/__tests__/fhir-bundle-sdk.test.js.map +1 -0
  35. package/dist/__tests__/fixtures/fhir-bundles.d.ts +31 -0
  36. package/dist/__tests__/fixtures/fhir-bundles.d.ts.map +1 -0
  37. package/dist/__tests__/fixtures/fhir-bundles.js +487 -0
  38. package/dist/__tests__/fixtures/fhir-bundles.js.map +1 -0
  39. package/dist/__tests__/phase1-verification.test.d.ts +2 -0
  40. package/dist/__tests__/phase1-verification.test.d.ts.map +1 -0
  41. package/dist/__tests__/phase1-verification.test.js +141 -0
  42. package/dist/__tests__/phase1-verification.test.js.map +1 -0
  43. package/dist/__tests__/phase2-verification.test.d.ts +2 -0
  44. package/dist/__tests__/phase2-verification.test.d.ts.map +1 -0
  45. package/dist/__tests__/phase2-verification.test.js +234 -0
  46. package/dist/__tests__/phase2-verification.test.js.map +1 -0
  47. package/dist/__tests__/phase3-verification.test.d.ts +2 -0
  48. package/dist/__tests__/phase3-verification.test.d.ts.map +1 -0
  49. package/dist/__tests__/phase3-verification.test.js +121 -0
  50. package/dist/__tests__/phase3-verification.test.js.map +1 -0
  51. package/dist/__tests__/phase4-verification.test.d.ts +2 -0
  52. package/dist/__tests__/phase4-verification.test.d.ts.map +1 -0
  53. package/dist/__tests__/phase4-verification.test.js +168 -0
  54. package/dist/__tests__/phase4-verification.test.js.map +1 -0
  55. package/dist/__tests__/phase5-verification.test.d.ts +2 -0
  56. package/dist/__tests__/phase5-verification.test.d.ts.map +1 -0
  57. package/dist/__tests__/phase5-verification.test.js +397 -0
  58. package/dist/__tests__/phase5-verification.test.js.map +1 -0
  59. package/dist/__tests__/reverse-references.test.d.ts +2 -0
  60. package/dist/__tests__/reverse-references.test.d.ts.map +1 -0
  61. package/dist/__tests__/reverse-references.test.js +294 -0
  62. package/dist/__tests__/reverse-references.test.js.map +1 -0
  63. package/dist/__tests__/type-guards.test.d.ts +2 -0
  64. package/dist/__tests__/type-guards.test.d.ts.map +1 -0
  65. package/dist/__tests__/type-guards.test.js +163 -0
  66. package/dist/__tests__/type-guards.test.js.map +1 -0
  67. package/dist/clinical-dates.d.ts +26 -0
  68. package/dist/clinical-dates.d.ts.map +1 -0
  69. package/dist/clinical-dates.js +571 -0
  70. package/dist/clinical-dates.js.map +1 -0
  71. package/dist/fhir-bundle-sdk.d.ts +233 -0
  72. package/dist/fhir-bundle-sdk.d.ts.map +1 -0
  73. package/dist/fhir-bundle-sdk.js +545 -0
  74. package/dist/fhir-bundle-sdk.js.map +1 -0
  75. package/dist/index.d.ts +8 -0
  76. package/dist/index.d.ts.map +1 -0
  77. package/dist/index.js +23 -0
  78. package/dist/index.js.map +1 -0
  79. package/dist/internal/bundle-operations.d.ts +14 -0
  80. package/dist/internal/bundle-operations.d.ts.map +1 -0
  81. package/dist/internal/bundle-operations.js +55 -0
  82. package/dist/internal/bundle-operations.js.map +1 -0
  83. package/dist/internal/coding-systems.d.ts +48 -0
  84. package/dist/internal/coding-systems.d.ts.map +1 -0
  85. package/dist/internal/coding-systems.js +55 -0
  86. package/dist/internal/coding-systems.js.map +1 -0
  87. package/dist/internal/coding-utilities.d.ts +27 -0
  88. package/dist/internal/coding-utilities.d.ts.map +1 -0
  89. package/dist/internal/coding-utilities.js +297 -0
  90. package/dist/internal/coding-utilities.js.map +1 -0
  91. package/dist/internal/date-extraction.d.ts +12 -0
  92. package/dist/internal/date-extraction.d.ts.map +1 -0
  93. package/dist/internal/date-extraction.js +629 -0
  94. package/dist/internal/date-extraction.js.map +1 -0
  95. package/dist/internal/graph-traversal.d.ts +13 -0
  96. package/dist/internal/graph-traversal.d.ts.map +1 -0
  97. package/dist/internal/graph-traversal.js +89 -0
  98. package/dist/internal/graph-traversal.js.map +1 -0
  99. package/dist/internal/indexing.d.ts +17 -0
  100. package/dist/internal/indexing.d.ts.map +1 -0
  101. package/dist/internal/indexing.js +129 -0
  102. package/dist/internal/indexing.js.map +1 -0
  103. package/dist/internal/llm-context.d.ts +40 -0
  104. package/dist/internal/llm-context.d.ts.map +1 -0
  105. package/dist/internal/llm-context.js +214 -0
  106. package/dist/internal/llm-context.js.map +1 -0
  107. package/dist/internal/reference-resolution.d.ts +29 -0
  108. package/dist/internal/reference-resolution.d.ts.map +1 -0
  109. package/dist/internal/reference-resolution.js +338 -0
  110. package/dist/internal/reference-resolution.js.map +1 -0
  111. package/dist/internal/reference-utils.d.ts +26 -0
  112. package/dist/internal/reference-utils.d.ts.map +1 -0
  113. package/dist/internal/reference-utils.js +89 -0
  114. package/dist/internal/reference-utils.js.map +1 -0
  115. package/dist/internal/transparent-proxy.d.ts +12 -0
  116. package/dist/internal/transparent-proxy.d.ts.map +1 -0
  117. package/dist/internal/transparent-proxy.js +81 -0
  118. package/dist/internal/transparent-proxy.js.map +1 -0
  119. package/dist/internal/validation.d.ts +16 -0
  120. package/dist/internal/validation.d.ts.map +1 -0
  121. package/dist/internal/validation.js +45 -0
  122. package/dist/internal/validation.js.map +1 -0
  123. package/dist/type-guards.d.ts +212 -0
  124. package/dist/type-guards.d.ts.map +1 -0
  125. package/dist/type-guards.js +375 -0
  126. package/dist/type-guards.js.map +1 -0
  127. package/dist/types/coding-fields.d.ts +311 -0
  128. package/dist/types/coding-fields.d.ts.map +1 -0
  129. package/dist/types/coding-fields.js +3 -0
  130. package/dist/types/coding-fields.js.map +1 -0
  131. package/dist/types/sdk-types.d.ts +107 -0
  132. package/dist/types/sdk-types.d.ts.map +1 -0
  133. package/dist/types/sdk-types.js +17 -0
  134. package/dist/types/sdk-types.js.map +1 -0
  135. package/dist/types/smart-resources.d.ts +470 -0
  136. package/dist/types/smart-resources.d.ts.map +1 -0
  137. package/dist/types/smart-resources.js +249 -0
  138. package/dist/types/smart-resources.js.map +1 -0
  139. package/dist/utils/interval-tree/index.d.ts +87 -0
  140. package/dist/utils/interval-tree/index.d.ts.map +1 -0
  141. package/dist/utils/interval-tree/index.js +774 -0
  142. package/dist/utils/interval-tree/index.js.map +1 -0
  143. package/dist/utils/interval-tree/shallowequal/arrays.d.ts +3 -0
  144. package/dist/utils/interval-tree/shallowequal/arrays.d.ts.map +1 -0
  145. package/dist/utils/interval-tree/shallowequal/arrays.js +25 -0
  146. package/dist/utils/interval-tree/shallowequal/arrays.js.map +1 -0
  147. package/dist/utils/interval-tree/shallowequal/index.d.ts +6 -0
  148. package/dist/utils/interval-tree/shallowequal/index.d.ts.map +1 -0
  149. package/dist/utils/interval-tree/shallowequal/index.js +28 -0
  150. package/dist/utils/interval-tree/shallowequal/index.js.map +1 -0
  151. package/dist/utils/interval-tree/shallowequal/objects.d.ts +3 -0
  152. package/dist/utils/interval-tree/shallowequal/objects.d.ts.map +1 -0
  153. package/dist/utils/interval-tree/shallowequal/objects.js +28 -0
  154. package/dist/utils/interval-tree/shallowequal/objects.js.map +1 -0
  155. package/package.json +70 -0
@@ -0,0 +1,338 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createSmartResource = exports.resolveReference = exports.resolveReferenceObject = exports.isArrayReferenceField = void 0;
4
+ const util_1 = require("util");
5
+ const smart_resources_1 = require("../types/smart-resources");
6
+ const coding_utilities_1 = require("./coding-utilities");
7
+ const transparent_proxy_1 = require("./transparent-proxy");
8
+ /**
9
+ * Navigate through a nested path in a resource to get the value at that path.
10
+ * Handles both simple paths ("subject") and nested paths ("diagnosis.condition").
11
+ *
12
+ * For nested paths where the intermediate level is an array:
13
+ * - "diagnosis.condition" navigates to resource.diagnosis[], extracts .condition from each element
14
+ * - Returns an array of all reference values found
15
+ *
16
+ * For nested paths where the intermediate level is an object:
17
+ * - "hospitalization.origin" navigates to resource.hospitalization.origin
18
+ * - Returns the single reference value
19
+ *
20
+ * For deeply nested paths like "activity.detail.goal":
21
+ * - Flattens nested arrays that may result from navigating through multiple array levels
22
+ * - Returns a flat array of all references found
23
+ *
24
+ * @param resource - The FHIR resource to navigate
25
+ * @param path - Dot-separated path to the reference field
26
+ * @returns The value at the path, which could be a reference, array of references, or undefined
27
+ */
28
+ function getNestedValue(resource, path) {
29
+ const parts = path.split(".");
30
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
31
+ let current = resource;
32
+ for (const part of parts) {
33
+ if (!current) {
34
+ return undefined;
35
+ }
36
+ // If current is an array, map over it and collect values
37
+ if (Array.isArray(current)) {
38
+ const values = current.map(item => item?.[part]).filter(v => v !== undefined);
39
+ current = values.length > 0 ? values : undefined;
40
+ }
41
+ else {
42
+ current = current[part];
43
+ }
44
+ }
45
+ // Flatten nested arrays that may result from navigating through multiple array levels
46
+ // For example, activity.detail.goal where activity is an array and goal is also an array
47
+ // This prevents [[reference]] and instead returns [reference]
48
+ if (Array.isArray(current) && current.some(item => Array.isArray(item))) {
49
+ current = current.flat();
50
+ }
51
+ return current;
52
+ }
53
+ /**
54
+ * Check if a reference field expects an array of references.
55
+ * Handles both simple paths ("performer") and nested paths ("diagnosis.condition").
56
+ *
57
+ * For nested paths, if the intermediate level is an array, the method returns an array.
58
+ * For example, "diagnosis.condition" returns an array because diagnosis is an array field.
59
+ */
60
+ function isArrayReferenceField(fieldName) {
61
+ // Known simple array reference fields
62
+ const arrayFields = new Set(["performer", "participant", "result", "generalPractitioner"]);
63
+ // Check if this is a simple array field
64
+ if (arrayFields.has(fieldName)) {
65
+ return true;
66
+ }
67
+ // For nested paths, check if the base field (first part) is an array
68
+ // Examples: "diagnosis.condition", "participant.individual", "media.link"
69
+ if (fieldName.includes(".")) {
70
+ const parts = fieldName.split(".");
71
+ const baseField = parts[0];
72
+ // Known base fields that are arrays (and thus make their nested references arrays)
73
+ const arrayBaseFields = new Set([
74
+ "diagnosis",
75
+ "participant",
76
+ "location",
77
+ "contact",
78
+ "qualification",
79
+ "link",
80
+ "media",
81
+ "performer",
82
+ "attester",
83
+ "relatesTo",
84
+ "event",
85
+ "section",
86
+ "stage",
87
+ "evidence",
88
+ "protocolApplied",
89
+ "reaction",
90
+ "ingredient",
91
+ "activity",
92
+ ]);
93
+ return arrayBaseFields.has(baseField ?? "");
94
+ }
95
+ return false;
96
+ }
97
+ exports.isArrayReferenceField = isArrayReferenceField;
98
+ /**
99
+ * Resolve a single reference object to a resource
100
+ * FR-5.5: Reference resolution methods handle both resource.id and fullUrl matching
101
+ */
102
+ function resolveReferenceObject(referenceObj, resourcesById, resourcesByFullUrl, resolutionStack) {
103
+ if (!referenceObj || typeof referenceObj !== "object" || !("reference" in referenceObj)) {
104
+ return undefined;
105
+ }
106
+ const reference = referenceObj.reference;
107
+ // Circular reference protection
108
+ if (resolutionStack.has(reference)) {
109
+ return undefined;
110
+ }
111
+ resolutionStack.add(reference);
112
+ try {
113
+ // Try to resolve by resource ID (e.g., "Patient/123")
114
+ if (reference.includes("/")) {
115
+ const [, resourceId] = reference.split("/");
116
+ if (resourceId && resourcesById.has(resourceId)) {
117
+ return resourcesById.get(resourceId);
118
+ }
119
+ }
120
+ // Try to resolve by fullUrl (e.g., "urn:uuid:123")
121
+ if (resourcesByFullUrl.has(reference)) {
122
+ return resourcesByFullUrl.get(reference);
123
+ }
124
+ return undefined;
125
+ }
126
+ finally {
127
+ resolutionStack.delete(reference);
128
+ }
129
+ }
130
+ exports.resolveReferenceObject = resolveReferenceObject;
131
+ /**
132
+ * Resolve a reference method call to actual resources
133
+ * FR-5.2-5.6: Handle different reference types and patterns
134
+ */
135
+ function resolveReference(methodName, resource, resourcesById, resourcesByFullUrl, resolutionStack, createSmartResourceFn) {
136
+ const referenceField = (0, smart_resources_1.getReferenceField)(methodName, resource.resourceType);
137
+ if (!referenceField) {
138
+ return undefined;
139
+ }
140
+ // Use getNestedValue to handle both simple and nested paths
141
+ const referenceValue = getNestedValue(resource, referenceField);
142
+ if (!referenceValue) {
143
+ // FR-5.6: Return appropriate empty value for missing references
144
+ return isArrayReferenceField(referenceField) ? [] : undefined;
145
+ }
146
+ // Handle array references
147
+ if (Array.isArray(referenceValue)) {
148
+ const resolvedResources = [];
149
+ for (const ref of referenceValue) {
150
+ const resolved = resolveReferenceObject(ref, resourcesById, resourcesByFullUrl, resolutionStack);
151
+ if (resolved) {
152
+ resolvedResources.push(createSmartResourceFn(resolved));
153
+ }
154
+ }
155
+ return resolvedResources;
156
+ }
157
+ // Handle single reference - we know it's not an array at this point
158
+ const resolved = resolveReferenceObject(referenceValue, resourcesById, resourcesByFullUrl, resolutionStack);
159
+ if (resolved) {
160
+ // Type assertion is safe here because we've established this is the single reference path
161
+ return createSmartResourceFn(resolved);
162
+ }
163
+ return undefined;
164
+ }
165
+ exports.resolveReference = resolveReference;
166
+ /**
167
+ * Create a smart resource with reference resolution methods
168
+ * FR-5.1: Resources returned by SDK have additional getter methods for each Reference field
169
+ * FR-5.7: Reference resolution operates in O(1) time complexity per reference
170
+ * FR-5.8: Original reference fields remain unchanged
171
+ */
172
+ function createSmartResource(resource, smartResourceCache, resourcesById, resourcesByFullUrl, resolutionStack, getResourcesReferencingIdFn) {
173
+ // Check cache first to maintain object identity
174
+ const cached = smartResourceCache.get(resource);
175
+ if (cached) {
176
+ return cached;
177
+ }
178
+ const smartResource = new Proxy(resource, {
179
+ get: (target, prop, receiver) => {
180
+ // Handle the smart resource marker
181
+ if (prop === "__isSmartResource") {
182
+ return true;
183
+ }
184
+ // Handle reverse reference method
185
+ if (prop === "getReferencingResources") {
186
+ return (options) => {
187
+ const resourceId = target.id;
188
+ if (!resourceId) {
189
+ return [];
190
+ }
191
+ return getResourcesReferencingIdFn(resourceId, options);
192
+ };
193
+ }
194
+ // Handle forward reference method
195
+ if (prop === "getReferencedResources") {
196
+ return () => {
197
+ const referencedResources = [];
198
+ const referenceMethods = smart_resources_1.REFERENCE_METHOD_MAPPING[target.resourceType];
199
+ if (!referenceMethods) {
200
+ return referencedResources;
201
+ }
202
+ // Iterate through all reference methods for this resource type
203
+ for (const methodName of Object.keys(referenceMethods)) {
204
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
205
+ const result = smartResource[methodName]();
206
+ if (!result) {
207
+ continue;
208
+ }
209
+ // Handle both single and array references
210
+ if (Array.isArray(result)) {
211
+ referencedResources.push(...result.filter((r) => r !== undefined));
212
+ }
213
+ else {
214
+ referencedResources.push(result);
215
+ }
216
+ }
217
+ return referencedResources;
218
+ };
219
+ }
220
+ // Handle toString method
221
+ if (prop === "toString") {
222
+ return (space) => {
223
+ return JSON.stringify(target, null, space ?? 2);
224
+ };
225
+ }
226
+ // Handle Node.js util.inspect.custom for console.log and REPL
227
+ if (prop === util_1.inspect.custom) {
228
+ return () => {
229
+ return JSON.stringify(target, null, 2);
230
+ };
231
+ }
232
+ // Handle Symbol.toStringTag for better console display
233
+ if (prop === Symbol.toStringTag) {
234
+ return `Smart<${target.resourceType}>`;
235
+ }
236
+ // Handle toJSON for serialization
237
+ if (prop === "toJSON") {
238
+ return () => target;
239
+ }
240
+ // Check if this is a reference method call
241
+ if (typeof prop === "string" && (0, smart_resources_1.isReferenceMethod)(prop, target.resourceType)) {
242
+ return () => resolveReference(prop, target, resourcesById, resourcesByFullUrl, resolutionStack, res => createSmartResource(res, smartResourceCache, resourcesById, resourcesByFullUrl, resolutionStack, getResourcesReferencingIdFn));
243
+ }
244
+ // Get the property value
245
+ const value = Reflect.get(target, prop, receiver);
246
+ // Don't wrap null or undefined
247
+ if (value === null || value === undefined) {
248
+ return value;
249
+ }
250
+ // Wrap CodeableConcept objects (check before Coding to avoid misidentification)
251
+ if ((0, coding_utilities_1.isCodeableConcept)(value)) {
252
+ return (0, coding_utilities_1.createSmartCodeableConcept)(value);
253
+ }
254
+ // Wrap Coding objects
255
+ if ((0, coding_utilities_1.isCoding)(value)) {
256
+ return (0, coding_utilities_1.createSmartCoding)(value);
257
+ }
258
+ // Handle arrays - wrap each element if needed
259
+ if (Array.isArray(value)) {
260
+ return value.map(item => {
261
+ if (item === null || item === undefined) {
262
+ return item;
263
+ }
264
+ // Check CodeableConcept before Coding
265
+ if ((0, coding_utilities_1.isCodeableConcept)(item)) {
266
+ return (0, coding_utilities_1.createSmartCodeableConcept)(item);
267
+ }
268
+ if ((0, coding_utilities_1.isCoding)(item)) {
269
+ return (0, coding_utilities_1.createSmartCoding)(item);
270
+ }
271
+ // Recursively wrap plain objects with transparent proxy
272
+ // Only wrap plain objects, not built-in types
273
+ if (typeof item === "object" && !Array.isArray(item) && item.constructor === Object) {
274
+ return (0, transparent_proxy_1.createTransparentProxy)(item);
275
+ }
276
+ return item;
277
+ });
278
+ }
279
+ // Recursively wrap plain objects with transparent proxy (but not primitives, dates, etc.)
280
+ // Only wrap plain objects, not built-in types like Date, RegExp, etc.
281
+ if (typeof value === "object" && !Array.isArray(value) && value.constructor === Object) {
282
+ return (0, transparent_proxy_1.createTransparentProxy)(value);
283
+ }
284
+ // Return original property for primitives and other types
285
+ return value;
286
+ },
287
+ // Ensure JSON serialization works correctly (FR-5.8)
288
+ ownKeys: target => {
289
+ const keys = Reflect.ownKeys(target);
290
+ const virtualMethods = [
291
+ "getReferencingResources",
292
+ "getReferencedResources",
293
+ "toString",
294
+ ];
295
+ // Add reference methods for this resource type
296
+ const referenceMethods = smart_resources_1.REFERENCE_METHOD_MAPPING[target.resourceType];
297
+ if (referenceMethods) {
298
+ virtualMethods.push(...Object.keys(referenceMethods));
299
+ }
300
+ // Filter out internal markers and add virtual methods for DevTools
301
+ return [...keys.filter(key => key !== "__isSmartResource"), ...virtualMethods];
302
+ },
303
+ getOwnPropertyDescriptor: (target, prop) => {
304
+ // Hide internal markers from enumeration
305
+ if (prop === "__isSmartResource" ||
306
+ prop === Symbol.toStringTag ||
307
+ prop === "toJSON" ||
308
+ prop === util_1.inspect.custom) {
309
+ return undefined;
310
+ }
311
+ // Make virtual methods enumerable for DevTools
312
+ if (prop === "getReferencingResources" ||
313
+ prop === "getReferencedResources" ||
314
+ prop === "toString") {
315
+ return {
316
+ enumerable: true,
317
+ configurable: true,
318
+ writable: false,
319
+ };
320
+ }
321
+ // Make reference methods enumerable for DevTools
322
+ const referenceMethods = smart_resources_1.REFERENCE_METHOD_MAPPING[target.resourceType];
323
+ if (referenceMethods && typeof prop === "string" && prop in referenceMethods) {
324
+ return {
325
+ enumerable: true,
326
+ configurable: true,
327
+ writable: false,
328
+ };
329
+ }
330
+ return Reflect.getOwnPropertyDescriptor(target, prop);
331
+ },
332
+ });
333
+ // Cache the smart resource - cast to avoid type complexity issues
334
+ smartResourceCache.set(resource, smartResource);
335
+ return smartResource;
336
+ }
337
+ exports.createSmartResource = createSmartResource;
338
+ //# sourceMappingURL=reference-resolution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reference-resolution.js","sourceRoot":"","sources":["../../src/internal/reference-resolution.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import { Resource } from "@medplum/fhirtypes";
2
+ /**
3
+ * Find all Reference fields in a resource recursively
4
+ */
5
+ export declare function findAllReferences(resource: Resource): Array<{
6
+ field: string;
7
+ reference: string;
8
+ }>;
9
+ /**
10
+ * Extract target resource ID from a reference string
11
+ */
12
+ export declare function extractTargetIdFromReference(reference: string): string | undefined;
13
+ /**
14
+ * Normalize reference field path to base field name
15
+ * e.g., "participant.individual" -> "participant"
16
+ * "performer[0]" -> "performer"
17
+ */
18
+ export declare function normalizeReferenceField(field: string): string;
19
+ /**
20
+ * Check if a reference can be resolved within the bundle
21
+ * @param reference - The reference string to check
22
+ * @param resourcesById - Map of resources indexed by resource.id
23
+ * @param resourcesByFullUrl - Map of resources indexed by entry.fullUrl
24
+ */
25
+ export declare function canResolveReference(reference: string, resourcesById: Map<string, Resource>, resourcesByFullUrl: Map<string, Resource>): boolean;
26
+ //# sourceMappingURL=reference-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reference-utils.d.ts","sourceRoot":"","sources":["../../src/internal/reference-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,GAAG,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CAkCjG;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAalF;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAM7D;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,EACpC,kBAAkB,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,GACxC,OAAO,CAeT"}
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.canResolveReference = exports.normalizeReferenceField = exports.extractTargetIdFromReference = exports.findAllReferences = void 0;
4
+ /**
5
+ * Find all Reference fields in a resource recursively
6
+ */
7
+ function findAllReferences(resource) {
8
+ const references = [];
9
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
10
+ function searchObject(obj, path = "") {
11
+ if (!obj || typeof obj !== "object") {
12
+ return;
13
+ }
14
+ // Check if this object is a Reference
15
+ if (obj.reference && typeof obj.reference === "string") {
16
+ references.push({
17
+ field: path || "reference",
18
+ reference: obj.reference,
19
+ });
20
+ return;
21
+ }
22
+ // Recursively search object properties
23
+ for (const [key, value] of Object.entries(obj)) {
24
+ const currentPath = path ? `${path}.${key}` : key;
25
+ if (Array.isArray(value)) {
26
+ value.forEach((item, index) => {
27
+ searchObject(item, `${currentPath}[${index}]`);
28
+ });
29
+ }
30
+ else if (value && typeof value === "object") {
31
+ searchObject(value, currentPath);
32
+ }
33
+ }
34
+ }
35
+ searchObject(resource);
36
+ return references;
37
+ }
38
+ exports.findAllReferences = findAllReferences;
39
+ /**
40
+ * Extract target resource ID from a reference string
41
+ */
42
+ function extractTargetIdFromReference(reference) {
43
+ if (!reference) {
44
+ return undefined;
45
+ }
46
+ // Handle "ResourceType/id" pattern
47
+ if (reference.includes("/")) {
48
+ const parts = reference.split("/");
49
+ return parts[parts.length - 1];
50
+ }
51
+ // Handle other reference patterns (e.g., "urn:uuid:xxx")
52
+ return reference;
53
+ }
54
+ exports.extractTargetIdFromReference = extractTargetIdFromReference;
55
+ /**
56
+ * Normalize reference field path to base field name
57
+ * e.g., "participant.individual" -> "participant"
58
+ * "performer[0]" -> "performer"
59
+ */
60
+ function normalizeReferenceField(field) {
61
+ // Remove array indices
62
+ const withoutIndices = field.replace(/\[\d+\]/g, "");
63
+ // Take first part of dotted path
64
+ const parts = withoutIndices.split(".");
65
+ return parts[0] ?? field;
66
+ }
67
+ exports.normalizeReferenceField = normalizeReferenceField;
68
+ /**
69
+ * Check if a reference can be resolved within the bundle
70
+ * @param reference - The reference string to check
71
+ * @param resourcesById - Map of resources indexed by resource.id
72
+ * @param resourcesByFullUrl - Map of resources indexed by entry.fullUrl
73
+ */
74
+ function canResolveReference(reference, resourcesById, resourcesByFullUrl) {
75
+ // Try to resolve by resource ID (e.g., "Patient/123")
76
+ if (reference.includes("/")) {
77
+ const [, resourceId] = reference.split("/");
78
+ if (resourceId && resourcesById.has(resourceId)) {
79
+ return true;
80
+ }
81
+ }
82
+ // Try to resolve by fullUrl (e.g., "urn:uuid:123")
83
+ if (resourcesByFullUrl.has(reference)) {
84
+ return true;
85
+ }
86
+ return false;
87
+ }
88
+ exports.canResolveReference = canResolveReference;
89
+ //# sourceMappingURL=reference-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reference-utils.js","sourceRoot":"","sources":["../../src/internal/reference-utils.ts"],"names":[],"mappings":";;;AAEA;;GAEG;AACH,SAAgB,iBAAiB,CAAC,QAAkB;IAClD,MAAM,UAAU,GAAgD,EAAE,CAAC;IAEnE,8DAA8D;IAC9D,SAAS,YAAY,CAAC,GAAQ,EAAE,IAAI,GAAG,EAAE;QACvC,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE;YACnC,OAAO;SACR;QAED,sCAAsC;QACtC,IAAI,GAAG,CAAC,SAAS,IAAI,OAAO,GAAG,CAAC,SAAS,KAAK,QAAQ,EAAE;YACtD,UAAU,CAAC,IAAI,CAAC;gBACd,KAAK,EAAE,IAAI,IAAI,WAAW;gBAC1B,SAAS,EAAE,GAAG,CAAC,SAAS;aACzB,CAAC,CAAC;YACH,OAAO;SACR;QAED,uCAAuC;QACvC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;YAC9C,MAAM,WAAW,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;YAElD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;gBACxB,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;oBAC5B,YAAY,CAAC,IAAI,EAAE,GAAG,WAAW,IAAI,KAAK,GAAG,CAAC,CAAC;gBACjD,CAAC,CAAC,CAAC;aACJ;iBAAM,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;gBAC7C,YAAY,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;aAClC;SACF;IACH,CAAC;IAED,YAAY,CAAC,QAAQ,CAAC,CAAC;IACvB,OAAO,UAAU,CAAC;AACpB,CAAC;AAlCD,8CAkCC;AAED;;GAEG;AACH,SAAgB,4BAA4B,CAAC,SAAiB;IAC5D,IAAI,CAAC,SAAS,EAAE;QACd,OAAO,SAAS,CAAC;KAClB;IAED,mCAAmC;IACnC,IAAI,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;QAC3B,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACnC,OAAO,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;KAChC;IAED,yDAAyD;IACzD,OAAO,SAAS,CAAC;AACnB,CAAC;AAbD,oEAaC;AAED;;;;GAIG;AACH,SAAgB,uBAAuB,CAAC,KAAa;IACnD,uBAAuB;IACvB,MAAM,cAAc,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IACrD,iCAAiC;IACjC,MAAM,KAAK,GAAG,cAAc,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACxC,OAAO,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC;AAC3B,CAAC;AAND,0DAMC;AAED;;;;;GAKG;AACH,SAAgB,mBAAmB,CACjC,SAAiB,EACjB,aAAoC,EACpC,kBAAyC;IAEzC,sDAAsD;IACtD,IAAI,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;QAC3B,MAAM,CAAC,EAAE,UAAU,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC5C,IAAI,UAAU,IAAI,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE;YAC/C,OAAO,IAAI,CAAC;SACb;KACF;IAED,mDAAmD;IACnD,IAAI,kBAAkB,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE;QACrC,OAAO,IAAI,CAAC;KACb;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAnBD,kDAmBC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Create a transparent proxy that wraps plain objects to intercept property access.
3
+ * This enables deep access to Coding and CodeableConcept objects at any nesting level.
4
+ *
5
+ * Unlike SmartResource proxies, transparent proxies don't add methods - they just
6
+ * intercept property access to wrap Coding/CodeableConcept objects when accessed.
7
+ *
8
+ * @param obj - The plain object to wrap
9
+ * @returns A proxied object that wraps Coding/CodeableConcept on access
10
+ */
11
+ export declare function createTransparentProxy<T extends object>(obj: T): T;
12
+ //# sourceMappingURL=transparent-proxy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transparent-proxy.d.ts","sourceRoot":"","sources":["../../src/internal/transparent-proxy.ts"],"names":[],"mappings":"AAYA;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,SAAS,MAAM,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAuElE"}
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createTransparentProxy = void 0;
4
+ const coding_utilities_1 = require("./coding-utilities");
5
+ /**
6
+ * Cache for transparent proxy objects to maintain object identity
7
+ */
8
+ const transparentProxyCache = new WeakMap();
9
+ /**
10
+ * Create a transparent proxy that wraps plain objects to intercept property access.
11
+ * This enables deep access to Coding and CodeableConcept objects at any nesting level.
12
+ *
13
+ * Unlike SmartResource proxies, transparent proxies don't add methods - they just
14
+ * intercept property access to wrap Coding/CodeableConcept objects when accessed.
15
+ *
16
+ * @param obj - The plain object to wrap
17
+ * @returns A proxied object that wraps Coding/CodeableConcept on access
18
+ */
19
+ function createTransparentProxy(obj) {
20
+ // Check cache first to maintain object identity
21
+ const cached = transparentProxyCache.get(obj);
22
+ if (cached) {
23
+ return cached;
24
+ }
25
+ const proxy = new Proxy(obj, {
26
+ get: (target, prop, receiver) => {
27
+ const value = Reflect.get(target, prop, receiver);
28
+ // Don't wrap null or undefined
29
+ if (value === null || value === undefined) {
30
+ return value;
31
+ }
32
+ // Wrap CodeableConcept objects (check before Coding to avoid misidentification)
33
+ if ((0, coding_utilities_1.isCodeableConcept)(value)) {
34
+ return (0, coding_utilities_1.createSmartCodeableConcept)(value);
35
+ }
36
+ // Wrap Coding objects
37
+ if ((0, coding_utilities_1.isCoding)(value)) {
38
+ return (0, coding_utilities_1.createSmartCoding)(value);
39
+ }
40
+ // Handle arrays - wrap each element if needed
41
+ if (Array.isArray(value)) {
42
+ return value.map(item => {
43
+ if (item === null || item === undefined) {
44
+ return item;
45
+ }
46
+ // Check CodeableConcept before Coding
47
+ if ((0, coding_utilities_1.isCodeableConcept)(item)) {
48
+ return (0, coding_utilities_1.createSmartCodeableConcept)(item);
49
+ }
50
+ if ((0, coding_utilities_1.isCoding)(item)) {
51
+ return (0, coding_utilities_1.createSmartCoding)(item);
52
+ }
53
+ // Recursively wrap plain objects, not built-in types
54
+ if (typeof item === "object" && !Array.isArray(item) && item.constructor === Object) {
55
+ return createTransparentProxy(item);
56
+ }
57
+ return item;
58
+ });
59
+ }
60
+ // Recursively wrap plain objects (but not primitives, dates, etc.)
61
+ // Only wrap plain objects, not built-in types like Date, RegExp, etc.
62
+ if (typeof value === "object" && !Array.isArray(value) && value.constructor === Object) {
63
+ return createTransparentProxy(value);
64
+ }
65
+ // Return primitives, dates, and other built-in types as-is
66
+ return value;
67
+ },
68
+ // Handle Symbol.toStringTag for better console display
69
+ ownKeys: target => {
70
+ return Reflect.ownKeys(target);
71
+ },
72
+ getOwnPropertyDescriptor: (target, prop) => {
73
+ return Reflect.getOwnPropertyDescriptor(target, prop);
74
+ },
75
+ });
76
+ // Cache the proxy
77
+ transparentProxyCache.set(obj, proxy);
78
+ return proxy;
79
+ }
80
+ exports.createTransparentProxy = createTransparentProxy;
81
+ //# sourceMappingURL=transparent-proxy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transparent-proxy.js","sourceRoot":"","sources":["../../src/internal/transparent-proxy.ts"],"names":[],"mappings":";;;AAAA,yDAK4B;AAE5B;;GAEG;AACH,MAAM,qBAAqB,GAAG,IAAI,OAAO,EAAkB,CAAC;AAE5D;;;;;;;;;GASG;AACH,SAAgB,sBAAsB,CAAmB,GAAM;IAC7D,gDAAgD;IAChD,MAAM,MAAM,GAAG,qBAAqB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC9C,IAAI,MAAM,EAAE;QACV,OAAO,MAAW,CAAC;KACpB;IAED,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,GAAG,EAAE;QAC3B,GAAG,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;YAC9B,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;YAElD,+BAA+B;YAC/B,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE;gBACzC,OAAO,KAAK,CAAC;aACd;YAED,gFAAgF;YAChF,IAAI,IAAA,oCAAiB,EAAC,KAAK,CAAC,EAAE;gBAC5B,OAAO,IAAA,6CAA0B,EAAC,KAAK,CAAC,CAAC;aAC1C;YAED,sBAAsB;YACtB,IAAI,IAAA,2BAAQ,EAAC,KAAK,CAAC,EAAE;gBACnB,OAAO,IAAA,oCAAiB,EAAC,KAAK,CAAC,CAAC;aACjC;YAED,8CAA8C;YAC9C,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;gBACxB,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;oBACtB,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,SAAS,EAAE;wBACvC,OAAO,IAAI,CAAC;qBACb;oBACD,sCAAsC;oBACtC,IAAI,IAAA,oCAAiB,EAAC,IAAI,CAAC,EAAE;wBAC3B,OAAO,IAAA,6CAA0B,EAAC,IAAI,CAAC,CAAC;qBACzC;oBACD,IAAI,IAAA,2BAAQ,EAAC,IAAI,CAAC,EAAE;wBAClB,OAAO,IAAA,oCAAiB,EAAC,IAAI,CAAC,CAAC;qBAChC;oBACD,qDAAqD;oBACrD,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,WAAW,KAAK,MAAM,EAAE;wBACnF,OAAO,sBAAsB,CAAC,IAAI,CAAC,CAAC;qBACrC;oBACD,OAAO,IAAI,CAAC;gBACd,CAAC,CAAC,CAAC;aACJ;YAED,mEAAmE;YACnE,sEAAsE;YACtE,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,WAAW,KAAK,MAAM,EAAE;gBACtF,OAAO,sBAAsB,CAAC,KAAK,CAAC,CAAC;aACtC;YAED,2DAA2D;YAC3D,OAAO,KAAK,CAAC;QACf,CAAC;QAED,uDAAuD;QACvD,OAAO,EAAE,MAAM,CAAC,EAAE;YAChB,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACjC,CAAC;QAED,wBAAwB,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE;YACzC,OAAO,OAAO,CAAC,wBAAwB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACxD,CAAC;KACF,CAAM,CAAC;IAER,kBAAkB;IAClB,qBAAqB,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAEtC,OAAO,KAAK,CAAC;AACf,CAAC;AAvED,wDAuEC"}
@@ -0,0 +1,16 @@
1
+ import { Bundle, Resource } from "@medplum/fhirtypes";
2
+ import { ValidationResult } from "../types/sdk-types";
3
+ /**
4
+ * Validate all references in the bundle
5
+ * FR-2.1: Validate all references in the bundle
6
+ * FR-2.2: Identifies references by Resource/id pattern and fullUrl references
7
+ * FR-2.3: Handles both relative and absolute references
8
+ * FR-2.4: Returns validation result with broken reference details
9
+ *
10
+ * @param bundle - The FHIR bundle to validate
11
+ * @param resourcesById - Map of resources indexed by resource.id
12
+ * @param resourcesByFullUrl - Map of resources indexed by entry.fullUrl
13
+ * @returns ValidationResult with broken reference details
14
+ */
15
+ export declare function lookForBrokenReferences(bundle: Bundle, resourcesById: Map<string, Resource>, resourcesByFullUrl: Map<string, Resource>): ValidationResult;
16
+ //# sourceMappingURL=validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/internal/validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAmB,MAAM,oBAAoB,CAAC;AAGvE;;;;;;;;;;;GAWG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,EACpC,kBAAkB,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,GACxC,gBAAgB,CA+BlB"}
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.lookForBrokenReferences = void 0;
4
+ const reference_utils_1 = require("./reference-utils");
5
+ /**
6
+ * Validate all references in the bundle
7
+ * FR-2.1: Validate all references in the bundle
8
+ * FR-2.2: Identifies references by Resource/id pattern and fullUrl references
9
+ * FR-2.3: Handles both relative and absolute references
10
+ * FR-2.4: Returns validation result with broken reference details
11
+ *
12
+ * @param bundle - The FHIR bundle to validate
13
+ * @param resourcesById - Map of resources indexed by resource.id
14
+ * @param resourcesByFullUrl - Map of resources indexed by entry.fullUrl
15
+ * @returns ValidationResult with broken reference details
16
+ */
17
+ function lookForBrokenReferences(bundle, resourcesById, resourcesByFullUrl) {
18
+ const brokenReferences = [];
19
+ if (!bundle.entry) {
20
+ return { hasBrokenReferences: false, brokenReferences: [] };
21
+ }
22
+ for (const entry of bundle.entry) {
23
+ if (!entry.resource) {
24
+ continue;
25
+ }
26
+ const resource = entry.resource;
27
+ const resourceReferences = (0, reference_utils_1.findAllReferences)(resource);
28
+ for (const { field, reference } of resourceReferences) {
29
+ if (!(0, reference_utils_1.canResolveReference)(reference, resourcesById, resourcesByFullUrl)) {
30
+ brokenReferences.push({
31
+ sourceResourceId: resource.id || entry.fullUrl || "unknown",
32
+ sourceResourceType: resource.resourceType,
33
+ referenceField: field,
34
+ reference: reference,
35
+ });
36
+ }
37
+ }
38
+ }
39
+ return {
40
+ hasBrokenReferences: brokenReferences.length > 0,
41
+ brokenReferences: brokenReferences,
42
+ };
43
+ }
44
+ exports.lookForBrokenReferences = lookForBrokenReferences;
45
+ //# sourceMappingURL=validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/internal/validation.ts"],"names":[],"mappings":";;;AAEA,uDAA2E;AAE3E;;;;;;;;;;;GAWG;AACH,SAAgB,uBAAuB,CACrC,MAAc,EACd,aAAoC,EACpC,kBAAyC;IAEzC,MAAM,gBAAgB,GAAsB,EAAE,CAAC;IAE/C,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE;QACjB,OAAO,EAAE,mBAAmB,EAAE,KAAK,EAAE,gBAAgB,EAAE,EAAE,EAAE,CAAC;KAC7D;IAED,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,KAAK,EAAE;QAChC,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE;YACnB,SAAS;SACV;QAED,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;QAChC,MAAM,kBAAkB,GAAG,IAAA,mCAAiB,EAAC,QAAQ,CAAC,CAAC;QAEvD,KAAK,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,kBAAkB,EAAE;YACrD,IAAI,CAAC,IAAA,qCAAmB,EAAC,SAAS,EAAE,aAAa,EAAE,kBAAkB,CAAC,EAAE;gBACtE,gBAAgB,CAAC,IAAI,CAAC;oBACpB,gBAAgB,EAAE,QAAQ,CAAC,EAAE,IAAI,KAAK,CAAC,OAAO,IAAI,SAAS;oBAC3D,kBAAkB,EAAE,QAAQ,CAAC,YAAY;oBACzC,cAAc,EAAE,KAAK;oBACrB,SAAS,EAAE,SAAS;iBACrB,CAAC,CAAC;aACJ;SACF;KACF;IAED,OAAO;QACL,mBAAmB,EAAE,gBAAgB,CAAC,MAAM,GAAG,CAAC;QAChD,gBAAgB,EAAE,gBAAgB;KACnC,CAAC;AACJ,CAAC;AAnCD,0DAmCC"}