@atomic-ehr/fhir-canonical-manager 0.0.13 → 0.0.15

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 (170) hide show
  1. package/dist/cache.d.ts +17 -0
  2. package/dist/cache.d.ts.map +1 -0
  3. package/dist/cache.js +50 -0
  4. package/dist/cache.js.map +1 -0
  5. package/dist/cli/index.d.ts.map +1 -1
  6. package/dist/cli/index.js +15 -15
  7. package/dist/cli/index.js.map +1 -1
  8. package/dist/cli/init.d.ts.map +1 -1
  9. package/dist/cli/init.js +7 -10
  10. package/dist/cli/init.js.map +1 -1
  11. package/dist/cli/list.d.ts.map +1 -1
  12. package/dist/cli/list.js +14 -10
  13. package/dist/cli/list.js.map +1 -1
  14. package/dist/cli/resolve.js +7 -7
  15. package/dist/cli/resolve.js.map +1 -1
  16. package/dist/cli/search.js +9 -9
  17. package/dist/cli/search.js.map +1 -1
  18. package/dist/cli/searchparam.d.ts.map +1 -1
  19. package/dist/cli/searchparam.js +27 -24
  20. package/dist/cli/searchparam.js.map +1 -1
  21. package/dist/fs/index.d.ts +1 -1
  22. package/dist/fs/index.d.ts.map +1 -1
  23. package/dist/fs/index.js +1 -1
  24. package/dist/fs/index.js.map +1 -1
  25. package/dist/fs/utils.js +2 -2
  26. package/dist/fs/utils.js.map +1 -1
  27. package/dist/index.d.ts +6 -6
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +4 -4
  30. package/dist/index.js.map +1 -1
  31. package/dist/manager/canonical.d.ts +1 -1
  32. package/dist/manager/canonical.d.ts.map +1 -1
  33. package/dist/manager/canonical.js +77 -45
  34. package/dist/manager/canonical.js.map +1 -1
  35. package/dist/manager/index.d.ts +1 -2
  36. package/dist/manager/index.d.ts.map +1 -1
  37. package/dist/manager/index.js +1 -2
  38. package/dist/manager/index.js.map +1 -1
  39. package/dist/package.d.ts +4 -0
  40. package/dist/package.d.ts.map +1 -0
  41. package/dist/package.js +69 -0
  42. package/dist/package.js.map +1 -0
  43. package/dist/{reference/manager.d.ts → reference.d.ts} +8 -3
  44. package/dist/reference.d.ts.map +1 -0
  45. package/dist/{reference/manager.js → reference.js} +13 -4
  46. package/dist/reference.js.map +1 -0
  47. package/dist/resolver.d.ts +4 -0
  48. package/dist/resolver.d.ts.map +1 -0
  49. package/dist/{resolver/context.js → resolver.js} +2 -2
  50. package/dist/resolver.js.map +1 -0
  51. package/dist/scanner/directory.d.ts +2 -2
  52. package/dist/scanner/directory.d.ts.map +1 -1
  53. package/dist/scanner/directory.js +24 -27
  54. package/dist/scanner/directory.js.map +1 -1
  55. package/dist/scanner/index.d.ts +4 -4
  56. package/dist/scanner/index.d.ts.map +1 -1
  57. package/dist/scanner/index.js +4 -4
  58. package/dist/scanner/index.js.map +1 -1
  59. package/dist/scanner/package.d.ts +1 -1
  60. package/dist/scanner/package.d.ts.map +1 -1
  61. package/dist/scanner/package.js +4 -4
  62. package/dist/scanner/package.js.map +1 -1
  63. package/dist/scanner/parser.d.ts +2 -2
  64. package/dist/scanner/parser.d.ts.map +1 -1
  65. package/dist/scanner/parser.js +1 -1
  66. package/dist/scanner/parser.js.map +1 -1
  67. package/dist/scanner/processor.d.ts +2 -2
  68. package/dist/scanner/processor.d.ts.map +1 -1
  69. package/dist/scanner/processor.js +3 -3
  70. package/dist/scanner/processor.js.map +1 -1
  71. package/dist/search/index.d.ts +2 -2
  72. package/dist/search/index.d.ts.map +1 -1
  73. package/dist/search/index.js +2 -2
  74. package/dist/search/index.js.map +1 -1
  75. package/dist/search/smart.d.ts +1 -1
  76. package/dist/search/smart.d.ts.map +1 -1
  77. package/dist/search/smart.js +3 -7
  78. package/dist/search/smart.js.map +1 -1
  79. package/dist/search/terms.js.map +1 -1
  80. package/dist/types/core.d.ts +5 -4
  81. package/dist/types/core.d.ts.map +1 -1
  82. package/dist/types/index.d.ts +2 -2
  83. package/dist/types/index.js +2 -2
  84. package/dist/types/internal.d.ts +7 -4
  85. package/dist/types/internal.d.ts.map +1 -1
  86. package/package.json +12 -2
  87. package/src/cache.ts +59 -0
  88. package/src/cli/index.ts +112 -114
  89. package/src/cli/init.ts +104 -108
  90. package/src/cli/list.ts +84 -77
  91. package/src/cli/resolve.ts +57 -57
  92. package/src/cli/search.ts +72 -72
  93. package/src/cli/searchparam.ts +118 -117
  94. package/src/constants.ts +1 -1
  95. package/src/fs/index.ts +1 -1
  96. package/src/fs/utils.ts +16 -16
  97. package/src/index.ts +9 -12
  98. package/src/manager/canonical.ts +349 -360
  99. package/src/manager/index.ts +1 -3
  100. package/src/package.ts +79 -0
  101. package/src/reference.ts +77 -0
  102. package/src/resolver.ts +38 -0
  103. package/src/scanner/directory.ts +25 -31
  104. package/src/scanner/index.ts +4 -4
  105. package/src/scanner/package.ts +26 -29
  106. package/src/scanner/parser.ts +25 -27
  107. package/src/scanner/processor.ts +51 -55
  108. package/src/search/index.ts +2 -2
  109. package/src/search/smart.ts +41 -48
  110. package/src/search/terms.ts +17 -17
  111. package/src/types/core.ts +102 -89
  112. package/src/types/index.ts +2 -2
  113. package/src/types/internal.ts +36 -34
  114. package/dist/cache/core.d.ts +0 -7
  115. package/dist/cache/core.d.ts.map +0 -1
  116. package/dist/cache/core.js +0 -11
  117. package/dist/cache/core.js.map +0 -1
  118. package/dist/cache/index.d.ts +0 -4
  119. package/dist/cache/index.d.ts.map +0 -1
  120. package/dist/cache/index.js +0 -4
  121. package/dist/cache/index.js.map +0 -1
  122. package/dist/cache/persistence.d.ts +0 -5
  123. package/dist/cache/persistence.d.ts.map +0 -1
  124. package/dist/cache/persistence.js +0 -25
  125. package/dist/cache/persistence.js.map +0 -1
  126. package/dist/cache/validation.d.ts +0 -2
  127. package/dist/cache/validation.d.ts.map +0 -1
  128. package/dist/cache/validation.js +0 -21
  129. package/dist/cache/validation.js.map +0 -1
  130. package/dist/package/detector.d.ts +0 -2
  131. package/dist/package/detector.d.ts.map +0 -1
  132. package/dist/package/detector.js +0 -19
  133. package/dist/package/detector.js.map +0 -1
  134. package/dist/package/index.d.ts +0 -3
  135. package/dist/package/index.d.ts.map +0 -1
  136. package/dist/package/index.js +0 -3
  137. package/dist/package/index.js.map +0 -1
  138. package/dist/package/installer.d.ts +0 -2
  139. package/dist/package/installer.d.ts.map +0 -1
  140. package/dist/package/installer.js +0 -55
  141. package/dist/package/installer.js.map +0 -1
  142. package/dist/reference/index.d.ts +0 -5
  143. package/dist/reference/index.d.ts.map +0 -1
  144. package/dist/reference/index.js +0 -4
  145. package/dist/reference/index.js.map +0 -1
  146. package/dist/reference/manager.d.ts.map +0 -1
  147. package/dist/reference/manager.js.map +0 -1
  148. package/dist/reference/store.d.ts +0 -6
  149. package/dist/reference/store.d.ts.map +0 -1
  150. package/dist/reference/store.js +0 -6
  151. package/dist/reference/store.js.map +0 -1
  152. package/dist/resolver/context.d.ts +0 -4
  153. package/dist/resolver/context.d.ts.map +0 -1
  154. package/dist/resolver/context.js.map +0 -1
  155. package/dist/resolver/index.d.ts +0 -2
  156. package/dist/resolver/index.d.ts.map +0 -1
  157. package/dist/resolver/index.js +0 -2
  158. package/dist/resolver/index.js.map +0 -1
  159. package/src/cache/core.ts +0 -20
  160. package/src/cache/index.ts +0 -7
  161. package/src/cache/persistence.ts +0 -39
  162. package/src/cache/validation.ts +0 -27
  163. package/src/package/detector.ts +0 -24
  164. package/src/package/index.ts +0 -6
  165. package/src/package/installer.ts +0 -77
  166. package/src/reference/index.ts +0 -10
  167. package/src/reference/manager.ts +0 -51
  168. package/src/reference/store.ts +0 -15
  169. package/src/resolver/context.ts +0 -25
  170. package/src/resolver/index.ts +0 -5
