Skip to content

feat(validate): accept file and http(s) URLs as input - #102

Merged
char0n merged 2 commits into
mainfrom
feature/validate-uri-input
Jul 20, 2026
Merged

feat(validate): accept file and http(s) URLs as input#102
char0n merged 2 commits into
mainfrom
feature/validate-uri-input

Conversation

@char0n

@char0n char0n commented Jul 20, 2026

Copy link
Copy Markdown
Member

Summary

speclynx validate now accepts any URI as its input argument — a local file path (as before), a file:// URL, or an http(s):// URL — instead of only a local filesystem path.

Input is read through @speclynx/apidom-reference's readFile, which dispatches to file and HTTP resolver plugins, replacing the file-only fs.readFileSync. The resolvers are passed explicitly (FileResolver with an open allow-list + HTTPResolverAxios with the network egress policy spelled out) rather than inherited from apidom-reference's mutable global options singleton, so the CLI's file access and network behavior are legible and reviewable in our source.

URI canonicalization

The input is normalized to a canonical URI before use:

  • http(s):// URLs pass through untouched.
  • file: URLs are round-tripped through fileURLToPathpathToFileURL, so every legal form (file:/x, file:///x, file://localhost/x) normalizes to the same file:///x.
  • Everything else is treated as a filesystem path and made absolute.

This canonicalization is not for readFile (it sanitizes its own argument) but because the same URI serves as the baseURI apidom-ls uses verbatim to resolve relative external $refs — where a raw Windows path throws ERR_INVALID_URL and a relative path would resolve against the filesystem root instead of the document. Only http/https/file are treated as schemes, so a relative filename containing a colon (draft:v1.json) is still read as a path.

Tests

New input URIs test block covering:

  • file:// URL to JSON and YAML documents
  • single-slash file: URL normalization
  • relative-path resolution from an unrelated cwd (asserts an invalid doc's diagnostics, so it proves the bytes were actually parsed)
  • http fetch via an ephemeral loopback server
  • query-string URL language detection (extension wins over Content-Type)
  • clean error + non-zero exit on an HTTP 404

The test CI job now runs on an ubuntu-latest + windows-latest matrix, giving real coverage for the Windows path → file:// URL branch that can't be exercised on Linux.

Docs

README updated: <file><uri> argument, a URL example, and the reference-validation description clarified to note it checks local (#/...) refs (external refs are not validated in apidom-ls's default mode).

Test plan

  • npm run lint, npm run typescript:check-types clean
  • npm test — 75 passing
  • Manually verified local path, file:// (single/triple-slash), and http URL inputs, plus the colon-in-filename and 404 cases

Read the validate input through @speclynx/apidom-reference's readFile so a
local path, a file:// URL, or an http(s):// URL are all accepted, replacing
the file-only fs.readFileSync. Resolvers are passed explicitly (FileResolver
with an open allow-list + HTTPResolverAxios) rather than inherited from the
mutable global options, keeping the CLI's file access and network egress
policy legible.

The input is canonicalized to a URI before use: http(s) URLs pass through,
file: URLs are round-tripped through fileURLToPath so every legal form
normalizes alike, and bare paths become absolute file:// URLs. This matters
because the URI also serves as the apidom-ls baseURI, where a raw Windows
path or a relative path would otherwise misresolve.

Add tests for file:// (JSON, YAML, single-slash), relative-path resolution,
http fetch, query-string language detection, and a 404 error path, and run
the test job on a Windows matrix leg to cover platform path handling.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Extends speclynx validate to accept local paths, file URLs, and HTTP(S) URLs.

Changes:

  • Canonicalizes input URIs and reads them through explicit ApiDOM resolvers.
  • Adds URI and HTTP validation tests across Linux and Windows.
  • Updates CLI help and documentation.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/commands/validate/action.ts Adds URI normalization and resolver-based input loading.
src/commands/validate/index.ts Renames the input argument to <uri>.
test/commands/validate/index.ts Tests file and HTTP URL inputs.
README.md Documents URL validation support.
.github/workflows/build.yml Runs tests on Ubuntu and Windows.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/commands/validate/action.ts Outdated
Use a /.*/ allow-list instead of the '*' glob so the file resolver
accepts leading-dot basenames (.openapi.yaml). picomatch does not match a
leading dot without dot:true, so '*' regressed valid local paths that the
previous fs.readFileSync accepted.
@char0n
char0n merged commit 36fb6d0 into main Jul 20, 2026
9 checks passed
@char0n
char0n deleted the feature/validate-uri-input branch July 20, 2026 12:59
github-actions Bot pushed a commit that referenced this pull request Jul 20, 2026
# [1.3.0](v1.2.0...v1.3.0) (2026-07-20)

### Features

* **validate:** accept file and http(s) URLs as input ([#102](#102)) ([36fb6d0](36fb6d0))
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 1.3.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

frantuma added a commit that referenced this pull request Jul 20, 2026
Address review of the rebased branch (char0n, Copilot):

- Fix the overwrite guard, broken by the rebase onto the URL-input work
  (#102). It referenced an undefined `resolvedPath` (build failure) and,
  once named, compared a filesystem path against a file:// URI so it
  never matched. Now compares path-to-path via fileURLToPath(fileURI),
  and skips http(s) inputs where there is no local file to clobber.
- Remove duplicate `fs` import in the validate test left by the rebase
  (was a duplicate-identifier build error).
- Simplify color handling: instead of threading a `color` flag through
  FormatterContext/stylish/severityToString, strip ANSI at the single
  file write site. Formatters are oblivious to their destination again;
  stylish.ts and types.ts revert to their pre-refactor form.

tsc, eslint, and the validate suite (incl. the overwrite and no-ANSI
file tests) pass.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants