Skip to content

Removing DependsOnMethod#2938

Merged
RobinTail merged 20 commits intomake-v26from
rm-DependsOnMethod
Sep 17, 2025
Merged

Removing DependsOnMethod#2938
RobinTail merged 20 commits intomake-v26from
rm-DependsOnMethod

Conversation

@RobinTail
Copy link
Copy Markdown
Owner

@RobinTail RobinTail commented Sep 14, 2025

It can now be replaced with ${method} / syntax

todo

  • rename tests
  • fate of Routable
  • migration

Summary by CodeRabbit

  • Breaking Changes

    • Removed DependsOnMethod from the public API.
    • Routing now uses flat, path-scoped objects with explicit "METHOD /" keys (e.g., "get /").
    • Deprecation is applied per Endpoint; Endpoint now provides nest().
  • New Features

    • Added an automatic migration rule to convert DependsOnMethod usages to the new routing syntax.
  • Documentation

    • README and CHANGELOG updated with new routing examples and deprecation guidance.
  • Examples

    • Updated example routing to the new flat object mapping.

@RobinTail RobinTail added refactoring The better way to achieve the same result breaking Backward incompatible changes labels Sep 14, 2025
@RobinTail RobinTail added this to the v26 milestone Sep 14, 2025
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Sep 14, 2025

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Pre-merge checks

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
Title Check ✅ Passed The title "Removing DependsOnMethod" is concise and accurately reflects the PR's primary change — removal of the DependsOnMethod export and related Routable API across code, docs, tests, and migrations. It clearly communicates the main intent without extraneous detail, making it easy for a teammate scanning history to understand the key change.

@RobinTail RobinTail added the documentation Improvements or additions to documentation label Sep 14, 2025
@RobinTail RobinTail changed the base branch from master to make-v26 September 15, 2025 15:32
@RobinTail RobinTail mentioned this pull request Sep 15, 2025
@coveralls-official
Copy link
Copy Markdown

coveralls-official Bot commented Sep 15, 2025

Coverage Status

coverage: 100.0%. remained the same
when pulling ba7951c on rm-DependsOnMethod
into bb5d891 on make-v26.

@RobinTail RobinTail marked this pull request as ready for review September 16, 2025 18:22
@RobinTail
Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Sep 16, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
express-zod-api/src/endpoint.ts (1)

148-151: Bug: Object.freeze(undefined) will throw when methods are not set

If an endpoint is built without explicit methods, accessing methods throws a TypeError. Return undefined instead when absent.