@@ -2,7 +2,5 @@
2
2
  * Manager module exports
3
3
  */
4
4
 
5
- export { createCanonicalManager } from './canonical.js';
6
-
7
5
  // For backward compatibility
8
- export { createCanonicalManager as CanonicalManager } from './canonical.js';
6
+ export { createCanonicalManager, createCanonicalManager as CanonicalManager } from "./canonical.js";
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
+ };
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Reference management module
3
+ * Merged from reference/index.ts, reference/manager.ts, and reference/store.ts
4
+ */
5
+
6
+ import { createHash } from "node:crypto";
7
+ import type { Reference, ReferenceMetadata, ReferenceStore } from "./types/index.js";
8
+
9
+ /**
10
+ * Generate a unique reference ID from metadata
11
+ */
12
+ export const generateReferenceId = (metadata: {
13
+ packageName: string;
14
+ packageVersion: string;
15
+ filePath: string;
16
+ }): string => {
17
+ const input = `${metadata.packageName}@${metadata.packageVersion}:${metadata.filePath}`;
18
+ return createHash("sha256").update(input).digest("base64url");
19
+ };
20
+
21
+ /**
22
+ * Reference manager interface
23
+ */
24
+ export interface ReferenceManager extends ReferenceStore {
25
+ generateId: typeof generateReferenceId;
26
+ getIdsByUrl: (url: string) => string[];
27
+ createReference: (id: string, metadata: ReferenceMetadata) => Reference;
28
+ getAllReferences: () => Record<string, ReferenceMetadata>;
29
+ }
30
+
31
+ /**
32
+ * Create a reference manager instance
33
+ */
34
+ export const createReferenceManager = (): ReferenceManager => {
35
+ const references: Record<string, ReferenceMetadata> = {};
36
+ const urlToIds: Record<string, string[]> = {};
37
+
38
+ const set = (id: string, metadata: ReferenceMetadata): void => {
39
+ references[id] = metadata;
40
+ if (metadata.url) {
41
+ if (!urlToIds[metadata.url]) {
42
+ urlToIds[metadata.url] = [];
43
+ }
44
+ const ids = urlToIds[metadata.url];
45
+ if (ids && !ids.includes(id)) {
46
+ ids.push(id);
47
+ }
48
+ }
49
+ };
50
+
51
+ const clear = (): void => {
52
+ Object.keys(references).forEach((key) => {
53
+ delete references[key];
54
+ });
55
+ Object.keys(urlToIds).forEach((key) => {
56
+ delete urlToIds[key];
57
+ });
58
+ };
59
+
60
+ return {
61
+ generateId: generateReferenceId,
62
+ get: (id: string) => references[id],
63
+ set,
64
+ has: (id: string) => id in references,
65
+ clear,
66
+ size: () => Object.keys(references).length,
67
+ getIdsByUrl: (url: string) => urlToIds[url] || [],
68
+ createReference: (id: string, metadata: ReferenceMetadata): Reference => ({
69
+ id,
70
+ resourceType: metadata.resourceType,
71
+ }),
72
+ getAllReferences: () => references,
73
+ };
74
+ };
75
+
76
+ // For backward compatibility - function alias (will be deprecated)
77
+ export { createReferenceManager as ReferenceManagerFactory };
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Resolver module - Context-aware resolution functionality
3
+ * Merged from resolver/index.ts and resolver/context.ts
4
+ */
5
+
6
+ import type { ExtendedCache } from "./cache.js";
7
+ import type { IndexEntry, SourceContext } from "./types/index.js";
8
+
9
+ /**
10
+ * Resolve a canonical URL with context awareness
11
+ *
12
+ * Attempts to resolve a URL within a specific package context first,
13
+ * then falls back to global resolution if the context-specific resolution fails.
14
+ *
15
+ * @param url - The canonical URL to resolve
16
+ * @param context - The source context containing package information
17
+ * @param _cache - The extended cache instance (currently unused but kept for future use)
18
+ * @param resolveEntry - Function to resolve an entry by URL with optional package/version
19
+ * @returns The resolved index entry or null if resolution fails
20
+ */
21
+ export const resolveWithContext = async (
22
+ url: string,
23
+ context: SourceContext,
24
+ _cache: ExtendedCache,
25
+ resolveEntry: (url: string, options?: any) => Promise<IndexEntry>,
26
+ ): Promise<IndexEntry | null> => {
27
+ if (context.package) {
28
+ try {
29
+ return await resolveEntry(url, {
30
+ package: context.package.name,
31
+ version: context.package.version,
32
+ });
33
+ } catch {
34
+ // Fall through to global resolution
35
+ }
36
+ }
37
+ return null;
38
+ };
@@ -2,41 +2,35 @@
2
2
  * Directory scanning functionality
