gofront 0.0.1

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.
@@ -0,0 +1,114 @@
1
+ // Resolves import paths to .d.ts files.
2
+ //
3
+ // Resolution order for `import "pkg"`:
4
+ // 1. Local `js:` prefix → relative .d.ts path (already handled in index.js)
5
+ // 2. node_modules/pkg/package.json → "types" or "typings" field
6
+ // 3. node_modules/pkg/index.d.ts
7
+ // 4. node_modules/@types/pkg/index.d.ts
8
+ //
9
+ // Returns: { dtsPath: string, importPath: string } or null if not found.
10
+ // dtsPath — absolute path to the .d.ts file to parse
11
+ // importPath — the JS import path to emit in generated code (e.g. "gl-matrix")
12
+
13
+ import { existsSync, readdirSync, readFileSync } from "node:fs";
14
+ import { dirname, join, resolve } from "node:path";
15
+
16
+ // Walk up from startDir looking for a node_modules directory
17
+ function findNodeModules(startDir) {
18
+ let dir = resolve(startDir);
19
+ while (true) {
20
+ const candidate = join(dir, "node_modules");
21
+ if (existsSync(candidate)) return candidate;
22
+ const parent = dirname(dir);
23
+ if (parent === dir) return null; // reached filesystem root
24
+ dir = parent;
25
+ }
26
+ }
27
+
28
+ // Returns true for local relative paths (start with ./ or ../)
29
+ export function isLocalPath(importPath) {
30
+ return importPath.startsWith("./") || importPath.startsWith("../");
31
+ }
32
+
33
+ // Resolve a local relative import path to an absolute directory of .go files.
34
+ // Returns the absolute dir path, or null if it doesn't contain any .go files.
35
+ export function resolveGwDir(importPath, fromFile) {
36
+ const fromDir = dirname(resolve(fromFile));
37
+ const dir = resolve(fromDir, importPath);
38
+ if (!existsSync(dir)) return null;
39
+ const gwFiles = readdirSync(dir).filter((f) => f.endsWith(".go"));
40
+ return gwFiles.length > 0 ? dir : null;
41
+ }
42
+
43
+ export function resolveImport(importPath, fromFile) {
44
+ const fromDir = dirname(resolve(fromFile));
45
+ const nodeModules = findNodeModules(fromDir);
46
+
47
+ if (!nodeModules) return null;
48
+
49
+ const pkgDir = join(nodeModules, importPath);
50
+
51
+ // 1. Check package.json "types" / "typings" field
52
+ const pkgJson = join(pkgDir, "package.json");
53
+ if (existsSync(pkgJson)) {
54
+ try {
55
+ const pkg = JSON.parse(readFileSync(pkgJson, "utf8"));
56
+ const typesField = pkg.types || pkg.typings;
57
+ if (typesField) {
58
+ const dtsPath = resolve(pkgDir, typesField);
59
+ if (existsSync(dtsPath)) return { dtsPath, importPath };
60
+ }
61
+ } catch {}
62
+ }
63
+
64
+ // 2. node_modules/pkg/index.d.ts
65
+ const indexDts = join(pkgDir, "index.d.ts");
66
+ if (existsSync(indexDts)) return { dtsPath: indexDts, importPath };
67
+
68
+ // 3. @types/pkg
69
+ // Normalize scoped packages: @scope/pkg → @types/scope__pkg
70
+ const atTypesName = importPath.startsWith("@")
71
+ ? importPath.slice(1).replace(/\//g, "__")
72
+ : importPath;
73
+ const atTypesDts = join(nodeModules, "@types", atTypesName, "index.d.ts");
74
+ if (existsSync(atTypesDts)) return { dtsPath: atTypesDts, importPath };
75
+
76
+ return null;
77
+ }
78
+
79
+ // Given an AST's import list, resolve all imports.
80
+ // Returns Map<importPath, { dtsPath, importPath, types, values }>
81
+ export function resolveAll(imports, fromFile, parseDts) {
82
+ const resolved = new Map();
83
+
84
+ for (const imp of imports) {
85
+ for (const path of imp.paths) {
86
+ if (path.startsWith("js:")) continue; // handled separately
87
+ if (isLocalPath(path)) continue; // local .go packages — handled by compiler
88
+
89
+ if (resolved.has(path)) continue;
90
+
91
+ const result = resolveImport(path, fromFile);
92
+ if (!result) {
93
+ console.error(
94
+ `gofront: warning: cannot find types for '${path}', treating as any`,
95
+ );
96
+ resolved.set(path, null);
97
+ continue;
98
+ }
99
+
100
+ try {
101
+ const source = readFileSync(result.dtsPath, "utf8");
102
+ const { types, values } = parseDts(source);
103
+ resolved.set(path, { ...result, types, values });
104
+ } catch (e) {
105
+ console.error(
106
+ `gofront: warning: failed to parse '${result.dtsPath}': ${e.message}`,
107
+ );
108
+ resolved.set(path, null);
109
+ }
110
+ }
111
+ }
112
+
113
+ return resolved;
114
+ }