-  public override get methods() {
-    return Object.freeze(this.#def.methods);
-  }
+  public override get methods() {
+    return this.#def.methods
+      ? (Object.freeze(this.#def.methods) as ReadonlyArray<Method>)
+      : undefined;
+  }
🧹 Nitpick comments (8)
express-zod-api/src/endpoints-factory.ts (1)

55-56: Nit: tighten JSDoc wording for clarity.

“defined by Routing” can read as behavior-driven; suggest “defined in Routing keys” to point at the declaration site.

-   * @default "get" unless method is explicitly defined by Routing
+   * @default "get" unless method is explicitly defined in Routing keys
CHANGELOG.md (1)

7-19: v26 entry looks good; add one migration hint re HEAD.

Many users relied on implicit HEAD with GET. A one-line note here will reduce confusion.

 ### v26.0.0

 - `DependsOnMethod` removed: use flat syntax with explicit method and a slash;
+  - Note: HEAD remains auto-handled for endpoints that support GET; no `"head /"` mapping is required.
migration/index.ts (1)

88-91: Tiny consistency nit: keep trailing commas in fallback branch.

Add a trailing comma after the manual-migration comment for uniform diffs and to match outputs in tests.

-                  : `${ctx.sourceCode.getText(prop)}, /** @todo migrate manually */`;
+                  : `${ctx.sourceCode.getText(prop)}, /** @todo migrate manually */,`;
migration/index.spec.ts (1)

20-68: Add test coverage: string-literal keys and chained .deprecated().nest() orders.

These cases guard against regressions in the fixer and reflect how real code may appear.

   tester.run("v26", migration.rules.v26, {
     valid: [`const routing = { "get /": someEndpoint };`],
     invalid: [
+      {
+        name: "string-literal method key",
+        code: `const routing = new DependsOnMethod({ "get": someEndpoint });`,
+        output: `const routing = {\n"get /": someEndpoint,\n};`,
+        errors: [{ messageId: "change", data: { subject: "value", from: "new DependsOnMethod(...)", to: "its argument object and append its keys with ' /'" } }],
+      },
       {
         name: "basic DependsOnMethod",
         code: `const routing = new DependsOnMethod({ get: someEndpoint });`,
         output: `const routing = {\n"get /": someEndpoint,\n};`,
         errors: [
           {
             messageId: "change",
             data: {
               subject: "value",
               from: "new DependsOnMethod(...)",
               to: "its argument object and append its keys with ' /'",
             },
           },
         ],
       },
+      {
+        name: "deprecated + nest (deprecated before nest)",
+        code: `const routing = new DependsOnMethod({ get: epA }).deprecated().nest({ some: epB });`,
+        output: `const routing = {\n"get /": epA.deprecated(),\n"some": epB,\n};`,
+        errors: [{ messageId: "change", data: { subject: "value", from: "new DependsOnMethod(...)", to: "its argument object and append its keys with ' /'" } }],
+      },
+      {
+        name: "deprecated + nest (nest before deprecated)",
+        code: `const routing = new DependsOnMethod({ get: epA }).nest({ some: epB }).deprecated();`,
+        output: `const routing = {\n"get /": epA.deprecated(),\n"some": epB,\n};`,
+        errors: [{ messageId: "change", data: { subject: "value", from: "new DependsOnMethod(...)", to: "its argument object and append its keys with ' /'" } }],
+      },
       {
         name: "deprecated DependsOnMethod",
         code: `const routing = new DependsOnMethod({ get: someEndpoint }).deprecated();`,
         output: `const routing = {\n"get /": someEndpoint.deprecated(),\n};`,
         errors: [
           {
             messageId: "change",
             data: {
               subject: "value",
               from: "new DependsOnMethod(...)",
               to: "its argument object and append its keys with ' /'",
             },
           },
         ],
       },
       {
         name: "DependsOnMethod with nesting",
         code: `const routing = new DependsOnMethod({ get: someEndpoint }).nest({ some: otherEndpoint });`,
         output: `const routing = {\n"get /": someEndpoint,\n"some": otherEndpoint,\n};`,
         errors: [
           {
             messageId: "change",
             data: {
               subject: "value",
               from: "new DependsOnMethod(...)",
               to: "its argument object and append its keys with ' /'",
             },
           },
         ],
       },
     ],
   });
README.md (1)

301-306: LGTM: method-based routing example matches the new syntax.

Clear illustration of "METHOD /" keys under a path. Consider a side note that HEAD is auto-handled for GET (no "head /" needed).

example/routing.ts (1)

1-1: Use a type-only import for Routing

To avoid emitting a value import in JS builds (and to play nicely with TS “verbatimModuleSyntax”), import Routing as a type.

-import { Routing, ServeStatic } from "express-zod-api";
+import type { Routing } from "express-zod-api";
+import { ServeStatic } from "express-zod-api";
express-zod-api/src/routing.ts (1)

7-7: Correct: type-only import for AbstractEndpoint

This avoids runtime imports; matches the library’s typing style. While here, consider also marking OnEndpoint as a type-only import for consistency.

-import { OnEndpoint, walkRouting } from "./routing-walker";
+import type { OnEndpoint } from "./routing-walker";
+import { walkRouting } from "./routing-walker";
express-zod-api/src/endpoint.ts (1)

44-49: Avoid mutating arguments in .nest()

Object.assign mutates the provided routing object. Prefer returning a new object (keeps surprises low for callers).

-  public nest(routing: Routing): Routing {
-    return Object.assign(routing, { "": this });
-  }
+  public nest(routing: Routing): Routing {
+    return { "": this, ...routing };
+  }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4e9bd1b and c5899e0.

⛔ Files ignored due to path filters (2)
  • express-zod-api/tests/__snapshots__/index.spec.ts.snap is excluded by !**/*.snap
  • express-zod-api/tests/__snapshots__/routing.spec.ts.snap is excluded by !**/*.snap
📒 Files selected for processing (16)
  • CHANGELOG.md (1 hunks)
  • README.md (4 hunks)
  • example/routing.ts (2 hunks)
  • express-zod-api/src/depends-on-method.ts (0 hunks)
  • express-zod-api/src/endpoint.ts (2 hunks)
  • express-zod-api/src/endpoints-factory.ts (1 hunks)
  • express-zod-api/src/index.ts (0 hunks)
  • express-zod-api/src/routable.ts (0 hunks)
  • express-zod-api/src/routing-walker.ts (0 hunks)
  • express-zod-api/src/routing.ts (2 hunks)
  • express-zod-api/tests/depends-on-method.spec.ts (0 hunks)
  • express-zod-api/tests/endpoint.spec.ts (1 hunks)
  • express-zod-api/tests/routable.spec.ts (0 hunks)
  • express-zod-api/tests/routing.spec.ts (8 hunks)
  • migration/index.spec.ts (1 hunks)
  • migration/index.ts (2 hunks)
💤 Files with no reviewable changes (6)
  • express-zod-api/tests/routable.spec.ts
  • express-zod-api/tests/depends-on-method.spec.ts
  • express-zod-api/src/routing-walker.ts
  • express-zod-api/src/routable.ts
  • express-zod-api/src/index.ts
  • express-zod-api/src/depends-on-method.ts
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2025-05-28T18:58:10.064Z
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2428
File: express-zod-api/src/index.ts:44-44
Timestamp: 2025-05-28T18:58:10.064Z
Learning: The type-only import `import type {} from "qs";` in express-zod-api/src/index.ts is necessary to avoid TS2742 errors for exported functions like attachRouting, makeRequestMock, testEndpoint, and testMiddleware that have types depending on types/qs. This import provides the reference TypeScript needs to infer portable type names.

Applied to files:

  • express-zod-api/src/routing.ts
  • example/routing.ts
  • README.md
  • express-zod-api/tests/routing.spec.ts
📚 Learning: 2025-05-27T20:03:34.213Z
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2546
File: example/factories.ts:35-42
Timestamp: 2025-05-27T20:03:34.213Z
Learning: The `./example` directory in the express-zod-api repository contains demonstration code for educational purposes only, not intended for production use. Example code can make simplified assumptions for brevity and clarity, and should not be flagged for missing production-level error handling, security measures, or edge case handling.

Applied to files:

  • example/routing.ts
  • README.md
📚 Learning: 2025-05-27T20:27:17.015Z
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2546
File: express-zod-api/src/json-schema-helpers.ts:1-3
Timestamp: 2025-05-27T20:27:17.015Z
Learning: Ramda is correctly listed as a dependency in express-zod-api/package.json, so imports of ramda utilities are properly supported.

Applied to files:

  • example/routing.ts
📚 Learning: 2025-05-28T07:58:09.853Z
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2546
File: express-zod-api/src/documentation-helpers.ts:508-512
Timestamp: 2025-05-28T07:58:09.853Z
Learning: In express-zod-api, when working with Zod's JSON schema override callbacks, using `delete` to mutate `ctx.jsonSchema` is the recommended approach per Zod's official documentation, even if it triggers performance linting warnings. This is preferable to creating copies with `undefined` values, especially for snapshot testing.

Applied to files:

  • README.md
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Socket Security: Pull Request Alerts
🔇 Additional comments (9)
README.md (2)

1178-1179: LGTM: deprecation API wording aligns with removal of DependsOnMethod.

Accurately scopes .deprecated() to schemas and Endpoint.


1182-1195: LGTM: updated routing deprecation example.

Shows path-level deprecation via Endpoint instance without the removed wrapper.

express-zod-api/tests/endpoint.spec.ts (1)

134-147: Good coverage for the new .nest() API

The assertions match the contract and validate both presence and shape. Consider also asserting that input isn’t mutated (or is, if that’s the intended contract) to lock the behavior.

If immutability is desired, add:

const input = { subpath: subject };
const result = subject.nest(input);
expect(result).toEqual({ "": subject, subpath: subject });
expect(result).not.toBe(input); // immutability
example/routing.ts (1)

19-24: New per-method route syntax reads well

Switch to "patch /" under the :id node is clear and aligns with the v26 routing shape.

express-zod-api/tests/routing.spec.ts (4)

111-155: Nice: method-scoped assignments exercise the new shape

Good assertions on method registrations and a single OPTIONS route per path with CORS enabled.


156-182: Correct guard: endpoint must support assigned method

The negative case ensures method/endpoint compatibility is enforced. Snapshot-based error check is appropriate here.


183-239: CORS header set includes all assigned methods (+HEAD)

Solid regression for issue 705; verifies deterministic order and the custom header passthrough.


410-424: Good constraint: no nesting under explicitly-method routes

Prevents ambiguous shapes early; error snapshot makes this future-proof.

express-zod-api/src/routing.ts (1)

21-21: Public API: DependsOnMethod removal — leftover references found; verify & update

Ripgrep found occurrences in: migration/index.ts (lines 19, 81); migration/index.spec.ts (lines 24, 25, 32, 39, 40, 47, 54, 55, 62); and numerous entries in CHANGELOG.md.
Action: update migration/index.ts and migration/index.spec.ts to remove or adapt DependsOnMethod usage to the new flat routing syntax, or confirm these migrations intentionally target legacy code; keep CHANGELOG.md mentions only as historical notes if desired.

Comment thread migration/index.ts
Comment thread migration/index.ts
Comment thread express-zod-api/src/endpoints-factory.ts Outdated
@RobinTail RobinTail changed the title v26: Removing DependsOnMethod Removing DependsOnMethod Sep 17, 2025
@RobinTail RobinTail merged commit 8d4a69a into make-v26 Sep 17, 2025
13 checks passed
@RobinTail RobinTail deleted the rm-DependsOnMethod branch September 17, 2025 13:20
RobinTail added a commit that referenced this pull request Nov 9, 2025
Due to #2938 

This will set us free from the requirement to write slash to the keys
when we imply method depending routing.

Breaking change: `Integration` requires `config` parameter.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Added `methodLikeRouteBehavior` configuration option to control
interpretation of method-like routing keys ("method" or "path")
* Added `hasHeadMethod` option for endpoint documentation configuration

* **Refactor**
* Integration constructor now requires a `config` parameter during
initialization
  * Routing syntax simplified to use cleaner method-based keys

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
RobinTail added a commit that referenced this pull request Dec 1, 2025
<img width="283" height="353" alt="image"
src="https://github.com/user-attachments/assets/5355c68c-e807-4b61-83a8-17e66a117f7d"
/>

[Lia Smith](https://en.wikipedia.org/wiki/Suicide_of_Lia_Smith) was a 21
years young transgender woman.

She attended Middlebury College in Middlebury, Vermont, majoring in
computer science and statistics. She was a member of the college's chess
club, bridge club, LGBTQ+ club, and Japanese club. She was a diver on
the Middlebury Panthers women's swimming and diving team.

In February 2025 Middlebury College had removed Lia Smith diving profile
from their website, following President Donald Trump's executive order,
which attempts to ban transgender women and girls from competing in
women's sports.

On October 18, 2025 Lia Smith committed suicide.

The tragedy of Lia Smith highlights that the push for exclusion of
transgender women from public women's spaces and sports is not an issue
of theoretical fairness, but one with devastating consequences for the
dignity, safety, and lives of trans individuals. Smith, who was an
openly transgender student athlete, described the immense difficulty and
feeling of being unwelcome in locker rooms, emphasizing the lack of a
clear, safe space for her. Her plea that transgender people are "not
trying to get into women's spaces to be perverts... we're just being
ourselves" underscores that inclusion is a matter of allowing trans
women to exist and access necessary public facilities with basic
dignity, rather than an invasion of privacy or a threat. Denying access
to these spaces does not eliminate their need for them, but instead
subjects them to alienation and heightened psychological distress.

Furthermore, Lia's experience as a diver, where she was reportedly
targeted by anti-trans websites and ultimately left her team citing
difficulties, demonstrates the severe emotional and social toll of
exclusion in sports. Critics of anti-trans policies explicitly linked
her death by suicide to the hostile climate and constant public scrutiny
and harassment directed at trans athletes. Allowing trans women to
participate in women's sports and access women's facilities is therefore
a vital component of protecting the mental health and physical safety of
transgender people. When a society creates systems that reject a
person’s identity and deny them opportunities for community, activity,
and belonging—all essential parts of a functioning life—it creates an
environment of intense hostility and vulnerability. Inclusion, in
contrast, affirms the full humanity of trans women and is a necessary
measure against the systemic discrimination that contributed to her
anguish.

--------------------------------

- #2938 
- #3049
- #2934 
- #3086 
- #3087 
- #3094
- ❔  #3102 

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Config-driven routing behavior; Integration instances accept
per-instance config.
  * Zod plugin adds CJS compatibility and new schema metadata helpers.
  * Release bumped to v26 (beta).

* **Bug Fixes**
  * Restored Zod examples/metadata in CommonJS environments.

* **Breaking Changes**
  * Handler/middleware parameter renamed: options → ctx.
  * Removed DependsOnMethod; use inline per-route objects.
  * EndpointsFactory.addOptions() renamed to addContext().

* **Docs**
  * README and CHANGELOG updated for v26 migration and examples.

* **Tests**
  * Added CJS runtime tests and updated tests to use ctx.

<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking Backward incompatible changes documentation Improvements or additions to documentation refactoring The better way to achieve the same result

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant