Skip to content

fix: JSDoc parameter parsing for deeply nested parameters#16

Merged
Zih0 merged 7 commits intov0.0.2from
fix/js-doc-parser-nested-param
Feb 16, 2026
Merged

fix: JSDoc parameter parsing for deeply nested parameters#16
Zih0 merged 7 commits intov0.0.2from
fix/js-doc-parser-nested-param

Conversation

@Zih0
Copy link
Copy Markdown
Collaborator

@Zih0 Zih0 commented Jan 23, 2026

Changes

Fix JSDoc parser to correctly handle deeply nested parameter properties (3+ levels)

Example

/**
 * @param {Object} config - Configuration object
 * @param {Object} config.database - Database settings
 * @param {Object} config.database.connection - Connection settings
 * @param {string} config.database.connection.host - Database host
 * @param {number} config.database.connection.port - Database port
 * @param {string} config.database.name - Database name
 */

AS-IS

config.database.connection.host → config.nested[database.connection.host]
SCR-20260123-lchy

TO-BE

config.database.connection.host → config.nested[database].nested[connection].nested[host]
SCR-20260123-ldui

@vercel
Copy link
Copy Markdown

vercel bot commented Jan 23, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
docflow-docs Ready Ready Preview, Comment Feb 16, 2026 11:31am

Request Review

@Zih0 Zih0 self-assigned this Jan 23, 2026
expect(result.parameters?.[0].nested?.[2].defaultValue).toBe("true");
});

