-
-
Notifications
You must be signed in to change notification settings - Fork 34
chores: tsconfig module: node20 and import extensions
#2974
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
WalkthroughRepository-wide normalization: convert many local import specifiers to explicit Changes
Sequence Diagram(s)sequenceDiagram
participant TSDown as tsdown build
participant Env as process.env
participant Module as runtime module (zod-plugin / server-helpers)
Note over TSDown: tsdown.config.ts imports package.json\nand defines TSDOWN_SELF = manifest.name
TSDown->>Env: set process.env.TSDOWN_SELF
Env->>Module: Module reads process.env.TSDOWN_SELF
Module->>Module: pluginFlag = Symbol.for(process.env.TSDOWN_SELF!)
alt pluginFlag not present on globalThis
Module->>Global: attach augmentations (e.g., Zod prototypes)
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🧰 Additional context used🧠 Learnings (2)📓 Common learnings📚 Learning: 2025-06-02T21:11:20.768ZApplied to files:
🔇 Additional comments (4)
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. Comment |
node20module: node20
module: node20module: node20
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 8
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
express-zod-api/src/endpoint.ts (1)
141-145: Bug: Object.freeze called on possibly undefined
this.#def.methodsis optional;Object.freeze(undefined)throws. Returnundefinedwhen not set, otherwise freeze the array.- public override get methods() { - return Object.freeze(this.#def.methods); - } + public override get methods() { + const m = this.#def.methods; + return m ? Object.freeze(m) : undefined; + }express-zod-api/tests/server-helpers.spec.ts (1)
106-108: Use the importedfail()in server-helpers.spec.ts
Replace the twoassert.failcalls with the already-importedfail:- () => assert.fail("I am faulty"), - async () => assert.fail("I am faulty"), + () => fail("I am faulty"), + async () => fail("I am faulty"),To verify there are no additional
assert.failcalls in this file:rg -nP '\bassert\.fail\s*\(' express-zod-api/tests/server-helpers.spec.ts
🧹 Nitpick comments (35)
express-zod-api/tests/startup-logo.spec.ts (1)
1-2: Convert the TTY import to a type-only import
The project’s tsconfig.json already has"module": "node20"and"allowImportingTsExtensions": true, so the.tsspecifier is supported and no runtime change is needed. MarkingWriteStreamas a type-only import prevents an unnecessary ESM load:-import { WriteStream } from "node:tty"; +import type { WriteStream } from "node:tty";express-zod-api/tests/logger-helpers.spec.ts (2)
2-2: Make this a type‑only import
BuiltinLoggerConfigis used only as a type in this file. Switching toimport typeavoids an unnecessary runtime binding and future-proofs for stricter verbatim module semantics.-import { BuiltinLoggerConfig } from "../src/builtin-logger.ts"; +import type { BuiltinLoggerConfig } from "../src/builtin-logger.ts";
3-10: Split type from value imports to avoid runtime named import of a type
AbstractLoggerappears to be used purely as a type parameter here. Keep value imports as-is, but import the type separately to prevent a runtime named import that may not exist if/when verbatim module syntax is enabled or when running TS natively.-import { - AbstractLogger, - isLoggerInstance, - isSeverity, - isHidden, - makeNumberFormat, - formatDuration, -} from "../src/logger-helpers.ts"; +import type { AbstractLogger } from "../src/logger-helpers.ts"; +import { + isLoggerInstance, + isSeverity, + isHidden, + makeNumberFormat, + formatDuration, +} from "../src/logger-helpers.ts";express-zod-api/src/routing-walker.ts (2)
1-6: Imports updated to .ts: good; split type-only imports for cleaner emits under node20.To avoid unnecessary runtime loads with
module: node20+erasableSyntaxOnly/verbatimModuleSyntax, split type-only symbols from value imports and keep .ts specifiers.-import { ClientMethod, isMethod, Method } from "./method.ts"; -import { Routing } from "./routing.ts"; +import { isMethod } from "./method.ts"; +import type { ClientMethod, Method } from "./method.ts"; +import type { Routing } from "./routing.ts";Also ensure
allowImportingTsExtensions: trueis set in the root tsconfig so these specifiers compile cleanly.
83-85: Minor perf nit: avoidshift()in hot loops.
shift()is O(n); switch to an index pointer or treatstackas LIFO withpop()for linear behavior.-while (stack.length) { - const [path, element, explicitMethod] = stack.shift()!; +for (let i = 0; i < stack.length; i++) { + const [path, element, explicitMethod] = stack[i]!;tools/license.ts (1)
2-2: JSON import attribute compatibility + author shape guard
- Node 20.10.0 introduced import-attributes
with { type: "json" }without flags and TypeScript 5.9 (--module node20) follows that form; if yourengines.noderange is below 20.10.0, switch toassert { type: "json" }or bump the engine requirement.manifest.authormay be a string or an object—guard its shape:-import manifest from "../express-zod-api/package.json" with { type: "json" }; +import manifest from "../express-zod-api/package.json" assert { type: "json" }; // or keep `with { type: "json" }` if engines.node ≥20.10.0 … -const text = ` +const author = + typeof manifest.author === "string" + ? manifest.author + : manifest.author?.name ?? ""; +const text = ` MIT License Copyright (c) ${new Date().getFullYear()} ${author} … `;express-zod-api/src/diagnostics.ts (2)
8-8: Use type-only imports to avoid unnecessary runtime loads under verbatim module syntax.
ActualLoggeris used only for typing in the ctor and should be a type-only import. Also splitFlatObject(type) fromgetRoutePathParams(value) to keep emitted imports minimal.-import { FlatObject, getRoutePathParams } from "./common-helpers.ts"; -import { ActualLogger } from "./logger-helpers.ts"; +import { getRoutePathParams } from "./common-helpers.ts"; +import type { FlatObject } from "./common-helpers.ts"; +import type { ActualLogger } from "./logger-helpers.ts";Also applies to: 17-17
36-39: Prefer non-mutating context enrichment in logs.
Object.assign(ctx, ...)mutates the caller-provided ctx; use spread to avoid side effects.- Object.assign(ctx, { reason }), + { ...ctx, reason },and
- Object.assign(ctx, { reason }), + { ...ctx, reason },and
- Object.assign(ctx, { path, param }), + { ...ctx, path, param },Also applies to: 47-50, 77-79
express-zod-api/src/zts-helpers.ts (1)
2-3: Prefer type‑only imports for purely type usageBoth FlatObject and SchemaHandler are used only in types here. Mark them as type imports to avoid unintended runtime bindings under verbatimModuleSyntax.
-import { FlatObject } from "./common-helpers.ts"; -import { SchemaHandler } from "./schema-walker.ts"; +import type { FlatObject } from "./common-helpers.ts"; +import type { SchemaHandler } from "./schema-walker.ts";This aligns with TS guidance on verbatimModuleSyntax and type‑only imports. (typescriptlang.org)
express-zod-api/src/middleware.ts (1)
3-8: Split value vs type imports to avoid runtime bindingsOnly emptySchema and InputValidationError are used at runtime here. Mark the rest as type imports to keep emitted JS clean with verbatimModuleSyntax.
-import { emptySchema, FlatObject } from "./common-helpers.ts"; -import { InputValidationError } from "./errors.ts"; -import { IOSchema } from "./io-schema.ts"; -import { LogicalContainer } from "./logical-container.ts"; -import { Security } from "./security.ts"; -import { ActualLogger } from "./logger-helpers.ts"; +import { emptySchema, type FlatObject } from "./common-helpers.ts"; +import { InputValidationError } from "./errors.ts"; +import type { IOSchema } from "./io-schema.ts"; +import type { LogicalContainer } from "./logical-container.ts"; +import type { Security } from "./security.ts"; +import type { ActualLogger } from "./logger-helpers.ts";This follows TS 5.x guidance on verbatimModuleSyntax/type imports. (typescriptlang.org)
express-zod-api/src/result-handler.ts (2)
11-11: MarkActualLoggeras a type-only import to avoid emitting a runtime importIt’s used purely in types; switch to
import typeto keep JS clean under verbatim/erasable settings.Apply:
-import { ActualLogger } from "./logger-helpers.ts"; +import type { ActualLogger } from "./logger-helpers.ts";Based on learnings.
10-10: Also markIOSchemaas type-onlyIt’s used only in type positions; this avoids an extra runtime import of
./io-schema.ts.-import { IOSchema } from "./io-schema.ts"; +import type { IOSchema } from "./io-schema.ts";express-zod-api/src/sse.ts (1)
1-1: Prefer type-only imports where the symbol is types-only (TS-native friendly).To reduce unnecessary runtime imports under node20 and TS-native scenarios, make
ResponseandFlatObjecttype-only. Keep other imports as values.-import { Response } from "express"; +import type { Response } from "express"; @@ -import { FlatObject } from "./common-helpers.ts"; +import type { FlatObject } from "./common-helpers.ts";Also applies to: 3-7
example/tsconfig.json (1)
2-2: Explicitly target the example tsconfig in pretest
In example/package.json, update the pretest script to"pretest": "tsc -p example/tsconfig.json --noEmit"to avoid accidentally picking up the root tsconfig when invoking tsc from the repo root.
example/generate-documentation.ts (1)
3-5: Update JSON import assertion for Node 20 compatibility
Node.js 20.0–20.9 only supportsimport … assert { type: "json" }, whereas Node.js 20.10+ supportsimport … with { type: "json" }. To target all Node 20 LTS minors, either bump your minimum Node.js version to ≥ 20.10 or replace:-import manifest from "./package.json" with { type: "json" }; +import manifest from "./package.json" assert { type: "json" };tools/make-tests.ts (1)
3-3: No extension-less imports detected—extension normalization helper remains an optional future enhancement.express-zod-api/tests/common-helpers.spec.ts (1)
15-15: Prefer type‑only imports for types to keep runtime clean
EmptySchema,EmptyObject,CommonConfig, andInputSourcesare types in usage here. Import them viaimport typeto avoid emitting (or preserving) unnecessary runtime imports under node20/verbatim/erasable settings.-import { +import { combinations, defaultInputSources, getInput, getMessageFromError, makeCleanId, ensureError, getRoutePathParams, shouldHaveContent, getInputSources, emptySchema, - EmptySchema, - EmptyObject, } from "../src/common-helpers.ts"; +import type { EmptySchema, EmptyObject } from "../src/common-helpers.ts"; -import { CommonConfig, InputSources } from "../src/config-type.ts"; +import type { CommonConfig, InputSources } from "../src/config-type.ts";Also applies to: 17-17, 19-19
express-zod-api/src/routable.ts (1)
1-1: Use a type-only import for Routing
- Switch to
sinceimport type { Routing } from "./routing.ts";Routingis an interface and should not emit a runtime import.- Your express-zod-api/tsconfig.json doesn’t declare Node20 module mode or erasure flags—please verify your root TS config enables type-only import erasure (e.g.
importsNotUsedAsValues: "remove",verbatimModuleSyntax/erasableSyntaxOnly, or equivalent).express-zod-api/src/endpoints-factory.ts (1)
1-1: Confirm repo-wide compiler settings for Node 20 modeTo avoid surprises with the new specifier rules and JSON handling:
- Prefer
moduleResolution: "node16"withmodule: "node20".- Ensure
allowImportingTsExtensions: true; TS will rewrite.ts→.json emit.- If targeting TS-native runtimes later, keep
erasableSyntaxOnly: true(instead ofverbatimModuleSyntax) as per your issue notes.Add to root tsconfig if missing:
{ "compilerOptions": { "module": "node20", + "moduleResolution": "node16", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "erasableSyntaxOnly": true } }express-zod-api/src/integration.ts (1)
4-6: Split value vs type imports for cleaner ESM output.Use
import typeforResponseVariant,Routing,OnEndpoint,HandlingRules,ZTSContext,ClientMethodwhile keeping runtime values as value imports. This trims emitted JS and avoids accidental side‑effects under node20.Example:
-import { ResponseVariant, responseVariants } from "./api-response.ts"; +import { responseVariants } from "./api-response.ts"; +import type { ResponseVariant } from "./api-response.ts"; -import { IntegrationBase } from "./integration-base.ts"; +import { IntegrationBase } from "./integration-base.ts"; ... -import { Routing } from "./routing.ts"; -import { OnEndpoint, walkRouting, withHead } from "./routing-walker.ts"; -import { HandlingRules } from "./schema-walker.ts"; +import type { Routing } from "./routing.ts"; +import { walkRouting, withHead } from "./routing-walker.ts"; +import type { OnEndpoint } from "./routing-walker.ts"; +import type { HandlingRules } from "./schema-walker.ts"; ... -import { ZTSContext } from "./zts-helpers.ts"; +import type { ZTSContext } from "./zts-helpers.ts"; ... -import { ClientMethod } from "./method.ts"; +import type { ClientMethod } from "./method.ts";Also applies to: 16-26
express-zod-api/tests/last-resort.spec.ts (1)
2-4: Make HttpError a type‑only import to avoid named CJS import at runtime.
s/http-errorsdoesn’t expose a runtimeHttpErrorbinding; it’s a type. Import it withimport typeto prevent runtime lookup.Use:
import createHttpError from "http-errors"; import type { HttpError } from "http-errors";express-zod-api/tests/index.spec.ts (1)
4-4: Useimport typefor named types to keep tests emission clean.Prevents unnecessary runtime imports under
verbatimModuleSyntaxand aligns with prior repo practice for type‑only imports. Based on learnings.-import * as entrypoint from "../src/index.ts"; +import * as entrypoint from "../src/index.ts"; @@ -import { +import type { ApiResponse, AppConfig, BasicSecurity, BearerSecurity, CommonConfig, CookieSecurity, HeaderSecurity, Depicter, FlatObject, IOSchema, InputSecurity, LoggerOverrides, Method, OAuth2Security, OpenIdSecurity, Producer, Routing, ServerConfig, -} from "../src/index.ts"; +} from "../src/index.ts";Also applies to: 24-24
express-zod-api/tests/documentation-helpers.spec.ts (1)
4-4: Switch to explicit .ts specifiers — looks good.Tests targeting source with .ts specifiers align with node20 mode.
Optionally, add a minimal suite importing from the package entry (bare import) to catch regressions in published “exports” mapping, while keeping current tests for internal behavior.
Also applies to: 28-28
express-zod-api/src/peer-helpers.ts (1)
7-11: Don’t swallow non-not-found errors; also guard missing exportEmpty catch masks real import-time failures (e.g., syntax/runtime errors inside the peer), rethrowing MissingPeerError and hiding root cause. Also, if the requested export is absent, the current code returns undefined as T. Prefer precise handling.
Apply this diff:
export const loadPeer = async <T>( moduleName: string, moduleExport: string = "default", ): Promise<T> => { try { - return (await import(moduleName))[moduleExport]; - } catch {} - throw new MissingPeerError(moduleName); + const mod = await import(moduleName); + if (!(moduleExport in mod)) { + // export missing: surface a clear error + throw new MissingPeerError(moduleName); + } + return mod[moduleExport] as T; + } catch (err) { + const e = err as any; + const code = e?.code ?? e?.cause?.code; + if (code === "ERR_MODULE_NOT_FOUND" || code === "MODULE_NOT_FOUND") { + throw new MissingPeerError(moduleName); + } + // Different failure (e.g., peer threw during init) — propagate + throw e instanceof Error ? e : new Error(String(e)); + } };express-zod-api/tests/builtin-logger.spec.ts (1)
141-141: Avoid busy-wait in testsThe spin loop can be flaky/CPU-heavy in CI. Prefer advancing timers or stubbing performance.now().
express-zod-api/tests/result-handler.spec.ts (2)
1-1: Avoid importing types as values under Node20/TS “verbatim module” semantics.Split type-only names to
import typeto prevent runtime named-import mismatches and reduce unnecessary runtime deps in tests.Apply:
- import { Response } from "express"; + import type { Response } from "express"; @@ - } from "../src/index.ts"; + } from "../src/index.ts"; - import { AbstractResultHandler, Result } from "../src/result-handler.ts"; + import { AbstractResultHandler } from "../src/result-handler.ts"; + import type { Result } from "../src/result-handler.ts"; @@ - } from "../src/testing.ts"; + } from "../src/testing.ts";Note:
AbstractResultHandleris used at runtime (instanceof), so keep it as a value import;Resultis types-only.Also applies to: 9-11, 16-16
9-11: TS config validated:allowImportingTsExtensionsis already set totruein tsconfig.json. Optional: enableverbatimModuleSyntaxorerasableSyntaxOnlyto future-proof Node-24/JSR import handling.express-zod-api/src/server.ts (1)
5-5: Split type-only imports from value imports to be Node20/TS-runtime friendly.
AppConfig | CommonConfig | HttpConfig | ServerConfig | Parsers | Routingare used as types only. Import them withimport typeand keepinitRoutingas a value import.Apply:
-import { BuiltinLogger } from "./builtin-logger.ts"; +import { BuiltinLogger } from "./builtin-logger.ts"; @@ -import { - AppConfig, - CommonConfig, - HttpConfig, - ServerConfig, -} from "./config-type.ts"; +import type { + AppConfig, + CommonConfig, + HttpConfig, + ServerConfig, +} from "./config-type.ts"; @@ -import { isLoggerInstance } from "./logger-helpers.ts"; +import { isLoggerInstance } from "./logger-helpers.ts"; @@ -import { loadPeer } from "./peer-helpers.ts"; +import { loadPeer } from "./peer-helpers.ts"; @@ -import { defaultResultHandler } from "./result-handler.ts"; +import { defaultResultHandler } from "./result-handler.ts"; @@ -import { Parsers, Routing, initRouting } from "./routing.ts"; +import type { Parsers, Routing } from "./routing.ts"; +import { initRouting } from "./routing.ts"; @@ -import { +import { createLoggingMiddleware, createNotFoundHandler, createCatcher, createUploadParsers, makeGetLogger, installDeprecationListener, moveRaw, installTerminationListener, } from "./server-helpers.ts"; -import { printStartupLogo } from "./startup-logo.ts"; +import { printStartupLogo } from "./startup-logo.ts";This prevents accidental runtime named-import of type-only exports and keeps output clean under
verbatimModuleSyntaxor Node’s TS-native stripping.Also applies to: 11-15, 25-26
express-zod-api/src/errors.ts (1)
2-4: Use type‑only import for OpenAPIContextIt’s only used for typing; mark it as
import typeto avoid emitting runtime imports with node20 + verbatim/erasable settings.-import { OpenAPIContext } from "./documentation-helpers.ts"; +import type { OpenAPIContext } from "./documentation-helpers.ts";express-zod-api/src/testing.ts (1)
2-4: Split value vs type imports for cleaner ESM under node20Mark type‑only symbols with
import type; keep runtime values as normal imports.-import { ensureError, FlatObject, getInput } from "./common-helpers.ts"; +import { ensureError, getInput } from "./common-helpers.ts"; +import type { FlatObject } from "./common-helpers.ts"; -import { CommonConfig } from "./config-type.ts"; +import type { CommonConfig } from "./config-type.ts"; -import { AbstractEndpoint } from "./endpoint.ts"; +import type { AbstractEndpoint } from "./endpoint.ts"; -import { - AbstractLogger, - ActualLogger, - isSeverity, - Severity, -} from "./logger-helpers.ts"; +import { isSeverity } from "./logger-helpers.ts"; +import type { AbstractLogger, ActualLogger, Severity } from "./logger-helpers.ts"; -import { AbstractMiddleware } from "./middleware.ts"; +import type { AbstractMiddleware } from "./middleware.ts";Also applies to: 10-11, 18-19
express-zod-api/src/endpoint.ts (1)
4-6: Useimport typefor pure type imports
Updateexpress-zod-api/src/endpoint.tsso that all type-only symbols are imported withimport type, leaving value imports untouched:-import { NormalizedResponse, ResponseVariant } from "./api-response.ts"; +import type { NormalizedResponse, ResponseVariant } from "./api-response.ts"; -import { - FlatObject, - getActualMethod, - getInput, - ensureError, - isSchema, -} from "./common-helpers.ts"; +import { getActualMethod, getInput, ensureError, isSchema } from "./common-helpers.ts"; +import type { FlatObject } from "./common-helpers.ts"; -import { CommonConfig } from "./config-type.ts"; +import type { CommonConfig } from "./config-type.ts"; -import { IOSchema } from "./io-schema.ts"; +import type { IOSchema } from "./io-schema.ts"; -import { ActualLogger } from "./logger-helpers.ts"; +import type { ActualLogger } from "./logger-helpers.ts"; -import { LogicalContainer } from "./logical-container.ts"; +import type { LogicalContainer } from "./logical-container.ts"; -import { ClientMethod, CORSMethod, Method } from "./method.ts"; +import type { ClientMethod, CORSMethod, Method } from "./method.ts"; -import { AbstractMiddleware, ExpressMiddleware } from "./middleware.ts"; +import { ExpressMiddleware } from "./middleware.ts"; +import type { AbstractMiddleware } from "./middleware.ts"; -import { ContentType } from "./content-type.ts"; +import type { ContentType } from "./content-type.ts"; -import { DiscriminatedResult, pullResponseExamples } from "./result-helpers.ts"; +import { pullResponseExamples } from "./result-helpers.ts"; +import type { DiscriminatedResult } from "./result-helpers.ts"; -import { AbstractResultHandler } from "./result-handler.ts"; +import type { AbstractResultHandler } from "./result-handler.ts"; -import { Security } from "./security.ts"; +import type { Security } from "./security.ts";Ensure your root
tsconfig.jsonis configured for TypeScript 5.9 targeting Node.js 20 ESM, for example:{ "compilerOptions": { "module": "node20", "moduleResolution": "node20", "target": "es2023", "allowImportingTsExtensions": true, "rewriteRelativeImportExtensions": true } }Rebuild and confirm the emitted JavaScript uses
.jsimport specifiers and contains no runtime imports for types.express-zod-api/src/documentation-helpers.ts (1)
1-1: Preferimport typefor type‑only symbols (future‑proof w/ verbatimModuleSyntax)Under
module: node20, ifverbatimModuleSyntaxis ever enabled, plain imports that are used only as types will become runtime imports. Mark them astypenow to be safe and clearer.Suggested diff:
- import { - ExamplesObject, - isReferenceObject, - isSchemaObject, - MediaTypeObject, - OAuthFlowObject, - ParameterObject, - ReferenceObject, - RequestBodyObject, - ResponseObject, - SchemaObject, - SchemaObjectType, - SecurityRequirementObject, - SecuritySchemeObject, - TagObject, - } from "openapi3-ts/oas31"; + import type { + ExamplesObject, + MediaTypeObject, + OAuthFlowObject, + ParameterObject, + ReferenceObject, + RequestBodyObject, + ResponseObject, + SchemaObject, + SchemaObjectType, + SecurityRequirementObject, + SecuritySchemeObject, + TagObject, + } from "openapi3-ts/oas31"; + import { isReferenceObject, isSchemaObject } from "openapi3-ts/oas31";- import { NormalizedResponse, ResponseVariant } from "./api-response.ts"; + import type { NormalizedResponse, ResponseVariant } from "./api-response.ts";- } from "./common-helpers.ts"; + type FlatObject, + type Tag, + } from "./common-helpers.ts";- import { InputSource } from "./config-type.ts"; + import type { InputSource } from "./config-type.ts";- import { IOSchema } from "./io-schema.ts"; + import type { IOSchema } from "./io-schema.ts";- import { Alternatives } from "./logical-container.ts"; + import type { Alternatives } from "./logical-container.ts";- import { ClientMethod } from "./method.ts"; + import type { ClientMethod } from "./method.ts";- import { ProprietaryBrand } from "./proprietary-schemas.ts"; + import type { ProprietaryBrand } from "./proprietary-schemas.ts";- import { FirstPartyKind } from "./schema-walker.ts"; + import type { FirstPartyKind } from "./schema-walker.ts";- import { Security } from "./security.ts"; + import type { Security } from "./security.ts";This keeps value imports (e.g., brands, helpers,
contentTypes) intact while making type usage explicit.If you prefer not to change imports, confirm tsconfig keeps
"erasableSyntaxOnly": true(and does not enableverbatimModuleSyntax).Also applies to: 19-19, 33-33, 34-34, 39-39, 41-41, 43-43, 44-44, 46-46, 47-47
express-zod-api/src/result-helpers.ts (1)
5-5: Make these imports type-only to avoid unnecessary runtime edges.They’re only used in types here; switch to
import typeto prevent loadingapi-response.tsat runtime.-import { NormalizedResponse, ResponseVariant } from "./api-response.ts"; +import type { NormalizedResponse, ResponseVariant } from "./api-response.ts";express-zod-api/src/integration-base.ts (1)
3-3: Use a type-only import for ResponseVariant.It’s only a type here; avoid a value import to keep runtime clean.
-import { ResponseVariant } from "./api-response.ts"; +import type { ResponseVariant } from "./api-response.ts";express-zod-api/src/server-helpers.ts (1)
14-14: HardenlocalsIDagainst missingmanifest.name.If
package.jsonname is undefined during tests/build,Symbol.for(undefined)throws. Add a safe fallback.-export const localsID = Symbol.for(manifest.name); +const manifestName = manifest?.name ?? "express-zod-api"; +export const localsID = Symbol.for(manifestName);
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (107)
compat-test/quick-start.spec.ts(1 hunks)esm-test/quick-start.spec.ts(1 hunks)esm-test/tsconfig.json(0 hunks)example/config.ts(1 hunks)example/endpoints/create-user.ts(1 hunks)example/endpoints/delete-user.ts(1 hunks)example/endpoints/list-users.ts(1 hunks)example/endpoints/retrieve-user.ts(1 hunks)example/endpoints/send-avatar.ts(1 hunks)example/endpoints/stream-avatar.ts(1 hunks)example/endpoints/time-subscription.ts(1 hunks)example/endpoints/update-user.ts(1 hunks)example/factories.ts(1 hunks)example/generate-client.ts(1 hunks)example/generate-documentation.ts(1 hunks)example/index.spec.ts(1 hunks)example/index.ts(1 hunks)example/routing.ts(1 hunks)example/tsconfig.json(1 hunks)express-zod-api/src/builtin-logger.ts(1 hunks)express-zod-api/src/common-helpers.ts(1 hunks)express-zod-api/src/config-type.ts(1 hunks)express-zod-api/src/deep-checks.ts(1 hunks)express-zod-api/src/depends-on-method.ts(1 hunks)express-zod-api/src/diagnostics.ts(1 hunks)express-zod-api/src/documentation-helpers.ts(2 hunks)express-zod-api/src/documentation.ts(2 hunks)express-zod-api/src/endpoint.ts(1 hunks)express-zod-api/src/endpoints-factory.ts(1 hunks)express-zod-api/src/errors.ts(1 hunks)express-zod-api/src/graceful-shutdown.ts(1 hunks)express-zod-api/src/index.ts(2 hunks)express-zod-api/src/integration-base.ts(2 hunks)express-zod-api/src/integration.ts(2 hunks)express-zod-api/src/json-schema-helpers.ts(1 hunks)express-zod-api/src/last-resort.ts(1 hunks)express-zod-api/src/logger-helpers.ts(1 hunks)express-zod-api/src/logical-container.ts(1 hunks)express-zod-api/src/middleware.ts(1 hunks)express-zod-api/src/peer-helpers.ts(1 hunks)express-zod-api/src/proprietary-schemas.ts(1 hunks)express-zod-api/src/raw-schema.ts(1 hunks)express-zod-api/src/result-handler.ts(1 hunks)express-zod-api/src/result-helpers.ts(1 hunks)express-zod-api/src/routable.ts(1 hunks)express-zod-api/src/routing-walker.ts(1 hunks)express-zod-api/src/routing.ts(1 hunks)express-zod-api/src/schema-walker.ts(1 hunks)express-zod-api/src/server-helpers.ts(1 hunks)express-zod-api/src/server.ts(2 hunks)express-zod-api/src/sse.ts(1 hunks)express-zod-api/src/testing.ts(1 hunks)express-zod-api/src/zts-helpers.ts(1 hunks)express-zod-api/src/zts.ts(1 hunks)express-zod-api/tests/api-response.spec.ts(1 hunks)express-zod-api/tests/buffer-schema.spec.ts(1 hunks)express-zod-api/tests/builtin-logger.spec.ts(1 hunks)express-zod-api/tests/common-helpers.spec.ts(1 hunks)express-zod-api/tests/config-type.spec.ts(1 hunks)express-zod-api/tests/content-type.spec.ts(1 hunks)express-zod-api/tests/date-in-schema.spec.ts(1 hunks)express-zod-api/tests/date-out-schema.spec.ts(1 hunks)express-zod-api/tests/deep-checks.spec.ts(1 hunks)express-zod-api/tests/depends-on-method.spec.ts(1 hunks)express-zod-api/tests/documentation-helpers.spec.ts(2 hunks)express-zod-api/tests/documentation.spec.ts(1 hunks)express-zod-api/tests/endpoint.spec.ts(1 hunks)express-zod-api/tests/endpoints-factory.spec.ts(1 hunks)express-zod-api/tests/errors.spec.ts(1 hunks)express-zod-api/tests/form-schema.spec.ts(1 hunks)express-zod-api/tests/graceful-helpers.spec.ts(1 hunks)express-zod-api/tests/graceful-shutdown.spec.ts(1 hunks)express-zod-api/tests/index.spec.ts(2 hunks)express-zod-api/tests/integration.spec.ts(1 hunks)express-zod-api/tests/io-schema.spec.ts(1 hunks)express-zod-api/tests/json-schema-helpers.spec.ts(1 hunks)express-zod-api/tests/last-resort.spec.ts(1 hunks)express-zod-api/tests/logger-helpers.spec.ts(1 hunks)express-zod-api/tests/logical-container.spec.ts(1 hunks)express-zod-api/tests/method.spec.ts(1 hunks)express-zod-api/tests/middleware.spec.ts(1 hunks)express-zod-api/tests/peer-helpers.spec.ts(1 hunks)express-zod-api/tests/raw-schema.spec.ts(1 hunks)express-zod-api/tests/result-handler.spec.ts(1 hunks)express-zod-api/tests/result-helpers.spec.ts(1 hunks)express-zod-api/tests/routable.spec.ts(1 hunks)express-zod-api/tests/routing.spec.ts(2 hunks)express-zod-api/tests/serve-static.spec.ts(1 hunks)express-zod-api/tests/server-helpers.spec.ts(2 hunks)express-zod-api/tests/server.spec.ts(2 hunks)express-zod-api/tests/sse.spec.ts(1 hunks)express-zod-api/tests/startup-logo.spec.ts(1 hunks)express-zod-api/tests/system.spec.ts(1 hunks)express-zod-api/tests/testing.spec.ts(1 hunks)express-zod-api/tests/upload-schema.spec.ts(1 hunks)express-zod-api/tests/zts.spec.ts(1 hunks)express-zod-api/tsconfig.json(0 hunks)express-zod-api/vitest.setup.ts(1 hunks)migration/index.spec.ts(2 hunks)migration/tsconfig.json(1 hunks)tools/license.ts(1 hunks)tools/make-tests.ts(2 hunks)tools/tsconfig.json(1 hunks)tsconfig.json(1 hunks)zod-plugin/src/augmentation.ts(1 hunks)zod-plugin/src/brand.ts(1 hunks)zod-plugin/src/index.ts(1 hunks)
⛔ Files not processed due to max files limit (7)
- zod-plugin/src/runtime.ts
- zod-plugin/tests/brand.spec.ts
- zod-plugin/tests/index.spec.ts
- zod-plugin/tests/packer.spec.ts
- zod-plugin/tests/runtime.spec.ts
- zod-plugin/tsconfig.json
- zod-plugin/vitest.setup.ts
💤 Files with no reviewable changes (2)
- express-zod-api/tsconfig.json
- esm-test/tsconfig.json
🧰 Additional context used
🧠 Learnings (24)
📚 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/tests/common-helpers.spec.tscompat-test/quick-start.spec.tsexpress-zod-api/src/json-schema-helpers.tsexpress-zod-api/src/sse.tsexpress-zod-api/vitest.setup.tsexpress-zod-api/tests/sse.spec.tsexpress-zod-api/tests/testing.spec.tsexpress-zod-api/tests/documentation.spec.tsexpress-zod-api/src/testing.tstools/license.tstools/make-tests.tsexpress-zod-api/src/config-type.tsexpress-zod-api/tests/form-schema.spec.tsexpress-zod-api/tests/peer-helpers.spec.tsexpress-zod-api/tests/buffer-schema.spec.tsexpress-zod-api/tests/startup-logo.spec.tsexample/index.tsexpress-zod-api/src/deep-checks.tsexpress-zod-api/src/integration-base.tszod-plugin/src/augmentation.tsexample/factories.tsexpress-zod-api/tests/errors.spec.tsexpress-zod-api/tests/api-response.spec.tsexpress-zod-api/tests/result-helpers.spec.tsexpress-zod-api/tests/graceful-shutdown.spec.tsexpress-zod-api/tests/raw-schema.spec.tsexpress-zod-api/src/proprietary-schemas.tsexpress-zod-api/src/routing-walker.tsexpress-zod-api/tests/index.spec.tsexpress-zod-api/tests/deep-checks.spec.tsexpress-zod-api/tests/integration.spec.tsexample/routing.tsexpress-zod-api/src/server-helpers.tsexpress-zod-api/tests/server-helpers.spec.tsexpress-zod-api/src/builtin-logger.tsexpress-zod-api/src/graceful-shutdown.tsexpress-zod-api/src/middleware.tsexpress-zod-api/src/last-resort.tsexpress-zod-api/src/diagnostics.tsexample/index.spec.tsexpress-zod-api/tests/documentation-helpers.spec.tsexpress-zod-api/tests/server.spec.tsexpress-zod-api/src/zts.tsexpress-zod-api/src/zts-helpers.tsexpress-zod-api/tests/result-handler.spec.tsexpress-zod-api/tests/io-schema.spec.tsexpress-zod-api/tests/date-in-schema.spec.tsexpress-zod-api/tests/system.spec.tsexpress-zod-api/src/errors.tsexample/endpoints/retrieve-user.tsexpress-zod-api/src/result-handler.tsexpress-zod-api/tests/last-resort.spec.tsexpress-zod-api/tests/routing.spec.tsexpress-zod-api/tests/method.spec.tsexpress-zod-api/tests/serve-static.spec.tsexpress-zod-api/tests/content-type.spec.tsexpress-zod-api/src/schema-walker.tsexpress-zod-api/tests/json-schema-helpers.spec.tsexpress-zod-api/src/integration.tsexpress-zod-api/tests/date-out-schema.spec.tsexpress-zod-api/tests/zts.spec.tsexpress-zod-api/tests/routable.spec.tsexpress-zod-api/src/endpoints-factory.tsexpress-zod-api/src/documentation-helpers.tsexpress-zod-api/src/depends-on-method.tsexpress-zod-api/tests/config-type.spec.tszod-plugin/src/brand.tsexpress-zod-api/tests/graceful-helpers.spec.tsexpress-zod-api/src/routing.tsexpress-zod-api/src/routable.tsexpress-zod-api/tests/middleware.spec.tsexpress-zod-api/src/common-helpers.tsexpress-zod-api/src/server.tsexpress-zod-api/tests/logical-container.spec.tsexpress-zod-api/src/raw-schema.tsexpress-zod-api/src/documentation.tsexpress-zod-api/src/peer-helpers.tsesm-test/quick-start.spec.tsexpress-zod-api/src/index.tsexpress-zod-api/tests/upload-schema.spec.tsexpress-zod-api/tests/depends-on-method.spec.tsexpress-zod-api/src/result-helpers.tsexample/config.tsexpress-zod-api/tests/endpoints-factory.spec.tsexample/generate-documentation.tsexpress-zod-api/src/endpoint.tsexpress-zod-api/tests/endpoint.spec.ts
📚 Learning: 2025-05-27T19:35:57.357Z
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2546
File: express-zod-api/tests/buffer-schema.spec.ts:32-37
Timestamp: 2025-05-27T19:35:57.357Z
Learning: In the express-zod-api project, tests are run from the `express-zod-api` workspace directory, and the project uses an ESM-first environment without `__dirname`. Relative paths like `../logo.svg` in test files correctly resolve to the repository root due to this test execution context.
Applied to files:
express-zod-api/tests/common-helpers.spec.tsexpress-zod-api/vitest.setup.tsexpress-zod-api/tests/sse.spec.tsexpress-zod-api/tests/testing.spec.tsexpress-zod-api/tests/documentation.spec.tsexpress-zod-api/src/testing.tsexpress-zod-api/tests/form-schema.spec.tsexpress-zod-api/tests/buffer-schema.spec.tsexpress-zod-api/tests/startup-logo.spec.tsexpress-zod-api/tests/errors.spec.tsexpress-zod-api/tests/api-response.spec.tsexpress-zod-api/tests/result-helpers.spec.tsexpress-zod-api/tests/raw-schema.spec.tsexpress-zod-api/tests/index.spec.tsexpress-zod-api/tests/deep-checks.spec.tsexpress-zod-api/tests/integration.spec.tsexpress-zod-api/tests/server-helpers.spec.tsexpress-zod-api/tests/documentation-helpers.spec.tsexpress-zod-api/tests/server.spec.tsexpress-zod-api/src/zts.tsexpress-zod-api/tests/result-handler.spec.tsexpress-zod-api/tests/io-schema.spec.tsexpress-zod-api/tests/date-in-schema.spec.tsexpress-zod-api/tests/system.spec.tsexpress-zod-api/tests/last-resort.spec.tsexpress-zod-api/tests/routing.spec.tsexpress-zod-api/tests/method.spec.tsexpress-zod-api/tests/builtin-logger.spec.tsexpress-zod-api/tests/serve-static.spec.tsexpress-zod-api/tests/content-type.spec.tsexpress-zod-api/tests/json-schema-helpers.spec.tsexpress-zod-api/src/integration.tsexpress-zod-api/tests/zts.spec.tsexpress-zod-api/tests/routable.spec.tsexpress-zod-api/tests/config-type.spec.tsexpress-zod-api/tests/logger-helpers.spec.tsexpress-zod-api/tests/graceful-helpers.spec.tsexpress-zod-api/tests/middleware.spec.tsexpress-zod-api/src/server.tsexpress-zod-api/tests/logical-container.spec.tsexpress-zod-api/tests/upload-schema.spec.tsexpress-zod-api/tests/depends-on-method.spec.tsexpress-zod-api/tests/endpoints-factory.spec.tsexpress-zod-api/tests/endpoint.spec.ts
📚 Learning: 2025-06-14T16:42:52.972Z
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2736
File: express-zod-api/tsup.config.ts:12-26
Timestamp: 2025-06-14T16:42:52.972Z
Learning: In express-zod-api tsup configurations, the direct mutation of `options.supported` in the `esbuildOptions` callback is intentional behavior and should not be flagged as a side effect issue.
Applied to files:
express-zod-api/tests/common-helpers.spec.tsexpress-zod-api/src/sse.tsexpress-zod-api/tests/sse.spec.tsexpress-zod-api/tests/testing.spec.tsexpress-zod-api/tests/documentation.spec.tsexpress-zod-api/src/testing.tsexpress-zod-api/src/config-type.tsexpress-zod-api/tests/buffer-schema.spec.tsexpress-zod-api/src/deep-checks.tsexpress-zod-api/src/integration-base.tsexpress-zod-api/tests/graceful-shutdown.spec.tsexpress-zod-api/tests/raw-schema.spec.tsexpress-zod-api/src/proprietary-schemas.tsexpress-zod-api/src/routing-walker.tsexpress-zod-api/tests/index.spec.tsexpress-zod-api/tests/deep-checks.spec.tsexpress-zod-api/tests/server-helpers.spec.tsexpress-zod-api/src/graceful-shutdown.tsexpress-zod-api/src/middleware.tsexpress-zod-api/src/last-resort.tsexpress-zod-api/src/diagnostics.tsexpress-zod-api/src/zts.tsexpress-zod-api/src/zts-helpers.tsexpress-zod-api/tests/io-schema.spec.tsexpress-zod-api/src/errors.tsexpress-zod-api/src/result-handler.tsexpress-zod-api/tests/last-resort.spec.tsexample/tsconfig.jsonexpress-zod-api/tests/content-type.spec.tsexpress-zod-api/tests/json-schema-helpers.spec.tsexpress-zod-api/src/integration.tsexpress-zod-api/tests/zts.spec.tsexpress-zod-api/src/documentation-helpers.tsexpress-zod-api/src/depends-on-method.tsexpress-zod-api/tests/graceful-helpers.spec.tsexpress-zod-api/src/routing.tsexpress-zod-api/src/common-helpers.tsexpress-zod-api/src/server.tsexpress-zod-api/src/raw-schema.tsexpress-zod-api/src/documentation.tsexpress-zod-api/src/index.ts
📚 Learning: 2025-06-02T21:08:56.475Z
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2697
File: CHANGELOG.md:5-5
Timestamp: 2025-06-02T21:08:56.475Z
Learning: The `cjs-test` directory in the express-zod-api repository is a test workspace and should be excluded when checking for main project version consistency with changelog entries.
Applied to files:
express-zod-api/tests/common-helpers.spec.tsexpress-zod-api/tests/sse.spec.tsexpress-zod-api/tests/testing.spec.tsexpress-zod-api/tests/documentation.spec.tsexpress-zod-api/src/testing.tsexpress-zod-api/tests/buffer-schema.spec.tsexpress-zod-api/tests/startup-logo.spec.tsexpress-zod-api/tests/api-response.spec.tsexpress-zod-api/tests/graceful-shutdown.spec.tsexpress-zod-api/tests/raw-schema.spec.tsexpress-zod-api/tests/index.spec.tsexpress-zod-api/tests/deep-checks.spec.tsexpress-zod-api/tests/integration.spec.tsexpress-zod-api/tests/documentation-helpers.spec.tsexpress-zod-api/tests/server.spec.tsexpress-zod-api/src/zts.tsexpress-zod-api/tests/io-schema.spec.tsexpress-zod-api/tests/date-in-schema.spec.tsexpress-zod-api/tests/system.spec.tsexpress-zod-api/tests/last-resort.spec.tsexpress-zod-api/tests/routing.spec.tsexpress-zod-api/tests/method.spec.tsexpress-zod-api/tests/serve-static.spec.tsexpress-zod-api/tests/content-type.spec.tsexpress-zod-api/tests/json-schema-helpers.spec.tsexpress-zod-api/tests/zts.spec.tsexpress-zod-api/tests/config-type.spec.tsexpress-zod-api/tests/middleware.spec.tsexpress-zod-api/tests/logical-container.spec.tsexpress-zod-api/tests/depends-on-method.spec.ts
📚 Learning: 2025-08-01T09:48:13.742Z
Learnt from: RobinTail
PR: RobinTail/express-zod-api#0
File: :0-0
Timestamp: 2025-08-01T09:48:13.742Z
Learning: In express-zod-api, when migrating from Zod v3 to v4, the correct approach for internal type imports is to change from `import type { $ZodType } from "zod/v4/core"` to `import { z } from "zod"` and then use `z.core.$ZodType`. The zod/v4/core module is reexported as z.core by the main zod package, making this a valid and working approach.
Applied to files:
express-zod-api/tests/common-helpers.spec.tsexpress-zod-api/src/json-schema-helpers.tsexpress-zod-api/src/sse.tsexpress-zod-api/vitest.setup.tsexpress-zod-api/tests/testing.spec.tsexpress-zod-api/tests/documentation.spec.tsexpress-zod-api/src/testing.tstools/license.tsexpress-zod-api/src/config-type.tsexpress-zod-api/tests/form-schema.spec.tsexpress-zod-api/tests/buffer-schema.spec.tsexpress-zod-api/src/deep-checks.tsexpress-zod-api/src/integration-base.tszod-plugin/src/augmentation.tsexpress-zod-api/tests/errors.spec.tsexpress-zod-api/tests/api-response.spec.tsexpress-zod-api/tests/result-helpers.spec.tsexpress-zod-api/tests/raw-schema.spec.tsexpress-zod-api/src/proprietary-schemas.tsexpress-zod-api/src/logical-container.tsexpress-zod-api/tests/index.spec.tsexpress-zod-api/tests/deep-checks.spec.tsexpress-zod-api/tests/integration.spec.tsexpress-zod-api/src/server-helpers.tsexpress-zod-api/src/graceful-shutdown.tsexpress-zod-api/src/middleware.tsexpress-zod-api/src/last-resort.tsexpress-zod-api/tests/documentation-helpers.spec.tsexpress-zod-api/tests/server.spec.tsexpress-zod-api/src/zts.tsexpress-zod-api/src/zts-helpers.tsexpress-zod-api/tests/result-handler.spec.tsexpress-zod-api/tests/io-schema.spec.tsexpress-zod-api/tests/date-in-schema.spec.tsexpress-zod-api/tests/system.spec.tsexpress-zod-api/src/errors.tsexpress-zod-api/src/result-handler.tsexpress-zod-api/tests/last-resort.spec.tsexpress-zod-api/tests/method.spec.tsexpress-zod-api/tests/content-type.spec.tsexpress-zod-api/src/schema-walker.tsexpress-zod-api/tests/json-schema-helpers.spec.tsexpress-zod-api/src/integration.tsexpress-zod-api/tests/date-out-schema.spec.tsexpress-zod-api/tests/zts.spec.tsexpress-zod-api/tests/routable.spec.tsexpress-zod-api/src/endpoints-factory.tsexpress-zod-api/src/documentation-helpers.tsexpress-zod-api/src/depends-on-method.tsexpress-zod-api/tests/config-type.spec.tszod-plugin/src/brand.tsexpress-zod-api/src/routing.tsexpress-zod-api/src/routable.tsexpress-zod-api/tests/middleware.spec.tsexpress-zod-api/src/common-helpers.tsexpress-zod-api/src/server.tsexpress-zod-api/src/raw-schema.tsexpress-zod-api/src/documentation.tsexpress-zod-api/src/index.tsexpress-zod-api/tests/depends-on-method.spec.tsexpress-zod-api/src/result-helpers.tszod-plugin/src/index.tsexpress-zod-api/src/endpoint.ts
📚 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: The JSONSchema type is not exported from the main "zod" module and must be imported from "zod/v4/core" when using Zod v4. This is acceptable for type-only imports as they don't create runtime dependencies.
Applied to files:
express-zod-api/src/json-schema-helpers.tsexpress-zod-api/src/deep-checks.tszod-plugin/src/augmentation.tsexpress-zod-api/tests/io-schema.spec.tszod-plugin/src/brand.tsexpress-zod-api/src/raw-schema.ts
📚 Learning: 2025-05-27T20:40:19.548Z
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2546
File: express-zod-api/src/json-schema-helpers.ts:75-87
Timestamp: 2025-05-27T20:40:19.548Z
Learning: In express-zod-api's `flattenIO` function in json-schema-helpers.ts, the `additionalProperties` field is used as a template to generate property schemas for literal property names extracted from `propertyNames.const` and `propertyNames.enum`. Converting boolean `additionalProperties` values to empty objects `{}` via `Object(entry.additionalProperties)` is intentional behavior, as the function only needs property schema templates, not the boolean semantics of `additionalProperties`.
Applied to files:
express-zod-api/src/json-schema-helpers.tsexpress-zod-api/tests/json-schema-helpers.spec.ts
📚 Learning: 2025-08-08T11:59:04.814Z
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2878
File: zod-plugin/runtime.ts:39-42
Timestamp: 2025-08-08T11:59:04.814Z
Learning: express-zod-api/zod-plugin/runtime.ts (TypeScript): Do not memoize the ZodType.prototype.brand getter. The current design returning setBrand.bind(this) on each access is intentional/preferred; avoid redefining "brand" as a data property per instance.
Applied to files:
express-zod-api/vitest.setup.tsexpress-zod-api/src/config-type.tsexpress-zod-api/tests/form-schema.spec.tsexpress-zod-api/src/deep-checks.tsexpress-zod-api/tests/raw-schema.spec.tsexpress-zod-api/src/proprietary-schemas.tsexpress-zod-api/src/zts.tsexpress-zod-api/tests/date-in-schema.spec.tsexpress-zod-api/src/schema-walker.tsexpress-zod-api/tests/date-out-schema.spec.tszod-plugin/src/brand.tsexpress-zod-api/src/raw-schema.tsexpress-zod-api/tests/upload-schema.spec.tszod-plugin/src/index.ts
📚 Learning: 2025-08-08T16:45:20.527Z
Learnt from: RobinTail
PR: RobinTail/express-zod-api#0
File: :0-0
Timestamp: 2025-08-08T16:45:20.527Z
Learning: express-zod-api/zod-plugin: The brand setter must be immutable and always invoke pack→.check() via the getter-bound setBrand. Including brandProperty with an explicit undefined enables unbranding and should not be optimized away.
Applied to files:
express-zod-api/vitest.setup.tsexpress-zod-api/tests/raw-schema.spec.tsexpress-zod-api/tests/date-in-schema.spec.tsexpress-zod-api/src/schema-walker.tszod-plugin/src/brand.tsexpress-zod-api/src/raw-schema.tsexpress-zod-api/tests/upload-schema.spec.tszod-plugin/src/index.ts
📚 Learning: 2025-08-08T16:45:20.527Z
Learnt from: RobinTail
PR: RobinTail/express-zod-api#0
File: :0-0
Timestamp: 2025-08-08T16:45:20.527Z
Learning: express-zod-api/zod-plugin: The ZodType.prototype.brand getter returns setBrand.bind(this) each time (no memoization). setBrand must always call pack() and include { brand: undefined } when unbranding so that pack → .check() runs and prior brand is overwritten; do not suggest removing the explicit undefined entry.
Applied to files:
express-zod-api/vitest.setup.tsexpress-zod-api/tests/form-schema.spec.tsexpress-zod-api/src/deep-checks.tsexpress-zod-api/tests/raw-schema.spec.tsexpress-zod-api/tests/date-in-schema.spec.tsexpress-zod-api/src/schema-walker.tsexpress-zod-api/tests/date-out-schema.spec.tszod-plugin/src/brand.tsexpress-zod-api/src/raw-schema.tsexpress-zod-api/tests/upload-schema.spec.tszod-plugin/src/index.ts
📚 Learning: 2025-08-08T16:45:20.527Z
Learnt from: RobinTail
PR: RobinTail/express-zod-api#0
File: :0-0
Timestamp: 2025-08-08T16:45:20.527Z
Learning: In express-zod-api zod-plugin, the brand setter must be immutable and always call `.check()` (packer’s onattach). Therefore, writing an explicit undefined entry in the bag for brand is intentional and should not be suggested for removal.
Applied to files:
express-zod-api/vitest.setup.tsexpress-zod-api/tests/raw-schema.spec.tsexpress-zod-api/src/schema-walker.tszod-plugin/src/brand.tsexpress-zod-api/src/raw-schema.tszod-plugin/src/index.ts
📚 Learning: 2025-08-08T16:45:20.527Z
Learnt from: RobinTail
PR: RobinTail/express-zod-api#0
File: :0-0
Timestamp: 2025-08-08T16:45:20.527Z
Learning: express-zod-api zod-plugin: The brand setter must stay immutable and always invoke pack→.check() (onattach). Including brandProperty with an explicit undefined enables “unbranding” (overwriting a previous brand) and should not be optimized away.
Applied to files:
express-zod-api/vitest.setup.tsexpress-zod-api/tests/raw-schema.spec.tsexpress-zod-api/src/schema-walker.tszod-plugin/src/brand.tszod-plugin/src/index.ts
📚 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:
tools/license.tsexpress-zod-api/src/deep-checks.tsexpress-zod-api/src/common-helpers.ts
📚 Learning: 2025-06-02T21:11:20.768Z
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2697
File: CHANGELOG.md:5-5
Timestamp: 2025-06-02T21:11:20.768Z
Learning: In the express-zod-api repository, RobinTail follows a release workflow where package.json version is only updated on the master branch after merging all planned release changes. Changelog entries may show future version numbers while package.json remains at the previous version during feature development, and this is intentional workflow, not a version inconsistency that needs to be flagged.
Applied to files:
tools/license.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:
tools/license.tsexample/factories.tsexpress-zod-api/tests/errors.spec.tsexample/routing.tsexample/endpoints/retrieve-user.tsexpress-zod-api/tests/routable.spec.tsexample/generate-client.tsexample/generate-documentation.ts
📚 Learning: 2025-05-27T19:30:51.885Z
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2546
File: compat-test/sample.ts:1-1
Timestamp: 2025-05-27T19:30:51.885Z
Learning: Files in compat-test/ directories, especially those named sample.ts or similar, are often test fixtures for migration scripts and may intentionally contain deprecated or "incorrect" code that the migration tooling is designed to fix. These should not be flagged as issues.
Applied to files:
tools/make-tests.tsexpress-zod-api/tests/last-resort.spec.tsexpress-zod-api/tests/zts.spec.tsmigration/index.spec.ts
📚 Learning: 2025-05-27T19:27:13.492Z
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2546
File: express-zod-api/tests/form-schema.spec.ts:31-31
Timestamp: 2025-05-27T19:27:13.492Z
Learning: Zod version 3.25.0 and later expose the Zod v4 API through the special import paths "zod/v4" and "zod/v4/core", allowing v4 features like .loose() to be used even when the package.json dependency shows a 3.x version.
Applied to files:
zod-plugin/src/augmentation.ts
📚 Learning: 2025-05-28T05:49:36.540Z
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2546
File: express-zod-api/src/common-helpers.ts:64-69
Timestamp: 2025-05-28T05:49:36.540Z
Learning: ZodError does not extend Error, but ZodRealError does extend Error. This is why in ensureError functions, you need to check for ZodError separately and wrap it in ZodRealError to convert it to a proper Error instance.
Applied to files:
express-zod-api/tests/errors.spec.ts
📚 Learning: 2025-05-28T05:04:40.327Z
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2546
File: express-zod-api/src/io-schema.ts:5-8
Timestamp: 2025-05-28T05:04:40.327Z
Learning: The Base type `object & { [Symbol.iterator]?: never }` in express-zod-api correctly excludes arrays and other iterables from IOSchema. Arrays are properly rejected because they have a defined Symbol.iterator method which conflicts with the never constraint, as demonstrated by TypeScript compiler errors when attempting to assign z.array() to IOSchema.
Applied to files:
express-zod-api/tests/io-schema.spec.tsexample/endpoints/retrieve-user.tsexpress-zod-api/tests/json-schema-helpers.spec.ts
📚 Learning: 2025-09-28T10:09:35.674Z
Learnt from: RobinTail
PR: RobinTail/express-zod-api#0
File: :0-0
Timestamp: 2025-09-28T10:09:35.674Z
Learning: In TypeScript configuration, when `strict: true` is set (including through extended configurations like tsconfig/node20), it automatically enables strictNullChecks along with other strict type-checking options, making explicit `strictNullChecks: true` redundant.
Applied to files:
example/tsconfig.json
📚 Learning: 2025-07-20T11:09:58.980Z
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2833
File: express-zod-api/src/method.ts:3-3
Timestamp: 2025-07-20T11:09:58.980Z
Learning: In express-zod-api, the `SomeMethod` type (defined as `Lowercase<string>`) is intentionally broad to represent raw, unvalidated HTTP methods from requests. The narrower `Method` type is used after validation with `isMethod()`. This defensive programming pattern separates raw external input types from validated types, allowing graceful handling of unknown methods.
Applied to files:
express-zod-api/tests/method.spec.ts
📚 Learning: 2025-05-27T20:22:30.428Z
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2546
File: express-zod-api/tests/zts.spec.ts:160-162
Timestamp: 2025-05-27T20:22:30.428Z
Learning: In express-zod-api/tests/zts.spec.ts, the `Fruits` enum intentionally contains both string and numeric members (Apple = "apple", Banana = "banana", Cantaloupe = "cantaloupe", A = 5) and is used with `z.enum(Fruits)` to test how the system handles mixed enum types. This is by design for testing purposes.
Applied to files:
express-zod-api/tests/zts.spec.ts
📚 Learning: 2025-09-26T09:00:24.416Z
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2965
File: express-zod-api/src/sse.ts:0-0
Timestamp: 2025-09-26T09:00:24.416Z
Learning: In express-zod-api SSE implementation, the ensureStream function checks response.headersSent before calling response.writeHead, which prevents writing to closed responses even if setTimeout fires after client disconnect. No cleanup of the headers timeout is needed.
Applied to files:
example/endpoints/time-subscription.ts
📚 Learning: 2025-08-25T17:43:34.491Z
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2904
File: express-zod-api/src/routing.ts:74-79
Timestamp: 2025-08-25T17:43:34.491Z
Learning: In express-zod-api, OPTIONS (CORS preflight) requests intentionally go through the same middleware and parser chain as other HTTP methods. This was specifically implemented to fix Issue #514 where middlewares were not running for OPTIONS requests. The framework seeds "options" with the same [parsers, endpoint] pair as other methods to ensure consistent middleware execution for CORS preflight requests.
Applied to files:
express-zod-api/src/endpoint.ts
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
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/documentation.ts (1)
11-34: Blocking: publishing with.tsspecifiers will break consumersWith
module: "node20"+moduleResolution: "node16", TypeScript preserves the exact text of your import specifiers. After this change the emitted ESM files (and the.d.tsdeclarations) will still reference"./api-response.ts","./common-helpers.ts", etc. Our published package only ships compiled.jsfiles (+ declarations), so Node will try to load.tsfiles that do not exist, and downstream TypeScript users withoutallowImportingTsExtensionswill get resolution failures.Please keep the source specifiers pointed at the runtime extension (
.js) and let the compiler map them back to the.tssources, or introduce a build step that rewrites these paths before publishing. For example:-import { responseVariants } from "./api-response.ts"; +import { responseVariants } from "./api-response.js";Apply the same fix to every internal import introduced in this PR (unless we change the packaging strategy to ship the raw
.tsfiles).
🧹 Nitpick comments (1)
tools/tsconfig.json (1)
2-2: Override test globals in tools tsconfig
tools/tsconfig.json currently inherits"vitest/globals"from the root, causing test globals to bleed into tooling code. Prevent this by adding a local override:{ "extends": "../tsconfig.json", + "compilerOptions": { + "types": [] + } }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (107)
compat-test/quick-start.spec.ts(1 hunks)esm-test/quick-start.spec.ts(1 hunks)esm-test/tsconfig.json(0 hunks)example/config.ts(1 hunks)example/endpoints/create-user.ts(1 hunks)example/endpoints/delete-user.ts(1 hunks)example/endpoints/list-users.ts(1 hunks)example/endpoints/retrieve-user.ts(1 hunks)example/endpoints/send-avatar.ts(1 hunks)example/endpoints/stream-avatar.ts(1 hunks)example/endpoints/time-subscription.ts(1 hunks)example/endpoints/update-user.ts(1 hunks)example/factories.ts(1 hunks)example/generate-client.ts(1 hunks)example/generate-documentation.ts(1 hunks)example/index.spec.ts(1 hunks)example/index.ts(1 hunks)example/routing.ts(1 hunks)example/tsconfig.json(1 hunks)express-zod-api/src/builtin-logger.ts(1 hunks)express-zod-api/src/common-helpers.ts(1 hunks)express-zod-api/src/config-type.ts(1 hunks)express-zod-api/src/deep-checks.ts(1 hunks)express-zod-api/src/depends-on-method.ts(1 hunks)express-zod-api/src/diagnostics.ts(1 hunks)express-zod-api/src/documentation-helpers.ts(2 hunks)express-zod-api/src/documentation.ts(2 hunks)express-zod-api/src/endpoint.ts(1 hunks)express-zod-api/src/endpoints-factory.ts(1 hunks)express-zod-api/src/errors.ts(1 hunks)express-zod-api/src/graceful-shutdown.ts(1 hunks)express-zod-api/src/index.ts(2 hunks)express-zod-api/src/integration-base.ts(2 hunks)express-zod-api/src/integration.ts(2 hunks)express-zod-api/src/json-schema-helpers.ts(1 hunks)express-zod-api/src/last-resort.ts(1 hunks)express-zod-api/src/logger-helpers.ts(1 hunks)express-zod-api/src/logical-container.ts(1 hunks)express-zod-api/src/middleware.ts(1 hunks)express-zod-api/src/peer-helpers.ts(1 hunks)express-zod-api/src/proprietary-schemas.ts(1 hunks)express-zod-api/src/raw-schema.ts(1 hunks)express-zod-api/src/result-handler.ts(1 hunks)express-zod-api/src/result-helpers.ts(1 hunks)express-zod-api/src/routable.ts(1 hunks)express-zod-api/src/routing-walker.ts(1 hunks)express-zod-api/src/routing.ts(1 hunks)express-zod-api/src/schema-walker.ts(1 hunks)express-zod-api/src/server-helpers.ts(1 hunks)express-zod-api/src/server.ts(2 hunks)express-zod-api/src/sse.ts(1 hunks)express-zod-api/src/testing.ts(1 hunks)express-zod-api/src/zts-helpers.ts(1 hunks)express-zod-api/src/zts.ts(1 hunks)express-zod-api/tests/api-response.spec.ts(1 hunks)express-zod-api/tests/buffer-schema.spec.ts(1 hunks)express-zod-api/tests/builtin-logger.spec.ts(1 hunks)express-zod-api/tests/common-helpers.spec.ts(1 hunks)express-zod-api/tests/config-type.spec.ts(1 hunks)express-zod-api/tests/content-type.spec.ts(1 hunks)express-zod-api/tests/date-in-schema.spec.ts(1 hunks)express-zod-api/tests/date-out-schema.spec.ts(1 hunks)express-zod-api/tests/deep-checks.spec.ts(1 hunks)express-zod-api/tests/depends-on-method.spec.ts(1 hunks)express-zod-api/tests/documentation-helpers.spec.ts(2 hunks)express-zod-api/tests/documentation.spec.ts(1 hunks)express-zod-api/tests/endpoint.spec.ts(1 hunks)express-zod-api/tests/endpoints-factory.spec.ts(1 hunks)express-zod-api/tests/errors.spec.ts(1 hunks)express-zod-api/tests/form-schema.spec.ts(1 hunks)express-zod-api/tests/graceful-helpers.spec.ts(1 hunks)express-zod-api/tests/graceful-shutdown.spec.ts(1 hunks)express-zod-api/tests/index.spec.ts(2 hunks)express-zod-api/tests/integration.spec.ts(1 hunks)express-zod-api/tests/io-schema.spec.ts(1 hunks)express-zod-api/tests/json-schema-helpers.spec.ts(1 hunks)express-zod-api/tests/last-resort.spec.ts(1 hunks)express-zod-api/tests/logger-helpers.spec.ts(1 hunks)express-zod-api/tests/logical-container.spec.ts(1 hunks)express-zod-api/tests/method.spec.ts(1 hunks)express-zod-api/tests/middleware.spec.ts(1 hunks)express-zod-api/tests/peer-helpers.spec.ts(1 hunks)express-zod-api/tests/raw-schema.spec.ts(1 hunks)express-zod-api/tests/result-handler.spec.ts(1 hunks)express-zod-api/tests/result-helpers.spec.ts(1 hunks)express-zod-api/tests/routable.spec.ts(1 hunks)express-zod-api/tests/routing.spec.ts(2 hunks)express-zod-api/tests/serve-static.spec.ts(1 hunks)express-zod-api/tests/server-helpers.spec.ts(2 hunks)express-zod-api/tests/server.spec.ts(2 hunks)express-zod-api/tests/sse.spec.ts(1 hunks)express-zod-api/tests/startup-logo.spec.ts(1 hunks)express-zod-api/tests/system.spec.ts(1 hunks)express-zod-api/tests/testing.spec.ts(1 hunks)express-zod-api/tests/upload-schema.spec.ts(1 hunks)express-zod-api/tests/zts.spec.ts(1 hunks)express-zod-api/tsconfig.json(0 hunks)express-zod-api/tsdown.config.ts(1 hunks)express-zod-api/vitest.setup.ts(1 hunks)migration/index.spec.ts(2 hunks)migration/tsconfig.json(1 hunks)tools/license.ts(1 hunks)tools/make-tests.ts(2 hunks)tools/tsconfig.json(1 hunks)tsconfig.json(1 hunks)zod-plugin/src/augmentation.ts(1 hunks)zod-plugin/src/brand.ts(1 hunks)
⛔ Files not processed due to max files limit (8)
- zod-plugin/src/index.ts
- zod-plugin/src/runtime.ts
- zod-plugin/tests/brand.spec.ts
- zod-plugin/tests/index.spec.ts
- zod-plugin/tests/packer.spec.ts
- zod-plugin/tests/runtime.spec.ts
- zod-plugin/tsconfig.json
- zod-plugin/vitest.setup.ts
💤 Files with no reviewable changes (2)
- express-zod-api/tsconfig.json
- esm-test/tsconfig.json
🧰 Additional context used
🧠 Learnings (23)
📓 Common learnings
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.
📚 Learning: 2025-05-27T19:35:57.357Z
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2546
File: express-zod-api/tests/buffer-schema.spec.ts:32-37
Timestamp: 2025-05-27T19:35:57.357Z
Learning: In the express-zod-api project, tests are run from the `express-zod-api` workspace directory, and the project uses an ESM-first environment without `__dirname`. Relative paths like `../logo.svg` in test files correctly resolve to the repository root due to this test execution context.
Applied to files:
express-zod-api/tests/builtin-logger.spec.tsexpress-zod-api/src/sse.tsexpress-zod-api/tests/documentation-helpers.spec.tsexpress-zod-api/tests/common-helpers.spec.tsexpress-zod-api/tests/logical-container.spec.tsexpress-zod-api/tests/peer-helpers.spec.tsexpress-zod-api/tests/testing.spec.tsexpress-zod-api/tests/method.spec.tsexpress-zod-api/tests/documentation.spec.tsexpress-zod-api/tests/integration.spec.tsexpress-zod-api/tests/sse.spec.tsexpress-zod-api/tests/logger-helpers.spec.tsexpress-zod-api/tests/result-handler.spec.tsexpress-zod-api/tests/routing.spec.tsexpress-zod-api/tests/middleware.spec.tsexpress-zod-api/tests/zts.spec.tsexpress-zod-api/tests/server.spec.tsexpress-zod-api/tests/deep-checks.spec.tsexpress-zod-api/tests/depends-on-method.spec.tsexpress-zod-api/tests/date-out-schema.spec.tsexpress-zod-api/tests/upload-schema.spec.tsexpress-zod-api/tests/system.spec.tsexpress-zod-api/tests/io-schema.spec.tsexpress-zod-api/tests/json-schema-helpers.spec.tsexpress-zod-api/tests/endpoints-factory.spec.tsexpress-zod-api/src/testing.tsexpress-zod-api/tests/api-response.spec.tsexpress-zod-api/src/integration.tsexpress-zod-api/tests/serve-static.spec.tsexpress-zod-api/tests/config-type.spec.tsexpress-zod-api/tests/raw-schema.spec.tsexpress-zod-api/tests/index.spec.tsexpress-zod-api/tests/server-helpers.spec.tsexpress-zod-api/tests/routable.spec.tsexpress-zod-api/tests/date-in-schema.spec.tsexpress-zod-api/vitest.setup.tsexpress-zod-api/tests/endpoint.spec.tsexpress-zod-api/tests/result-helpers.spec.tsexpress-zod-api/tests/content-type.spec.tsexpress-zod-api/tests/errors.spec.tsexpress-zod-api/tests/startup-logo.spec.tsexpress-zod-api/tests/form-schema.spec.tsexpress-zod-api/tests/buffer-schema.spec.ts
📚 Learning: 2025-09-26T09:00:24.416Z
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2965
File: express-zod-api/src/sse.ts:0-0
Timestamp: 2025-09-26T09:00:24.416Z
Learning: In express-zod-api SSE implementation, the ensureStream function checks response.headersSent before calling response.writeHead, which prevents writing to closed responses even if setTimeout fires after client disconnect. No cleanup of the headers timeout is needed.
Applied to files:
example/endpoints/time-subscription.ts
📚 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/sse.tsexpress-zod-api/tests/documentation-helpers.spec.tsexample/factories.tsexpress-zod-api/tests/common-helpers.spec.tsexpress-zod-api/src/routable.tsexpress-zod-api/src/proprietary-schemas.tsexpress-zod-api/tests/peer-helpers.spec.tsexpress-zod-api/tests/testing.spec.tsexpress-zod-api/tests/method.spec.tsexpress-zod-api/src/config-type.tsexpress-zod-api/tests/documentation.spec.tstools/make-tests.tsexpress-zod-api/tests/integration.spec.tsexpress-zod-api/tests/last-resort.spec.tsexpress-zod-api/tests/sse.spec.tsexpress-zod-api/src/diagnostics.tsexpress-zod-api/tests/result-handler.spec.tsexpress-zod-api/tests/routing.spec.tsexpress-zod-api/src/peer-helpers.tsexpress-zod-api/src/middleware.tsexpress-zod-api/src/routing.tsexpress-zod-api/tests/middleware.spec.tsexpress-zod-api/src/depends-on-method.tsexpress-zod-api/src/endpoint.tsexpress-zod-api/tests/zts.spec.tsexpress-zod-api/tests/server.spec.tsexpress-zod-api/tests/deep-checks.spec.tsexpress-zod-api/tests/graceful-helpers.spec.tsexpress-zod-api/tests/graceful-shutdown.spec.tsexpress-zod-api/tests/depends-on-method.spec.tsexpress-zod-api/tests/date-out-schema.spec.tsexpress-zod-api/tests/upload-schema.spec.tsexpress-zod-api/src/server.tsexpress-zod-api/tests/system.spec.tsexpress-zod-api/tests/io-schema.spec.tsexpress-zod-api/tests/json-schema-helpers.spec.tsexpress-zod-api/src/documentation.tsexpress-zod-api/src/zts-helpers.tscompat-test/quick-start.spec.tsexpress-zod-api/tests/endpoints-factory.spec.tsexpress-zod-api/src/json-schema-helpers.tsexpress-zod-api/src/testing.tsexpress-zod-api/src/documentation-helpers.tsexpress-zod-api/src/last-resort.tsexpress-zod-api/tests/api-response.spec.tsexpress-zod-api/src/common-helpers.tsesm-test/quick-start.spec.tsexpress-zod-api/src/integration.tsexpress-zod-api/src/result-helpers.tsexpress-zod-api/src/schema-walker.tsexpress-zod-api/tests/serve-static.spec.tsexpress-zod-api/tests/config-type.spec.tsexpress-zod-api/src/integration-base.tsexpress-zod-api/src/result-handler.tsexpress-zod-api/tests/raw-schema.spec.tsexpress-zod-api/src/zts.tsexpress-zod-api/src/graceful-shutdown.tsexpress-zod-api/tests/index.spec.tsexpress-zod-api/tests/server-helpers.spec.tsexpress-zod-api/src/raw-schema.tsexpress-zod-api/tests/routable.spec.tsexample/index.spec.tsexpress-zod-api/tests/date-in-schema.spec.tsexpress-zod-api/src/logical-container.tsexample/routing.tsexpress-zod-api/vitest.setup.tsexpress-zod-api/tests/endpoint.spec.tsexpress-zod-api/src/routing-walker.tsexample/endpoints/retrieve-user.tsexpress-zod-api/tests/result-helpers.spec.tsexpress-zod-api/src/errors.tsexpress-zod-api/src/endpoints-factory.tsexpress-zod-api/tsdown.config.tsexpress-zod-api/tests/content-type.spec.tsexpress-zod-api/src/deep-checks.tszod-plugin/src/augmentation.tsexpress-zod-api/tests/errors.spec.tsexpress-zod-api/tests/form-schema.spec.tsexpress-zod-api/src/server-helpers.tsexpress-zod-api/tests/buffer-schema.spec.tsexpress-zod-api/src/index.ts
📚 Learning: 2025-06-14T16:42:52.972Z
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2736
File: express-zod-api/tsup.config.ts:12-26
Timestamp: 2025-06-14T16:42:52.972Z
Learning: In express-zod-api tsup configurations, the direct mutation of `options.supported` in the `esbuildOptions` callback is intentional behavior and should not be flagged as a side effect issue.
Applied to files:
express-zod-api/src/sse.tsexpress-zod-api/tests/documentation-helpers.spec.tsexpress-zod-api/tests/common-helpers.spec.tsexpress-zod-api/src/proprietary-schemas.tsexpress-zod-api/src/config-type.tsexpress-zod-api/tests/documentation.spec.tsexpress-zod-api/tests/integration.spec.tsexpress-zod-api/tests/last-resort.spec.tsexpress-zod-api/src/diagnostics.tsexpress-zod-api/src/middleware.tsexpress-zod-api/src/routing.tsexpress-zod-api/src/endpoint.tsexpress-zod-api/tests/zts.spec.tsexpress-zod-api/tests/server.spec.tsexpress-zod-api/tests/deep-checks.spec.tsexpress-zod-api/tests/graceful-helpers.spec.tsexpress-zod-api/tests/graceful-shutdown.spec.tsexpress-zod-api/src/server.tsexpress-zod-api/tests/system.spec.tsexpress-zod-api/src/documentation.tsexpress-zod-api/src/zts-helpers.tsexpress-zod-api/src/json-schema-helpers.tsexpress-zod-api/src/testing.tsexpress-zod-api/src/documentation-helpers.tsexpress-zod-api/src/last-resort.tsexpress-zod-api/src/common-helpers.tsexpress-zod-api/src/integration.tsexpress-zod-api/src/result-helpers.tsexpress-zod-api/tests/serve-static.spec.tsexpress-zod-api/tests/config-type.spec.tsexpress-zod-api/src/integration-base.tsexpress-zod-api/src/result-handler.tsexpress-zod-api/tests/raw-schema.spec.tsexpress-zod-api/src/zts.tsexpress-zod-api/src/graceful-shutdown.tsexpress-zod-api/tests/index.spec.tsexpress-zod-api/tests/server-helpers.spec.tsexpress-zod-api/src/raw-schema.tsexpress-zod-api/src/routing-walker.tsexpress-zod-api/src/errors.tsexpress-zod-api/tsdown.config.tsexpress-zod-api/src/deep-checks.tsexpress-zod-api/src/server-helpers.tsexpress-zod-api/tests/buffer-schema.spec.tsexpress-zod-api/src/index.ts
📚 Learning: 2025-08-01T09:48:13.742Z
Learnt from: RobinTail
PR: RobinTail/express-zod-api#0
File: :0-0
Timestamp: 2025-08-01T09:48:13.742Z
Learning: In express-zod-api, when migrating from Zod v3 to v4, the correct approach for internal type imports is to change from `import type { $ZodType } from "zod/v4/core"` to `import { z } from "zod"` and then use `z.core.$ZodType`. The zod/v4/core module is reexported as z.core by the main zod package, making this a valid and working approach.
Applied to files:
express-zod-api/src/sse.tsexpress-zod-api/tests/documentation-helpers.spec.tsexpress-zod-api/tests/common-helpers.spec.tsexpress-zod-api/src/routable.tsexpress-zod-api/src/proprietary-schemas.tsexpress-zod-api/tests/testing.spec.tsexpress-zod-api/tests/method.spec.tsexpress-zod-api/src/config-type.tsexpress-zod-api/tests/documentation.spec.tsexpress-zod-api/tests/integration.spec.tsexpress-zod-api/src/diagnostics.tsexpress-zod-api/src/peer-helpers.tsexpress-zod-api/src/middleware.tsexpress-zod-api/src/routing.tsexpress-zod-api/src/depends-on-method.tsexpress-zod-api/src/endpoint.tsexpress-zod-api/tests/zts.spec.tsexpress-zod-api/tests/server.spec.tsexpress-zod-api/tests/deep-checks.spec.tsexpress-zod-api/tests/depends-on-method.spec.tsexpress-zod-api/src/server.tsexpress-zod-api/tests/system.spec.tsexpress-zod-api/tests/io-schema.spec.tsexpress-zod-api/tests/json-schema-helpers.spec.tsexpress-zod-api/src/documentation.tsexpress-zod-api/src/zts-helpers.tsexpress-zod-api/tests/endpoints-factory.spec.tsexpress-zod-api/src/json-schema-helpers.tsexpress-zod-api/src/testing.tsexpress-zod-api/src/documentation-helpers.tsexpress-zod-api/src/last-resort.tsexpress-zod-api/src/common-helpers.tsexpress-zod-api/src/integration.tsexpress-zod-api/src/result-helpers.tsexpress-zod-api/src/schema-walker.tsexpress-zod-api/tests/config-type.spec.tsexpress-zod-api/src/integration-base.tsexpress-zod-api/src/result-handler.tsexpress-zod-api/tests/raw-schema.spec.tsexpress-zod-api/src/zts.tsexpress-zod-api/src/graceful-shutdown.tsexpress-zod-api/tests/index.spec.tsexpress-zod-api/tests/server-helpers.spec.tsexpress-zod-api/src/raw-schema.tsexpress-zod-api/tests/routable.spec.tsexpress-zod-api/tests/date-in-schema.spec.tsexpress-zod-api/src/logical-container.tsexpress-zod-api/vitest.setup.tszod-plugin/src/brand.tsexpress-zod-api/src/logger-helpers.tsexpress-zod-api/tests/endpoint.spec.tsexpress-zod-api/src/routing-walker.tsexpress-zod-api/tests/result-helpers.spec.tsexpress-zod-api/src/errors.tsexpress-zod-api/src/endpoints-factory.tsexpress-zod-api/tsdown.config.tsexpress-zod-api/tests/content-type.spec.tsexpress-zod-api/src/deep-checks.tszod-plugin/src/augmentation.tsexpress-zod-api/tests/errors.spec.tsexpress-zod-api/tests/form-schema.spec.tsexpress-zod-api/src/server-helpers.tsexpress-zod-api/tests/buffer-schema.spec.tsexpress-zod-api/src/index.ts
📚 Learning: 2025-06-02T21:08:56.475Z
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2697
File: CHANGELOG.md:5-5
Timestamp: 2025-06-02T21:08:56.475Z
Learning: The `cjs-test` directory in the express-zod-api repository is a test workspace and should be excluded when checking for main project version consistency with changelog entries.
Applied to files:
express-zod-api/tests/documentation-helpers.spec.tsexpress-zod-api/tests/common-helpers.spec.tsexpress-zod-api/tests/testing.spec.tsexpress-zod-api/tests/method.spec.tsexpress-zod-api/tests/documentation.spec.tsexpress-zod-api/tests/integration.spec.tsexpress-zod-api/tests/result-handler.spec.tsexpress-zod-api/tests/routing.spec.tsexpress-zod-api/tests/zts.spec.tsexpress-zod-api/tests/server.spec.tsexpress-zod-api/tests/deep-checks.spec.tsexpress-zod-api/tests/depends-on-method.spec.tsexpress-zod-api/tests/date-out-schema.spec.tsexpress-zod-api/tests/upload-schema.spec.tsexpress-zod-api/tests/system.spec.tsexpress-zod-api/tests/io-schema.spec.tsexpress-zod-api/tests/json-schema-helpers.spec.tsexpress-zod-api/tests/endpoints-factory.spec.tsexpress-zod-api/src/testing.tsexpress-zod-api/tests/api-response.spec.tsexpress-zod-api/tests/serve-static.spec.tsexpress-zod-api/tests/config-type.spec.tsexpress-zod-api/tests/raw-schema.spec.tsexpress-zod-api/src/zts.tsexpress-zod-api/tests/index.spec.tsexpress-zod-api/tests/server-helpers.spec.tsexpress-zod-api/tests/date-in-schema.spec.tsexpress-zod-api/tests/endpoint.spec.tsexpress-zod-api/tests/errors.spec.tsexpress-zod-api/tests/startup-logo.spec.tsexpress-zod-api/tests/form-schema.spec.tsexpress-zod-api/tests/buffer-schema.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/factories.tsexample/generate-documentation.tstools/license.tsexample/generate-client.tsexpress-zod-api/tests/routable.spec.tsexample/routing.tsexample/endpoints/retrieve-user.tsexpress-zod-api/tests/errors.spec.ts
📚 Learning: 2025-05-27T20:40:19.548Z
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2546
File: express-zod-api/src/json-schema-helpers.ts:75-87
Timestamp: 2025-05-27T20:40:19.548Z
Learning: In express-zod-api's `flattenIO` function in json-schema-helpers.ts, the `additionalProperties` field is used as a template to generate property schemas for literal property names extracted from `propertyNames.const` and `propertyNames.enum`. Converting boolean `additionalProperties` values to empty objects `{}` via `Object(entry.additionalProperties)` is intentional behavior, as the function only needs property schema templates, not the boolean semantics of `additionalProperties`.
Applied to files:
express-zod-api/src/proprietary-schemas.tsexpress-zod-api/tests/json-schema-helpers.spec.tsexpress-zod-api/src/zts-helpers.tsexpress-zod-api/src/json-schema-helpers.tsexpress-zod-api/src/schema-walker.ts
📚 Learning: 2025-08-08T11:59:04.814Z
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2878
File: zod-plugin/runtime.ts:39-42
Timestamp: 2025-08-08T11:59:04.814Z
Learning: express-zod-api/zod-plugin/runtime.ts (TypeScript): Do not memoize the ZodType.prototype.brand getter. The current design returning setBrand.bind(this) on each access is intentional/preferred; avoid redefining "brand" as a data property per instance.
Applied to files:
express-zod-api/src/proprietary-schemas.tsexpress-zod-api/tests/date-out-schema.spec.tsexpress-zod-api/tests/upload-schema.spec.tsexpress-zod-api/src/zts-helpers.tsexpress-zod-api/src/schema-walker.tsexpress-zod-api/tests/raw-schema.spec.tsexpress-zod-api/src/zts.tsexpress-zod-api/src/raw-schema.tsexpress-zod-api/tests/date-in-schema.spec.tsexpress-zod-api/vitest.setup.tszod-plugin/src/brand.tsexpress-zod-api/src/deep-checks.tsexpress-zod-api/tests/form-schema.spec.ts
📚 Learning: 2025-07-20T11:09:58.980Z
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2833
File: express-zod-api/src/method.ts:3-3
Timestamp: 2025-07-20T11:09:58.980Z
Learning: In express-zod-api, the `SomeMethod` type (defined as `Lowercase<string>`) is intentionally broad to represent raw, unvalidated HTTP methods from requests. The narrower `Method` type is used after validation with `isMethod()`. This defensive programming pattern separates raw external input types from validated types, allowing graceful handling of unknown methods.
Applied to files:
express-zod-api/tests/method.spec.ts
📚 Learning: 2025-09-28T10:09:35.674Z
Learnt from: RobinTail
PR: RobinTail/express-zod-api#0
File: :0-0
Timestamp: 2025-09-28T10:09:35.674Z
Learning: In TypeScript configuration, when `strict: true` is set (including through extended configurations like tsconfig/node20), it automatically enables strictNullChecks along with other strict type-checking options, making explicit `strictNullChecks: true` redundant.
Applied to files:
tsconfig.json
📚 Learning: 2025-05-27T19:30:51.885Z
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2546
File: compat-test/sample.ts:1-1
Timestamp: 2025-05-27T19:30:51.885Z
Learning: Files in compat-test/ directories, especially those named sample.ts or similar, are often test fixtures for migration scripts and may intentionally contain deprecated or "incorrect" code that the migration tooling is designed to fix. These should not be flagged as issues.
Applied to files:
tools/make-tests.tsmigration/index.spec.tscompat-test/quick-start.spec.ts
📚 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:
express-zod-api/src/routing.tsexpress-zod-api/src/depends-on-method.tsexpress-zod-api/src/json-schema-helpers.tsexpress-zod-api/src/common-helpers.tsexpress-zod-api/src/integration.tsexpress-zod-api/src/deep-checks.ts
📚 Learning: 2025-08-25T17:43:34.491Z
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2904
File: express-zod-api/src/routing.ts:74-79
Timestamp: 2025-08-25T17:43:34.491Z
Learning: In express-zod-api, OPTIONS (CORS preflight) requests intentionally go through the same middleware and parser chain as other HTTP methods. This was specifically implemented to fix Issue #514 where middlewares were not running for OPTIONS requests. The framework seeds "options" with the same [parsers, endpoint] pair as other methods to ensure consistent middleware execution for CORS preflight requests.
Applied to files:
express-zod-api/src/endpoint.ts
📚 Learning: 2025-05-27T19:27:13.492Z
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2546
File: express-zod-api/tests/form-schema.spec.ts:31-31
Timestamp: 2025-05-27T19:27:13.492Z
Learning: Zod version 3.25.0 and later expose the Zod v4 API through the special import paths "zod/v4" and "zod/v4/core", allowing v4 features like .loose() to be used even when the package.json dependency shows a 3.x version.
Applied to files:
express-zod-api/tests/zts.spec.tszod-plugin/src/augmentation.ts
📚 Learning: 2025-08-08T16:45:20.527Z
Learnt from: RobinTail
PR: RobinTail/express-zod-api#0
File: :0-0
Timestamp: 2025-08-08T16:45:20.527Z
Learning: express-zod-api/zod-plugin: The ZodType.prototype.brand getter returns setBrand.bind(this) each time (no memoization). setBrand must always call pack() and include { brand: undefined } when unbranding so that pack → .check() runs and prior brand is overwritten; do not suggest removing the explicit undefined entry.
Applied to files:
express-zod-api/tests/date-out-schema.spec.tsexpress-zod-api/tests/upload-schema.spec.tsexpress-zod-api/src/schema-walker.tsexpress-zod-api/tests/raw-schema.spec.tsexpress-zod-api/src/raw-schema.tsexpress-zod-api/tests/date-in-schema.spec.tsexpress-zod-api/vitest.setup.tszod-plugin/src/brand.tsexpress-zod-api/src/deep-checks.tsexpress-zod-api/tests/form-schema.spec.ts
📚 Learning: 2025-08-08T16:45:20.527Z
Learnt from: RobinTail
PR: RobinTail/express-zod-api#0
File: :0-0
Timestamp: 2025-08-08T16:45:20.527Z
Learning: express-zod-api/zod-plugin: The brand setter must be immutable and always invoke pack→.check() via the getter-bound setBrand. Including brandProperty with an explicit undefined enables unbranding and should not be optimized away.
Applied to files:
express-zod-api/tests/upload-schema.spec.tsexpress-zod-api/src/schema-walker.tsexpress-zod-api/tests/raw-schema.spec.tsexpress-zod-api/src/raw-schema.tsexpress-zod-api/tests/date-in-schema.spec.tsexpress-zod-api/vitest.setup.tszod-plugin/src/brand.ts
📚 Learning: 2025-05-28T05:04:40.327Z
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2546
File: express-zod-api/src/io-schema.ts:5-8
Timestamp: 2025-05-28T05:04:40.327Z
Learning: The Base type `object & { [Symbol.iterator]?: never }` in express-zod-api correctly excludes arrays and other iterables from IOSchema. Arrays are properly rejected because they have a defined Symbol.iterator method which conflicts with the never constraint, as demonstrated by TypeScript compiler errors when attempting to assign z.array() to IOSchema.
Applied to files:
express-zod-api/tests/io-schema.spec.tsexpress-zod-api/tests/json-schema-helpers.spec.tsexample/endpoints/retrieve-user.ts
📚 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: The JSONSchema type is not exported from the main "zod" module and must be imported from "zod/v4/core" when using Zod v4. This is acceptable for type-only imports as they don't create runtime dependencies.
Applied to files:
express-zod-api/tests/io-schema.spec.tsexpress-zod-api/src/json-schema-helpers.tsexpress-zod-api/src/raw-schema.tszod-plugin/src/brand.tsexpress-zod-api/src/deep-checks.tszod-plugin/src/augmentation.ts
📚 Learning: 2025-08-08T16:45:20.527Z
Learnt from: RobinTail
PR: RobinTail/express-zod-api#0
File: :0-0
Timestamp: 2025-08-08T16:45:20.527Z
Learning: express-zod-api zod-plugin: The brand setter must stay immutable and always invoke pack→.check() (onattach). Including brandProperty with an explicit undefined enables “unbranding” (overwriting a previous brand) and should not be optimized away.
Applied to files:
express-zod-api/src/schema-walker.tsexpress-zod-api/tests/raw-schema.spec.tsexpress-zod-api/vitest.setup.tszod-plugin/src/brand.ts
📚 Learning: 2025-08-08T16:45:20.527Z
Learnt from: RobinTail
PR: RobinTail/express-zod-api#0
File: :0-0
Timestamp: 2025-08-08T16:45:20.527Z
Learning: In express-zod-api zod-plugin, the brand setter must be immutable and always call `.check()` (packer’s onattach). Therefore, writing an explicit undefined entry in the bag for brand is intentional and should not be suggested for removal.
Applied to files:
express-zod-api/src/schema-walker.tsexpress-zod-api/tests/raw-schema.spec.tsexpress-zod-api/src/raw-schema.tsexpress-zod-api/vitest.setup.tszod-plugin/src/brand.ts
📚 Learning: 2025-05-28T05:49:36.540Z
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2546
File: express-zod-api/src/common-helpers.ts:64-69
Timestamp: 2025-05-28T05:49:36.540Z
Learning: ZodError does not extend Error, but ZodRealError does extend Error. This is why in ensureError functions, you need to check for ZodError separately and wrap it in ZodRealError to convert it to a proper Error instance.
Applied to files:
express-zod-api/tests/errors.spec.ts
🔇 Additional comments (71)
example/endpoints/retrieve-user.ts (1)
5-5: Import extension update looks correct.Explicit
.tsextension matches the newmodule: node20requirements and resolves toexample/middlewares.tswithout changing runtime behavior.zod-plugin/src/augmentation.ts (1)
2-2: Extension update aligns with Node20 module mode.Explicit
.tsspecifier keeps the compiler happy undermodule: "node20"/allowImportingTsExtensions, and since this is a type-only import it won’t leak into emitted JS. 👍tools/make-tests.ts (1)
3-20: Explicit.tsspecifier aligns with node20 expectations.Thanks for updating both the tool import and the generated template to reference
ports.tsexplicitly. That keeps the script and emitted fixtures consistent with the newmodule: node20+allowImportingTsExtensionssetup and prevents drift when these tests are regenerated.compat-test/quick-start.spec.ts (1)
11-11: Good: explicit .ts specifier under node20.Import path update aligns with the new module strategy and tsx runner.
express-zod-api/src/proprietary-schemas.ts (1)
1-6: Build output not found; please run a production build and verify no “.ts” extensions remain in emitted code.
Once you’ve generated your JS and .d.ts artifacts (e.g. in dist, build, or lib), search them for".ts"to confirm all import specifiers have been rewritten to extension-less or.jspaths.tsconfig.json (1)
4-6: Couldn’t retrieve the effective TS compilerOptions in this environment—please run locally:npx typescript@latest tsc --showConfig -p tsconfig.json \ | jq '.compilerOptions | {module, moduleResolution, target, allowImportingTsExtensions, resolveJsonModule, verbatimModuleSyntax, erasableSyntaxOnly}'and confirm that
moduleResolutionand the chosen emit mode (verbatimModuleSyntaxorerasableSyntaxOnly) are set as expected.migration/tsconfig.json (1)
2-2: Confirm effective tsconfig options for the migration packageEnsure it inherits the following from the root config and that no overrides have changed them:
module:"node20"allowImportingTsExtensions:trueresolveJsonModule:truemoduleResolution:"node16"Please verify these effective compilerOptions manually.
example/config.ts (1)
4-4: Explicit.tsimport keeps module resolution predictable.The switch to
../tools/ports.tsis exactly whatmodule: "node20"expects whenallowImportingTsExtensionsis enabled. Looks good.example/routing.ts (1)
2-12: Consistent.tsspecifiers across endpoints.Updating every local endpoint import to a
.tssuffix matches the new compiler settings and keeps the example routing tree working without side effects.express-zod-api/tests/startup-logo.spec.ts (1)
2-2: Test import updated for Node 20 module mode.Pointing directly to
startup-logo.tskeeps vitest aligned with the repo-wide extension policy—no other adjustments needed.express-zod-api/tests/server.spec.ts (1)
1-27: Server-spec imports follow the new explicit-extension rule.All updated paths (
server-helpers.ts,ports.ts, mocks, andindex.ts) reflect the Node 20 ESM expectations while keeping the test harness unchanged.example/index.ts (1)
2-3: Example entrypoint now matches explicit extension policy.Importing
./config.tsand./routing.tskeeps the example app consistent with the new module settings. All good.express-zod-api/src/server-helpers.ts (1)
12-15: Manifest-based locals symbol aligns multi-package scenariosTying the locals key to
manifest.namekeeps the shared symbol stable across multiple copies of the package while staying future-proof with Node 20 JSON imports. Nicely done.express-zod-api/tests/graceful-shutdown.spec.ts (1)
6-8: Import extensions updated for Node 20The
.tsspecifiers line up with the newmodule: node20expectations and keep the test harness working. Looks good.example/generate-client.ts (1)
3-4: Example import updates stay consistentExplicit
.tsimports keep the example aligned with the new compiler settings without affecting runtime behavior.express-zod-api/tests/middleware.spec.ts (1)
2-8: Test suite imports match the tightened module resolutionThe switch to explicit
.tspaths ensures the tests continue to compile undermodule: node20while leaving behavior untouched.example/generate-documentation.ts (1)
3-5: Typed JSON and explicit extensions keep the doc generator compliantBringing in the manifest with
{ type: "json" }and updating the local imports keeps this script compatible with the new TS/Node settings.esm-test/quick-start.spec.ts (1)
2-2: Explicit .ts import keeps the ESM test aligned with node20 resolutionSwitching to
../tools/ports.tsmatches the new module settings and avoids implicit extension lookups. Looks good.express-zod-api/tsdown.config.ts (1)
2-9: JSON manifest import is a nice cleanupPulling the version via a typed JSON import removes the async file read and keeps the define block intact. 👍
express-zod-api/tests/upload-schema.spec.ts (1)
2-4: Test imports now point directly at the TS sourcesThe explicit
.tsspecifiers ensure vitest/tsx resolve the modules without relying on directory indexes. All good here.express-zod-api/tests/form-schema.spec.ts (1)
2-3: Consistent.tsimports for form schema testsThis keeps the test suite in lockstep with the repo-wide module settings. No issues found.
tools/license.ts (1)
2-8: JSON import matches the new tooling expectationsUsing the import attribute keeps the license script simple under the new TypeScript/Node setup. Looks great.
express-zod-api/src/testing.ts (1)
2-4: Consistent .ts specifiers in testing utilities — LGTM.Tests typically run under tsx/vitest where .ts specifiers are fine. Just ensure the library build step won’t emit JS that still references .ts here (tsup bundling is fine; plain tsc preserveModules is not).
If you plan to execute this file under Node without a TS runner, confirm Node 24+ type‑stripping is enabled in your CI matrix and that package.json “type”/exports don’t conflict.
Also applies to: 10-11, 18-19
express-zod-api/tests/graceful-helpers.spec.ts (1)
7-7: Test imports updated to explicit .ts — looks good.No behavioral changes. Keep using makeRequestMock from src/testing.ts; matches the new import‑extension convention.
Also applies to: 9-9
express-zod-api/src/zts.ts (1)
4-12: Confirm tsconfig and bundler for .ts imports
- Root
tsconfig.jsonsets"allowImportingTsExtensions": truebut omits"moduleResolution"(should be"node20") and neither"verbatimModuleSyntax"nor"erasableSyntaxOnly"is enabled. Add:
•"moduleResolution": "node20"to match"module": "node20"
•"erasableSyntaxOnly": trueif relying on Node 24+ TS stripping, or
•"verbatimModuleSyntax": trueif bundling with esbuild/tsup to rewrite extensions- I don’t see a
tsup.config.tsinexpress-zod-api; ensure your build pipeline rewrites.tsimports to.jsbefore publishing, or switch to a TS‐at‐runtime setup with the flags above.migration/index.spec.ts (1)
2-18: Explicit .ts/JSON imports look correct.The .ts specifier and the JSON
with { type: "json" }import both align with Node 20 module semantics, and the major-version assertion preserves the prior behavior.express-zod-api/src/documentation-helpers.ts (1)
19-48: Consistent .ts specifiers across internal deps.Every updated import now resolves via an explicit .ts suffix (plus the JSON
with { type: "json" }), matching the newmodule: "node20"+allowImportingTsExtensionssetup without altering runtime behavior.express-zod-api/src/sse.ts (1)
3-12: SSE helpers now use explicit .ts paths.The updated imports map one-to-one to existing modules, so the SSE factory continues to compile under the stricter resolver.
express-zod-api/src/peer-helpers.ts (1)
1-1: Peer error import matches new specifier rules.Pointing at
./errors.tskeeps dynamic peer loading intact under Node 20 module resolution.express-zod-api/src/routable.ts (1)
1-1: Routing import aligned with .ts suffix policy.The explicit extension keeps Routable compatible with the updated resolver without changing behavior.
example/endpoints/delete-user.ts (1)
4-4: Import extension aligns with module: node20 expectations.The
.tsspecifier keeps this example aligned with the new compiler settings while still resolving to the intended factory module. No further action needed.express-zod-api/tests/testing.spec.ts (1)
9-9: Test import updated to explicit entrypoint.Confirming the switch to
../src/index.tskeeps the tests targeting the published surface while satisfying the new explicit-extension rule. Looks good.example/factories.ts (1)
10-10: Example middleware import stays consistent.The
.tssuffix mirrors the adjacent endpoint updates and keeps the demo code runnable under the new resolver. All set.express-zod-api/tests/integration.spec.ts (1)
9-9: Integration test import matches explicit-export policy.Using
../src/index.tsretains access to the public exports while satisfying the stricter resolver—no further adjustments needed.express-zod-api/tests/config-type.spec.ts (1)
2-2: Config-type test import remains correct.The explicit
.tskeeps the test pointed at the publiccreateConfigexport under the new module configuration. Looks good.express-zod-api/tests/buffer-schema.spec.ts (1)
3-3: Explicit .ts specifier keeps ez buffer tests compatibleThe updated import complies with the new
module: node20requirement while preserving existing test behavior.express-zod-api/vitest.setup.ts (1)
4-4: Serializer import aligns with node20 module rulesAdding the
.tsextension matches the revised compiler settings and doesn’t affect the serializer logic.express-zod-api/tests/method.spec.ts (1)
10-10: Method test import tracks new extension policyAppending
.tskeeps the test suite consistent with the repository-wide module resolution update.example/endpoints/stream-avatar.ts (1)
2-2: Factory import updated for explicit extensionsThe
.tssuffix matches the new TypeScript module configuration with no functional fallout.express-zod-api/tests/api-response.spec.ts (1)
1-1: API response test import follows .ts conventionThe explicit extension satisfies the stricter module resolution while leaving test logic untouched.
express-zod-api/tests/logical-container.spec.ts (1)
1-1: Import extension update looks good.The .ts specifier aligns the test import with the node20 module settings introduced in this PR.
express-zod-api/tests/raw-schema.spec.ts (1)
2-4: Imports match the new module resolution strategy.Switching to explicit .ts paths keeps these tests compatible with the node20 configuration and verbatim module syntax workflow.
express-zod-api/tests/routable.spec.ts (1)
2-2: Extension-qualified import looks correct.The update ensures the spec stays in sync with the rest of the codebase under node20 semantics.
express-zod-api/tests/builtin-logger.spec.ts (1)
2-2: Explicit .ts import confirmed.The logger test now references the resolved TypeScript module directly, matching the project-wide convention.
express-zod-api/src/routing-walker.ts (1)
1-6: Module specifiers updated appropriately.All internal imports now include .ts extensions, which is required for the node20 module target without altering routing logic.
express-zod-api/src/logical-container.ts (1)
2-2: Import extension update looks goodSwitching to the explicit
.tssuffix keeps this module consistent with the Node 20 resolver requirements introduced in the PR. No further action needed.example/endpoints/create-user.ts (1)
4-4: Consistent.tsspecifierThanks for updating this factory import to the explicit
.tsspecifier—matches the rest of the example endpoints and the new compiler settings.express-zod-api/tests/endpoint.spec.ts (1)
10-11: Tests aligned with explicit entrypointsGood call re-pointing the test imports at
index.tsandendpoint.ts; keeps the suite aligned with the updated module resolution rules.express-zod-api/src/depends-on-method.ts (1)
2-4: Internal wiring matches the new resolution settingsThe explicit
.tsimports forAbstractEndpoint,Method, andRoutablekeep this module in step with the rest of the source tree. Looks great.express-zod-api/tests/system.spec.ts (1)
16-17: System test imports updated correctlyRepointing to
../src/index.tsand../../tools/ports.tsfits the new Node 20 module rules; the rest of the test body remains unaffected.express-zod-api/tests/serve-static.spec.ts (1)
1-2: LGTM on explicit test importsSwitching the spec file to explicit extensions keeps it aligned with the new module settings; no issues spotted here.
express-zod-api/src/builtin-logger.ts (1)
4-11: Same .ts import concern as flagged elsewherePlease see my blocking note on express-zod-api/src/documentation.ts (Lines 11-34); the same reasoning applies to these .ts specifiers.
express-zod-api/tests/index.spec.ts (1)
4-24: Tests keep matching the public barrelPointing the snapshot tests at the explicit index.ts entrypoint fits the new resolution rules; everything still lines up.
express-zod-api/src/result-helpers.ts (1)
5-14: Same.tsspecifier issue as documentation.tsThis file shares the runtime/declaration breakage described in my comment on express-zod-api/src/documentation.ts (Lines 11-34); please address it here as well.
express-zod-api/tests/date-out-schema.spec.ts (1)
2-3: Import specifiers updated appropriately.Switching these test imports to explicit
.tsis the right move for themodule: "node20"/moduleResolution: "node16"combo—everything keeps pointing at the same source entry points with no extra churn. Nicely done.express-zod-api/tests/documentation-helpers.spec.ts (1)
4-28: Import updates look good.Explicit
.tsspecifiers line up with the newmodule: node20setup and keep tests in sync with runtime resolution.express-zod-api/tests/json-schema-helpers.spec.ts (1)
2-2: Consistent extension usage.The explicit
.tsimport ensures compatibility with the new Node20 module configuration; no further action needed.express-zod-api/tests/result-handler.spec.ts (1)
9-16: Clear, extension-aware imports.Splitting the barrel import into explicit
.tspaths keeps type access predictable undermodule: node20while preserving test behavior.express-zod-api/src/integration-base.ts (1)
3-42: Imports updated correctly for node20 module mode.Explicit
.tsspecifiers keep this module in step with the new compiler settings; nothing else to flag.express-zod-api/src/deep-checks.ts (1)
3-12: Import specifiers look good.The
.tsextensions match the node20 transition without touching runtime behavior.express-zod-api/tests/date-in-schema.spec.ts (1)
2-3: Test import updates are consistent.Pointing directly at the
.tsmodules matches the new resolution strategy; assertions remain intact.express-zod-api/tests/endpoints-factory.spec.ts (1)
10-12: Good swap to explicit.tsimports.Direct module targets will play nicely with the new compiler module settings.
express-zod-api/tests/common-helpers.spec.ts (1)
15-20: Helper imports updated appropriately.Explicit
.tsspecifiers keep the test suite aligned with the node20 configuration.express-zod-api/tests/errors.spec.ts (1)
2-10: Imports align with node20 specifier requirementsThanks for updating the test imports to the explicit
.tspaths—this keeps the suite in step with the module/node20 switch without altering behavior.express-zod-api/src/integration.ts (1)
4-26: Core integration imports updated consistentlyThe import block now targets the
.tssources directly, matching the repo-wide module setting change while keeping the integration surface untouched. Looks good.express-zod-api/src/server.ts (1)
5-27: Server wiring stays stable under explicit extensionsThese
.tsspecifiers keep server wiring compatible with the node20 resolver with no other behavior shifts. All good here.express-zod-api/src/zts-helpers.ts (1)
2-4: Helper imports kept in syncExplicit
.tspaths for the helper dependencies look correct and maintain the existing typing surface.express-zod-api/tests/zts.spec.ts (1)
3-6: zts tests align with new specifiersThe test harness now points at the
.tsentry points, matching the rest of the refactor without affecting coverage.express-zod-api/tests/server-helpers.spec.ts (1)
2-26: Explicit.tsimports align with the Node 20 module target.The updated specifiers fit the new
module: node20+ relative-extension policy without affecting test behavior. Looks good.express-zod-api/tests/result-helpers.spec.ts (1)
3-12: Consistent.tsspecifiers for direct TS execution.Nice job keeping these result-helper tests in sync with the new import-extension requirements while leaving logic untouched.
express-zod-api/tests/logger-helpers.spec.ts (1)
1-11: Logger helper test imports updated correctly.The
.tsextensions ensure compatibility with the strict Node 20 resolution setup and match the source re-exports. All good here.
@coderabbitai, there are 3 packages in this repo at the moment that are published, they are located in |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain@RobinTail, thank you for the clarification! Let me verify the build configuration to better understand the publishing workflow. 🏁 Script executed: Length of output: 1224 @RobinTail, perfect! Thank you for the detailed explanation. I can see from the configuration that:
This completely resolves my concern about breaking consumers. Since the source code with The approach also positions you well for JSR publishing, which does indeed require explicit I withdraw my blocking concern - this change is safe and follows a proper build-then-publish workflow. ✏️ Learnings added
🧠 Learnings used |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (1)
eslint.config.js (1)
209-209: Broaden TS file globs so package‑scoped rules hit subfoldersCurrent globs only match direct children of src/. Use recursive patterns to cover nested modules.
- files: ["express-zod-api/src/*.ts"], + files: ["express-zod-api/src/**/*.ts"],- files: ["zod-plugin/src/*.ts"], + files: ["zod-plugin/src/**/*.ts"],Also applies to: 222-222
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
eslint.config.js(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: RobinTail
PR: RobinTail/express-zod-api#0
File: :0-0
Timestamp: 2025-09-29T03:35:55.530Z
Learning: In the express-zod-api repository, packages are built using tsdown before publishing. Source code with .ts extensions is not published - only the built JavaScript bundles and declaration files in the dist/ directory are published to npm. This means .ts extensions in source imports don't affect consumers.
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.
RobinTail
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
☑️ reviewed
035815d to
4d1debb
Compare
RobinTail
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🏁 kinda ready
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
eslint.config.js (2)
27-30: Tighten the regex to match only relative imports and optionally cover dynamic imports.The current regex
/\.js$/matches any import ending in.js. Anchor it to explicitly target relative imports:{ - selector: "ImportDeclaration[source.value=/\\.js$/]", + selector: "ImportDeclaration[source.value=/^\\..*\\.js$/]", message: "use .ts extension for relative imports", },If you also want to catch dynamic imports like
import('./foo.js'), extend the selector:- selector: "ImportDeclaration[source.value=/^\\..*\\.js$/]", + selector: "ImportDeclaration[source.value=/^\\..*\\.js$/], ImportExpression[source.value=/^\\..*\\.js$/]",
71-74: Good addition for tree-shaking awareness.This rule correctly flags a performance concern. Importing
package.jsonprevents tree-shaking and the suggestion to use tsdown and process.env aligns with the build setup.Optional: Consider fixing the grammar in the message:
- message: "it can not be tree shaken, use tsdown and process.env instead", + message: "it cannot be tree-shaken; use tsdown and process.env instead",
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
eslint.config.js(2 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: RobinTail
PR: RobinTail/express-zod-api#0
File: :0-0
Timestamp: 2025-09-29T03:35:55.530Z
Learning: In the express-zod-api repository, packages are built using tsdown before publishing. Source code with .ts extensions is not published - only the built JavaScript bundles and declaration files in the dist/ directory are published to npm. This means .ts extensions in source imports don't affect consumers.
📚 Learning: 2025-09-25T14:04:50.830Z
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2965
File: express-zod-api/src/sse.ts:0-0
Timestamp: 2025-09-25T14:04:50.830Z
Learning: [monologue]
[task analyze_typescript_behavior_1/1]
The user RobinTail is correcting my understanding of TypeScript's type inference for the `return setTimeout(...) && { ... }` expression.
[observations]
- I previously stated that `return setTimeout(...) && { ... }` would have type `NodeJS.Timeout | Emitter<E>`
- RobinTail is claiming the type is actually `Emitter<E>` because the `&&` operator evaluates to its right side when the left side (setTimeout return value) is truthy
- The setTimeout function returns a NodeJS.Timeout which is indeed truthy
- In TypeScript, the `&&` operator has specific type inference rules
- I need to verify the actual TypeScript behavior for this pattern
[analysis]
Let me think through TypeScript's `&&` operator type inference:
1. `setTimeout()` returns `NodeJS.Timeout` which is truthy
2. In `A && B`, if A is always truthy, TypeScript should infer the type as B
3. However, there's also the possibility that TypeScript might still consider the union type `A | B`...
Applied to files:
eslint.config.js
📚 Learning: 2025-06-14T16:42:52.972Z
Learnt from: RobinTail
PR: RobinTail/express-zod-api#2736
File: express-zod-api/tsup.config.ts:12-26
Timestamp: 2025-06-14T16:42:52.972Z
Learning: In express-zod-api tsup configurations, the direct mutation of `options.supported` in the `esbuildOptions` callback is intentional behavior and should not be flagged as a side effect issue.
Applied to files:
eslint.config.js
⏰ 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: report
|
File extensions are also required to run typescript natively by |
|
dynamic migration rule name might be required for #2980 but I probably would do it in another PR |
RobinTail
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🏁 ready now
module: node20module: node20 and import extensions
module: node20 and import extensionsmodule: node20 and import extensions
module: node20introduced in Typescript 5.9 as a stable replacement fornodenext:https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-9.html#support-for---module-node20
The recommended combination is with
moduleResolution: node16:microsoft/TypeScript#61805
That change implies relative imports to have extensions, however, it's possible to change them directly to
.ts, which will also reiterate and resolve #2289 . It will enable running typescript natively by Node.js withouttsx. It may also come handy if I decide to publish to JSR.Summary by CodeRabbit