3
3
  */
4
4
 
5
- import * as fs from 'fs/promises';
6
- import * as path from 'path';
7
- import type { ExtendedCache } from '../cache/core.js';
8
- import { isFhirPackage } from '../fs/index.js';
9
- import { scanPackage } from './package.js';
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
- if (!entry.isDirectory()) continue;
15
+ if (!entry.isDirectory()) continue;
16
+
17
+ const fullPath = path.join(entry.parentPath, entry.name);
20
18
 
21
- const fullPath = path.join(dirPath, entry.name);
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
- if (entry.name.startsWith("@")) {
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
- const scopedPath = path.join(fullPath, scopedEntry.name);
31
- if (await isFhirPackage(scopedPath)) {
32
- await scanPackage(scopedPath, cache);
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
- } catch {
40
- // Silently ignore scan errors
41
- }
42
- };
36
+ };
@@ -2,7 +2,7 @@
2
2
  * Scanner module exports
3
3
  */
4
4
 
5
- export { parseIndex, isValidFileEntry, isValidIndexFile } from './parser.js';
6
- export { processIndex } from './processor.js';
7
- export { scanPackage } from './package.js';
8
- export { scanDirectory } from './directory.js';
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";
@@ -2,37 +2,34 @@
2
2
  * Package scanning functionality
