@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.
- package/README.md +72 -0
- package/dist/cache/core.d.ts +7 -0
- package/dist/cache/core.d.ts.map +1 -0
- package/dist/cache/core.js +11 -0
- package/dist/cache/core.js.map +1 -0
- package/dist/cache/index.d.ts +4 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +4 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/cache/persistence.d.ts +5 -0
- package/dist/cache/persistence.d.ts.map +1 -0
- package/dist/cache/persistence.js +25 -0
- package/dist/cache/persistence.js.map +1 -0
- package/dist/cache/validation.d.ts +2 -0
- package/dist/cache/validation.d.ts.map +1 -0
- package/dist/cache/validation.js +21 -0
- package/dist/cache/validation.js.map +1 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +8 -4
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/searchparam.d.ts +2 -0
- package/dist/cli/searchparam.d.ts.map +1 -0
- package/dist/cli/searchparam.js +131 -0
- package/dist/cli/searchparam.js.map +1 -0
- package/dist/constants.d.ts +2 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +2 -0
- package/dist/constants.js.map +1 -0
- package/dist/fs/index.d.ts +2 -0
- package/dist/fs/index.d.ts.map +1 -0
- package/dist/fs/index.js +2 -0
- package/dist/fs/index.js.map +1 -0
- package/dist/fs/utils.d.ts +4 -0
- package/dist/fs/utils.d.ts.map +1 -0
- package/dist/fs/utils.js +23 -0
- package/dist/fs/utils.js.map +1 -0
- package/dist/index.d.ts +6 -111
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -592
- package/dist/index.js.map +1 -1
- package/dist/manager/canonical.d.ts +3 -0
- package/dist/manager/canonical.d.ts.map +1 -0
- package/dist/manager/canonical.js +194 -0
- package/dist/manager/canonical.js.map +1 -0
- package/dist/manager/index.d.ts +3 -0
- package/dist/manager/index.d.ts.map +1 -0
- package/dist/manager/index.js +3 -0
- package/dist/manager/index.js.map +1 -0
- package/dist/package/detector.d.ts +2 -0
- package/dist/package/detector.d.ts.map +1 -0
- package/dist/package/detector.js +19 -0
- package/dist/package/detector.js.map +1 -0
- package/dist/package/index.d.ts +3 -0
- package/dist/package/index.d.ts.map +1 -0
- package/dist/package/index.js +3 -0
- package/dist/package/index.js.map +1 -0
- package/dist/package/installer.d.ts +2 -0
- package/dist/package/installer.d.ts.map +1 -0
- package/dist/package/installer.js +55 -0
- package/dist/package/installer.js.map +1 -0
- package/dist/reference/index.d.ts +5 -0
- package/dist/reference/index.d.ts.map +1 -0
- package/dist/reference/index.js +4 -0
- package/dist/reference/index.js.map +1 -0
- package/dist/reference/manager.d.ts +10 -0
- package/dist/reference/manager.d.ts.map +1 -0
- package/dist/reference/manager.js +36 -0
- package/dist/reference/manager.js.map +1 -0
- package/dist/reference/store.d.ts +6 -0
- package/dist/reference/store.d.ts.map +1 -0
- package/dist/reference/store.js +6 -0
- package/dist/reference/store.js.map +1 -0
- package/dist/resolver/context.d.ts +4 -0
- package/dist/resolver/context.d.ts.map +1 -0
- package/dist/resolver/context.js +14 -0
- package/dist/resolver/context.js.map +1 -0
- package/dist/resolver/index.d.ts +2 -0
- package/dist/resolver/index.d.ts.map +1 -0
- package/dist/resolver/index.js +2 -0
- package/dist/resolver/index.js.map +1 -0
- package/dist/scanner/directory.d.ts +3 -0
- package/dist/scanner/directory.d.ts.map +1 -0
- package/dist/scanner/directory.js +33 -0
- package/dist/scanner/directory.js.map +1 -0
- package/dist/scanner/index.d.ts +5 -0
- package/dist/scanner/index.d.ts.map +1 -0
- package/dist/scanner/index.js +5 -0
- package/dist/scanner/index.js.map +1 -0
- package/dist/scanner/package.d.ts +3 -0
- package/dist/scanner/package.d.ts.map +1 -0
- package/dist/scanner/package.js +26 -0
- package/dist/scanner/package.js.map +1 -0
- package/dist/scanner/parser.d.ts +5 -0
- package/dist/scanner/parser.d.ts.map +1 -0
- package/dist/scanner/parser.js +39 -0
- package/dist/scanner/parser.js.map +1 -0
- package/dist/scanner/processor.d.ts +4 -0
- package/dist/scanner/processor.d.ts.map +1 -0
- package/dist/scanner/processor.js +53 -0
- package/dist/scanner/processor.js.map +1 -0
- package/dist/search/index.d.ts +3 -0
- package/dist/search/index.d.ts.map +1 -0
- package/dist/search/index.js +3 -0
- package/dist/search/index.js.map +1 -0
- package/dist/search/smart.d.ts +9 -0
- package/dist/search/smart.d.ts.map +1 -0
- package/dist/search/smart.js +31 -0
- package/dist/search/smart.js.map +1 -0
- package/dist/search/terms.d.ts +2 -0
- package/dist/search/terms.d.ts.map +1 -0
- package/dist/search/terms.js +19 -0
- package/dist/search/terms.js.map +1 -0
- package/dist/types/core.d.ts +91 -0
- package/dist/types/core.d.ts.map +1 -0
- package/dist/types/core.js +2 -0
- package/dist/types/core.js.map +1 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +3 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/internal.d.ts +48 -0
- package/dist/types/internal.d.ts.map +1 -0
- package/dist/types/internal.js +2 -0
- package/dist/types/internal.js.map +1 -0
- package/package.json +1 -1
- package/src/cache/core.ts +20 -0
- package/src/cache/index.ts +7 -0
- package/src/cache/persistence.ts +39 -0
- package/src/cache/validation.ts +27 -0
- package/src/cli/index.ts +8 -4
- package/src/cli/searchparam.ts +162 -0
- package/src/constants.ts +6 -0
- package/src/fs/index.ts +5 -0
- package/src/fs/utils.ts +28 -0
- package/src/index.ts +13 -990
- package/src/manager/canonical.ts +338 -0
- package/src/manager/index.ts +8 -0
- package/src/package/detector.ts +24 -0
- package/src/package/index.ts +6 -0
- package/src/package/installer.ts +77 -0
- package/src/reference/index.ts +10 -0
- package/src/reference/manager.ts +51 -0
- package/src/reference/store.ts +15 -0
- package/src/resolver/context.ts +25 -0
- package/src/resolver/index.ts +5 -0
- package/src/scanner/directory.ts +42 -0
- package/src/scanner/index.ts +8 -0
- package/src/scanner/package.ts +38 -0
- package/src/scanner/parser.ts +42 -0
- package/src/scanner/processor.ts +69 -0
- package/src/search/index.ts +6 -0
- package/src/search/smart.ts +57 -0
- package/src/search/terms.ts +22 -0
- package/src/types/core.ts +117 -0
- package/src/types/index.ts +6 -0
- 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,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,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
|
+
}
|