@atomic-ehr/fhir-canonical-manager 0.0.6 → 0.0.8
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 +30 -30
- package/dist/cli/index.d.ts +2 -2
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +45 -35
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/init.d.ts.map +1 -1
- package/dist/cli/init.js +25 -16
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/list.d.ts.map +1 -1
- package/dist/cli/list.js +6 -0
- package/dist/cli/list.js.map +1 -1
- package/dist/cli/resolve.d.ts.map +1 -1
- package/dist/cli/resolve.js +9 -0
- package/dist/cli/resolve.js.map +1 -1
- package/dist/cli/search.d.ts.map +1 -1
- package/dist/cli/search.js +16 -22
- package/dist/cli/search.js.map +1 -1
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +239 -64
- package/dist/index.js.map +1 -1
- package/package.json +4 -3
- package/src/cli/index.ts +53 -39
- package/src/cli/init.ts +36 -23
- package/src/cli/list.ts +6 -0
- package/src/cli/resolve.ts +9 -0
- package/src/cli/search.ts +20 -36
- package/src/index.ts +443 -146
- package/dist/compat.d.ts +0 -17
- package/dist/compat.d.ts.map +0 -1
- package/dist/compat.js +0 -56
- package/dist/compat.js.map +0 -1
- package/src/compat.ts +0 -98
package/dist/cli/search.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/cli/search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAClF,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE/C,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAc;IAChD,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAChD,MAAM,WAAW,GAAG,UAAU,CAAC;IAC/B,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,KAAK,IAAI,CAAC;IACrC,MAAM,kBAAkB,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,YAAY,CAAuB,CAAC;IACxF,MAAM,UAAU,GAAG,OAAO,CAAC,CAAuB,CAAC;IACnD,MAAM,UAAU,GAAG,OAAO,CAAC,CAAuB,CAAC;IACnD,MAAM,aAAa,GAAG,OAAO,CAAC,OAA6B,CAAC;IAG5D,MAAM,WAAW,GAAG,MAAM,eAAe,EAAE,CAAC;IAC5C,IAAI,CAAC,WAAW,EAAE,GAAG,EAAE,QAAQ,IAAI,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzE,OAAO,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;QACpD,OAAO,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;QAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAG,wBAAwB,CAAC,WAAW,CAAC,CAAC;IACrD,MAAM,OAAO,GAAG,gBAAgB,CAAC,MAAa,CAAC,CAAC;IAChD,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;IAErB,IAAI,CAAC;QAEH,MAAM,
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/cli/search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAClF,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE/C,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAc;IAChD,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAChD,MAAM,WAAW,GAAG,UAAU,CAAC;IAC/B,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,KAAK,IAAI,CAAC;IACrC,MAAM,kBAAkB,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,YAAY,CAAuB,CAAC;IACxF,MAAM,UAAU,GAAG,OAAO,CAAC,CAAuB,CAAC;IACnD,MAAM,UAAU,GAAG,OAAO,CAAC,CAAuB,CAAC;IACnD,MAAM,aAAa,GAAG,OAAO,CAAC,OAA6B,CAAC;IAG5D,MAAM,WAAW,GAAG,MAAM,eAAe,EAAE,CAAC;IAC5C,IAAI,CAAC,WAAW,EAAE,GAAG,EAAE,QAAQ,IAAI,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzE,OAAO,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;QACpD,OAAO,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;QAC7D,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;YAC5D,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;QACjD,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAG,wBAAwB,CAAC,WAAW,CAAC,CAAC;IACrD,MAAM,OAAO,GAAG,gBAAgB,CAAC,MAAa,CAAC,CAAC;IAChD,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;IAErB,IAAI,CAAC;QAEH,MAAM,OAAO,GAAQ,EAAE,CAAC;QAExB,IAAI,kBAAkB,EAAE,CAAC;YACvB,OAAO,CAAC,YAAY,GAAG,kBAAkB,CAAC;QAC5C,CAAC;QAED,IAAI,UAAU,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,GAAG,UAAU,CAAC;QAC5B,CAAC;QAED,IAAI,UAAU,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,GAAG,UAAU,CAAC;QAC5B,CAAC;QAED,IAAI,aAAa,EAAE,CAAC;YAClB,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,QAAQ,EAAE,CAAC;YAC1C,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,aAAa,CAAC,CAAC;YACzD,IAAI,CAAC,GAAG,EAAE,CAAC;gBACT,OAAO,CAAC,KAAK,CAAC,mBAAmB,aAAa,aAAa,CAAC,CAAC;gBAC7D,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;oBAC5D,MAAM,IAAI,KAAK,CAAC,YAAY,aAAa,aAAa,CAAC,CAAC;gBAC1D,CAAC;gBACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YACD,OAAO,CAAC,OAAO,GAAG,GAAG,CAAC;QACxB,CAAC;QAGD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QAEhE,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAChD,CAAC;aAAM,CAAC;YACN,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACzB,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;YACpC,CAAC;iBAAM,CAAC;gBACN,MAAM,UAAU,GAAG,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;gBACxF,OAAO,CAAC,GAAG,CAAC,SAAS,OAAO,CAAC,MAAM,YAAY,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,UAAU,GAAG,CAAC,CAAC;gBAEhG,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;oBACzB,MAAM,IAAI,GAAG;wBACX,YAAY,EAAE,QAAQ,CAAC,YAAY;wBACnC,IAAI,EAAE,QAAQ,CAAC,IAAI;wBACnB,IAAI,EAAE,QAAQ,CAAC,IAAI;wBACnB,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,IAAI;qBAChC,CAAC;oBACF,OAAO,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,GAAG,KAAK,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBAC1D,CAAC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;YAAS,CAAC;QACT,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;IAC1B,CAAC;AACH,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
declare class ShellError extends Error {
|
|
2
|
+
exitCode: number;
|
|
3
|
+
stdout: string;
|
|
4
|
+
stderr: string;
|
|
5
|
+
constructor(message: string, exitCode: number, stdout: string, stderr: string);
|
|
6
|
+
}
|
|
7
|
+
declare function detectPackageManager(): Promise<"bun" | "npm" | null>;
|
|
8
|
+
export { ShellError, detectPackageManager };
|
|
1
9
|
export interface Reference {
|
|
2
10
|
id: string;
|
|
3
11
|
resourceType: string;
|
|
@@ -59,6 +67,12 @@ export interface CanonicalManager {
|
|
|
59
67
|
version?: string;
|
|
60
68
|
package?: PackageId;
|
|
61
69
|
}): Promise<Resource[]>;
|
|
70
|
+
smartSearch(searchTerms: string[], filters?: {
|
|
71
|
+
resourceType?: string;
|
|
72
|
+
type?: string;
|
|
73
|
+
kind?: string;
|
|
74
|
+
package?: PackageId;
|
|
75
|
+
}): Promise<IndexEntry[]>;
|
|
62
76
|
}
|
|
63
77
|
export interface PackageInfo {
|
|
64
78
|
id: PackageId;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,101 @@
|
|
|
1
|
-
import * as path from
|
|
2
|
-
import * as fs from
|
|
3
|
-
import { createHash } from
|
|
4
|
-
import {
|
|
1
|
+
import * as path from "path";
|
|
2
|
+
import * as fs from "fs/promises";
|
|
3
|
+
import { createHash } from "crypto";
|
|
4
|
+
import { exec } from "child_process";
|
|
5
|
+
import { promisify } from "util";
|
|
6
|
+
const execAsync = promisify(exec);
|
|
7
|
+
class ShellError extends Error {
|
|
8
|
+
exitCode;
|
|
9
|
+
stdout;
|
|
10
|
+
stderr;
|
|
11
|
+
constructor(message, exitCode, stdout, stderr) {
|
|
12
|
+
super(message);
|
|
13
|
+
this.name = "ShellError";
|
|
14
|
+
this.exitCode = exitCode;
|
|
15
|
+
this.stdout = stdout;
|
|
16
|
+
this.stderr = stderr;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function $(strings, ...values) {
|
|
20
|
+
const command = strings.reduce((acc, str, i) => {
|
|
21
|
+
return acc + str + (values[i] || "");
|
|
22
|
+
}, "");
|
|
23
|
+
let envVars = {};
|
|
24
|
+
const execute = async (options = {}) => {
|
|
25
|
+
try {
|
|
26
|
+
const execOptions = {
|
|
27
|
+
shell: true,
|
|
28
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
29
|
+
};
|
|
30
|
+
if (Object.keys(envVars).length > 0) {
|
|
31
|
+
execOptions.env = { ...process.env, ...envVars };
|
|
32
|
+
}
|
|
33
|
+
const { stdout, stderr } = await execAsync(command, execOptions);
|
|
34
|
+
return {
|
|
35
|
+
stdout: stdout?.toString() || "",
|
|
36
|
+
stderr: stderr?.toString() || "",
|
|
37
|
+
exitCode: 0,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
const code = error.code || 1;
|
|
42
|
+
const stdout = error.stdout?.toString() || "";
|
|
43
|
+
const stderr = error.stderr?.toString() || error.message || "";
|
|
44
|
+
throw new ShellError(`Command failed: ${command}`, code, stdout, stderr);
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
let executed = false;
|
|
48
|
+
let resultPromise = null;
|
|
49
|
+
const lazyPromise = {
|
|
50
|
+
then(onFulfilled, onRejected) {
|
|
51
|
+
if (!executed) {
|
|
52
|
+
executed = true;
|
|
53
|
+
resultPromise = execute();
|
|
54
|
+
}
|
|
55
|
+
return resultPromise.then(onFulfilled, onRejected);
|
|
56
|
+
},
|
|
57
|
+
catch(onRejected) {
|
|
58
|
+
return this.then(undefined, onRejected);
|
|
59
|
+
},
|
|
60
|
+
finally(onFinally) {
|
|
61
|
+
return this.then((value) => {
|
|
62
|
+
onFinally?.();
|
|
63
|
+
return value;
|
|
64
|
+
}, (reason) => {
|
|
65
|
+
onFinally?.();
|
|
66
|
+
throw reason;
|
|
67
|
+
});
|
|
68
|
+
},
|
|
69
|
+
quiet() {
|
|
70
|
+
return execute({ quiet: true });
|
|
71
|
+
},
|
|
72
|
+
env(vars) {
|
|
73
|
+
envVars = vars;
|
|
74
|
+
return this;
|
|
75
|
+
},
|
|
76
|
+
[Symbol.toStringTag]: "ShellPromise",
|
|
77
|
+
};
|
|
78
|
+
return lazyPromise;
|
|
79
|
+
}
|
|
80
|
+
async function detectPackageManager() {
|
|
81
|
+
try {
|
|
82
|
+
await $ `bun --version`.quiet();
|
|
83
|
+
return "bun";
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
try {
|
|
87
|
+
await $ `npm --version`.quiet();
|
|
88
|
+
return "npm";
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
export { ShellError, detectPackageManager };
|
|
5
96
|
const generateReferenceId = (metadata) => {
|
|
6
97
|
const input = `${metadata.packageName}@${metadata.packageVersion}:${metadata.filePath}`;
|
|
7
|
-
return createHash(
|
|
98
|
+
return createHash("sha256").update(input).digest("base64url");
|
|
8
99
|
};
|
|
9
100
|
export const ReferenceManager = () => {
|
|
10
101
|
const references = {};
|
|
@@ -22,8 +113,8 @@ export const ReferenceManager = () => {
|
|
|
22
113
|
}
|
|
23
114
|
};
|
|
24
115
|
const clear = () => {
|
|
25
|
-
Object.keys(references).forEach(key => delete references[key]);
|
|
26
|
-
Object.keys(urlToIds).forEach(key => delete urlToIds[key]);
|
|
116
|
+
Object.keys(references).forEach((key) => delete references[key]);
|
|
117
|
+
Object.keys(urlToIds).forEach((key) => delete urlToIds[key]);
|
|
27
118
|
};
|
|
28
119
|
return {
|
|
29
120
|
generateId: generateReferenceId,
|
|
@@ -35,32 +126,32 @@ export const ReferenceManager = () => {
|
|
|
35
126
|
getIdsByUrl: (url) => urlToIds[url] || [],
|
|
36
127
|
createReference: (id, metadata) => ({
|
|
37
128
|
id,
|
|
38
|
-
resourceType: metadata.resourceType
|
|
129
|
+
resourceType: metadata.resourceType,
|
|
39
130
|
}),
|
|
40
|
-
getAllReferences: () => references
|
|
131
|
+
getAllReferences: () => references,
|
|
41
132
|
};
|
|
42
133
|
};
|
|
43
134
|
const isValidFileEntry = (entry) => {
|
|
44
|
-
if (!entry || typeof entry !==
|
|
135
|
+
if (!entry || typeof entry !== "object")
|
|
45
136
|
return false;
|
|
46
|
-
if (!entry.filename || typeof entry.filename !==
|
|
137
|
+
if (!entry.filename || typeof entry.filename !== "string")
|
|
47
138
|
return false;
|
|
48
|
-
if (!entry.resourceType || typeof entry.resourceType !==
|
|
139
|
+
if (!entry.resourceType || typeof entry.resourceType !== "string")
|
|
49
140
|
return false;
|
|
50
|
-
if (!entry.id || typeof entry.id !==
|
|
141
|
+
if (!entry.id || typeof entry.id !== "string")
|
|
51
142
|
return false;
|
|
52
|
-
const optionalStringFields = [
|
|
143
|
+
const optionalStringFields = ["url", "version", "kind", "type"];
|
|
53
144
|
for (const field of optionalStringFields) {
|
|
54
|
-
if (entry[field] !== undefined && typeof entry[field] !==
|
|
145
|
+
if (entry[field] !== undefined && typeof entry[field] !== "string") {
|
|
55
146
|
return false;
|
|
56
147
|
}
|
|
57
148
|
}
|
|
58
149
|
return true;
|
|
59
150
|
};
|
|
60
151
|
const isValidIndexFile = (data) => {
|
|
61
|
-
if (!data || typeof data !==
|
|
152
|
+
if (!data || typeof data !== "object")
|
|
62
153
|
return false;
|
|
63
|
-
if (!data[
|
|
154
|
+
if (!data["index-version"] || typeof data["index-version"] !== "number")
|
|
64
155
|
return false;
|
|
65
156
|
if (!Array.isArray(data.files))
|
|
66
157
|
return false;
|
|
@@ -95,7 +186,7 @@ const ensureDir = async (dirPath) => {
|
|
|
95
186
|
}
|
|
96
187
|
};
|
|
97
188
|
const isFhirPackage = async (dirPath) => {
|
|
98
|
-
const indexPath = path.join(dirPath,
|
|
189
|
+
const indexPath = path.join(dirPath, ".index.json");
|
|
99
190
|
return fileExists(indexPath);
|
|
100
191
|
};
|
|
101
192
|
const createCache = () => {
|
|
@@ -104,14 +195,21 @@ const createCache = () => {
|
|
|
104
195
|
entries: {},
|
|
105
196
|
packages: {},
|
|
106
197
|
references: {},
|
|
107
|
-
referenceManager
|
|
198
|
+
referenceManager,
|
|
108
199
|
};
|
|
109
200
|
};
|
|
110
201
|
const computePackageLockHash = async (workingDir) => {
|
|
111
202
|
try {
|
|
112
|
-
const packageLockPath = path.join(workingDir,
|
|
113
|
-
|
|
114
|
-
|
|
203
|
+
const packageLockPath = path.join(workingDir, "package-lock.json");
|
|
204
|
+
try {
|
|
205
|
+
const content = await fs.readFile(packageLockPath, "utf-8");
|
|
206
|
+
return createHash("sha256").update(content).digest("hex");
|
|
207
|
+
}
|
|
208
|
+
catch {
|
|
209
|
+
const bunLockPath = path.join(workingDir, "bun.lock");
|
|
210
|
+
const content = await fs.readFile(bunLockPath, "utf-8");
|
|
211
|
+
return createHash("sha256").update(content).digest("hex");
|
|
212
|
+
}
|
|
115
213
|
}
|
|
116
214
|
catch {
|
|
117
215
|
return null;
|
|
@@ -123,15 +221,15 @@ const saveCacheToDisk = async (cache, cacheDir, workingDir) => {
|
|
|
123
221
|
entries: cache.entries,
|
|
124
222
|
packages: cache.packages,
|
|
125
223
|
references: cache.referenceManager.getAllReferences(),
|
|
126
|
-
packageLockHash: packageLockHash || undefined
|
|
224
|
+
packageLockHash: packageLockHash || undefined,
|
|
127
225
|
};
|
|
128
|
-
const cachePath = path.join(cacheDir,
|
|
226
|
+
const cachePath = path.join(cacheDir, "index.json");
|
|
129
227
|
await fs.writeFile(cachePath, JSON.stringify(cacheData, null, 2));
|
|
130
228
|
};
|
|
131
229
|
const loadCacheFromDisk = async (cacheDir) => {
|
|
132
230
|
try {
|
|
133
|
-
const cachePath = path.join(cacheDir,
|
|
134
|
-
const content = await fs.readFile(cachePath,
|
|
231
|
+
const cachePath = path.join(cacheDir, "index.json");
|
|
232
|
+
const content = await fs.readFile(cachePath, "utf-8");
|
|
135
233
|
return JSON.parse(content);
|
|
136
234
|
}
|
|
137
235
|
catch {
|
|
@@ -140,23 +238,37 @@ const loadCacheFromDisk = async (cacheDir) => {
|
|
|
140
238
|
};
|
|
141
239
|
const installPackages = async (packages, workingDir, registry) => {
|
|
142
240
|
await ensureDir(workingDir);
|
|
143
|
-
const packageJsonPath = path.join(workingDir,
|
|
241
|
+
const packageJsonPath = path.join(workingDir, "package.json");
|
|
144
242
|
if (!(await fileExists(packageJsonPath))) {
|
|
145
243
|
const minimalPackageJson = {
|
|
146
244
|
name: "fhir-canonical-manager-workspace",
|
|
147
245
|
version: "1.0.0",
|
|
148
246
|
private: true,
|
|
149
|
-
dependencies: {}
|
|
247
|
+
dependencies: {},
|
|
150
248
|
};
|
|
151
249
|
await fs.writeFile(packageJsonPath, JSON.stringify(minimalPackageJson, null, 2));
|
|
152
250
|
}
|
|
251
|
+
const packageManager = await detectPackageManager();
|
|
252
|
+
if (!packageManager) {
|
|
253
|
+
throw new Error("No package manager found. Please install npm or bun.");
|
|
254
|
+
}
|
|
153
255
|
for (const pkg of packages) {
|
|
154
256
|
try {
|
|
155
|
-
if (
|
|
156
|
-
|
|
257
|
+
if (packageManager === "bun") {
|
|
258
|
+
const env = {
|
|
259
|
+
HOME: workingDir,
|
|
260
|
+
NPM_CONFIG_USERCONFIG: "/dev/null",
|
|
261
|
+
};
|
|
262
|
+
const cmd = registry
|
|
263
|
+
? `cd ${workingDir} && bun add ${pkg} --registry ${registry}`
|
|
264
|
+
: `cd ${workingDir} && bun add ${pkg}`;
|
|
265
|
+
await $ `${cmd}`.env(env);
|
|
157
266
|
}
|
|
158
267
|
else {
|
|
159
|
-
|
|
268
|
+
const cmd = registry
|
|
269
|
+
? `cd ${workingDir} && npm add ${pkg} --registry ${registry}`
|
|
270
|
+
: `cd ${workingDir} && npm add ${pkg}`;
|
|
271
|
+
await $ `${cmd}`;
|
|
160
272
|
}
|
|
161
273
|
}
|
|
162
274
|
catch (err) {
|
|
@@ -166,9 +278,9 @@ const installPackages = async (packages, workingDir, registry) => {
|
|
|
166
278
|
}
|
|
167
279
|
};
|
|
168
280
|
const processIndex = async (basePath, packageJson, cache) => {
|
|
169
|
-
const indexPath = path.join(basePath,
|
|
281
|
+
const indexPath = path.join(basePath, ".index.json");
|
|
170
282
|
try {
|
|
171
|
-
const indexContent = await fs.readFile(indexPath,
|
|
283
|
+
const indexContent = await fs.readFile(indexPath, "utf-8");
|
|
172
284
|
const index = parseIndex(indexContent, indexPath);
|
|
173
285
|
if (!index)
|
|
174
286
|
return;
|
|
@@ -179,7 +291,7 @@ const processIndex = async (basePath, packageJson, cache) => {
|
|
|
179
291
|
const id = cache.referenceManager.generateId({
|
|
180
292
|
packageName: packageJson.name,
|
|
181
293
|
packageVersion: packageJson.version,
|
|
182
|
-
filePath
|
|
294
|
+
filePath,
|
|
183
295
|
});
|
|
184
296
|
cache.referenceManager.set(id, {
|
|
185
297
|
packageName: packageJson.name,
|
|
@@ -187,20 +299,20 @@ const processIndex = async (basePath, packageJson, cache) => {
|
|
|
187
299
|
filePath,
|
|
188
300
|
resourceType: file.resourceType,
|
|
189
301
|
url: file.url,
|
|
190
|
-
version: file.version
|
|
302
|
+
version: file.version,
|
|
191
303
|
});
|
|
192
304
|
const entry = {
|
|
193
305
|
id,
|
|
194
306
|
resourceType: file.resourceType,
|
|
195
|
-
indexVersion: index[
|
|
307
|
+
indexVersion: index["index-version"],
|
|
196
308
|
url: file.url,
|
|
197
309
|
version: file.version,
|
|
198
310
|
kind: file.kind,
|
|
199
311
|
type: file.type,
|
|
200
312
|
package: {
|
|
201
313
|
name: packageJson.name,
|
|
202
|
-
version: packageJson.version
|
|
203
|
-
}
|
|
314
|
+
version: packageJson.version,
|
|
315
|
+
},
|
|
204
316
|
};
|
|
205
317
|
if (!cache.entries[file.url]) {
|
|
206
318
|
cache.entries[file.url] = [];
|
|
@@ -216,19 +328,19 @@ const processIndex = async (basePath, packageJson, cache) => {
|
|
|
216
328
|
};
|
|
217
329
|
const scanPackage = async (packagePath, cache) => {
|
|
218
330
|
try {
|
|
219
|
-
const packageJsonPath = path.join(packagePath,
|
|
220
|
-
const packageJsonContent = await fs.readFile(packageJsonPath,
|
|
331
|
+
const packageJsonPath = path.join(packagePath, "package.json");
|
|
332
|
+
const packageJsonContent = await fs.readFile(packageJsonPath, "utf-8");
|
|
221
333
|
const packageJson = JSON.parse(packageJsonContent);
|
|
222
334
|
const packageInfo = {
|
|
223
335
|
id: { name: packageJson.name, version: packageJson.version },
|
|
224
336
|
path: packagePath,
|
|
225
337
|
canonical: packageJson.canonical,
|
|
226
|
-
fhirVersions: packageJson.fhirVersions
|
|
338
|
+
fhirVersions: packageJson.fhirVersions,
|
|
227
339
|
};
|
|
228
340
|
cache.packages[packageJson.name] = packageInfo;
|
|
229
341
|
await processIndex(packagePath, packageJson, cache);
|
|
230
|
-
const examplesPath = path.join(packagePath,
|
|
231
|
-
if (await fileExists(path.join(examplesPath,
|
|
342
|
+
const examplesPath = path.join(packagePath, "examples");
|
|
343
|
+
if (await fileExists(path.join(examplesPath, ".index.json"))) {
|
|
232
344
|
await processIndex(examplesPath, packageJson, cache);
|
|
233
345
|
}
|
|
234
346
|
}
|
|
@@ -242,8 +354,10 @@ const scanDirectory = async (dirPath, cache) => {
|
|
|
242
354
|
if (!entry.isDirectory())
|
|
243
355
|
continue;
|
|
244
356
|
const fullPath = path.join(dirPath, entry.name);
|
|
245
|
-
if (entry.name.startsWith(
|
|
246
|
-
const scopedEntries = await fs.readdir(fullPath, {
|
|
357
|
+
if (entry.name.startsWith("@")) {
|
|
358
|
+
const scopedEntries = await fs.readdir(fullPath, {
|
|
359
|
+
withFileTypes: true,
|
|
360
|
+
});
|
|
247
361
|
for (const scopedEntry of scopedEntries) {
|
|
248
362
|
if (!scopedEntry.isDirectory())
|
|
249
363
|
continue;
|
|
@@ -266,7 +380,7 @@ const resolveWithContext = async (url, context, cache, resolveEntry) => {
|
|
|
266
380
|
try {
|
|
267
381
|
return await resolveEntry(url, {
|
|
268
382
|
package: context.package.name,
|
|
269
|
-
version: context.package.version
|
|
383
|
+
version: context.package.version,
|
|
270
384
|
});
|
|
271
385
|
}
|
|
272
386
|
catch {
|
|
@@ -274,16 +388,19 @@ const resolveWithContext = async (url, context, cache, resolveEntry) => {
|
|
|
274
388
|
}
|
|
275
389
|
return null;
|
|
276
390
|
};
|
|
277
|
-
const DEFAULT_REGISTRY =
|
|
391
|
+
const DEFAULT_REGISTRY = "https://fs.get-ig.org/pkgs/";
|
|
278
392
|
export const CanonicalManager = (config) => {
|
|
279
|
-
const { packages, workingDir
|
|
280
|
-
const
|
|
281
|
-
|
|
393
|
+
const { packages, workingDir } = config;
|
|
394
|
+
const registry = config.registry
|
|
395
|
+
? config.registry.endsWith('/') ? config.registry : `${config.registry}/`
|
|
396
|
+
: DEFAULT_REGISTRY;
|
|
397
|
+
const nodeModulesPath = path.join(workingDir, "node_modules");
|
|
398
|
+
const cacheDir = path.join(workingDir, ".fcm", "cache");
|
|
282
399
|
let cache = createCache();
|
|
283
400
|
let initialized = false;
|
|
284
401
|
const ensureInitialized = () => {
|
|
285
402
|
if (!initialized) {
|
|
286
|
-
throw new Error(
|
|
403
|
+
throw new Error("CanonicalManager not initialized. Call init() first.");
|
|
287
404
|
}
|
|
288
405
|
};
|
|
289
406
|
const init = async () => {
|
|
@@ -305,7 +422,7 @@ export const CanonicalManager = (config) => {
|
|
|
305
422
|
}
|
|
306
423
|
else {
|
|
307
424
|
if (cachedData && cachedData.packageLockHash !== currentPackageLockHash) {
|
|
308
|
-
console.log(
|
|
425
|
+
console.log("Package dependencies have changed, rebuilding index...");
|
|
309
426
|
}
|
|
310
427
|
await installPackages(packages, workingDir, registry);
|
|
311
428
|
cache = createCache();
|
|
@@ -322,7 +439,7 @@ export const CanonicalManager = (config) => {
|
|
|
322
439
|
};
|
|
323
440
|
const getPackages = async () => {
|
|
324
441
|
ensureInitialized();
|
|
325
|
-
return Object.values(cache.packages).map(p => p.id);
|
|
442
|
+
return Object.values(cache.packages).map((p) => p.id);
|
|
326
443
|
};
|
|
327
444
|
const resolveEntry = async (canonicalUrl, options) => {
|
|
328
445
|
ensureInitialized();
|
|
@@ -338,10 +455,10 @@ export const CanonicalManager = (config) => {
|
|
|
338
455
|
}
|
|
339
456
|
let filtered = [...entries];
|
|
340
457
|
if (options?.package) {
|
|
341
|
-
filtered = filtered.filter(e => e.package?.name === options.package);
|
|
458
|
+
filtered = filtered.filter((e) => e.package?.name === options.package);
|
|
342
459
|
}
|
|
343
460
|
if (options?.version) {
|
|
344
|
-
filtered = filtered.filter(e => e.version === options.version);
|
|
461
|
+
filtered = filtered.filter((e) => e.version === options.version);
|
|
345
462
|
}
|
|
346
463
|
if (filtered.length === 0) {
|
|
347
464
|
throw new Error(`No matching resource found for ${canonicalUrl} with given options`);
|
|
@@ -359,12 +476,12 @@ export const CanonicalManager = (config) => {
|
|
|
359
476
|
throw new Error(`Invalid reference ID: ${reference.id}`);
|
|
360
477
|
}
|
|
361
478
|
try {
|
|
362
|
-
const content = await fs.readFile(metadata.filePath,
|
|
479
|
+
const content = await fs.readFile(metadata.filePath, "utf-8");
|
|
363
480
|
const resource = JSON.parse(content);
|
|
364
481
|
return {
|
|
365
482
|
...resource,
|
|
366
483
|
id: reference.id,
|
|
367
|
-
resourceType: reference.resourceType
|
|
484
|
+
resourceType: reference.resourceType,
|
|
368
485
|
};
|
|
369
486
|
}
|
|
370
487
|
catch (err) {
|
|
@@ -383,26 +500,83 @@ export const CanonicalManager = (config) => {
|
|
|
383
500
|
}
|
|
384
501
|
}
|
|
385
502
|
if (params.kind !== undefined) {
|
|
386
|
-
results = results.filter(e => e.kind === params.kind);
|
|
503
|
+
results = results.filter((e) => e.kind === params.kind);
|
|
387
504
|
}
|
|
388
505
|
if (params.type !== undefined) {
|
|
389
|
-
results = results.filter(e => e.type === params.type);
|
|
506
|
+
results = results.filter((e) => e.type === params.type);
|
|
390
507
|
}
|
|
391
508
|
if (params.version !== undefined) {
|
|
392
|
-
results = results.filter(e => e.version === params.version);
|
|
509
|
+
results = results.filter((e) => e.version === params.version);
|
|
393
510
|
}
|
|
394
511
|
if (params.package) {
|
|
395
512
|
const pkg = params.package;
|
|
396
|
-
results = results.filter(e => e.package?.name === pkg.name &&
|
|
397
|
-
e.package?.version === pkg.version);
|
|
513
|
+
results = results.filter((e) => e.package?.name === pkg.name && e.package?.version === pkg.version);
|
|
398
514
|
}
|
|
399
515
|
return results;
|
|
400
516
|
};
|
|
401
517
|
const search = async (params) => {
|
|
402
518
|
const entries = await searchEntries(params);
|
|
403
|
-
const resources = await Promise.all(entries.map(entry => read(entry)));
|
|
519
|
+
const resources = await Promise.all(entries.map((entry) => read(entry)));
|
|
404
520
|
return resources;
|
|
405
521
|
};
|
|
522
|
+
const smartSearch = async (searchTerms, filters) => {
|
|
523
|
+
ensureInitialized();
|
|
524
|
+
let results = await searchEntries({
|
|
525
|
+
kind: filters?.kind,
|
|
526
|
+
package: filters?.package,
|
|
527
|
+
});
|
|
528
|
+
if (filters?.resourceType) {
|
|
529
|
+
results = results.filter(entry => entry.resourceType === filters.resourceType);
|
|
530
|
+
}
|
|
531
|
+
if (filters?.type) {
|
|
532
|
+
results = results.filter(entry => entry.type === filters.type);
|
|
533
|
+
}
|
|
534
|
+
if (searchTerms.length > 0) {
|
|
535
|
+
const terms = searchTerms.map(t => t.toLowerCase());
|
|
536
|
+
results = results.filter(entry => {
|
|
537
|
+
if (!entry.url)
|
|
538
|
+
return false;
|
|
539
|
+
const urlLower = entry.url.toLowerCase();
|
|
540
|
+
const fullText = [
|
|
541
|
+
urlLower,
|
|
542
|
+
entry.type?.toLowerCase() || '',
|
|
543
|
+
entry.resourceType?.toLowerCase() || ''
|
|
544
|
+
].join(' ');
|
|
545
|
+
return terms.every(term => {
|
|
546
|
+
const allParts = fullText.split(/[\/\-_\.\s]+/);
|
|
547
|
+
const directMatch = allParts.some(part => part.startsWith(term));
|
|
548
|
+
if (directMatch)
|
|
549
|
+
return true;
|
|
550
|
+
const expandedTerms = {
|
|
551
|
+
'str': ['structure'],
|
|
552
|
+
'struct': ['structure'],
|
|
553
|
+
'def': ['definition'],
|
|
554
|
+
'pati': ['patient'],
|
|
555
|
+
'obs': ['observation'],
|
|
556
|
+
'org': ['organization'],
|
|
557
|
+
'pract': ['practitioner'],
|
|
558
|
+
'med': ['medication', 'medicinal'],
|
|
559
|
+
'req': ['request'],
|
|
560
|
+
'resp': ['response'],
|
|
561
|
+
'ref': ['reference'],
|
|
562
|
+
'val': ['value'],
|
|
563
|
+
'code': ['codesystem', 'code'],
|
|
564
|
+
'cs': ['codesystem'],
|
|
565
|
+
'vs': ['valueset'],
|
|
566
|
+
'sd': ['structuredefinition'],
|
|
567
|
+
};
|
|
568
|
+
const expansions = expandedTerms[term] || [];
|
|
569
|
+
for (const expansion of expansions) {
|
|
570
|
+
if (allParts.some(part => part.startsWith(expansion))) {
|
|
571
|
+
return true;
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
return fullText.includes(term);
|
|
575
|
+
});
|
|
576
|
+
});
|
|
577
|
+
}
|
|
578
|
+
return results;
|
|
579
|
+
};
|
|
406
580
|
return {
|
|
407
581
|
init,
|
|
408
582
|
destroy,
|
|
@@ -411,7 +585,8 @@ export const CanonicalManager = (config) => {
|
|
|
411
585
|
resolve,
|
|
412
586
|
read,
|
|
413
587
|
searchEntries,
|
|
414
|
-
search
|
|
588
|
+
search,
|
|
589
|
+
smartSearch,
|
|
415
590
|
};
|
|
416
591
|
};
|
|
417
592
|
export default CanonicalManager;
|