3
3
  */
4
4
 
5
- import * as fs from 'fs/promises';
6
- import * as path from 'path';
7
- import type { PackageJson, PackageInfo } from '../types/index.js';
8
- import type { ExtendedCache } from '../cache/core.js';
9
- import { fileExists } from '../fs/index.js';
10
- import { processIndex } from './processor.js';
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
- packagePath: string,
14
- cache: ExtendedCache,
15
- ): Promise<void> => {
16
- try {
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
- const packageInfo: PackageInfo = {
22
- id: { name: packageJson.name, version: packageJson.version },
23
- path: packagePath,
24
- canonical: packageJson.canonical,
25
- fhirVersions: packageJson.fhirVersions,
26
- };
27
- cache.packages[packageJson.name] = packageInfo;
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
- await processIndex(packagePath, packageJson, cache);
26
+ await processIndex(packagePath, packageJson, cache);
30
27
 
31
- const examplesPath = path.join(packagePath, "examples");
32
- if (await fileExists(path.join(examplesPath, ".index.json"))) {
33
- await processIndex(examplesPath, packageJson, cache);
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
- } catch {
36
- // Silently ignore package scan errors
37
- }
38
- };
35
+ };
@@ -2,41 +2,39 @@
2
2
  * Index file parsing and validation
3
3
  */
4
4
 
5
- import type { IndexFile, IndexFileEntry } from '../types/index.js';
5
+ import type { IndexFile } from "../types/index.js";
6
6
 