it("should parse deeply nested parameter properties (3+ levels)", () => {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I think we should add some test cases for edge cases like this to improve robustness. For example, what happens if the parent is declared after its children?

/**
 * @param {Object} config.database.connection - Connection settings
 * @param {string} config.database.connection.host - Database host
 * @param {number} config.database.connection.port - Database port
 * @param {string} config.database.name - Database name
 * @param {Object} config.database - Database settings
 * @param {Object} config - Configuration object
 */
export function configure(config: any): void {
  // implementation
}

Copy link
Copy Markdown
Collaborator Author

@Zih0 Zih0 Jan 26, 2026

Choose a reason for hiding this comment

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

I added test cases.
cf3e539
a3d58cd

Comment on lines 163 to 201
private insertParamAtPath({ into, path, param }: {
into: ParameterData[];
path: string[];
param: ParameterData;
}): void {
const [currentSegment, ...remainingPath] = path;
if (currentSegment == null) {
return;
}

if (isEmpty(remainingPath)) {
into.push({ ...param, name: currentSegment, nested: [] });

return;
}

const existingChild = into.find((n) => n.name === currentSegment);
const child = existingChild ?? this.createPlaceholderObjectParam(currentSegment);
if (existingChild == null) {
into.push(child);
}

const nestedParam = { ...param, name: parts.slice(1).join(".") };
parent.nested = parent.nested || [];
parent.nested.push(nestedParam);
this.insertParamAtPath({
into: child.nested ?? [],
path: remainingPath,
param,
});
}

private createPlaceholderObjectParam(name: string): ParameterData {
return {
name,
type: "Object",
description: "",
required: true,
defaultValue: undefined,
nested: [],
};
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I'm not sure this is the optimal way to write this method — it relies heavily on imperative code with mutations rather than declarative code that returns values. Also, looking at this call in isolation, it's hard to tell what the method actually does without seeing the implementation:

// Can we understand what this method does without the surrounding context?
this.insertParamAtPath({
  into: child.nested ?? [],
  path: remainingPath,
  param,
});

I think we can rewrite this to return a value instead, making it more declarative and predictable. Let me think about this for a moment.

Copy link
Copy Markdown
Collaborator Author

@Zih0 Zih0 Jan 26, 2026

Choose a reason for hiding this comment

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

I refactored some mutable logic to make it more immutable, but please let me know if you see any issues.

e7ae3ad
5931920

@Zih0 Zih0 merged commit 9515808 into v0.0.2 Feb 16, 2026
3 checks passed
@Zih0 Zih0 deleted the fix/js-doc-parser-nested-param branch February 16, 2026 11:32
@Zih0 Zih0 mentioned this pull request Mar 25, 2026
Zih0 added a commit that referenced this pull request Mar 25, 2026
* fix: remove root tsconfig fallback and add error handling for package tsconfig resolution (#14)

* fix: remove root tsconfig fallback and add error handling for package tsconfig resolution

* empty commit

* test: update getTsConfigPath test to throw error for non-existent package tsconfig

* feat: support running commands from subdirectories in monorepo (#15)

* feat: replace process.cwd() with INIT_CWD

* fix: resolve package paths relative to cwd

* test: update package-manager tests to include correct package locations

* refactor: update project path resolution to use projectRoot in commands

* fix: resolve symlink in temp path

* refactor: use find-up package

* chore: Prettier Setup (#18)

* setup prettier

* format all

* ci format

* fix: JSDoc parameter parsing for deeply nested parameters (#16)

* fix: enhance JSDoc parameter parsing for deeply nested properties

* add test cases

* refactor: mutable -> immutable

* fix: duplicate jsdoc tag case

* fix: format

* refactor: simplify logic

* refactor: enhance JSDoc parameter extraction and tree building logic

* feat(check): add @param, @Property, @returns validation to check command (#20)

* feat: check command -@param/@returns tag validation (#19)

* feat(check): add validation types and Validator base class

Add ValidationError/ValidationResult types and abstract Validator<T>
base class using Template Method pattern (validate -> collectErrors).

* feat(check): add JSDoc utility functions

Add EMPTY_PARSED_JSDOC constant and getJSDocParameterNames helper
for centralized JSDoc parameter name extraction with nested support.

* feat(check): add common validator utility functions

Add findMissingDocs, findUnusedDocs (difference-based detection)
and collectPropertySignaturePaths (recursive path collection).

* feat(check): add InterfaceValidator with tests

Validate interface property/method JSDoc coverage including nested
properties, optional/readonly modifiers. 13 test cases.

* fix: remove 'as const' assertion from missing and unused docs types

* refactor(check): unify findUnusedDocs parameter order

Swap findUnusedDocs(jsDocNames, validTargets) to
findUnusedDocs(validTargets, jsDocNames) so both find*Docs functions
take (codeSymbols, jsDocNames) consistently.

* fix(check): include interface methods in missing docs check

* fix: format

* feat(check): add validator utility functions

Add collectParameterPaths and collectPropertyAssignmentPaths utilities
for resolving nested dot-separated paths from function parameters and
object literal assignments. Add JSDoc to existing collectPropertySignaturePaths.

* feat(check): add TypeAliasValidator with tests

* feat(check): add ObjectLiteralValidator with tests

* feat(check): add FunctionValidator with tests

* feat(check): add validation pipeline with tests

* refactor(check): integrate validation pipeline into check command

* docs(check): enhance documentation for check command to include validation of @param and @returns tags

* feat(check): add @Property tag parsing to JSDocParser

* feat(check): validate @Property tags for interface, type alias, and object literal

* docs(check): update documentation to reflect @Property validation

* feat: support `@property` tag for JSDoc parsing (#21)

* feat: parse JSDoc `@property`

* feat: add support for JSDoc `@property` rendering in VitePress generator

* feat: add 'properties' label support for JSDoc in English and Korean docflow Config

* feat: export PropertyData type

* feat:  add GeneratorConfig label.properties type

* feat: update JSDoc comments to use @Property syntax for improved clarity and consistency

* feat: rename ParameterData to PropertyData in JSDoc utility functions for consistency

* refactor: update JSDoc comments to use @Property syntax for improved clarity and consistency across multiple interfaces

* feat: update JSDoc references to use 'properties'

* refactor: update documentation to replace '매개변수' with '속성' for consistency across multiple interfaces

* fix: add shebang (#8)

* fix: add cli.js with shebang

* package.json files

* feat: improve config usability (#9)

* feat: separate `Config` and `ResolvedConfig`

This allows user configs to omit fields with defaults

* feat: default `project.workspace.exclude` with `[]`

* feat: make object options with default values optional

---------

Co-authored-by: Jiho Shin <ziho.dev@gmail.com>

* format

* fix yarn.lock

* fix: jsdoc and generated docs

* feat: Improve extractSignature to include JSDoc comments (#22)

* feat(cli): include JSDoc and members in class/interface signatures

* test(cli): add JSDoc signature extraction tests

* fix(cli): resolve absolute file paths in type signatures

* test(cli): add cross-package return type path test

* fix(jsdoc): merge name and description for jsdoc tag (#23)

* test: move validation for plugin configuration in config schema

* fix(jsdoc): merge name and description for jsdoc tag

* Fix/barrel re export multiple file name (#24)

* test: move validation for plugin configuration in config schema

* fix(parser): preserve multiple non-barrel exports for same symbol

* fix: tag value trim

* fix:  Escape `<`, `>` inside backtick content (#25)

* changeset

* feat: docflow build docs

* feat: add properties and typedef labels to build schema and generator config

* add docs

* format

---------

Co-authored-by: Iha Shin (신의하) <me@xiniha.dev>
@github-actions github-actions bot mentioned this pull request Mar 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants