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.
- package/LICENSE +9 -0
- package/README.md +202 -0
- package/package.json +41 -0
- package/src/codegen.js +1192 -0
- package/src/compiler.js +156 -0
- package/src/dts-parser.js +762 -0
- package/src/index.js +338 -0
- package/src/lexer.js +465 -0
- package/src/parser.js +1120 -0
- package/src/resolver.js +114 -0
- package/src/typechecker.js +1252 -0
package/src/resolver.js
ADDED
|
@@ -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
|
+
}
|