@atomic-ehr/fhir-canonical-manager 0.0.8 → 0.0.9

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 (156) hide show
  1. package/README.md +72 -0
  2. package/dist/cache/core.d.ts +7 -0
  3. package/dist/cache/core.d.ts.map +1 -0
  4. package/dist/cache/core.js +11 -0
  5. package/dist/cache/core.js.map +1 -0
  6. package/dist/cache/index.d.ts +4 -0
  7. package/dist/cache/index.d.ts.map +1 -0
  8. package/dist/cache/index.js +4 -0
  9. package/dist/cache/index.js.map +1 -0
  10. package/dist/cache/persistence.d.ts +5 -0
  11. package/dist/cache/persistence.d.ts.map +1 -0
  12. package/dist/cache/persistence.js +25 -0
  13. package/dist/cache/persistence.js.map +1 -0
  14. package/dist/cache/validation.d.ts +2 -0
  15. package/dist/cache/validation.d.ts.map +1 -0
  16. package/dist/cache/validation.js +21 -0
  17. package/dist/cache/validation.js.map +1 -0
  18. package/dist/cli/index.d.ts.map +1 -1
  19. package/dist/cli/index.js +8 -4
  20. package/dist/cli/index.js.map +1 -1
  21. package/dist/cli/searchparam.d.ts +2 -0
  22. package/dist/cli/searchparam.d.ts.map +1 -0
  23. package/dist/cli/searchparam.js +131 -0
  24. package/dist/cli/searchparam.js.map +1 -0
  25. package/dist/constants.d.ts +2 -0
  26. package/dist/constants.d.ts.map +1 -0
  27. package/dist/constants.js +2 -0
  28. package/dist/constants.js.map +1 -0
  29. package/dist/fs/index.d.ts +2 -0
  30. package/dist/fs/index.d.ts.map +1 -0
  31. package/dist/fs/index.js +2 -0
  32. package/dist/fs/index.js.map +1 -0
  33. package/dist/fs/utils.d.ts +4 -0
  34. package/dist/fs/utils.d.ts.map +1 -0
  35. package/dist/fs/utils.js +23 -0
  36. package/dist/fs/utils.js.map +1 -0
  37. package/dist/index.d.ts +6 -111
  38. package/dist/index.d.ts.map +1 -1
  39. package/dist/index.js +5 -592
  40. package/dist/index.js.map +1 -1
  41. package/dist/manager/canonical.d.ts +3 -0
  42. package/dist/manager/canonical.d.ts.map +1 -0
  43. package/dist/manager/canonical.js +194 -0
  44. package/dist/manager/canonical.js.map +1 -0
  45. package/dist/manager/index.d.ts +3 -0
  46. package/dist/manager/index.d.ts.map +1 -0
  47. package/dist/manager/index.js +3 -0
  48. package/dist/manager/index.js.map +1 -0
  49. package/dist/package/detector.d.ts +2 -0
  50. package/dist/package/detector.d.ts.map +1 -0
  51. package/dist/package/detector.js +19 -0
  52. package/dist/package/detector.js.map +1 -0
  53. package/dist/package/index.d.ts +3 -0
  54. package/dist/package/index.d.ts.map +1 -0
  55. package/dist/package/index.js +3 -0
  56. package/dist/package/index.js.map +1 -0
  57. package/dist/package/installer.d.ts +2 -0
  58. package/dist/package/installer.d.ts.map +1 -0
  59. package/dist/package/installer.js +55 -0
  60. package/dist/package/installer.js.map +1 -0
  61. package/dist/reference/index.d.ts +5 -0
  62. package/dist/reference/index.d.ts.map +1 -0
  63. package/dist/reference/index.js +4 -0
  64. package/dist/reference/index.js.map +1 -0
  65. package/dist/reference/manager.d.ts +10 -0
  66. package/dist/reference/manager.d.ts.map +1 -0
  67. package/dist/reference/manager.js +36 -0
  68. package/dist/reference/manager.js.map +1 -0
  69. package/dist/reference/store.d.ts +6 -0
  70. package/dist/reference/store.d.ts.map +1 -0
  71. package/dist/reference/store.js +6 -0
  72. package/dist/reference/store.js.map +1 -0
  73. package/dist/resolver/context.d.ts +4 -0
  74. package/dist/resolver/context.d.ts.map +1 -0
  75. package/dist/resolver/context.js +14 -0
  76. package/dist/resolver/context.js.map +1 -0
  77. package/dist/resolver/index.d.ts +2 -0
  78. package/dist/resolver/index.d.ts.map +1 -0
  79. package/dist/resolver/index.js +2 -0
  80. package/dist/resolver/index.js.map +1 -0
  81. package/dist/scanner/directory.d.ts +3 -0
  82. package/dist/scanner/directory.d.ts.map +1 -0
  83. package/dist/scanner/directory.js +33 -0
  84. package/dist/scanner/directory.js.map +1 -0
  85. package/dist/scanner/index.d.ts +5 -0
  86. package/dist/scanner/index.d.ts.map +1 -0
  87. package/dist/scanner/index.js +5 -0
  88. package/dist/scanner/index.js.map +1 -0
  89. package/dist/scanner/package.d.ts +3 -0
  90. package/dist/scanner/package.d.ts.map +1 -0
  91. package/dist/scanner/package.js +26 -0
  92. package/dist/scanner/package.js.map +1 -0
  93. package/dist/scanner/parser.d.ts +5 -0
  94. package/dist/scanner/parser.d.ts.map +1 -0
  95. package/dist/scanner/parser.js +39 -0
  96. package/dist/scanner/parser.js.map +1 -0
  97. package/dist/scanner/processor.d.ts +4 -0
  98. package/dist/scanner/processor.d.ts.map +1 -0
  99. package/dist/scanner/processor.js +53 -0
  100. package/dist/scanner/processor.js.map +1 -0
  101. package/dist/search/index.d.ts +3 -0
  102. package/dist/search/index.d.ts.map +1 -0
  103. package/dist/search/index.js +3 -0
  104. package/dist/search/index.js.map +1 -0
  105. package/dist/search/smart.d.ts +9 -0
  106. package/dist/search/smart.d.ts.map +1 -0
  107. package/dist/search/smart.js +31 -0
  108. package/dist/search/smart.js.map +1 -0
  109. package/dist/search/terms.d.ts +2 -0
  110. package/dist/search/terms.d.ts.map +1 -0
  111. package/dist/search/terms.js +19 -0
  112. package/dist/search/terms.js.map +1 -0
  113. package/dist/types/core.d.ts +91 -0
  114. package/dist/types/core.d.ts.map +1 -0
  115. package/dist/types/core.js +2 -0
  116. package/dist/types/core.js.map +1 -0
  117. package/dist/types/index.d.ts +3 -0
  118. package/dist/types/index.d.ts.map +1 -0
  119. package/dist/types/index.js +3 -0
  120. package/dist/types/index.js.map +1 -0
  121. package/dist/types/internal.d.ts +48 -0
  122. package/dist/types/internal.d.ts.map +1 -0
  123. package/dist/types/internal.js +2 -0
  124. package/dist/types/internal.js.map +1 -0
  125. package/package.json +1 -1
  126. package/src/cache/core.ts +20 -0
  127. package/src/cache/index.ts +7 -0
  128. package/src/cache/persistence.ts +39 -0
  129. package/src/cache/validation.ts +27 -0
  130. package/src/cli/index.ts +8 -4
  131. package/src/cli/searchparam.ts +162 -0
  132. package/src/constants.ts +6 -0
  133. package/src/fs/index.ts +5 -0
  134. package/src/fs/utils.ts +28 -0
  135. package/src/index.ts +13 -990
  136. package/src/manager/canonical.ts +338 -0
  137. package/src/manager/index.ts +8 -0
  138. package/src/package/detector.ts +24 -0
  139. package/src/package/index.ts +6 -0
  140. package/src/package/installer.ts +77 -0
  141. package/src/reference/index.ts +10 -0
  142. package/src/reference/manager.ts +51 -0
  143. package/src/reference/store.ts +15 -0
  144. package/src/resolver/context.ts +25 -0
  145. package/src/resolver/index.ts +5 -0
  146. package/src/scanner/directory.ts +42 -0
  147. package/src/scanner/index.ts +8 -0
  148. package/src/scanner/package.ts +38 -0
  149. package/src/scanner/parser.ts +42 -0
  150. package/src/scanner/processor.ts +69 -0
  151. package/src/search/index.ts +6 -0
  152. package/src/search/smart.ts +57 -0
  153. package/src/search/terms.ts +22 -0
  154. package/src/types/core.ts +117 -0
  155. package/src/types/index.ts +6 -0
  156. package/src/types/internal.ts +57 -0
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Index processing functionality
3
+ */
4
+
5
+ import * as fs from 'fs/promises';
6
+ import * as path from 'path';
7
+ import type { PackageJson, IndexEntry } from '../types';
8
+ import type { ExtendedCache } from '../cache/core';
9
+ import { parseIndex } from './parser';
10
+
11
+ export const processIndex = async (
12
+ basePath: string,
13
+ packageJson: PackageJson,
14
+ cache: ExtendedCache,
15
+ ): Promise<void> => {
16
+ const indexPath = path.join(basePath, ".index.json");
17
+
18
+ try {
19
+ const indexContent = await fs.readFile(indexPath, "utf-8");
20
+ const index = parseIndex(indexContent, indexPath);
21
+
22
+ if (!index) return;
23
+
24
+ for (const file of index.files) {
25
+ if (!file.url) continue;
26
+
27
+ const filePath = path.join(basePath, file.filename);
28
+
29
+ const id = cache.referenceManager.generateId({
30
+ packageName: packageJson.name,
31
+ packageVersion: packageJson.version,
32
+ filePath,
33
+ });
34
+
35
+ cache.referenceManager.set(id, {
36
+ packageName: packageJson.name,
37
+ packageVersion: packageJson.version,
38
+ filePath,
39
+ resourceType: file.resourceType,
40
+ url: file.url,
41
+ version: file.version,
42
+ });
43
+
44
+ const entry: IndexEntry = {
45
+ id,
46
+ resourceType: file.resourceType,
47
+ indexVersion: index["index-version"],
48
+ url: file.url,
49
+ version: file.version,
50
+ kind: file.kind,
51
+ type: file.type,
52
+ package: {
53
+ name: packageJson.name,
54
+ version: packageJson.version,
55
+ },
56
+ };
57
+
58
+ if (!cache.entries[file.url]) {
59
+ cache.entries[file.url] = [];
60
+ }
61
+ const entries = cache.entries[file.url];
62
+ if (entries) {
63
+ entries.push(entry);
64
+ }
65
+ }
66
+ } catch {
67
+ // Silently ignore index processing errors
68
+ }
69
+ };
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Search module exports
3
+ */
4
+
5
+ export { expandedTerms } from './terms';
6
+ export { filterBySmartSearch, type SmartSearchFilters } from './smart';
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Smart search functionality with abbreviation support
3
+ */
4
+
5
+ import type { IndexEntry, PackageId } from '../types';
6
+ import { expandedTerms } from './terms';
7
+
8
+ export interface SmartSearchFilters {
9
+ resourceType?: string;
10
+ type?: string;
11
+ kind?: string;
12
+ package?: PackageId;
13
+ }
14
+
15
+ export const filterBySmartSearch = (
16
+ results: IndexEntry[],
17
+ searchTerms: string[],
18
+ ): IndexEntry[] => {
19
+ if (searchTerms.length === 0) {
20
+ return results;
21
+ }
22
+
23
+ const terms = searchTerms.map((t) => t.toLowerCase());
24
+
25
+ return results.filter((entry) => {
26
+ if (!entry.url) return false;
27
+ const urlLower = entry.url.toLowerCase();
28
+
29
+ // Also check type and resourceType for matching
30
+ const fullText = [
31
+ urlLower,
32
+ entry.type?.toLowerCase() || "",
33
+ entry.resourceType?.toLowerCase() || "",
34
+ ].join(" ");
35
+
36
+ // Check if all search terms match
37
+ return terms.every((term) => {
38
+ // Split the text into parts (by /, -, _, ., spaces)
39
+ const allParts = fullText.split(/[\/\-_\.\s]+/);
40
+
41
+ // Check if any part starts with the search term
42
+ const directMatch = allParts.some((part) => part.startsWith(term));
43
+ if (directMatch) return true;
44
+
45
+ // Check if the term is an abbreviation
46
+ const expansions = expandedTerms[term] || [];
47
+ for (const expansion of expansions) {
48
+ if (allParts.some((part) => part.startsWith(expansion))) {
49
+ return true;
50
+ }
51
+ }
52
+
53
+ // If still no match, check if the term appears anywhere (substring match)
54
+ return fullText.includes(term);
55
+ });
56
+ });
57
+ };
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Search term expansion and abbreviations
3
+ */
4
+
5
+ export const expandedTerms: Record<string, string[]> = {
6
+ str: ["structure"],
7
+ struct: ["structure"],
8
+ def: ["definition"],
9
+ pati: ["patient"],
10
+ obs: ["observation"],
11
+ org: ["organization"],
12
+ pract: ["practitioner"],
13
+ med: ["medication", "medicinal"],
14
+ req: ["request"],
15
+ resp: ["response"],
16
+ ref: ["reference"],
17
+ val: ["value"],
18
+ code: ["codesystem", "code"],
19
+ cs: ["codesystem"],
20
+ vs: ["valueset"],
21
+ sd: ["structuredefinition"],
22
+ };
@@ -0,0 +1,117 @@
1
+ /**
2
+ * Core public API types for FHIR Canonical Manager
3
+ */
4
+
5
+ export interface Reference {
6
+ id: string;
7
+ resourceType: string;
8
+ }
9
+
10
+ export interface PackageId {
11
+ name: string;
12
+ version: string;
13
+ }
14
+
15
+ export interface IndexEntry extends Reference {
16
+ indexVersion: number;
17
+ kind?: string;
18
+ url?: string;
19
+ type?: string;
20
+ version?: string;
21
+ package?: PackageId;
22
+ }
23
+
24
+ export interface Resource extends Reference {
25
+ url?: string;
26
+ version?: string;
27
+ [key: string]: any;
28
+ }
29
+
30
+ export interface SearchParameter {
31
+ // Required fields
32
+ url: string;
33
+ name: string;
34
+ code: string;
35
+ base: string[];
36
+ type: string;
37
+ expression: string;
38
+
39
+ // Optional commonly-used fields
40
+ version?: string;
41
+ target?: string[];
42
+ multipleOr?: boolean;
43
+ multipleAnd?: boolean;
44
+ comparator?: Array<'eq' | 'ne' | 'gt' | 'lt' | 'ge' | 'le' | 'sa' | 'eb' | 'ap'>;
45
+ modifier?: Array<'missing' | 'exact' | 'contains' | 'not' | 'text' |
46
+ 'in' | 'not-in' | 'below' | 'above' | 'type' | 'identifier' | 'ofType'>;
47
+
48
+ // Open for all other FHIR SearchParameter fields
49
+ [key: string]: any;
50
+ }
51
+
52
+ export interface SourceContext {
53
+ id?: string;
54
+ package?: PackageId;
55
+ url?: string;
56
+ path?: string;
57
+ }
58
+
59
+ export interface Config {
60
+ packages: string[];
61
+ workingDir: string;
62
+ registry?: string;
63
+ }
64
+
65
+ export interface PackageInfo {
66
+ id: PackageId;
67
+ path: string;
68
+ canonical?: string;
69
+ fhirVersions?: string[];
70
+ }
71
+
72
+ export interface CanonicalManager {
73
+ init(): Promise<void>;
74
+ destroy(): Promise<void>;
75
+ packages(): Promise<PackageId[]>;
76
+ resolveEntry(
77
+ canonicalUrl: string,
78
+ options?: {
79
+ package?: string;
80
+ version?: string;
81
+ sourceContext?: SourceContext;
82
+ },
83
+ ): Promise<IndexEntry>;
84
+ resolve(
85
+ canonicalUrl: string,
86
+ options?: {
87
+ package?: string;
88
+ version?: string;
89
+ sourceContext?: SourceContext;
90
+ },
91
+ ): Promise<Resource>;
92
+ read(reference: Reference): Promise<Resource>;
93
+ searchEntries(params: {
94
+ kind?: string;
95
+ url?: string;
96
+ type?: string;
97
+ version?: string;
98
+ package?: PackageId;
99
+ }): Promise<IndexEntry[]>;
100
+ search(params: {
101
+ kind?: string;
102
+ url?: string;
103
+ type?: string;
104
+ version?: string;
105
+ package?: PackageId;
106
+ }): Promise<Resource[]>;
107
+ smartSearch(
108
+ searchTerms: string[],
109
+ filters?: {
110
+ resourceType?: string;
111
+ type?: string;
112
+ kind?: string;
113
+ package?: PackageId;
114
+ },
115
+ ): Promise<IndexEntry[]>;
116
+ getSearchParametersForResource(resourceType: string): Promise<SearchParameter[]>;
117
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Type exports for FHIR Canonical Manager
3
+ */
4
+
5
+ export * from './core';
6
+ export * from './internal';
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Internal implementation types for FHIR Canonical Manager
3
+ */
4
+
5
+ export interface IndexFile {
6
+ "index-version": number;
7
+ files: IndexFileEntry[];
8
+ }
9
+
10
+ export interface IndexFileEntry {
11
+ filename: string;
12
+ resourceType: string;
13
+ id: string;
14
+ url?: string;
15
+ version?: string;
16
+ kind?: string;
17
+ type?: string;
18
+ }
19
+
20
+ export interface PackageJson {
21
+ name: string;
22
+ version: string;
23
+ fhirVersions?: string[];
24
+ type?: string;
25
+ canonical?: string;
26
+ dependencies?: Record<string, string>;
27
+ }
28
+
29
+ export interface ReferenceMetadata {
30
+ packageName: string;
31
+ packageVersion: string;
32
+ filePath: string;
33
+ resourceType: string;
34
+ url?: string;
35
+ version?: string;
36
+ }
37
+
38
+ export interface IndexCache {
39
+ entries: Record<string, import('./core').IndexEntry[]>;
40
+ packages: Record<string, import('./core').PackageInfo>;
41
+ references: Record<string, ReferenceMetadata>;
42
+ }
43
+
44
+ export interface CacheData {
45
+ entries: Record<string, import('./core').IndexEntry[]>;
46
+ packages: Record<string, import('./core').PackageInfo>;
47
+ references: Record<string, ReferenceMetadata>;
48
+ packageLockHash?: string; // Hash of package-lock.json to detect changes
49
+ }
50
+
51
+ export interface ReferenceStore {
52
+ get(id: string): ReferenceMetadata | undefined;
53
+ set(id: string, metadata: ReferenceMetadata): void;
54
+ has(id: string): boolean;
55
+ clear(): void;
56
+ size(): number;
57
+ }