Skip to content

docs/: code-quality issues in the code-example subsystem and server utils #139

@IgorShevchik

Description

@IgorShevchik

Found during a multi-angle code review of the docs site (while maintaining the Russian mirror bitrix-tools/b24jssdk, which syncs docs/ from here 1:1). None are crashes today, but several are latent/fragile. Reporting upstream so the mirror can stay byte-identical. Line numbers are approximate (current main).

Medium

  1. Server util imports a browser composabledocs/server/utils/transformMDC.ts does import { useB24 } from '../../app/composables/useB24' and calls only prepareCode, but useB24.ts touches sessionStorage / window.name / useNuxtApp / nextTick. It works today only because those code paths aren't hit during SSR/prerender, but any change to useB24 init can break /raw and llms-full.txt generation. Suggestion: extract prepareCode / transformCodeForDocumentationSafe into a browser-free module (e.g. utils/codeTransform.ts).

  2. Brace counting ignores strings/commentsuseB24.ts transformCodeForDocumentationSafe increments/decrements braceDepth per literal {/} char without accounting for string literals or comments, so e.g. const s = 'a{b}' or // { result } skews the count and can truncate the example early/late. The region:start / endregion:start markers already present could be used instead.

  3. fetchCodeExample swallows errorsdocs/app/composables/fetchCodeExample.ts: on failure the .catch stores a stub object into state.value[name] and throws; the trailing await state.value[name] (now a non-promise object) silently resolves and returns the stub, so callers can't distinguish success from failure. Suggestion: keep the in-flight promise in a separate variable, set the result/stub only in finally.

Low

  1. Always-true conditiondocs/server/utils/normalizeComponentName.ts: normalizedName[1] === normalizedName[1]?.toUpperCase() compares a char with itself (always true). The JSDoc says "followed by an uppercase letter"; it should check the char after the B24 prefix (index 3). Note: this file also appears to be unused (no imports).

  2. Dead code (no imports anywhere)docs/app/composables/cachedParseMarkdown.ts, docs/server/utils/extractSections.ts, docs/server/utils/normalizeComponentName.ts. Consider removing or marking @deprecated.

  3. Dead branchdocs/server/utils/transformMDC.ts processLinks has a node[0] === 'tip' branch, but callouts (tip, …) are already converted to blockquote earlier in the same function, so the branch never runs.

  4. Possible key collisiondocs/modules/code-example.ts keys examples by parse(relativePath).name only; scanDirectory is recursive, so two files with the same basename in different subdirs would overwrite each other. Use the relative path as the key.

  5. Unnecessary awaitdocs/app/components/content/CodeExample.vue await useCodeExample()useCodeExample is synchronous; the await adds a needless Suspense barrier.

  6. any typesdocs/modules/code-example.ts let _configResolved: any (use ResolvedConfig from vite); fetchCodeExample.ts Record<string, CodeExample | any> collapses to any.

  7. Hardcoded dedentuseB24.ts uses .slice(2) to strip exactly 2 spaces of indentation from example lines; brittle if example indentation style changes (4 spaces/tabs). A min-indent dedent would be safer.

Minor

  1. Unneeded CORSdocs/server/api/code-examples.get.ts sets Access-Control-Allow-Origin: * on a same-origin, read-only endpoint; can be dropped/narrowed.

Happy to send PRs for any of these if useful.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions