Add FileResolver and PkgResolver implementations for Go#10
Conversation
Dependencies (all otherwise already at latest):
- npm: bump memfs 4.57.2 -> 4.57.6
- go: confirmed jsonic/directive/path go modules at latest (no change)
Resolver parity (TS is canonical and ships resolver/{mem,file,pkg};
the Go port previously shipped only MakeMemResolver):
- Add MakeFileResolver (filesystem) with FileResolverOptions
(PathFinder, Preload), mirroring src/resolver/file.ts
- Add MakePkgResolver (node_modules) with PkgResolverOptions (Paths),
the portable subset of src/resolver/pkg.ts: walks node_modules,
honours package.json "main", tries implicit extensions/index files
- buildPotentials now also tries the folder-name index variant
(foo/index.foo.jsonic), matching the TS resolver
- 12 new Go resolver tests (go/resolver_test.go)
Docs:
- CLAUDE.md: note TS is canonical, build/test commands, resolver/
processor parity map, and known Go<->TS differences
- doc/multisource-go.md: document file/pkg resolvers; fix stale Version
Tests: TS 32/32 pass, Go 29/29 pass; gofmt and go vet clean.
https://claude.ai/code/session_01FDYq13DCSWZz4mfS6yWEzv
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9b630b7345
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| func resolveInPkgDir(nodeModules, ref string, exts []string, search *[]string) (full, src string, found bool) { | ||
| target := filepath.Join(nodeModules, filepath.FromSlash(ref)) | ||
|
|
||
| for _, p := range buildPotentials(target, exts) { |
There was a problem hiding this comment.
Honor package.json main before index files
For a bare package that contains both package.json with a main field and an index.jsonic, this loop tries target/index.* before the code below ever reads package.json, so MakePkgResolver returns the index file and ignores the declared main entry. That contradicts the documented/canonical package resolution where package.json main wins for bare package references, and it will load the wrong source for packages that keep an index alongside their real main file.
Useful? React with 👍 / 👎.
TestFileResolverFolderIndex failed on Windows: the file resolver resolves to an absolute path via filepath.Abs, which uses backslash separators on Windows. buildPotentials extracted the folder name with path.Base, but the `path` package only splits on '/', so on Windows it returned the entire path instead of the final segment, corrupting the foo/index.foo.jsonic potential. Extract the final path segment with strings.LastIndexAny over both '/' and '\\', and take the extension from that segment. This also fixes a latent bug where a '.' in a Windows ancestor directory could wrongly suppress implicit extensions. The plain index and implicit-extension variants already worked because Windows tolerates mixed separators in os.ReadFile. Add a backslash-path assertion to TestBuildPotentials so the regression is covered on every platform, not just Windows. https://claude.ai/code/session_01FDYq13DCSWZz4mfS6yWEzv
Summary
This PR adds two new resolver implementations to the Go port of
@jsonic/multisource:MakeFileResolverfor loading sources from the filesystem andMakePkgResolverfor resolving references fromnode_modulesdirectories. These mirror the canonical TypeScript implementations and complete the resolver API parity between the two language ports.Key Changes
Added
MakeFileResolver(go/resolver.go):@a→a.jsonic)@mod→mod/index.jsonic)foo/index.foo.jsonic)FileResolverOptionsfor custom path transformation (PathFinder) and preloaded content (Preload)Added
MakePkgResolver(go/resolver.go):node_modulesdirectoriespackage.json"main"field for bare package referencesPkgResolverOptionsto specify search root pathsComprehensive test coverage (
go/resolver_test.go):package.jsonmain, index files, ancestor directory walking, and error casesUpdated documentation (
doc/multisource-go.md):FileResolverOptionsandPkgResolverOptionssignaturesMakePkgResolverimplements the portable subset of Node's module resolutionUpdated
CLAUDE.md:Minor updates:
buildPotentialsingo/multisource.gowith folder-specific index file support0.1.4Implementation Details
MakePkgResolveris a portable subset: it does not implement Node's fullrequire.resolvealgorithm (e.g., conditional"exports")ctx.meta.fs)Resolution.Searchfor debugging/transparencyhttps://claude.ai/code/session_01FDYq13DCSWZz4mfS6yWEzv