Skip to content

refactor(deps): replace url-parse with native URL API#122

Open
Kyzgor wants to merge 2 commits into
permitio:mainfrom
Kyzgor:fix/106-remove-url-parse-dependency
Open

refactor(deps): replace url-parse with native URL API#122
Kyzgor wants to merge 2 commits into
permitio:mainfrom
Kyzgor:fix/106-remove-url-parse-dependency

Conversation

@Kyzgor

@Kyzgor Kyzgor commented Mar 8, 2026

Copy link
Copy Markdown
  • What kind of change does this PR introduce?

    Refactor (removes a runtime dependency) + test coverage.

  • What is the current behavior? (link: url-parser is an unnecessary dependency #106)

    The SDK depends on url-parse (^1.5.10) and @types/url-parse (^1.4.11) solely to build the
    OPA client base URL in src/enforcement/enforcer.ts. Node's built-in WHATWG URL has been
    available since Node 10, and package.json already declares engines.node: ">=10", so the
    dependency is redundant. There is also no test guarding the OPA URL construction, so a regression
    in that logic would go undetected.

  • What is the new behavior (if this is a feature change)?

    • The OPA base URL is built with the native URL API; url-parse and @types/url-parse are removed.
    • The construction logic is extracted into a small pure helper buildOpaBaseUrl(pdp: string): string
      so it is unit-testable without a live PDP.
    • A hermetic ava unit test (yarn test:unitsrc/tests/enforcer.spec.ts) asserts the produced
      URL for the default PDP and edge cases (trailing slash, https-without-port, explicit-port
      override, path-prefix), asserts that the Enforcer actually wires its OPA client baseURL
      through the helper, and asserts a scheme-less PDP throws. Reverting the change fails the suite.

    Verified byte-identical to the old url-parse output by running both implementations over the
    same inputs:

    PDP old url-parse new native URL
    http://localhost:7766 http://localhost:8181/v1/data/permit/ http://localhost:8181/v1/data/permit/
    http://localhost:7766/ http://localhost:8181/v1/data/permit/ http://localhost:8181/v1/data/permit/
    https://pdp.example.com https://pdp.example.com:8181/v1/data/permit/ https://pdp.example.com:8181/v1/data/permit/
    https://pdp.example.com:1234 https://pdp.example.com:8181/v1/data/permit/ https://pdp.example.com:8181/v1/data/permit/
    http://localhost:7766/prefix http://localhost:8181/prefixv1/data/permit/ http://localhost:8181/prefixv1/data/permit/

    One disclosed difference on invalid input: a scheme-less PDP (localhost, //host:port)
    previously produced a silent malformed string and now fails fast with a TypeError at
    construction — an intentional improvement, locked by a t.throws test. (A host:port value like
    localhost:7766 is misparsed rather than rejected under both implementations — a pre-existing
    footgun, not changed here.)

  • Other information:

    Validated with yarn lint, yarn build, and yarn test:unit (7 tests); CI runs lint/build/test
    on Node 18 and 20.

    What's NOT in this PR: the main REST client baseURL (a plain string concat, never used
    url-parse) is untouched; no engines.node bump; no src/openapi/ changes. The yarn.lock
    change is the minimal removal of url-parse/@types/url-parse and their now-orphaned transitive
    dependencies (querystringify, requires-port) — no other entries are touched. A typed
    PermitError + scheme validation for an invalid PDP (which would also catch the localhost:7766
    misparse) is a sensible follow-up on url-parser is an unnecessary dependency #106, deliberately out of scope here.

    The security/snyk (permit) check is in an ERROR state due to an org quota condition on fork
    PRs ("You have used your limit of private tests"), not a vulnerability — this PR removes a
    dependency and adds none. A maintainer re-run/waiver would clear it.

    Fixes url-parser is an unnecessary dependency #106

@Kyzgor Kyzgor force-pushed the fix/106-remove-url-parse-dependency branch from 0053425 to aa6d88b Compare March 8, 2026 20:59
@Kyzgor

Kyzgor commented Jun 7, 2026

Copy link
Copy Markdown
Author

Heads-up on CI: the security/snyk (permit) check is in an ERROR state with the message "You have used your limit of private tests" — i.e. an org Snyk quota/billing condition on fork PRs, not a vulnerability finding. This PR actually removes a runtime dependency (url-parse) and its types, adding none. Could a maintainer re-run Snyk from a trusted context (or reset the quota)? Happy to help if anything is needed.

@zeevmoney zeevmoney left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Clean, behavior-equivalent refactor with a wired-in unit test — nice. Two minor notes.

[MEDIUM] The yarn.lock diff also pulls in ~43 unrelated @esbuild/* and @rollup/* entries resolved against registry.yarnpkg.com while the rest of the lockfile uses registry.npmjs.org. That's regeneration noise that mixes registry hosts and inflates the diff. Consider regenerating from main with the pinned yarn 1.22.22 so only the url-parse/@types/url-parse removals remain.

* @returns The OPA base URL string (e.g. `http://localhost:8181/v1/data/permit/`).
*/
export function buildOpaBaseUrl(pdp: string): string {
const opaBaseUrl = new URL(pdp);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

[LOW] Scheme-less PDP input now throws instead of returning a (bad) string

new URL('localhost:7766') throws TypeError [ERR_INVALID_URL], whereas url-parse returned a malformed string without throwing. Scheme-less PDP is unsupported either way, but the failure mode changed from silent-bad-string to a throw in the Enforcer constructor.

Suggestion: Add a @throws note to buildOpaBaseUrl (optionally a t.throws test) so callers know a scheme-less pdp throws.

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

Refactors OPA client base URL construction to use Node’s native WHATWG URL API instead of url-parse, and adds unit coverage to prevent regressions in the URL-building logic.

Changes:

  • Replaced url-parse usage with a small helper (buildOpaBaseUrl) based on the native URL API.
  • Added an AVA unit test suite covering default and edge-case PDP URL inputs.
  • Removed url-parse / @types/url-parse from dependencies and regenerated the lockfile; added a test:unit script.

Reviewed changes

Copilot reviewed 3 out of 4 changed files in this pull request and generated 2 comments.

File Description
src/enforcement/enforcer.ts Removes url-parse, introduces buildOpaBaseUrl(), and uses it to configure the OPA axios baseURL.
src/tests/enforcer.spec.ts Adds unit tests validating the exact OPA base URL string for several PDP inputs.
package.json Removes url-parse deps and adds a test:unit script to run the new test.
yarn.lock Lockfile regeneration reflecting dependency removal and resulting resolution changes.

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

Comment on lines +128 to +133
export function buildOpaBaseUrl(pdp: string): string {
const opaBaseUrl = new URL(pdp);
opaBaseUrl.port = '8181';
opaBaseUrl.pathname = `${opaBaseUrl.pathname}v1/data/permit/`;
return opaBaseUrl.toString();
}
Comment on lines +120 to +127
/**
* Builds the OPA client base URL from the configured PDP URL by forcing the OPA
* port (8181) and appending the OPA data path. Uses the native WHATWG `URL`
* (Node >= 10), replacing the previous `url-parse` dependency (#106).
*
* @param pdp - The configured PDP base URL (e.g. `http://localhost:7766`).
* @returns The OPA base URL string (e.g. `http://localhost:8181/v1/data/permit/`).
*/
Kyzgor added 2 commits June 23, 2026 22:48
url-parse was used only to build the OPA client base URL. Node's native
WHATWG URL (available since v10; engines.node already requires >=10) does
the same, so extract a buildOpaBaseUrl() helper and drop url-parse and
@types/url-parse.

yarn.lock is pruned of url-parse and its now-orphaned transitive
dependencies (querystringify, requires-port) only; every other entry is
left byte-for-byte unchanged.
Lock the exact OPA base URL produced for the default PDP, trailing-slash,
explicit-port, https, and path-prefix inputs so the url-parse -> native URL
refactor is proven behaviour-equivalent on valid input and any regression
fails here; assert a scheme-less PDP (bare host or //host:port) throws; and
assert the Enforcer wires the OPA client baseURL to buildOpaBaseUrl(pdp).
@Kyzgor Kyzgor force-pushed the fix/106-remove-url-parse-dependency branch from a42b43d to 575f1b3 Compare June 23, 2026 22:37
@Kyzgor

Kyzgor commented Jun 23, 2026

Copy link
Copy Markdown
Author

Thanks — pushed an update:

  • Lockfile: regenerating with yarn 1.22.22 didn't give a clean diff; a full install pulls in the esbuild/rollup platform packages the committed lockfile predates (the registry.yarnpkg.com host churn you flagged). So I pruned it by hand: the yarn.lock diff is now just the url-parse/@types/url-parse removals plus their orphaned querystringify/requires-port, and yarn install --frozen-lockfile is happy with it.
  • Scheme-less PDP: added a @throws note and a t.throws test, and the equivalence table now shows real old-vs-new output side by side. One thing I confirmed: a bare host or //host:port throws, but localhost:7766 is misparsed (read as <scheme>:<path>), not rejected — same footgun url-parse had.
  • PermitError: left it out here on purpose — the constructor does no config validation today, so a typed pdp error is a new surface rather than part of a dependency swap. Happy to do it as a follow-up on url-parser is an unnecessary dependency #106 that also covers the host:port case.

Rebased on main; the red check is just the fork Snyk quota error.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

url-parser is an unnecessary dependency

3 participants