7
7
  export const isValidFileEntry = (entry: any): boolean => {
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")
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
- const optionalStringFields = ["url", "version", "kind", "type"];
15
- for (const field of optionalStringFields) {
16
- if (entry[field] !== undefined && typeof entry[field] !== "string") {
17
- return false;
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
- return true;
20
+ return true;
22
21
  };
23
22
 
24
23
  export const isValidIndexFile = (data: any): boolean => {
25
- if (!data || typeof data !== "object") return false;
26
- if (!data["index-version"] || typeof data["index-version"] !== "number")
27
- return false;
28
- if (!Array.isArray(data.files)) return false;
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, filePath: string): IndexFile | null => {
33
- try {
34
- const data = JSON.parse(content);
35
- if (!isValidIndexFile(data)) {
36
- return null;
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
- return data as IndexFile;
39
- } catch {
40
- return null;
41
- }
42
- };
40
+ };
@@ -2,68 +2,64 @@
2
2
  * Index processing functionality
3
3
  */
4
4
 
5
- import * as fs from 'fs/promises';
6
- import * as path from 'path';
7
- import type { PackageJson, IndexEntry } from '../types/index.js';
8
- import type { ExtendedCache } from '../cache/core.js';
9
- import { parseIndex } from './parser.js';
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
- basePath: string,
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
- try {
19
- const indexContent = await fs.readFile(indexPath, "utf-8");
20
- const index = parseIndex(indexContent, indexPath);
14
+ try {
15
+ const indexContent = await fs.readFile(indexPath, "utf-8");
16
+ const index = parseIndex(indexContent, indexPath);
21
17
 
22
- if (!index) return;
18
+ if (!index) return;
23
19
 
24
- for (const file of index.files) {
25
- if (!file.url) continue;
20
+ for (const file of index.files) {
21
+ if (!file.url) continue;
26
22
 
27
- const filePath = path.join(basePath, file.filename);
23
+ const filePath = path.join(basePath, file.filename);
28
24
 
29
- const id = cache.referenceManager.generateId({
30
- packageName: packageJson.name,
31
- packageVersion: packageJson.version,
32
- filePath,
33
- });
25
+ const id = cache.referenceManager.generateId({
26
+ packageName: packageJson.name,
27
+ packageVersion: packageJson.version,
28
+ filePath,
29
+ });
34
30
 
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
- });
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
- 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
- };
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
- 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
- }
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
- } catch {
67
- // Silently ignore index processing errors
68
- }
69
- };
65
+ };
@@ -2,5 +2,5 @@
2
2
  * Search module exports
3
3
  */
4
4
 
5
- export { expandedTerms } from './terms.js';
6
- export { filterBySmartSearch, type SmartSearchFilters } from './smart.js';
5
+ export { filterBySmartSearch, type SmartSearchFilters } from "./smart.js";
6
+ export { expandedTerms } from "./terms.js";
@@ -2,56 +2,49 @@
2
2
  * Smart search functionality with abbreviation support
3
3
  */
4
4
 
5
- import type { IndexEntry, PackageId } from '../types/index.js';
6
- import { expandedTerms } from './terms.js';
5
+ import type { IndexEntry, PackageId } from "../types/index.js";
6
+ import { expandedTerms } from "./terms.js";
7
7
 
8
8
  export interface SmartSearchFilters {
9
- resourceType?: string;
10
- type?: string;
11
- kind?: string;
12
- package?: PackageId;
9
+ resourceType?: string;
10
+ type?: string;
11
+ kind?: string;
12
+ package?: PackageId;
13
13
  }
14
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);
15
+ export const filterBySmartSearch = (results: IndexEntry[], searchTerms: string[]): IndexEntry[] => {
16
+ if (searchTerms.length === 0) {
17
+ return results;
18
+ }
19
+
20
+ const terms = searchTerms.map((t) => t.toLowerCase());
21
+
22
+ return results.filter((entry) => {
23
+ if (!entry.url) return false;
24
+ const urlLower = entry.url.toLowerCase();
25
+
26
+ // Also check type and resourceType for matching
27
+ const fullText = [urlLower, entry.type?.toLowerCase() || "", entry.resourceType?.toLowerCase() || ""].join(" ");
28
+
29
+ // Check if all search terms match
30
+ return terms.every((term) => {
31
+ // Split the text into parts (by /, -, _, ., spaces)
32
+ const allParts = fullText.split(/[/\-_.\s]+/);
33
+
34
+ // Check if any part starts with the search term
35
+ const directMatch = allParts.some((part) => part.startsWith(term));
36
+ if (directMatch) return true;
37
+
38
+ // Check if the term is an abbreviation
39
+ const expansions = expandedTerms[term] || [];
40
+ for (const expansion of expansions) {
41
+ if (allParts.some((part) => part.startsWith(expansion))) {
42
+ return true;
43
+ }
44
+ }
45
+
46
+ // If still no match, check if the term appears anywhere (substring match)
47
+ return fullText.includes(term);
48
+ });
55
49
  });
56
- });
57
- };
50
+ };