From 8fcc8fb6c2af1e672a43797474ecb2db659c634a Mon Sep 17 00:00:00 2001 From: Jaehyun Yoon Date: Thu, 13 Aug 2026 17:29:15 +0900 Subject: [PATCH] docs: correct stale and inaccurate JSDoc across the library --- packages/express-cargo/src/analysis.ts | 6 +++--- packages/express-cargo/src/decorators/missingHandler.ts | 2 +- packages/express-cargo/src/decorators/transform.ts | 5 ++--- packages/express-cargo/src/decorators/typeHelper.ts | 2 +- packages/express-cargo/src/decorators/validators/array.ts | 4 ++-- packages/express-cargo/src/rules/errors.ts | 2 +- packages/express-cargo/src/rules/ruleChecker.ts | 7 +------ packages/express-cargo/src/rules/types.ts | 5 +++++ packages/express-cargo/src/types.ts | 2 ++ 9 files changed, 18 insertions(+), 17 deletions(-) diff --git a/packages/express-cargo/src/analysis.ts b/packages/express-cargo/src/analysis.ts index 6503605..de212e4 100644 --- a/packages/express-cargo/src/analysis.ts +++ b/packages/express-cargo/src/analysis.ts @@ -18,13 +18,13 @@ function collectNestedClasses(classMeta: CargoClassMetadata): ClassConstructor[] if (isUserDefinedClass(typeFn)) { nested.push(typeFn) } else if (typeFn.length === 0) { - // @Type(() => Foo) — Thunk form. Resolver form (`(data) => Foo`) can't be - // evaluated statically and will throw on the no-arg call; we catch and skip. + // @Type(() => Foo) — Thunk form. A Resolver declares a parameter, so the arity + // check already excludes it; a zero-arg function may still read runtime data. try { const result = (typeFn as TypeThunk)() if (isUserDefinedClass(result)) nested.push(result) } catch { - // Resolver-shaped functions need runtime data; ignore. + // Needs runtime data; resolved during binding instead. } } diff --git a/packages/express-cargo/src/decorators/missingHandler.ts b/packages/express-cargo/src/decorators/missingHandler.ts index 1c71f45..7c8090a 100644 --- a/packages/express-cargo/src/decorators/missingHandler.ts +++ b/packages/express-cargo/src/decorators/missingHandler.ts @@ -2,7 +2,7 @@ import { CargoClassMetadata } from '../metadata' /** * Marks a property as optional. - * If the property is missing in the request, it will be ignored during validation. + * When the property is missing from the request it is set to `null` and its validators are skipped. */ export function Optional(): PropertyDecorator { return (target: any, propertyKey: string | symbol) => { diff --git a/packages/express-cargo/src/decorators/transform.ts b/packages/express-cargo/src/decorators/transform.ts index d015d57..1e9ccb3 100644 --- a/packages/express-cargo/src/decorators/transform.ts +++ b/packages/express-cargo/src/decorators/transform.ts @@ -45,9 +45,8 @@ export function Request(transformer: (req: Request) => T): TypedPropertyDecor /** * Defines a virtual property that is calculated based on other properties of the instance. * @remarks - * **Important:** This property must be declared **after** all the properties it depends on. - * Since decorators are evaluated in the order they are defined, accessing a property - * declared below the virtual property will result in `undefined`. + * Every source field is bound before any virtual field runs, so a virtual property may read them regardless of declaration order. + * Virtual fields are computed in declaration order, however, so one that reads **another virtual field** must be declared after it. * @param transformer - A function that receives the current object instance. * @example * ```ts diff --git a/packages/express-cargo/src/decorators/typeHelper.ts b/packages/express-cargo/src/decorators/typeHelper.ts index f4fa612..9d808a9 100644 --- a/packages/express-cargo/src/decorators/typeHelper.ts +++ b/packages/express-cargo/src/decorators/typeHelper.ts @@ -26,7 +26,7 @@ export function List(elementType: ArrayElementType): TypedPropertyDecorator Class` (Static types & circular refs) * 2. **Resolver**: `(data) => Class` (Dynamic polymorphism) * 3. **Discriminator**: Structural mapping via `options.discriminator`. diff --git a/packages/express-cargo/src/decorators/validators/array.ts b/packages/express-cargo/src/decorators/validators/array.ts index fd7df5f..d328ce0 100644 --- a/packages/express-cargo/src/decorators/validators/array.ts +++ b/packages/express-cargo/src/decorators/validators/array.ts @@ -13,7 +13,7 @@ import { addValidator } from './addValidator' * @param message - Optional custom error message. */ export function ListContains(values: any[], comparator?: ArrayComparator, message?: CargoErrorMessage): TypedPropertyDecorator { - // Pre-split only when using default comparison (Set + deepEqual optimization) + // Pre-split only when using default comparison (Set + isDeepEqual optimization) const expectedPrimitives = !comparator ? values.filter(v => v === null || typeof v !== 'object') : [] const expectedObjects = !comparator ? values.filter(v => v !== null && typeof v === 'object') : [] @@ -73,7 +73,7 @@ export function ListContains(values: any[], comparator?: ArrayComparator, messag * @param message - Optional custom error message. */ export function ListNotContains(values: any[], comparator?: ArrayComparator, message?: CargoErrorMessage): TypedPropertyDecorator { - // Pre-split only when using default comparison (Set + deepEqual optimization) + // Pre-split only when using default comparison (Set + isDeepEqual optimization) const excludedPrimitives = !comparator ? values.filter(v => v === null || typeof v !== 'object') : [] const excludedObjects = !comparator ? values.filter(v => v !== null && typeof v === 'object') : [] diff --git a/packages/express-cargo/src/rules/errors.ts b/packages/express-cargo/src/rules/errors.ts index 39b8fe1..8c5b65a 100644 --- a/packages/express-cargo/src/rules/errors.ts +++ b/packages/express-cargo/src/rules/errors.ts @@ -1,7 +1,7 @@ import type { ClassConstructor } from '../types' import type { RuleViolation } from './types' -/** Thrown by `validateCargoSchema()` when one or more rule violations are detected. */ +/** Thrown by `bindingCargo()` at route registration when the cargo class breaks one or more schema rules. */ export class CargoSchemaError extends Error { name: string violations: RuleViolation[] diff --git a/packages/express-cargo/src/rules/ruleChecker.ts b/packages/express-cargo/src/rules/ruleChecker.ts index 4d9d5a3..2206f82 100644 --- a/packages/express-cargo/src/rules/ruleChecker.ts +++ b/packages/express-cargo/src/rules/ruleChecker.ts @@ -1,12 +1,7 @@ import type { CargoFieldMetadata } from '../metadata' import type { FieldRuleFn, FieldState, RuleChecker, RuleViolation } from './types' -/** - * Contract for a single rule checker. - * - * Inspects one class (`ctx.cargoClass`) and returns every violation it finds. - * Nested-DTO traversal is handled by `validateCargoSchema`, so checkers don't recurse. - */ +/** Pre-computes the per-field view a {@link FieldRuleFn} receives. */ function buildFieldState(propertyKey: string | symbol, fieldMeta: CargoFieldMetadata, siblingFields: ReadonlySet): FieldState { const appliedSelf = fieldMeta.getAppliedDecorators('self') const appliedEach = fieldMeta.getAppliedDecorators('each') diff --git a/packages/express-cargo/src/rules/types.ts b/packages/express-cargo/src/rules/types.ts index f30d47e..590ec2c 100644 --- a/packages/express-cargo/src/rules/types.ts +++ b/packages/express-cargo/src/rules/types.ts @@ -33,4 +33,9 @@ export interface RuleViolation { message: string } +/** + * Contract for a single rule checker: inspects one class (`ctx.cargoClass`) and returns + * every violation it finds. Nested-DTO traversal is handled by `validateAnalysis`, so + * checkers don't recurse. + */ export type RuleChecker = (ctx: RuleContext) => RuleViolation[] diff --git a/packages/express-cargo/src/types.ts b/packages/express-cargo/src/types.ts index 393176b..c0c257b 100644 --- a/packages/express-cargo/src/types.ts +++ b/packages/express-cargo/src/types.ts @@ -7,6 +7,8 @@ import type { CargoClassMetadata } from './metadata' * - `params`: req.params * - `header`: req.headers * - `session`: req.session + * - `file`: one uploaded file, via the configured file locator + * - `files`: every uploaded file sharing the field name */ export type Source = 'body' | 'query' | 'params' | 'header' | 'session' | 'file' | 'files'