@atomic-ehr/fhir-canonical-manager 0.0.13 → 0.0.14
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/dist/cache.d.ts +16 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +49 -0
- package/dist/cache.js.map +1 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +15 -15
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/init.d.ts.map +1 -1
- package/dist/cli/init.js +7 -10
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/list.d.ts.map +1 -1
- package/dist/cli/list.js +14 -10
- package/dist/cli/list.js.map +1 -1
- package/dist/cli/resolve.js +7 -7
- package/dist/cli/resolve.js.map +1 -1
- package/dist/cli/search.js +9 -9
- package/dist/cli/search.js.map +1 -1
- package/dist/cli/searchparam.d.ts.map +1 -1
- package/dist/cli/searchparam.js +27 -24
- package/dist/cli/searchparam.js.map +1 -1
- package/dist/fs/index.d.ts +1 -1
- package/dist/fs/index.d.ts.map +1 -1
- package/dist/fs/index.js +1 -1
- package/dist/fs/index.js.map +1 -1
- package/dist/fs/utils.js +2 -2
- package/dist/fs/utils.js.map +1 -1
- package/dist/index.d.ts +6 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/dist/manager/canonical.d.ts +1 -1
- package/dist/manager/canonical.d.ts.map +1 -1
- package/dist/manager/canonical.js +46 -42
- package/dist/manager/canonical.js.map +1 -1
- package/dist/manager/index.d.ts +1 -2
- package/dist/manager/index.d.ts.map +1 -1
- package/dist/manager/index.js +1 -2
- package/dist/manager/index.js.map +1 -1
- package/dist/package.d.ts +4 -0
- package/dist/package.d.ts.map +1 -0
- package/dist/package.js +69 -0
- package/dist/package.js.map +1 -0
- package/dist/reference/index.d.ts +3 -4
- package/dist/reference/index.d.ts.map +1 -1
- package/dist/reference/index.js +2 -3
- package/dist/reference/index.js.map +1 -1
- package/dist/reference/manager.d.ts +2 -2
- package/dist/reference/manager.d.ts.map +1 -1
- package/dist/reference/manager.js +7 -3
- package/dist/reference/manager.js.map +1 -1
- package/dist/reference/store.d.ts.map +1 -1
- package/dist/reference/store.js +1 -1
- package/dist/reference/store.js.map +1 -1
- package/dist/resolver/context.d.ts +3 -3
- package/dist/resolver/context.d.ts.map +1 -1
- package/dist/resolver/context.js +1 -1
- package/dist/resolver/context.js.map +1 -1
- package/dist/resolver/index.d.ts +1 -1
- package/dist/resolver/index.js +1 -1
- package/dist/scanner/directory.d.ts +2 -2
- package/dist/scanner/directory.d.ts.map +1 -1
- package/dist/scanner/directory.js +24 -27
- package/dist/scanner/directory.js.map +1 -1
- package/dist/scanner/index.d.ts +4 -4
- package/dist/scanner/index.d.ts.map +1 -1
- package/dist/scanner/index.js +4 -4
- package/dist/scanner/index.js.map +1 -1
- package/dist/scanner/package.d.ts +1 -1
- package/dist/scanner/package.d.ts.map +1 -1
- package/dist/scanner/package.js +4 -4
- package/dist/scanner/package.js.map +1 -1
- package/dist/scanner/parser.d.ts +2 -2
- package/dist/scanner/parser.d.ts.map +1 -1
- package/dist/scanner/parser.js +1 -1
- package/dist/scanner/parser.js.map +1 -1
- package/dist/scanner/processor.d.ts +2 -2
- package/dist/scanner/processor.d.ts.map +1 -1
- package/dist/scanner/processor.js +3 -3
- package/dist/scanner/processor.js.map +1 -1
- package/dist/search/index.d.ts +2 -2
- package/dist/search/index.d.ts.map +1 -1
- package/dist/search/index.js +2 -2
- package/dist/search/index.js.map +1 -1
- package/dist/search/smart.d.ts +1 -1
- package/dist/search/smart.d.ts.map +1 -1
- package/dist/search/smart.js +3 -7
- package/dist/search/smart.js.map +1 -1
- package/dist/search/terms.js.map +1 -1
- package/dist/types/core.d.ts +3 -2
- package/dist/types/core.d.ts.map +1 -1
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.js +2 -2
- package/dist/types/internal.d.ts +7 -4
- package/dist/types/internal.d.ts.map +1 -1
- package/package.json +12 -2
- package/src/cache.ts +58 -0
- package/src/cli/index.ts +112 -114
- package/src/cli/init.ts +104 -108
- package/src/cli/list.ts +84 -77
- package/src/cli/resolve.ts +57 -57
- package/src/cli/search.ts +72 -72
- package/src/cli/searchparam.ts +118 -117
- package/src/constants.ts +1 -1
- package/src/fs/index.ts +1 -1
- package/src/fs/utils.ts +16 -16
- package/src/index.ts +9 -12
- package/src/manager/canonical.ts +317 -360
- package/src/manager/index.ts +1 -3
- package/src/package.ts +79 -0
- package/src/reference/index.ts +3 -5
- package/src/reference/manager.ts +43 -39
- package/src/reference/store.ts +7 -8
- package/src/resolver/context.ts +17 -17
- package/src/resolver/index.ts +1 -1
- package/src/scanner/directory.ts +25 -31
- package/src/scanner/index.ts +4 -4
- package/src/scanner/package.ts +26 -29
- package/src/scanner/parser.ts +25 -27
- package/src/scanner/processor.ts +51 -55
- package/src/search/index.ts +2 -2
- package/src/search/smart.ts +41 -48
- package/src/search/terms.ts +17 -17
- package/src/types/core.ts +102 -89
- package/src/types/index.ts +2 -2
- package/src/types/internal.ts +36 -34
- package/dist/cache/core.d.ts +0 -7
- package/dist/cache/core.d.ts.map +0 -1
- package/dist/cache/core.js +0 -11
- package/dist/cache/core.js.map +0 -1
- package/dist/cache/index.d.ts +0 -4
- package/dist/cache/index.d.ts.map +0 -1
- package/dist/cache/index.js +0 -4
- package/dist/cache/index.js.map +0 -1
- package/dist/cache/persistence.d.ts +0 -5
- package/dist/cache/persistence.d.ts.map +0 -1
- package/dist/cache/persistence.js +0 -25
- package/dist/cache/persistence.js.map +0 -1
- package/dist/cache/validation.d.ts +0 -2
- package/dist/cache/validation.d.ts.map +0 -1
- package/dist/cache/validation.js +0 -21
- package/dist/cache/validation.js.map +0 -1
- package/dist/package/detector.d.ts +0 -2
- package/dist/package/detector.d.ts.map +0 -1
- package/dist/package/detector.js +0 -19
- package/dist/package/detector.js.map +0 -1
- package/dist/package/index.d.ts +0 -3
- package/dist/package/index.d.ts.map +0 -1
- package/dist/package/index.js +0 -3
- package/dist/package/index.js.map +0 -1
- package/dist/package/installer.d.ts +0 -2
- package/dist/package/installer.d.ts.map +0 -1
- package/dist/package/installer.js +0 -55
- package/dist/package/installer.js.map +0 -1
- package/src/cache/core.ts +0 -20
- package/src/cache/index.ts +0 -7
- package/src/cache/persistence.ts +0 -39
- package/src/cache/validation.ts +0 -27
- package/src/package/detector.ts +0 -24
- package/src/package/index.ts +0 -6
- package/src/package/installer.ts +0 -77
package/src/package.ts
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Package management functionality
|
|
3
|
+
* Merged from package/detector.ts, package/installer.ts, and package/index.ts
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { exec } from "node:child_process";
|
|
7
|
+
import * as afs from "node:fs/promises";
|
|
8
|
+
import * as Path from "node:path";
|
|
9
|
+
import { promisify } from "node:util";
|
|
10
|
+
import { ensureDir, fileExists } from "./fs/index.js";
|
|
11
|
+
|
|
12
|
+
const execAsync = promisify(exec);
|
|
13
|
+
|
|
14
|
+
export type PackageManager = "bun" | "npm";
|
|
15
|
+
|
|
16
|
+
export const detectPackageManager = async (): Promise<PackageManager | undefined> => {
|
|
17
|
+
try {
|
|
18
|
+
await execAsync("bun --version");
|
|
19
|
+
return "bun";
|
|
20
|
+
} catch {
|
|
21
|
+
try {
|
|
22
|
+
await execAsync("npm --version");
|
|
23
|
+
return "npm";
|
|
24
|
+
} catch {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const ensurePackageJson = async (pwd: string) => {
|
|
31
|
+
const packageJsonPath = Path.join(pwd, "package.json");
|
|
32
|
+
if (!(await fileExists(packageJsonPath))) {
|
|
33
|
+
const minimalPackageJson = {
|
|
34
|
+
name: "fhir-canonical-manager-workspace",
|
|
35
|
+
version: "1.0.0",
|
|
36
|
+
private: true,
|
|
37
|
+
dependencies: {},
|
|
38
|
+
};
|
|
39
|
+
await afs.writeFile(packageJsonPath, JSON.stringify(minimalPackageJson, null, 2));
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export const installPackages = async (packages: string[], pwd: string, registry?: string): Promise<void> => {
|
|
44
|
+
await ensureDir(pwd);
|
|
45
|
+
ensurePackageJson(pwd);
|
|
46
|
+
|
|
47
|
+
const packageManager = await detectPackageManager();
|
|
48
|
+
if (!packageManager) throw new Error("No package manager found. Please install bun or npm.");
|
|
49
|
+
|
|
50
|
+
for (const pkg of packages) {
|
|
51
|
+
try {
|
|
52
|
+
if (packageManager === "bun") {
|
|
53
|
+
// Use bun with auth bypass trick for FHIR registry
|
|
54
|
+
const env = {
|
|
55
|
+
...process.env,
|
|
56
|
+
HOME: pwd, // Prevent reading user's .npmrc
|
|
57
|
+
NPM_CONFIG_USERCONFIG: "/dev/null", // Extra safety
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const cmd = registry
|
|
61
|
+
? `bun add ${pkg} --cwd='${pwd}' --registry='${registry}'`
|
|
62
|
+
: `bun add --cwd='${pwd}' ${pkg}`;
|
|
63
|
+
await execAsync(cmd, {
|
|
64
|
+
env,
|
|
65
|
+
maxBuffer: 10 * 1024 * 1024, // 10MB buffer
|
|
66
|
+
});
|
|
67
|
+
} else {
|
|
68
|
+
// Use npm (handles auth correctly)
|
|
69
|
+
const cmd = registry ? `cd ${pwd} && npm add ${pkg} --registry=${registry}` : `npm add ${pkg}`;
|
|
70
|
+
await execAsync(cmd, {
|
|
71
|
+
maxBuffer: 10 * 1024 * 1024, // 10MB buffer
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
} catch (err) {
|
|
75
|
+
console.error(`Failed to install package ${pkg}:`, err);
|
|
76
|
+
throw err;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
};
|
package/src/reference/index.ts
CHANGED
|
@@ -2,9 +2,7 @@
|
|
|
2
2
|
* Reference management exports
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
export {
|
|
6
|
-
export { createReferenceManager } from './manager.js';
|
|
7
|
-
export type { ReferenceManager } from './manager.js';
|
|
8
|
-
|
|
5
|
+
export type { ReferenceManager } from "./manager.js";
|
|
9
6
|
// For backward compatibility - function alias (will be deprecated)
|
|
10
|
-
export { createReferenceManager as ReferenceManagerFactory } from
|
|
7
|
+
export { createReferenceManager, createReferenceManager as ReferenceManagerFactory } from "./manager.js";
|
|
8
|
+
export { generateReferenceId } from "./store.js";
|
package/src/reference/manager.ts
CHANGED
|
@@ -2,50 +2,54 @@
|
|
|
2
2
|
* Reference manager factory
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import type { Reference, ReferenceMetadata, ReferenceStore } from
|
|
6
|
-
import { generateReferenceId } from
|
|
5
|
+
import type { Reference, ReferenceMetadata, ReferenceStore } from "../types/index.js";
|
|
6
|
+
import { generateReferenceId } from "./store.js";
|
|
7
7
|
|
|
8
8
|
export interface ReferenceManager extends ReferenceStore {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
generateId: typeof generateReferenceId;
|
|
10
|
+
getIdsByUrl: (url: string) => string[];
|
|
11
|
+
createReference: (id: string, metadata: ReferenceMetadata) => Reference;
|
|
12
|
+
getAllReferences: () => Record<string, ReferenceMetadata>;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
export const createReferenceManager = (): ReferenceManager => {
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
const references: Record<string, ReferenceMetadata> = {};
|
|
17
|
+
const urlToIds: Record<string, string[]> = {};
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
19
|
+
const set = (id: string, metadata: ReferenceMetadata): void => {
|
|
20
|
+
references[id] = metadata;
|
|
21
|
+
if (metadata.url) {
|
|
22
|
+
if (!urlToIds[metadata.url]) {
|
|
23
|
+
urlToIds[metadata.url] = [];
|
|
24
|
+
}
|
|
25
|
+
const ids = urlToIds[metadata.url];
|
|
26
|
+
if (ids && !ids.includes(id)) {
|
|
27
|
+
ids.push(id);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
const clear = (): void => {
|
|
33
|
+
Object.keys(references).forEach((key) => {
|
|
34
|
+
delete references[key];
|
|
35
|
+
});
|
|
36
|
+
Object.keys(urlToIds).forEach((key) => {
|
|
37
|
+
delete urlToIds[key];
|
|
38
|
+
});
|
|
39
|
+
};
|
|
36
40
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
};
|
|
41
|
+
return {
|
|
42
|
+
generateId: generateReferenceId,
|
|
43
|
+
get: (id: string) => references[id],
|
|
44
|
+
set,
|
|
45
|
+
has: (id: string) => id in references,
|
|
46
|
+
clear,
|
|
47
|
+
size: () => Object.keys(references).length,
|
|
48
|
+
getIdsByUrl: (url: string) => urlToIds[url] || [],
|
|
49
|
+
createReference: (id: string, metadata: ReferenceMetadata): Reference => ({
|
|
50
|
+
id,
|
|
51
|
+
resourceType: metadata.resourceType,
|
|
52
|
+
}),
|
|
53
|
+
getAllReferences: () => references,
|
|
54
|
+
};
|
|
55
|
+
};
|
package/src/reference/store.ts
CHANGED
|
@@ -2,14 +2,13 @@
|
|
|
2
2
|
* Reference store implementation
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import { createHash } from
|
|
6
|
-
import type { ReferenceMetadata, ReferenceStore } from '../types/index.js';
|
|
5
|
+
import { createHash } from "node:crypto";
|
|
7
6
|
|
|
8
7
|
export const generateReferenceId = (metadata: {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
packageName: string;
|
|
9
|
+
packageVersion: string;
|
|
10
|
+
filePath: string;
|
|
12
11
|
}): string => {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
};
|
|
12
|
+
const input = `${metadata.packageName}@${metadata.packageVersion}:${metadata.filePath}`;
|
|
13
|
+
return createHash("sha256").update(input).digest("base64url");
|
|
14
|
+
};
|
package/src/resolver/context.ts
CHANGED
|
@@ -2,24 +2,24 @@
|
|
|
2
2
|
* Context-aware resolution functionality
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import type {
|
|
6
|
-
import type {
|
|
5
|
+
import type { ExtendedCache } from "../cache.js";
|
|
6
|
+
import type { IndexEntry, SourceContext } from "../types/index.js";
|
|
7
7
|
|
|
8
8
|
export const resolveWithContext = async (
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
url: string,
|
|
10
|
+
context: SourceContext,
|
|
11
|
+
_cache: ExtendedCache,
|
|
12
|
+
resolveEntry: (url: string, options?: any) => Promise<IndexEntry>,
|
|
13
13
|
): Promise<IndexEntry | null> => {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
14
|
+
if (context.package) {
|
|
15
|
+
try {
|
|
16
|
+
return await resolveEntry(url, {
|
|
17
|
+
package: context.package.name,
|
|
18
|
+
version: context.package.version,
|
|
19
|
+
});
|
|
20
|
+
} catch {
|
|
21
|
+
// Fall through to global resolution
|
|
22
|
+
}
|
|
22
23
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
};
|
|
24
|
+
return null;
|
|
25
|
+
};
|
package/src/resolver/index.ts
CHANGED
package/src/scanner/directory.ts
CHANGED
|
@@ -2,41 +2,35 @@
|
|
|
2
2
|
* Directory scanning functionality
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import * as fs from
|
|
6
|
-
import * as path from
|
|
7
|
-
import type { ExtendedCache } from
|
|
8
|
-
import { isFhirPackage } from
|
|
9
|
-
import { scanPackage } from
|
|
10
|
-
|
|
11
|
-
export const scanDirectory = async (
|
|
12
|
-
dirPath: string,
|
|
13
|
-
cache: ExtendedCache,
|
|
14
|
-
): Promise<void> => {
|
|
15
|
-
try {
|
|
16
|
-
const entries = await fs.readdir(dirPath, { withFileTypes: true });
|
|
5
|
+
import * as fs from "node:fs/promises";
|
|
6
|
+
import * as path from "node:path";
|
|
7
|
+
import type { ExtendedCache } from "../cache.js";
|
|
8
|
+
import { isFhirPackage } from "../fs/index.js";
|
|
9
|
+
import { scanPackage } from "./package.js";
|
|
17
10
|
|
|
11
|
+
export const scanDirectory = async (cache: ExtendedCache, pwd: string): Promise<void> => {
|
|
12
|
+
const nodeModulesPath = path.join(pwd, "node_modules");
|
|
13
|
+
const entries = await fs.readdir(nodeModulesPath, { withFileTypes: true });
|
|
18
14
|
for (const entry of entries) {
|
|
19
|
-
|
|
15
|
+
if (!entry.isDirectory()) continue;
|
|
16
|
+
|
|
17
|
+
const fullPath = path.join(entry.parentPath, entry.name);
|
|
20
18
|
|
|
21
|
-
|
|
19
|
+
if (entry.name.startsWith("@")) {
|
|
20
|
+
const scopedEntries = await fs.readdir(fullPath, {
|
|
21
|
+
withFileTypes: true,
|
|
22
|
+
});
|
|
23
|
+
for (const scopedEntry of scopedEntries) {
|
|
24
|
+
if (!scopedEntry.isDirectory()) continue;
|
|
22
25
|
|
|
23
|
-
|
|
24
|
-
const scopedEntries = await fs.readdir(fullPath, {
|
|
25
|
-
withFileTypes: true,
|
|
26
|
-
});
|
|
27
|
-
for (const scopedEntry of scopedEntries) {
|
|
28
|
-
if (!scopedEntry.isDirectory()) continue;
|
|
26
|
+
const scopedPath = path.join(fullPath, scopedEntry.name);
|
|
29
27
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
28
|
+
if (await isFhirPackage(scopedPath)) {
|
|
29
|
+
await scanPackage(scopedPath, cache);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
} else if (await isFhirPackage(fullPath)) {
|
|
33
|
+
await scanPackage(fullPath, cache);
|
|
34
34
|
}
|
|
35
|
-
} else if (await isFhirPackage(fullPath)) {
|
|
36
|
-
await scanPackage(fullPath, cache);
|
|
37
|
-
}
|
|
38
35
|
}
|
|
39
|
-
|
|
40
|
-
// Silently ignore scan errors
|
|
41
|
-
}
|
|
42
|
-
};
|
|
36
|
+
};
|
package/src/scanner/index.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Scanner module exports
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
export {
|
|
6
|
-
export {
|
|
7
|
-
export {
|
|
8
|
-
export {
|
|
5
|
+
export { scanDirectory } from "./directory.js";
|
|
6
|
+
export { scanPackage } from "./package.js";
|
|
7
|
+
export { isValidFileEntry, isValidIndexFile, parseIndex } from "./parser.js";
|
|
8
|
+
export { processIndex } from "./processor.js";
|
package/src/scanner/package.ts
CHANGED
|
@@ -2,37 +2,34 @@
|
|
|
2
2
|
* Package scanning functionality
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import * as fs from
|
|
6
|
-
import * as path from
|
|
7
|
-
import type {
|
|
8
|
-
import
|
|
9
|
-
import {
|
|
10
|
-
import { processIndex } from
|
|
5
|
+
import * as fs from "node:fs/promises";
|
|
6
|
+
import * as path from "node:path";
|
|
7
|
+
import type { ExtendedCache } from "../cache.js";
|
|
8
|
+
import { fileExists } from "../fs/index.js";
|
|
9
|
+
import type { PackageInfo, PackageJson } from "../types/index.js";
|
|
10
|
+
import { processIndex } from "./processor.js";
|
|
11
11
|
|
|
12
|
-
export const scanPackage = async (
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const packageJsonPath = path.join(packagePath, "package.json");
|
|
18
|
-
const packageJsonContent = await fs.readFile(packageJsonPath, "utf-8");
|
|
19
|
-
const packageJson: PackageJson = JSON.parse(packageJsonContent);
|
|
12
|
+
export const scanPackage = async (packagePath: string, cache: ExtendedCache): Promise<void> => {
|
|
13
|
+
try {
|
|
14
|
+
const packageJsonPath = path.join(packagePath, "package.json");
|
|
15
|
+
const packageJsonContent = await fs.readFile(packageJsonPath, "utf-8");
|
|
16
|
+
const packageJson: PackageJson = JSON.parse(packageJsonContent);
|
|
20
17
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
18
|
+
const packageInfo: PackageInfo = {
|
|
19
|
+
id: { name: packageJson.name, version: packageJson.version },
|
|
20
|
+
path: packagePath,
|
|
21
|
+
canonical: packageJson.canonical,
|
|
22
|
+
fhirVersions: packageJson.fhirVersions,
|
|
23
|
+
};
|
|
24
|
+
cache.packages[packageJson.name] = packageInfo;
|
|
28
25
|
|
|
29
|
-
|
|
26
|
+
await processIndex(packagePath, packageJson, cache);
|
|
30
27
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
28
|
+
const examplesPath = path.join(packagePath, "examples");
|
|
29
|
+
if (await fileExists(path.join(examplesPath, ".index.json"))) {
|
|
30
|
+
await processIndex(examplesPath, packageJson, cache);
|
|
31
|
+
}
|
|
32
|
+
} catch {
|
|
33
|
+
// Silently ignore package scan errors
|
|
34
34
|
}
|
|
35
|
-
|
|
36
|
-
// Silently ignore package scan errors
|
|
37
|
-
}
|
|
38
|
-
};
|
|
35
|
+
};
|
package/src/scanner/parser.ts
CHANGED
|
@@ -2,41 +2,39 @@
|
|
|
2
2
|
* Index file parsing and validation
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import type { IndexFile
|
|
5
|
+
import type { IndexFile } from "../types/index.js";
|
|
6
6
|
|
|
7
7
|
export const isValidFileEntry = (entry: any): boolean => {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
return false;
|
|
12
|
-
if (!entry.id || typeof entry.id !== "string") return false;
|
|
8
|
+
if (!entry || typeof entry !== "object") return false;
|
|
9
|
+
if (!entry.filename || typeof entry.filename !== "string") return false;
|
|
10
|
+
if (!entry.resourceType || typeof entry.resourceType !== "string") return false;
|
|
11
|
+
if (!entry.id || typeof entry.id !== "string") return false;
|
|
13
12
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
const optionalStringFields = ["url", "version", "kind", "type"];
|
|
14
|
+
for (const field of optionalStringFields) {
|
|
15
|
+
if (entry[field] !== undefined && typeof entry[field] !== "string") {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
18
|
}
|
|
19
|
-
}
|
|
20
19
|
|
|
21
|
-
|
|
20
|
+
return true;
|
|
22
21
|
};
|
|
23
22
|
|
|
24
23
|
export const isValidIndexFile = (data: any): boolean => {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
return false;
|
|
28
|
-
|
|
29
|
-
return data.files.every((file: any) => isValidFileEntry(file));
|
|
24
|
+
if (!data || typeof data !== "object") return false;
|
|
25
|
+
if (!data["index-version"] || typeof data["index-version"] !== "number") return false;
|
|
26
|
+
if (!Array.isArray(data.files)) return false;
|
|
27
|
+
return data.files.every((file: any) => isValidFileEntry(file));
|
|
30
28
|
};
|
|
31
29
|
|
|
32
|
-
export const parseIndex = (content: string,
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
30
|
+
export const parseIndex = (content: string, _filePath: string): IndexFile | null => {
|
|
31
|
+
try {
|
|
32
|
+
const data = JSON.parse(content);
|
|
33
|
+
if (!isValidIndexFile(data)) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
return data as IndexFile;
|
|
37
|
+
} catch {
|
|
38
|
+
return null;
|
|
37
39
|
}
|
|
38
|
-
|
|
39
|
-
} catch {
|
|
40
|
-
return null;
|
|
41
|
-
}
|
|
42
|
-
};
|
|
40
|
+
};
|
package/src/scanner/processor.ts
CHANGED
|
@@ -2,68 +2,64 @@
|
|
|
2
2
|
* Index processing functionality
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import * as fs from
|
|
6
|
-
import * as path from
|
|
7
|
-
import type {
|
|
8
|
-
import type {
|
|
9
|
-
import { parseIndex } from
|
|
5
|
+
import * as fs from "node:fs/promises";
|
|
6
|
+
import * as path from "node:path";
|
|
7
|
+
import type { ExtendedCache } from "../cache.js";
|
|
8
|
+
import type { IndexEntry, PackageJson } from "../types/index.js";
|
|
9
|
+
import { parseIndex } from "./parser.js";
|
|
10
10
|
|
|
11
|
-
export const processIndex = async (
|
|
12
|
-
|
|
13
|
-
packageJson: PackageJson,
|
|
14
|
-
cache: ExtendedCache,
|
|
15
|
-
): Promise<void> => {
|
|
16
|
-
const indexPath = path.join(basePath, ".index.json");
|
|
11
|
+
export const processIndex = async (basePath: string, packageJson: PackageJson, cache: ExtendedCache): Promise<void> => {
|
|
12
|
+
const indexPath = path.join(basePath, ".index.json");
|
|
17
13
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
14
|
+
try {
|
|
15
|
+
const indexContent = await fs.readFile(indexPath, "utf-8");
|
|
16
|
+
const index = parseIndex(indexContent, indexPath);
|
|
21
17
|
|
|
22
|
-
|
|
18
|
+
if (!index) return;
|
|
23
19
|
|
|
24
|
-
|
|
25
|
-
|
|
20
|
+
for (const file of index.files) {
|
|
21
|
+
if (!file.url) continue;
|
|
26
22
|
|
|
27
|
-
|
|
23
|
+
const filePath = path.join(basePath, file.filename);
|
|
28
24
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
25
|
+
const id = cache.referenceManager.generateId({
|
|
26
|
+
packageName: packageJson.name,
|
|
27
|
+
packageVersion: packageJson.version,
|
|
28
|
+
filePath,
|
|
29
|
+
});
|
|
34
30
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
31
|
+
cache.referenceManager.set(id, {
|
|
32
|
+
packageName: packageJson.name,
|
|
33
|
+
packageVersion: packageJson.version,
|
|
34
|
+
filePath,
|
|
35
|
+
resourceType: file.resourceType,
|
|
36
|
+
url: file.url,
|
|
37
|
+
version: file.version,
|
|
38
|
+
});
|
|
43
39
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
40
|
+
const entry: IndexEntry = {
|
|
41
|
+
id,
|
|
42
|
+
resourceType: file.resourceType,
|
|
43
|
+
indexVersion: index["index-version"],
|
|
44
|
+
url: file.url,
|
|
45
|
+
version: file.version,
|
|
46
|
+
kind: file.kind,
|
|
47
|
+
type: file.type,
|
|
48
|
+
package: {
|
|
49
|
+
name: packageJson.name,
|
|
50
|
+
version: packageJson.version,
|
|
51
|
+
},
|
|
52
|
+
};
|
|
57
53
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
54
|
+
if (!cache.entries[file.url]) {
|
|
55
|
+
cache.entries[file.url] = [];
|
|
56
|
+
}
|
|
57
|
+
const entries = cache.entries[file.url];
|
|
58
|
+
if (entries) {
|
|
59
|
+
entries.push(entry);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
} catch {
|
|
63
|
+
// Silently ignore index processing errors
|
|
65
64
|
}
|
|
66
|
-
|
|
67
|
-
// Silently ignore index processing errors
|
|
68
|
-
}
|
|
69
|
-
};
|
|
65
|
+
};
|
package/src/search/index.ts
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
* Search module exports
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
export {
|
|
6
|
-
export {
|
|
5
|
+
export { filterBySmartSearch, type SmartSearchFilters } from "./smart.js";
|
|
6
|
+
export { expandedTerms } from "./terms.js";
|