Skip to content

Conversation

@DaxServer
Copy link
Owner

No description provided.

@coderabbitai
Copy link

coderabbitai bot commented Aug 21, 2025

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • None (no user-facing changes).
  • Chores

    • Added linting and formatting plugins to enforce organized imports and disallow relative import paths.
    • Configured TypeScript path aliases for cleaner module resolution.
  • Refactor

    • Migrated source imports to use path aliases; no behavioral changes.
  • Style

    • Standardized import order and indentation in code and tests.
  • Tests

    • Updated test imports to shared fixtures and aligned expected outputs with new formatting.
    • Removed an obsolete test suite.

Walkthrough

Replaced many relative imports with TypeScript path aliases, added ESLint rule to forbid relative imports (including same-folder), added Prettier organize-imports plugin, introduced tsconfig path aliases, updated tests to use aliased test fixtures, adjusted some test formatting expectations, and removed one obsolete test file.

Changes

Cohort / File(s) Summary of changes
Tooling & config
eslint.config.ts, package.json, prettier.config.ts, tsconfig.json
Added eslint-plugin-no-relative-import-paths and enabled rule 'no-relative-import-paths/no-relative-import-paths' with { allowSameFolder: false }; added prettier-plugin-organize-imports; added baseUrl and path aliases for @daxserver/validation-schema-codegen/* and @test-fixtures/*.
TypeBox handlers (imports)
src/handlers/typebox/*-type-handler.ts, src/handlers/typebox/typebox-type-handlers.ts
Replaced relative imports with aliased package imports (e.g., @daxserver/validation-schema-codegen/handlers/typebox/...); minor import reorderings; no behavioral changes.
Parsers (imports)
src/parsers/*
Switched local relative imports to aliased package paths under @daxserver/validation-schema-codegen/...; consolidated/reordered some ts-morph imports; no logic changes.
Utils (imports)
src/utils/*
Updated internal imports to use package-scoped aliases (e.g., @daxserver/validation-schema-codegen/utils/...); functionality unchanged.
Codegen entrypoint
src/ts-morph-codegen.ts
Repointed parser and util imports to package aliases; adjusted import ordering/type imports; no runtime or API changes.
Parsers/Dependency tooling (imports)
src/utils/dependency-*.ts, src/parsers/parse-*.ts
Converted relative imports to alias imports; reorganized some ts-morph imports; preserved public signatures and behavior.
Tests — fixture imports
tests/ts-morph/*.test.ts, tests/ts-morph/utils.ts, tests/integration/wikibase/wikibase.ts
Replaced many local test helper imports with @test-fixtures/ts-morph/utils and other aliased imports; updated generateCode usage to generateFormattedCode where applicable; reorganized bun:test imports.
Tests — formatting expectations
tests/ts-morph/export-everything.test.ts, tests/ts-morph/function-types.test.ts, tests/ts-morph/utility-types.test.ts, ...
Adjusted expected output formatting/indentation in several tests to match new formatting/plugin behavior.
Tests — deletion
tests/ts-morph/generatecode-tsconfig.test.ts
Removed the obsolete test suite.
Misc. tests & small updates
tests/ts-morph/*.test.ts (multiple), tests/ts-morph/dependency-collector.*.test.ts
Minor import-path updates to use package aliases; some reordering of imports and type/value import distinctions.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch pathalias-imports

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

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 16

Caution

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

⚠️ Outside diff range comments (5)
tests/ts-morph/enum-types.test.ts (1)

27-37: Tests don’t await the async expectation — assertions may be skipped.

generateFormattedCode appears to return a Promise. Without await/return, the test can finish before the assertion runs. Fix by returning the promise from expect(...).resolves (no need to mark the test async).

-      expect(generateFormattedCode(sourceFile)).resolves.toBe(
+      return expect(generateFormattedCode(sourceFile)).resolves.toBe(
         formatWithPrettier(`enum A {
           B,
           C,
         }
 
         const A = Type.Enum(A);
 
         type A = Static<typeof A>;
       `),
       )

Apply the same change to the three other occurrences in this file.

Also applies to: 50-60, 75-85, 98-108

src/handlers/typebox/pick-type-handler.ts (2)

29-44: Bug: non-string keys lead to empty-string sentinel and possibly invalid Union([]).

If any union member isn’t a string literal, the current code pushes '', which will generate Type.Literal(''), or, if nothing matches, Type.Union([]). Both produce incorrect schemas.

Use a fail-fast approach: if a non-string-literal key is encountered, fall back to Any (or handle additional cases). Also normalize string extraction via getLiteralText().

-    let pickKeys: string[] = []
-    if (Node.isUnionTypeNode(keysType)) {
-      pickKeys = keysType.getTypeNodes().map((unionType) => {
-        if (Node.isLiteralTypeNode(unionType)) {
-          const literalExpression = unionType.getLiteral()
-          if (Node.isStringLiteral(literalExpression)) {
-            return literalExpression.getLiteralText()
-          }
-        }
-        return '' // Should not happen if keys are string literals
-      })
-    } else if (Node.isLiteralTypeNode(keysType)) {
-      const literalExpression = keysType.getLiteral()
-      if (Node.isStringLiteral(literalExpression)) {
-        pickKeys = [literalExpression.getLiteralText()]
-      }
-    }
+    let pickKeys: string[] = []
+    if (Node.isUnionTypeNode(keysType)) {
+      for (const unionType of keysType.getTypeNodes()) {
+        if (!Node.isLiteralTypeNode(unionType)) return makeTypeCall('Any')
+        const lit = unionType.getLiteral()
+        if (!Node.isStringLiteral(lit)) return makeTypeCall('Any')
+        pickKeys.push(lit.getLiteralText())
+      }
+    } else if (Node.isLiteralTypeNode(keysType)) {
+      const lit = keysType.getLiteral()
+      if (!Node.isStringLiteral(lit)) return makeTypeCall('Any')
+      pickKeys = [lit.getLiteralText()]
+    } else {
+      return makeTypeCall('Any')
+    }
+    if (pickKeys.length === 0) return makeTypeCall('Any')

46-56: Minor: guard against constructing Union([]) when no keys are present.

If upstream parsing yields no keys, Type.Union([]) is invalid. The suggested change above adds an early return to Any when pickKeys.length === 0.

tests/ts-morph/advanced-types.test.ts (1)

17-27: Tests don’t await Promise assertions; they may pass/fail nondeterministically.

expect(...).resolves returns a Promise; without await or returning that Promise, the test finishes before the assertion runs. Make tests async and await the expectation (or return it).

Apply these diffs:

@@
-    test('simple template literal', () => {
+    test('simple template literal', async () => {
@@
-      expect(generateFormattedCode(sourceFile)).resolves.toBe(
+      await expect(generateFormattedCode(sourceFile)).resolves.toBe(
@@
-    test('complex template literal', () => {
+    test('complex template literal', async () => {
@@
-      expect(generateFormattedCode(sourceFile)).resolves.toBe(
+      await expect(generateFormattedCode(sourceFile)).resolves.toBe(
@@
-    test('typeof variable', () => {
+    test('typeof variable', async () => {
@@
-      expect(generateFormattedCode(sourceFile)).resolves.toBe(
+      await expect(generateFormattedCode(sourceFile)).resolves.toBe(
@@
-    test('typeof with qualified name', () => {
+    test('typeof with qualified name', async () => {
@@
-      expect(generateFormattedCode(sourceFile)).resolves.toBe(
+      await expect(generateFormattedCode(sourceFile)).resolves.toBe(

Also applies to: 29-39, 43-59, 61-79

tests/ts-morph/primitive-types.test.ts (1)

16-27: All Promise-based assertions need awaiting.

Each test uses expect(...).resolves without awaiting/returning. Make tests async and await the expectations to ensure failures are caught.

You can apply the mechanical changes with a script:

#!/bin/bash
# Make all tests in this file async and await .resolves expectations
set -euo pipefail
file="tests/ts-morph/primitive-types.test.ts"

# 1) Mark test callbacks as async
#    handles: test('name', () => { ... })  -> test('name', async () => { ... })
gawk -i inplace '{
  if ($0 ~ /^[[:space:]]*test\([[:space:]]*'\''[^'\'']*'\''[[:space:]]*,[[:space:]]*\(\)[[:space:]]*=>[[:space:]]*\{[[:space:]]*$/) {
    sub(/\(\)[[:space:]]*=>/, "async () =>")
  }
  print
}' "$file"

# 2) Prefix `expect(...).resolves` with await when not already awaited
gawk -i inplace '{
  if ($0 ~ /expect\(.*\)\.resolves\.toBe\(/ && $0 !~ /await[[:space:]]+expect/) {
    sub(/expect/, "await expect")
  }
  print
}' "$file"

echo "Patched $file"

If you prefer manual patches, here’s the pattern to apply in each test block:

-    test('string', () => {
+    test('string', async () => {
@@
-      expect(generateFormattedCode(sourceFile)).resolves.toBe(
+      await expect(generateFormattedCode(sourceFile)).resolves.toBe(

Also applies to: 29-40, 41-52, 53-64, 65-76, 77-88, 89-100, 102-113, 115-126, 127-138, 139-150, 151-162, 163-174, 175-186

♻️ Duplicate comments (3)
src/handlers/typebox/tuple-type-handler.ts (1)

1-2: Consistent alias imports; mirrors InterfaceTypeHandler.

Change aligns with the repo-wide refactor. As noted on InterfaceTypeHandler, ensure subpath exports or alias rewriting at build time so deep self-imports remain resolvable after publish.

tests/ts-morph/import-resolution.test.ts (1)

1-7: Alias adoption across tests: looks good; double-check tsconfig path setup for Bun.

Imports now rely on:

  • @daxserver/validation-schema-codegen/utils/dependency-collector
  • @test-fixtures/ts-morph/utils

Bun typically respects tsconfig "paths"; ensure baseUrl/paths are present so bun:test resolves these at runtime.

Reuse the verification script from the handler file comment to confirm tsconfig paths and build/export strategy.

src/parsers/parse-imports.ts (1)

1-6: Parser imports switched to aliases: LGTM; ensure consistent usage across src to avoid duplicate module instances.

Mixing relative and alias imports to the same module can create duplicate singletons/types at runtime. This PR appears to standardize on aliases—good. Please confirm no remaining relative imports to these modules in src.

You can run the same script shared earlier to scan for remaining relative imports under src/.

🧹 Nitpick comments (27)
tsconfig.json (1)

24-24: Was relaxing noPropertyAccessFromIndexSignature intentional?

Setting "noPropertyAccessFromIndexSignature": false weakens safety by allowing dotted access for index signatures. If this change wasn’t part of the alias effort, consider reverting to true (or removing the override) to keep stricter checks.

Would you like me to scan for violations that would fail if this flag were true and propose minimal fixes?

src/handlers/typebox/function-type-handler.ts (2)

1-2: Use the configured alias prefix for consistency.

This file imports from 'src/...', while tsconfig provides the @daxserver/validation-schema-codegen/* alias. Prefer the alias for consistency and future publishability.

-import { BaseTypeHandler } from 'src/handlers/typebox/base-type-handler'
-import { makeTypeCall } from 'src/utils/typebox-codegen-utils'
+import { BaseTypeHandler } from '@daxserver/validation-schema-codegen/handlers/typebox/base-type-handler'
+import { makeTypeCall } from '@daxserver/validation-schema-codegen/utils/typebox-codegen-utils'

23-33: Optionally consider defaulted params as optional too.

A parameter with a default initializer behaves like an optional at call sites. If that aligns with your schema intent, treat hasInitializer() like hasQuestionToken().

-    const parameterTypes = parameters.map((param) => {
-      const paramTypeNode = param.getTypeNode()
-      const paramType = this.getTypeBoxType(paramTypeNode)
-
-      // Check if parameter is optional
-      if (param.hasQuestionToken()) {
-        return makeTypeCall('Optional', [paramType])
-      }
-
-      return paramType
-    })
+    const parameterTypes = parameters.map((param) => {
+      const paramTypeNode = param.getTypeNode()
+      const paramType = this.getTypeBoxType(paramTypeNode)
+      // Optional if ? or has a default
+      if (param.hasQuestionToken() || param.hasInitializer()) {
+        return makeTypeCall('Optional', [paramType])
+      }
+      return paramType
+    })

Follow-up: Rest parameters (param.isRest()) and a possible leading this parameter aren’t handled yet—flagging for awareness.

eslint.config.ts (2)

15-22: Rule enforcing non-relative imports: good addition.

The plugin and rule are correctly wired. Consider scoping it via overrides if you want different behavior for config files or fixtures.

Example override (optional):

export default defineConfig([
  // ...
  {
    files: ['**/*.{ts,tsx,js,jsx}'],
    plugins: { 'no-relative-import-paths': noRelativeImportPaths },
    rules: {
      'no-relative-import-paths/no-relative-import-paths': ['error', { allowSameFolder: false }],
    },
  },
  {
    files: ['**/*.config.{ts,js}'],
    rules: {
      'no-relative-import-paths/no-relative-import-paths': 'off',
    },
  },
])

9-12: Browser globals are enabled; include Node globals too to match this codebase.

Most of this repo is tooling (ts-morph, codegen) and runs in Node. Adding Node globals avoids lint noise for process, __dirname, etc.

-    languageOptions: {
-      globals: globals.browser,
-    },
+    languageOptions: {
+      globals: { ...globals.node, ...globals.browser },
+    },
src/handlers/typebox/type-operator-handler.ts (1)

14-25: Optional: Handle or log unsupported type operators (readonly/unique).

Currently only keyof is handled; all other operators fall back to Any. Consider either:

  • explicitly handling additional operators you care about, or
  • adding a small comment/TODO so future readers know the fallback is intentional.

Not blocking.

tests/integration/wikibase/wikibase.ts (2)

1-1: Use the same alias here for consistency.

This import still references src/.... Prefer the project alias to keep everything uniform and independent of baseUrl.

Apply this diff:

-import { generateCode } from 'src/ts-morph-codegen'
+import { generateCode } from '@daxserver/validation-schema-codegen/ts-morph-codegen'

15-18: Nit: build paths with path.join for portability.

Interpolating __dirname works, but path.join avoids accidental double slashes or missing separators on different OSes.

-const outputPath = `${__dirname}/output.ts`
+import { join } from 'node:path'
+const outputPath = join(__dirname, 'output.ts')
src/handlers/typebox/literal-type-handler.ts (3)

7-8: Avoid constructing an invalid identifier for the unused callback.

ts.factory.createIdentifier('') creates an invalid AST node. If this function is ever invoked, it will emit broken code. Use an explicit throw (safer) or a benign literal.

-  constructor() {
-    super(() => ts.factory.createIdentifier('')) // getTypeBoxType is not used in LiteralTypeHandler
-  }
+  constructor() {
+    super(() => {
+      throw new Error('LiteralTypeHandler.getTypeBoxType should not be called')
+    })
+  }

10-15: Simplify canHandle to what handle actually supports.

canHandle includes Node.isTrueLiteral/isFalseLiteral, but handle expects a LiteralTypeNode. To reduce confusion, consider narrowing canHandle to literal type nodes only.

-  canHandle(typeNode?: Node): boolean {
-    return (
-      Node.isLiteralTypeNode(typeNode) ||
-      Node.isTrueLiteral(typeNode) ||
-      Node.isFalseLiteral(typeNode)
-    )
-  }
+  canHandle(typeNode?: Node): boolean {
+    return Node.isLiteralTypeNode(typeNode)
+  }

26-30: Use getLiteralText() to preserve escapes and avoid manual slicing.

getText().slice(1, -1) can mishandle escaped quotes and template escapes. Prefer getLiteralText().

-      case SyntaxKind.StringLiteral:
-        return makeTypeCall('Literal', [
-          ts.factory.createStringLiteral(literal.getText().slice(1, -1)),
-        ])
+      case SyntaxKind.StringLiteral:
+        return makeTypeCall('Literal', [
+          ts.factory.createStringLiteral(literal.getLiteralText()),
+        ])
src/parsers/parse-type-aliases.ts (1)

1-3: Alias import refactor is consistent with the handler changes.

Nice consolidation to the package-scoped paths. One nuance: since this file will exist in the published output, confirm that either:

  • package.json exports exposes subpaths like utils/typebox-call and parsers/base-parser, or
  • the build step rewrites these aliases to relative paths.

Without one of those, publishing could yield unresolved imports at runtime.

If you prefer build-time rewriting over wide-open exports, consider adding tsc-alias postbuild:

  "scripts": {
-   "build": "tsc -p tsconfig.build.json"
+   "build": "tsc -p tsconfig.build.json && tsc-alias -p tsconfig.build.json"
  },
+ "devDependencies": {
+   "tsc-alias": "^1.8.10"
+ }
src/utils/dependency-collector.ts (1)

1-9: Consolidated imports look good; consider type-only import from ts-morph.

The alias-based imports from utils are correct and keep the runtime clean (nice use of type for FileResolver/TypeReferenceExtractor). Since ImportDeclaration, SourceFile, and TypeAliasDeclaration are only used as types here, switching to a type-only import will avoid generating a runtime dependency on ts-morph.

Apply this diff:

-import { ImportDeclaration, SourceFile, TypeAliasDeclaration } from 'ts-morph'
+import type { ImportDeclaration, SourceFile, TypeAliasDeclaration } from 'ts-morph'

Note: Keep import type usage on the other side as well (in dependency-type.ts) to prevent a runtime cycle between the extractor and collector modules.

src/handlers/typebox/omit-type-handler.ts (1)

1-2: Consistent alias imports; minor note on robustness of key extraction (optional).

Imports look good. As a future hardening (not part of this PR), consider filtering out non-string-literal keys before building the Union to avoid emitting empty string literals when unions contain unexpected members.

-    if (Node.isUnionTypeNode(keysType)) {
-      omitKeys = keysType.getTypeNodes().map((unionType) => {
-        if (Node.isLiteralTypeNode(unionType)) {
-          const literalExpression = unionType.getLiteral()
-          if (Node.isStringLiteral(literalExpression)) {
-            return literalExpression.getLiteralText()
-          }
-        }
-        return '' // Should not happen if keys are string literals
-      })
+    if (Node.isUnionTypeNode(keysType)) {
+      omitKeys = keysType
+        .getTypeNodes()
+        .map((unionType) => {
+          if (Node.isLiteralTypeNode(unionType)) {
+            const lit = unionType.getLiteral()
+            if (Node.isStringLiteral(lit)) return lit.getLiteralText()
+          }
+          return ''
+        })
+        .filter((k) => k !== '')
src/handlers/typebox/record-type-handler.ts (1)

1-2: Unify alias style: prefer the @daxserver/… alias over bare 'src/…'

Other files in this PR (e.g., PartialTypeHandler, parsers) use the @daxserver/validation-schema-codegen/* alias. Mixing 'src/…' and '@daxserver/…' increases cognitive load and can drift with future restructuring. Recommend standardizing to the package alias here.

Apply this diff:

-import { BaseTypeHandler } from 'src/handlers/typebox/base-type-handler'
-import { makeTypeCall } from 'src/utils/typebox-codegen-utils'
+import { BaseTypeHandler } from '@daxserver/validation-schema-codegen/handlers/typebox/base-type-handler'
+import { makeTypeCall } from '@daxserver/validation-schema-codegen/utils/typebox-codegen-utils'
tests/ts-morph/dependency-collector.integration.test.ts (1)

1-3: Minor import style nit

Grouping Bun’s test imports is fine either way; if you aim for consistency, mirror the project-wide Prettier organize-imports output everywhere. No action required.

src/handlers/typebox/typebox-type-handlers.ts (1)

1-21: Unify import style in src/handlers/typebox/typebox-type-handlers.ts

Your changes use bare src/… imports, but our tsconfig.json maps @daxserver/validation-schema-codegen/*./src/*. To keep imports consistent with the rest of the codebase (and ensure the compiled JS still resolves correctly outside of ts-morph), please update these to the package-scoped alias.

• File to update:
– src/handlers/typebox/typebox-type-handlers.ts (lines 1–21)

• Suggested diff (optional refactor):

-import { ArrayTypeHandler } from 'src/handlers/typebox/array-type-handler'
-import { BaseTypeHandler } from 'src/handlers/typebox/base-type-handler'
-import { FunctionTypeHandler } from 'src/handlers/typebox/function-type-handler'
-import { IndexedAccessTypeHandler } from 'src/handlers/typebox/indexed-access-type-handler'
-import { InterfaceTypeHandler } from 'src/handlers/typebox/interface-type-handler'
-import { IntersectionTypeHandler } from 'src/handlers/typebox/intersection-type-handler'
-import { LiteralTypeHandler } from 'src/handlers/typebox/literal-type-handler'
-import { ObjectTypeHandler } from 'src/handlers/typebox/object-type-handler'
-import { OmitTypeHandler } from 'src/handlers/typebox/omit-type-handler'
-import { PartialTypeHandler } from 'src/handlers/typebox/partial-type-handler'
-import { PickTypeHandler } from 'src/handlers/typebox/pick-type-handler'
-import { RecordTypeHandler } from 'src/handlers/typebox/record-type-handler'
-import { RequiredTypeHandler } from 'src/handlers/typebox/required-type-handler'
-import { SimpleTypeHandler } from 'src/handlers/typebox/simple-type-handler'
-import { TemplateLiteralTypeHandler } from 'src/handlers/typebox/template-literal-type-handler'
-import { TupleTypeHandler } from 'src/handlers/typebox/tuple-type-handler'
-import { TypeOperatorHandler } from 'src/handlers/typebox/type-operator-handler'
-import { TypeQueryHandler } from 'src/handlers/typebox/type-query-handler'
-import { TypeReferenceHandler } from 'src/handlers/typebox/type-reference-handler'
-import { UnionTypeHandler } from 'src/handlers/typebox/union-type-handler'
+import { ArrayTypeHandler } from '@daxserver/validation-schema-codegen/handlers/typebox/array-type-handler'
+import { BaseTypeHandler } from '@daxserver/validation-schema-codegen/handlers/typebox/base-type-handler'
+import { FunctionTypeHandler } from '@daxserver/validation-schema-codegen/handlers/typebox/function-type-handler'
+import { IndexedAccessTypeHandler } from '@daxserver/validation-schema-codegen/handlers/typebox/indexed-access-type-handler'
+import { InterfaceTypeHandler } from '@daxserver/validation-schema-codegen/handlers/typebox/interface-type-handler'
+import { IntersectionTypeHandler } from '@daxserver/validation-schema-codegen/handlers/typebox/intersection-type-handler'
+import { LiteralTypeHandler } from '@daxserver/validation-schema-codegen/handlers/typebox/literal-type-handler'
+import { ObjectTypeHandler } from '@daxserver/validation-schema-codegen/handlers/typebox/object-type-handler'
+import { OmitTypeHandler } from '@daxserver/validation-schema-codegen/handlers/typebox/omit-type-handler'
+import { PartialTypeHandler } from '@daxserver/validation-schema-codegen/handlers/typebox/partial-type-handler'
+import { PickTypeHandler } from '@daxserver/validation-schema-codegen/handlers/typebox/pick-type-handler'
+import { RecordTypeHandler } from '@daxserver/validation-schema-codegen/handlers/typebox/record-type-handler'
+import { RequiredTypeHandler } from '@daxserver/validation-schema-codegen/handlers/typebox/required-type-handler'
+import { SimpleTypeHandler } from '@daxserver/validation-schema-codegen/handlers/typebox/simple-type-handler'
+import { TemplateLiteralTypeHandler } from '@daxserver/validation-schema-codegen/handlers/typebox/template-literal-type-handler'
+import { TupleTypeHandler } from '@daxserver/validation-schema-codegen/handlers/typebox/tuple-type-handler'
+import { TypeOperatorHandler } from '@daxserver/validation-schema-codegen/handlers/typebox/type-operator-handler'
+import { TypeQueryHandler } from '@daxserver/validation-schema-codegen/handlers/typebox/type-query-handler'
+import { TypeReferenceHandler } from '@daxserver/validation-schema-codegen/handlers/typebox/type-reference-handler'
+import { UnionTypeHandler } from '@daxserver/validation-schema-codegen/handlers/typebox/union-type-handler'

Optional: Create a barrel at handlers/typebox/index.ts and import all handlers from there to reduce verbosity.

tests/ts-morph/dependency-collector.performance.test.ts (2)

1-3: Use the package-scoped alias consistently for internal imports

You switched to aliases for test fixtures, but this test still pulls DependencyCollector via the bare specifier src/.... To avoid mixed resolution strategies and ensure runtime works both in-repo and after publish, import it via the package alias like elsewhere in the PR.

Apply:

-import { createSourceFile } from '@test-fixtures/ts-morph/utils'
-import { beforeEach, describe, expect, test } from 'bun:test'
-import { DependencyCollector } from 'src/utils/dependency-collector'
+import { createSourceFile } from '@test-fixtures/ts-morph/utils'
+import { beforeEach, describe, expect, test } from 'bun:test'
+import { DependencyCollector } from '@daxserver/validation-schema-codegen/utils/dependency-collector'

38-40: Avoid tight wall-clock thresholds in perf tests

1s budget can be flaky in CI across runners and load. Consider:

  • Increasing headroom (e.g., 2–3s), or
  • Asserting relative performance (ops/visited nodes) instead of absolute wall time.
src/utils/typebox-call.ts (1)

7-12: Minor: simplify lazy init with nullish coalescing assignment

Functional no-op, but makes intent clearer.

-let handlers: TypeBoxTypeHandlers | null = null
+let handlers: TypeBoxTypeHandlers | null = null

 export const getTypeBoxType = (typeNode?: Node): ts.Expression => {
-  if (!handlers) {
-    handlers = new TypeBoxTypeHandlers(getTypeBoxType)
-  }
+  handlers ??= new TypeBoxTypeHandlers(getTypeBoxType)
   const handler = handlers.getHandler(typeNode)
   if (handler) {
     return handler.handle(typeNode)
   }
   return makeTypeCall('Any')
 }
src/handlers/typebox/type-reference-handler.ts (1)

14-24: Broaden support to qualified type names (A.B) instead of falling back to Any

Right now only simple identifiers are supported. For import type * as NS from "./x"; type T = NS.Foo; or nested namespaces, getTypeName() yields a QualifiedName. You can emit a chained property access instead of Any.

   handle(typeNode: Node): ts.Expression {
     if (!Node.isTypeReference(typeNode)) {
       return makeTypeCall('Any')
     }
     const referencedType = typeNode.getTypeName()
-    if (Node.isIdentifier(referencedType)) {
-      const typeName = referencedType.getText()
-      return ts.factory.createIdentifier(typeName)
-    }
-    return makeTypeCall('Any')
+    if (Node.isIdentifier(referencedType)) {
+      return ts.factory.createIdentifier(referencedType.getText())
+    }
+    if (Node.isQualifiedName(referencedType)) {
+      // Build A.B.C as a property access chain
+      const parts = referencedType.getText().split('.')
+      let expr: ts.Expression = ts.factory.createIdentifier(parts[0]!)
+      for (const p of parts.slice(1)) {
+        expr = ts.factory.createPropertyAccessExpression(expr, p!)
+      }
+      return expr
+    }
+    return makeTypeCall('Any')
   }
tests/ts-morph/export-everything.test.ts (2)

24-32: Reduce fragility from indentation-sensitive expected strings.

Many expectations changed only due to indentation. To make tests resilient to formatting shifts, consider normalizing indentation of template literals before passing to Prettier.

You can add a small helper to tests/ts-morph/utils.ts and apply it inside formatWithPrettier:

 export const formatWithPrettier = (input: string, addImport: boolean = true): string => {
-  const code = addImport ? `${typeboxImport}${input}` : input
-  return synchronizedPrettier.format(code, prettierOptions)
+  const stripIndent = (s: string): string => {
+    const lines = s.replace(/^\s*\n/, '').replace(/\s*$/, '').split('\n')
+    const indents = lines.filter(l => l.trim()).map(l => l.match(/^\s*/)?.[0].length ?? 0)
+    const min = indents.length ? Math.min(...indents) : 0
+    return lines.map(l => l.slice(min)).join('\n')
+  }
+  const code = addImport ? `${typeboxImport}${stripIndent(input)}` : stripIndent(input)
+  return synchronizedPrettier.format(code, prettierOptions)
 }

This keeps the test intent stable and avoids touching many lines whenever indentation nudges.

Also applies to: 41-44, 49-60, 69-71, 76-83, 105-117, 126-129, 134-145, 154-156, 161-164


24-32: Confirm enum re-emission order remains intentional.

The sequence:

  • export enum MyEnum ...
  • export const MyEnum = Type.Enum(MyEnum);
  • export type MyEnum = Static<...>;

is unchanged functionally but can be confusing due to reused identifier. If this is required by the codegen contract, ignore. Otherwise consider distinct const identifiers (e.g., MyEnumSchema) to improve readability of generated output expectations.

src/ts-morph-codegen.ts (4)

25-34: tsconfck integration: edge-case handling and test coverage.

Catching failures and defaulting verbatimModuleSyntax to false is reasonable. Consider adding a focused test that runs generateCode under a project with compilerOptions.verbatimModuleSyntax: true to ensure the split imports are emitted as intended.

I can add a fixture tsconfig and a minimal source to exercise both branches if you want.


36-51: Import emission correctly honors verbatimModuleSyntax.

  • When true: split value vs type imports is the right move.
  • When false: combined import keeps things concise.

One minor micro-nit: you could emit the two imports in one go by building the specifiers list dynamically, but current clarity is fine.


70-85: Dependency ordering logic is consistent; consider small deduping.

The branch that preserves original import order under exportEverything versus local-first otherwise is clear. If collectFromImports internally ignores the boolean, you can collapse duplication:

-  let orderedDependencies: TypeDependency[]
-  if (options.exportEverything) {
-    orderedDependencies = dependencyCollector.collectFromImports(
-      importDeclarations,
-      options.exportEverything,
-    )
-    dependencyCollector.addLocalTypes(localTypeAliases, sourceFile)
-  } else {
-    dependencyCollector.addLocalTypes(localTypeAliases, sourceFile)
-    orderedDependencies = dependencyCollector.collectFromImports(
-      importDeclarations,
-      options.exportEverything,
-    )
-  }
+  let orderedDependencies: TypeDependency[]
+  if (options.exportEverything) {
+    orderedDependencies = dependencyCollector.collectFromImports(importDeclarations, true)
+    dependencyCollector.addLocalTypes(localTypeAliases, sourceFile)
+  } else {
+    dependencyCollector.addLocalTypes(localTypeAliases, sourceFile)
+    orderedDependencies = dependencyCollector.collectFromImports(importDeclarations, false)
+  }

If that boolean is significant, keep as-is.


122-123: Return strategy is fine; consider getText() for normalized output.

getFullText() can include leading BOM or trivia differences; getText() returns a normalized snapshot that’s often better for string comparison. Tests may already normalize via Prettier, so this is optional.

-  return newSourceFile.getFullText()
+  return newSourceFile.getText()
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between b21dc46 and ed9d52e.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (49)
  • eslint.config.ts (2 hunks)
  • package.json (1 hunks)
  • prettier.config.ts (1 hunks)
  • src/handlers/typebox/array-type-handler.ts (1 hunks)
  • src/handlers/typebox/function-type-handler.ts (1 hunks)
  • src/handlers/typebox/indexed-access-type-handler.ts (1 hunks)
  • src/handlers/typebox/interface-type-handler.ts (1 hunks)
  • src/handlers/typebox/intersection-type-handler.ts (1 hunks)
  • src/handlers/typebox/literal-type-handler.ts (1 hunks)
  • src/handlers/typebox/object-type-handler.ts (1 hunks)
  • src/handlers/typebox/omit-type-handler.ts (1 hunks)
  • src/handlers/typebox/partial-type-handler.ts (1 hunks)
  • src/handlers/typebox/pick-type-handler.ts (1 hunks)
  • src/handlers/typebox/record-type-handler.ts (1 hunks)
  • src/handlers/typebox/required-type-handler.ts (1 hunks)
  • src/handlers/typebox/simple-type-handler.ts (1 hunks)
  • src/handlers/typebox/template-literal-type-handler.ts (1 hunks)
  • src/handlers/typebox/tuple-type-handler.ts (1 hunks)
  • src/handlers/typebox/type-operator-handler.ts (1 hunks)
  • src/handlers/typebox/type-query-handler.ts (1 hunks)
  • src/handlers/typebox/type-reference-handler.ts (1 hunks)
  • src/handlers/typebox/typebox-type-handlers.ts (1 hunks)
  • src/handlers/typebox/union-type-handler.ts (1 hunks)
  • src/parsers/parse-enums.ts (1 hunks)
  • src/parsers/parse-function-declarations.ts (1 hunks)
  • src/parsers/parse-imports.ts (1 hunks)
  • src/parsers/parse-interfaces.ts (1 hunks)
  • src/parsers/parse-type-aliases.ts (1 hunks)
  • src/ts-morph-codegen.ts (1 hunks)
  • src/utils/add-static-type-alias.ts (1 hunks)
  • src/utils/dependency-collector.ts (1 hunks)
  • src/utils/dependency-type.ts (1 hunks)
  • src/utils/typebox-call.ts (1 hunks)
  • tests/integration/wikibase/wikibase.ts (1 hunks)
  • tests/ts-morph/advanced-types.test.ts (1 hunks)
  • tests/ts-morph/array-types.test.ts (1 hunks)
  • tests/ts-morph/dependency-collector.integration.test.ts (1 hunks)
  • tests/ts-morph/dependency-collector.performance.test.ts (1 hunks)
  • tests/ts-morph/dependency-collector.unit.test.ts (1 hunks)
  • tests/ts-morph/enum-types.test.ts (1 hunks)
  • tests/ts-morph/export-everything.test.ts (7 hunks)
  • tests/ts-morph/function-types.test.ts (2 hunks)
  • tests/ts-morph/generatecode-tsconfig.test.ts (0 hunks)
  • tests/ts-morph/import-resolution.test.ts (1 hunks)
  • tests/ts-morph/object-types.test.ts (1 hunks)
  • tests/ts-morph/primitive-types.test.ts (1 hunks)
  • tests/ts-morph/utility-types.test.ts (13 hunks)
  • tests/ts-morph/utils.ts (1 hunks)
  • tsconfig.json (1 hunks)
💤 Files with no reviewable changes (1)
  • tests/ts-morph/generatecode-tsconfig.test.ts
🧰 Additional context used
🧬 Code graph analysis (3)
tests/ts-morph/utility-types.test.ts (1)
tests/ts-morph/utils.ts (3)
  • generateFormattedCode (19-25)
  • formatWithPrettier (14-17)
  • createSourceFile (10-12)
tests/ts-morph/export-everything.test.ts (1)
tests/ts-morph/utils.ts (2)
  • generateFormattedCode (19-25)
  • formatWithPrettier (14-17)
tests/ts-morph/function-types.test.ts (1)
tests/ts-morph/utils.ts (3)
  • createSourceFile (10-12)
  • generateFormattedCode (19-25)
  • formatWithPrettier (14-17)
🔇 Additional comments (35)
prettier.config.ts (1)

17-18: No side-effect imports detected; relative imports confined to tests

  • Searched for bare, side-effect-only imports (e.g., import 'foo'): none found across the repo.
  • All remaining relative imports are in tests/ts-morph/** files (necessary for import-resolution tests), not in production code.

No action required—plugin won’t remove any needed side-effect imports, and test-relative imports are intentional.

src/handlers/typebox/type-operator-handler.ts (1)

1-3: Good migration to path-alias imports.

Imports now use the project alias and look consistent with the PR’s goal. No functional changes introduced here.

tests/integration/wikibase/wikibase.ts (1)

5-11: Dependency ‘wikibase-sdk’ is already declared in package.json
The script confirms that "wikibase-sdk": "^10.2.3" is present at line 22 of package.json, so once you run bun install (or your package manager’s install command), Bun will resolve and load the module for the integration tests. No further changes are required.

src/handlers/typebox/literal-type-handler.ts (1)

1-3: Alias imports look good.

No functional changes introduced by the import refactor. All good here.

tests/ts-morph/enum-types.test.ts (1)

1-5: Nice move to centralized test utilities via the alias.

This keeps tests consistent with the new path strategy and reduces brittle relative paths.

src/handlers/typebox/pick-type-handler.ts (1)

1-2: Alias imports look consistent.

This aligns with the PR’s objective and avoids deep relative paths. Good.

src/handlers/typebox/interface-type-handler.ts (1)

1-3: Switch to path-alias imports looks good; runtime/test resolution and publish plan still need confirmation.

tsconfig paths and code checks

  • @daxserver/validation-schema-codegen/*./src/* and @test-fixtures/*./tests/* are correctly defined in tsconfig.json.
  • No relative imports remain in src/.
  • There’s no dist/ directory or "exports" field in package.json for deep imports.

Please confirm:

  • How your code is transpiled/bundled for runtime—e.g. are you using jiti, tsc-alias, or a bundler to rewrite TS paths so Node (and Bun) can resolve @daxserver/… at runtime?
  • If you intend to publish this package, that you’ve added a package.json exports mapping (for example "./*": "./dist/*") or equivalent so consumers can import deep subpaths.
  • That your test runner (Bun) honors tsconfig paths (or you’ve configured a resolver plugin such as tsconfig-paths).
tests/ts-morph/advanced-types.test.ts (1)

1-5: Centralizing test utils via @test-fixtures alias is a good move.

This will reduce churn on test file paths and plays well with your no-relative-imports rule.

tests/ts-morph/primitive-types.test.ts (1)

1-5: Shared test utilities via @test-fixtures alias: LGTM.

Consistent with the rest of the suite and your ESLint rule.

src/handlers/typebox/required-type-handler.ts (1)

1-1: Good migration to path alias.

Import now uses the package-scoped alias and matches the PR objective. No functional impact.

src/utils/dependency-type.ts (1)

1-1: Nice: type-only import avoids runtime cycles.

Using import type { TypeDependency } ... prevents a circular runtime dependency with dependency-collector while maintaining type safety. Matches the alias migration goal.

src/parsers/parse-function-declarations.ts (1)

1-4: Everything looks good – getTypeBoxType safely handles undefined inputs

I confirmed that getTypeBoxType is declared as

export const getTypeBoxType = (typeNode?: Node): ts.Expression => {  }

so it intentionally accepts undefined and will return a default makeTypeCall('Any') when no handler is found. No further changes are needed here.

src/handlers/typebox/array-type-handler.ts (1)

1-2: Alias import switch looks good and matches the handlers’ pattern.

No behavioral changes; keeps BaseTypeHandler and utility usage consistent across the TypeBox handlers.

src/utils/add-static-type-alias.ts (1)

1-1: Switch to package-scoped alias for TypeBoxStatic looks good

Import path aligns with the PR goal; no behavioral changes. The rest of the function remains correct and side-effect free.

src/handlers/typebox/partial-type-handler.ts (1)

1-2: Alias migration is consistent and correct

Matches the repo-wide direction to use @daxserver/… paths; no logic changes. Good.

src/parsers/parse-enums.ts (2)

1-3: Import alias refactor is coherent; no functional impact

Using internal package aliases for BaseParser and addStaticTypeAlias is consistent with the rest of the PR. Parse logic remains intact.


1-3: Path aliases validated for code generation

Imports for both BaseParser (from src/parsers/base-parser.ts) and addStaticTypeAlias (from src/utils/add-static-type-alias.ts) correctly resolve via the @daxserver/validation-schema-codegen/* path mapping defined in tsconfig.json. No further action is needed.

tests/ts-morph/dependency-collector.integration.test.ts (1)

1-3: All TS path aliases are in place and Bun’s test runner will resolve them

  • In tsconfig.json, under compilerOptions.paths, both
    @daxserver/validation-schema-codegen/* → ./src/*
    @test-fixtures/* → ./tests/*
    are correctly defined.
  • Bun’s runtime (and by extension bun test) automatically reads and applies the compilerOptions.paths mappings from your root tsconfig.json to re-map import paths at runtime (bun.com).

No further changes are needed—Bun will resolve your aliases in tests as configured.

src/handlers/typebox/object-type-handler.ts (1)

1-2: LGTM: imports now use the package-scoped alias

Importing BaseTypeHandler and makeTypeCall via '@daxserver/validation-schema-codegen/*' aligns with the PR’s alias strategy and improves portability. Nothing else changes functionally here.

src/handlers/typebox/template-literal-type-handler.ts (1)

1-2: LGTM: alias imports adopted

Consistent with the repo-wide change; no behavior change. Good to go.

src/handlers/typebox/type-query-handler.ts (1)

1-2: LGTM: alias imports adopted

Matches the new path alias scheme; implementation remains unchanged.

src/handlers/typebox/simple-type-handler.ts (1)

1-2: LGTM: alias imports adopted

Consistent with the rest of the handlers; no functional differences.

tests/ts-morph/array-types.test.ts (1)

1-5: LGTM on alias migration; verify path mapping exists

The switch to @test-fixtures/ts-morph/utils aligns with the PR direction. Just ensure tsconfig contains the "@test-fixtures/" → "./tests/" mapping and that Bun/Node resolves it in test runs (via native support or a resolver).

You can reuse the verification script from the other comment; it prints the tsconfig path mappings it finds.

src/utils/typebox-call.ts (1)

1-2: Self-referential package imports require matching exports or alias rewriting

Importing internal files via @daxserver/validation-schema-codegen/* inside the same package will leave those specifiers in the compiled JS. Ensure at least one of:

  • package.json "exports" exposes the used subpaths (e.g., "./handlers/typebox/typebox-type-handlers", "./utils/typebox-codegen-utils"), or
  • your build rewrites aliases to relative paths (tsc-alias/tsup with tsconfig-paths), or
  • test/runtime loader registers tsconfig paths.

Otherwise, consumers (and even local runtime without linking) may resolve failures.

Use the repo-wide script I provided to confirm "exports" and build steps.

src/handlers/typebox/type-reference-handler.ts (1)

1-2: Same note on self-referential aliasing

This file also depends on package-scoped internal paths. Please confirm the "exports" map or alias-rewrite in the build as noted earlier.

src/handlers/typebox/union-type-handler.ts (2)

1-2: Alias import note (exports/build rewrite)

Same self-referential import consideration applies here. Verify exports or alias rewriting.


15-21: LGTM: safe guard + construction look correct

canHandle/handle pairing is sound; Union([...]) emission reads well.

tests/ts-morph/export-everything.test.ts (1)

1-1: Test fixture alias import: LGTM.

The move to "@test-fixtures/ts-morph/utils" aligns with the repo-wide alias strategy.

tests/ts-morph/dependency-collector.unit.test.ts (1)

1-12: Good split between value and type imports; alias migration LGTM.

  • type-only imports from ts-morph prevent runtime overhead.
  • Using interface types (FileResolver, TypeReferenceExtractor) for mocks decouples tests from concrete implementations.
tests/ts-morph/utility-types.test.ts (2)

46-51: Prettier-aligned expected output is coherent with the generator’s TypeBox style.

The updated indentation and trailing commas in the expected “Record” case match the generator’s formatting via formatWithPrettier. No issues.


1-5: Path alias configuration verified

The project’s root tsconfig.json clearly defines both the baseUrl and the required path mappings (lines 25–28):

  • baseUrl: "."
  • "@daxserver/validation-schema-codegen/" → ["./src/"]
  • "@test-fixtures/" → ["./tests/"]

This covers the @test-fixtures/ts-morph/utils import, so Bun’s bun test runner will resolve it correctly. No further changes needed.

src/ts-morph-codegen.ts (2)

1-9: Path-alias refactor and type-only import are clean.

  • Swapping relative imports to @daxserver/validation-schema-codegen/* improves clarity and avoids brittle paths.
  • type TypeDependency as a type-only import is correct and keeps emitted JS lean.

87-104: Topological processing + processedTypes guard prevents duplication.

The check against processedTypes during both dependency and local passes looks correct and avoids duplicate emission.

tests/ts-morph/function-types.test.ts (2)

1-5: Path-alias import adoption acknowledged; confirm tsconfig paths cover this module.

Same guidance as in the other test file—ensure @test-fixtures/* is mapped in tsconfig, and Bun honors it.

You can reuse the earlier script; it checks both @test-fixtures/* and @daxserver/validation-schema-codegen/*.


33-39: Expected TypeBox output looks consistent for parameters and return types.

Type.Function([Type.Number(), Type.String()], Type.Boolean()) matches the generator’s convention. Good.

"eslint": "^9.33.0",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-prettier": "^5.5.4",
"eslint-plugin-no-relative-import-paths": "^1.6.1",
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Tooling deps added align with the config. LGTM.

eslint-plugin-no-relative-import-paths and prettier-plugin-organize-imports match the ESLint and Prettier changes. No runtime impact.

If CI doesn’t already, add a lightweight check to ensure imports stay organized:

Also applies to: 19-19


🏁 Script executed:

#!/bin/bash
# Verify formatting is stable
pnpm prettier --check . || npm run -s format -- --check

Length of output: 272


Ensure CI formatting check includes or excludes biome.json

LGTM on the added ESLint and Prettier plugins. To prevent CI breaks (as pnpm prettier --check . is currently warning on biome.json), please update your formatting setup:

• If you want Prettier to ignore biome.json, add it to your .prettierignore:

# .prettierignore  
biome.json  

• Otherwise, configure Prettier (or the import-organizer plugin) to format biome.json correctly—e.g. add a schema or plugin that supports its structure.

• Then add a dedicated CI script in package.json and your pipeline:

 // package.json
 {
   "scripts": {
+      "ci:format-check": "pnpm prettier --check .",
     "format":    "prettier --write ."
   }
 }

And in your CI config:

# example GitHub Actions step
- name: Check formatting
  run: pnpm ci:format-check

This will enforce that all intended files—including or excluding biome.json—stay correctly formatted in CI.

🤖 Prompt for AI Agents
In package.json around line 15, the CI formatting check currently fails because
biome.json is not handled; either add biome.json to .prettierignore so Prettier
skips it, or configure Prettier/plugins/schema to support formatting biome.json,
then add a dedicated script in package.json (e.g., "ci:format-check") that runs
the formatter check (pnpm prettier --check . or the chosen tool) and update your
CI pipeline to call that script (e.g., a workflow step running pnpm
ci:format-check) so CI consistently enforces the intended include/exclude
behavior for biome.json.

Comment on lines +1 to +2
import { BaseTypeHandler } from '@daxserver/validation-schema-codegen/handlers/typebox/base-type-handler'
import { makeTypeCall } from '@daxserver/validation-schema-codegen/utils/typebox-codegen-utils'
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Alias imports look correct; verify path mapping and publish-time resolution.

  • Good switch to package-scoped aliases; no behavioral changes.
  • Please confirm tsconfig has paths for:
    • "@daxserver/validation-schema-codegen/" -> "./src/"

If you publish compiled JS, ensure either:

  • package.json "exports" exposes subpaths like "./utils/" and "./handlers/", or
  • the build rewrites aliases to relative paths (e.g., tsc-alias/tscpaths/tsup).

Run this to validate mappings and export strategy:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== package.json name and exports =="
jq -r '.name, (.exports // "NO_EXPORTS_FIELD")' package.json

echo -e "\n== tsconfig.* path aliases =="
fd -a 'tsconfig*.json' | while read -r f; do
  echo "---- $f ----"
  jq -r '.compilerOptions.baseUrl // "baseUrl: <missing>"' "$f"
  jq -r '.compilerOptions.paths // {}' "$f"
done

echo -e "\n== Any remaining relative imports in src (should be none) =="
rg -nP --type=ts --type=tsx -g 'src/**' '\bfrom\s+[\"\']\.\.?(?:/|$)'

echo -e "\n== Alias imports present (sanity check) =="
rg -nP --type=ts --type=tsx '@daxserver/validation-schema-codegen/' src

echo -e "\n== Build scripts that rewrite aliases (tsc-alias/tsup/etc.) =="
jq -r '.scripts // {}' package.json
rg -n 'tsc-alias|tscpaths|tsup|rollup|esbuild' package.json

Length of output: 573


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Searching for baseUrl in tsconfig.json =="
rg -n '"baseUrl"' tsconfig.json -C3 || echo "baseUrl not found"

echo -e "\n== Searching for paths in tsconfig.json =="
rg -n '"paths"' tsconfig.json -C5 || echo "paths not found"

echo -e "\n== Showing first 20 lines of tsconfig.json =="
sed -n '1,20p' tsconfig.json

Length of output: 1583


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== package.json scripts =="
jq '.scripts // {}' package.json

echo -e "\n== package.json devDependencies (alias rewrite tools) =="
jq '.devDependencies // {}' package.json | grep -E 'tsc-alias|tscpaths|tsup|rollup|esbuild' || echo "none found"

echo -e "\n== Any remaining relative imports in src (should be none) =="
rg -nP --type=ts --type=tsx -g 'src/**' '\bfrom\s+[\"\']\.\.?(?:/|$)' || echo "no relative imports found"

echo -e "\n== Alias imports present in src =="
rg -nP --type=ts --type=tsx '@daxserver/validation-schema-codegen/' src || echo "no alias imports found"

Length of output: 707


Missing runtime resolution for package-scoped imports

Your tsconfig paths are correctly set up, but without runtime support your imports like

import { BaseTypeHandler } from '@daxserver/validation-schema-codegen/handlers/typebox/base-type-handler'

will fail once published. Currently:

  • No "exports" field in package.json
  • No alias‐rewriting tool (e.g. tsc-alias/tsup) in your build

You must choose one of the following refactoring strategies:

  • Add a proper "exports" map in package.json to expose each subpath. For example:

     {
       "name": "@daxserver/validation-schema-codegen",
    +  "exports": {
    +    "./handlers/*": "./dist/handlers/*",
    +    "./utils/*":    "./dist/utils/*"
    +  },
       ...
     }
  • Or integrate an alias‐rewriter into your build pipeline (e.g., install tsc-alias or use tsup) and update your package.json scripts accordingly. For example:

     {
       "scripts": {
    +    "build": "tsc && tsc-alias",
         "typecheck": "tsc --noEmit",
         "lint":      "eslint"
       },
       "devDependencies": {
    +    "tsc-alias": "^1.3.0",
         ...
       }
     }

Either approach will ensure that published code correctly resolves the new scoped imports at runtime.

🤖 Prompt for AI Agents
In src/handlers/typebox/intersection-type-handler.ts lines 1-2 the file imports
package-scoped paths (e.g. @daxserver/validation-schema-codegen/handlers/...),
which will break at runtime because there is no package.json "exports" map and
no alias-rewriter in the build; fix by either adding an exports map to
package.json that exposes each subpath used by the runtime (add entries for the
root and each nested import path referenced across the repo) or integrate an
alias-rewriting step into the build (install and invoke tsc-alias or use a
bundler like tsup that rewrites path aliases) and update package.json scripts to
run the rewriter post-build so the published JS contains valid require/import
paths.

Comment on lines 1 to 2
import { BaseTypeHandler } from 'src/handlers/typebox/base-type-handler'
import { makeTypeCall } from 'src/utils/typebox-codegen-utils'
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Quick repo check for lingering 'src/' imports

If you intend to enforce only alias imports, scan for remaining 'src/' usages and update or extend your ESLint rule accordingly.


🏁 Script executed:

#!/bin/bash
# List any TypeScript/TSX files still importing from bare 'src/...'
rg -nP --type=ts --type=tsx "from\s+['\"]src\/" -S -C0

# Confirm tsconfig path alias exists for the canonical alias
rg -n "paths" tsconfig*.json -n
rg -n "@daxserver/validation-schema-codegen/*" tsconfig*.json -n

Length of output: 265


🏁 Script executed:

#!/bin/bash
# Search for bare 'src/' imports in TS and TSX files
rg -nP "from\s+['\"]src\/" -g '*.ts' -g '*.tsx' -C0

# Check ESLint configuration for import restrictions on 'src/'
rg -n "no-restricted-imports" -g '.eslintrc*'
rg -n "import/no-unresolved" -g '.eslintrc*'

Length of output: 4213


Enforce path-alias imports in place of bare “src/…”

A quick Ripgrep scan shows numerous TypeScript files still importing directly from “src/…”, for example:

  • src/parsers/parse-interfaces.ts
  • tests/ts-morph/dependency-collector.performance.test.ts
  • all handlers under src/handlers/typebox/ (including record-type-handler.ts, function-type-handler.ts, etc.)

Since your tsconfig.json already maps @daxserver/validation-schema-codegen/*./src/*, please:

• Replace all remaining

import  from 'src/…'

with

import  from '@daxserver/validation-schema-codegen/…'

• Add (or extend) an ESLint rule to block bare “src/*” imports. For example, in your ESLint config:

{
  "rules": {
    "no-restricted-imports": [
      "error",
      {
        "patterns": ["src/*"]
      }
    ]
  },
  "settings": {
    "import/resolver": {
      "alias": {
        "map": [["@daxserver/validation-schema-codegen", "./src"]],
        "extensions": [".ts", ".tsx"]
      }
    }
  }
}

This will ensure all code uses the canonical path alias and prevent regressions.

🤖 Prompt for AI Agents
In src/handlers/typebox/record-type-handler.ts lines 1-2, the file currently
imports using the bare "src/…" path; update those imports to use the configured
TypeScript path alias "@daxserver/validation-schema-codegen/…" (e.g. replace
imports from 'src/handlers/…' with
'@daxserver/validation-schema-codegen/handlers/…'). After changing this file,
sweep other TS files that import from "src/…" and replace them similarly.
Finally, add or extend your ESLint configuration to include a
no-restricted-imports rule blocking "src/*" and ensure your import resolver maps
the alias to ./src to prevent future regressions.

Comment on lines +1 to +3
import { BaseTypeHandler } from '@daxserver/validation-schema-codegen/handlers/typebox/base-type-handler'
import { makeTypeCall } from '@daxserver/validation-schema-codegen/utils/typebox-codegen-utils'
import { Node, SyntaxKind, ts } from 'ts-morph'
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Repo-wide verification: ensure no lingering relative imports remain.

To validate the migration, run this script to surface any remaining relative import specifiers and stray absolute src/... imports that should be aliased.


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Relative imports (./ or ../):"
rg -nP --glob '!**/node_modules/**' --glob '!**/dist/**' --glob '!**/build/**' \
   -g '!**/*.map' -g '!**/*.snap' -g '!**/coverage/**' \
   $'\\bfrom\\s*[\'"]\\.{1,2}/' || true

echo
echo "Absolute root imports using 'src/...':"
rg -nP --glob '!**/node_modules/**' --glob '!**/dist/**' --glob '!**/build/**' \
   -g '!**/*.map' -g '!**/*.snap' -g '!**/coverage/**' \
   $'\\bfrom\\s*[\'"]src/' || true

Length of output: 9750


Remove all lingering relative (./ or ../) and hard-coded src/… imports

We ran the provided verification script and found that both relative imports and absolute‐root imports remain across tests and source files. These must be replaced with the configured path alias (for example, @daxserver/validation-schema-codegen/...) to complete the migration.

Files requiring updates:

  • Tests under tests/ts-morph/**/*.test.ts
    • Multiple from './utils', from './external-types', from './deeply-nested-types', etc.
  • Performance and integration tests
    • tests/ts-morph/dependency-collector.performance.test.ts: import { DependencyCollector } from 'src/utils/dependency-collector'
    • tests/integration/wikibase/wikibase.ts: import { generateCode } from 'src/ts-morph-codegen'
  • Parsers
    • src/parsers/parse-interfaces.ts: imports from 'src/parsers/base-parser', 'src/utils/add-static-type-alias', 'src/utils/typebox-call'
  • TypeBox handlers
    • src/handlers/typebox/*.ts: numerous import … from 'src/handlers/typebox/... and import … from 'src/utils/typebox-codegen-utils'

Next steps:

  • Replace all from 'src/... with the equivalent alias path (e.g. from '@daxserver/validation-schema-codegen/…').
  • Update test imports (from './…') to use the same alias, or adjust test setup to resolve the alias in tests.
  • Re-run the script to confirm zero matches.
🤖 Prompt for AI Agents
In src/handlers/typebox/type-operator-handler.ts lines 1-3, the imports use
hard-coded paths that must be converted to the configured path alias; replace
"import { BaseTypeHandler } from
'@daxserver/validation-schema-codegen/handlers/typebox/base-type-handler'" and
"import { makeTypeCall } from
'@daxserver/validation-schema-codegen/utils/typebox-codegen-utils'" (and any
other './' or 'src/...' imports in this file) with the correct alias-based paths
(e.g. '@daxserver/validation-schema-codegen/...') so no relative or src/…
imports remain; ensure the project path aliases (tsconfig/paths) are respected
and update any corresponding test imports or test resolver config if needed,
then re-run the verification script to confirm zero matches.

Comment on lines +1 to +5
import {
createSourceFile,
formatWithPrettier,
generateFormattedCode,
} from '@test-fixtures/ts-morph/utils'
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Good move to the @test-fixtures alias; verify Bun resolves tsconfig paths in tests.

Looks consistent with the PR’s aliasing strategy. To avoid surprise “Cannot find module '@test-fixtures/…'” at runtime, ensure Bun’s test runner picks up your tsconfig “paths” (either via default Bun behavior or bunfig.toml settings).

Run the script to confirm the mappings exist and that no lingering relative imports remain in tests:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Checking tsconfig path mappings..."
rg -nC2 '"paths"\s*:' tsconfig.json || { echo "Missing paths in tsconfig.json"; exit 1; }

rg -n '"@test-fixtures/\*"' tsconfig.json || echo "Missing @test-fixtures/* mapping in tsconfig.json"
rg -n '"@daxserver/validation-schema-codegen/\*"' tsconfig.json || echo "Missing @daxserver/validation-schema-codegen/* mapping in tsconfig.json"

echo
echo "Checking for lingering relative imports to ./utils in tests..."
rg -nP "from\s+['\"]\./utils['\"]" tests || echo "No direct ./utils imports found in tests."

echo
echo "If Bun uses bunfig.toml, show it for sanity:"
fd -a bunfig.toml && cat bunfig.toml || echo "No bunfig.toml; Bun should still honor tsconfig by default."

Length of output: 1250


Confirm tsconfig path mappings; address lingering relative imports

  • Verified tsconfig.json includes the expected path aliases:
    "@daxserver/validation-schema-codegen/*": ["./src/*"]
    "@test-fixtures/*": ["./tests/*"]
  • Detected two direct relative imports in tests/ts-morph/export-everything.test.ts that bypass the alias and may break under Bun:
    • Line 41: import { ImportedType } from './utils';
    • Line 126: import { ImportedType } from './utils';
    Please update these to use the alias (e.g. import { ImportedType } from '@test-fixtures/ts-morph/utils';).
  • No bunfig.toml was found—by default Bun should honor tsconfig.json paths, but you may add a bunfig.toml with a [tsconfig] section if you run into resolution issues.

Please refactor the two import lines to leverage the alias before merging.

🤖 Prompt for AI Agents
In tests/ts-morph/object-types.test.ts around lines 1 to 5, update the two
lingering relative imports reported in tests/ts-morph/export-everything.test.ts
(lines 41 and 126) so they use the path alias instead of './utils'; replace
those imports with the aliased import '@test-fixtures/ts-morph/utils'. Ensure
tsconfig.json contains the path mappings
("@daxserver/validation-schema-codegen/*": ["./src/*"] and "@test-fixtures/*":
["./tests/*"]) so the alias resolves (optionally add a bunfig.toml [tsconfig]
section if Bun resolution issues occur).

Comment on lines 28 to 39
expect(generateFormattedCode(sourceFile)).resolves.toBe(
formatWithPrettier(`
const T = Type.KeyOf(
Type.Object({
x: Type.Number(),
y: Type.String(),
}),
);
type T = Static<typeof T>;
`),
const T = Type.KeyOf(
Type.Object({
x: Type.Number(),
y: Type.String(),
}),
);
type T = Static<typeof T>;
`),
)
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Tests use Promise-based assertions without awaiting/returning them.

expect(promise).resolves... must be awaited (or returned) or the test may pass before the promise settles. Apply this across the file.

Use either pattern:

- test('keyof', () => {
+ test('keyof', async () => {
   const sourceFile = createSourceFile(
     project,
     `
       type T = keyof {
         x: number;
         y: string;
       };
     `,
   )
-  expect(generateFormattedCode(sourceFile)).resolves.toBe(
+  await expect(generateFormattedCode(sourceFile)).resolves.toBe(
     formatWithPrettier(`
       const T = Type.KeyOf(
         Type.Object({
           x: Type.Number(),
           y: Type.String(),
         }),
       );

       type T = Static<typeof T>;
     `),
   )
 })

Alternatively, keep the non-async function and return expect(...).

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
expect(generateFormattedCode(sourceFile)).resolves.toBe(
formatWithPrettier(`
const T = Type.KeyOf(
Type.Object({
x: Type.Number(),
y: Type.String(),
}),
);
type T = Static<typeof T>;
`),
const T = Type.KeyOf(
Type.Object({
x: Type.Number(),
y: Type.String(),
}),
);
type T = Static<typeof T>;
`),
)
test('keyof', async () => {
const sourceFile = createSourceFile(
project,
`
type T = keyof {
x: number;
y: string;
};
`,
)
await expect(generateFormattedCode(sourceFile)).resolves.toBe(
formatWithPrettier(`
const T = Type.KeyOf(
Type.Object({
x: Type.Number(),
y: Type.String(),
}),
);
type T = Static<typeof T>;
`),
)
})
🤖 Prompt for AI Agents
In tests/ts-morph/utility-types.test.ts around lines 28 to 39, the test uses
Promise-based assertions with expect(...).resolves.toBe(...) but does not await
or return the expectation, which can let the test finish before the promise
settles; make each Promise assertion either awaited (mark the test function
async and use await expect(...).resolves.toBe(...)) or return the expectation
(keep non-async test and use return expect(...).resolves.toBe(...)); apply this
change consistently for all similar expect(...).resolves / expect(...).rejects
calls in this file.

Comment on lines 164 to 175
expect(generateFormattedCode(sourceFile)).resolves.toBe(
formatWithPrettier(`
export const T = Type.KeyOf(
Type.Object({
x: Type.Number(),
y: Type.String(),
}),
);
export type T = Static<typeof T>;
`),
export const T = Type.KeyOf(
Type.Object({
x: Type.Number(),
y: Type.String(),
}),
);
export type T = Static<typeof T>;
`),
)
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Same “await/return the promise” issue in the exported variant.

Mirror the fix here and in all subsequent tests in this file that use .resolves or .rejects.

🤖 Prompt for AI Agents
In tests/ts-morph/utility-types.test.ts around lines 164 to 175, the test uses
expect(generateFormattedCode(sourceFile)).resolves.toBe(...) without returning
or awaiting the promise; change this to either return
expect(generateFormattedCode(sourceFile)).resolves.toBe(...) or prepend await
(i.e. await expect(...).resolves.toBe(...)) so Jest properly waits for the
assertion to resolve, and apply the same change to all later tests in this file
that use .resolves or .rejects.

Comment on lines +1 to +3
import { generateCode } from '@daxserver/validation-schema-codegen/ts-morph-codegen'
import synchronizedPrettier from '@prettier/sync'
import { generateCode } from '../../src/ts-morph-codegen'
import { Project, SourceFile } from 'ts-morph'
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Alias import for generateCode is correct; verify test runner resolves TS paths.

The move to @daxserver/validation-schema-codegen/ts-morph-codegen aligns with the new paths mapping. Ensure your test runner (Jest/Vitest/tsx/ts-node) is configured to resolve TS path aliases (e.g., ts-jest with pathsToModuleNameMapper, or tsconfig-paths/register for ts-node/tsx).

Run this script to sanity-check repo config and catch any lingering non-aliased imports:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== tsconfig paths =="
fd -a 'tsconfig*.json' | while read -r f; do
  echo "--- $f ---"
  jq '.compilerOptions.baseUrl, .compilerOptions.paths' "$f" || true
done

echo
echo "== Jest/Vitest alias config (if present) =="
fd -a 'jest.config*' 'vitest.config*' 2>/dev/null | while read -r f; do
  echo "--- $f ---"
  rg -nC2 -P '(moduleNameMapper|pathsToModuleNameMapper|tsconfigPaths|alias\()' "$f" || true
done

echo
echo "== Non-aliased imports still present (relative or src/) =="
rg -nP "from\\s+['\"](\\.{1,2}/|src/)" --glob '!**/node_modules/**' --glob '!dist/**' || true

Length of output: 520


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== tsconfig.json content =="
sed -n '1,200p' tsconfig.json || true

echo
echo "== baseUrl entries =="
grep -n '"baseUrl"' tsconfig.json || true

echo
echo "== paths entries =="
grep -n '"paths"' tsconfig.json -C3 || true

echo
echo "== package.json for test-related deps =="
grep -nE '"(jest|vitest|ts-node|tsx)"' package.json || true

echo
echo "== jest.config / vitest.config files =="
fd --no-ignore 'jest.config*' 'vitest.config*' || true

echo
echo "== Non-aliased imports =="
rg -nP "from\\s+['\"](\\.{1,2}/|src/)" --glob '!**/node_modules/**' --glob '!dist/**' || true

Length of output: 11244


Ensure TS path aliases are resolved in your test setup

Our tsconfig.json correctly defines baseUrl: "." and the mappings

"paths": {
  "@daxserver/validation-schema-codegen/*": ["./src/*"],
  "@test-fixtures/*": ["./tests/*"]
}

but there’s no Jest, Vitest, ts-node, or tsx configuration present to map these aliases at runtime. Meanwhile, many test files import directly from "src/…" (e.g. import { DependencyCollector } from 'src/utils/dependency-collector'), which will fail under Node without alias resolution.

Please add one of the following:

• If you’re using Jest, create or update jest.config.js with a moduleNameMapper that mirrors your TS paths (e.g. via ts-jest’s pathsToModuleNameMapper).
• If you prefer Vitest, define aliases in vitest.config.ts under the resolve.alias option.
• If running tests with ts-node or tsx, register tsconfig-paths/register (or a similar loader) so Node can resolve the mapped imports.
• Alternatively, refactor test imports to use the @daxserver/validation-schema-codegen/* alias instead of bare src/….

Addressing this will ensure your aliases work consistently across both compile time and test runtime.

🤖 Prompt for AI Agents
In tests/ts-morph/utils.ts around lines 1 to 3, test imports use TS path aliases
(and some tests import from bare "src/…") but there is no runtime alias mapping,
causing Node to fail resolving those imports; fix by adding runtime path
resolution: either update your test runner config (e.g., add moduleNameMapper in
jest.config.js using ts-jest's pathsToModuleNameMapper, or add resolve.alias in
vitest.config.ts), or register tsconfig-paths/register when running tests under
ts-node/tsx, or change test imports to use the declared alias
@daxserver/validation-schema-codegen/* and @test-fixtures/* so runtime
resolution matches tsconfig paths.

Comment on lines +25 to +29
"baseUrl": ".",
"paths": {
"@daxserver/validation-schema-codegen/*": ["./src/*"],
"@test-fixtures/*": ["./tests/*"]
}
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Path aliases look good — confirm all tooling resolves them consistently.

baseUrl + paths for @daxserver/validation-schema-codegen/* and @test-fixtures/* are correct. With moduleResolution: "bundler", TypeScript will resolve aliases; ensure any runtime/test tooling (ts-node, Bun, Vitest, ts-morph runners) either only type-checks or is configured to honor tsconfig paths.

Run:


🏁 Script executed:

#!/bin/bash
# 1) Type-check with aliases
pnpm run typecheck || npm run typecheck || bun x tsc --noEmit

# 2) Ensure no stray relative imports remain
rg -nP "(from\s+['\"]\.\.?/|import\s+['\"]\.\.?/|require\(\s*['\"]\.\.?/)" --glob '!**/node_modules/**' --glob '!**/dist/**'

Length of output: 28415


Fix build errors & ensure path aliases are honored at runtime

The tsc --noEmit step is failing across the board because external modules like ts-morph (and tsconfck) aren’t being resolved, and your tests are still using relative imports instead of the @test-fixtures/* alias. To unblock the build and confirm all tooling picks up your new baseUrl + paths, please address the following:

  • Install or declare missing external dependencies and their types
    • Add ts-morph (and tsconfck if used) to your devDependencies:
    npm install --save-dev ts-morph tsconfck
    • If type declarations aren’t bundled, also install:
    npm install --save-dev @types/ts-morph @types/tsconfck
    This ensures TypeScript can find the modules rather than erroring with “Cannot find module 'ts-morph'…”

  • Configure your test runner and any ts-node/Bun/Vitest scripts to respect tsconfig.json paths
    • For Bun’s test runner, enable --tsconfig ./tsconfig.json or equivalent in your package.json scripts
    • For Vitest/ts-node, use a plugin such as tsconfig-paths or configure vite.config.ts/tsconfig.json paths support
    This guarantees runtime imports using @daxserver/validation-schema-codegen/* and @test-fixtures/* resolve correctly

  • Migrate test imports to use the @test-fixtures/* alias (optional but recommended)
    Replace occurrences like
    import { ImportedType } from './utils'
    with
    import { ImportedType } from '@test-fixtures/ts-morph/utils'
    (or adjust the alias to match your test directory structure) to keep import styles consistent and fully leverage your path mappings

Once these changes are in place, rerun pnpm run typecheck (or npm run typecheck) and verify that no “Cannot find module” errors remain and that your tests still pass.

🤖 Prompt for AI Agents
In tsconfig.json around lines 25 to 29, the new baseUrl/paths mapping is causing
TypeScript and runtime tools to fail to resolve external modules (e.g.,
ts-morph, tsconfck) and test imports; to fix: add the missing devDependencies
(npm install --save-dev ts-morph tsconfck and their types if needed, e.g.,
@types/ts-morph, @types/tsconfck), ensure your test/runtime invocations pick up
tsconfig paths (for Bun add --tsconfig ./tsconfig.json, for ts-node/vitest add
tsconfig-paths or enable path resolution in vite.config.ts), and update test
import statements to use the @test-fixtures/* alias (or adjust the alias to
match the tests folder) so both tsc --noEmit and the test runner resolve modules
at runtime.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/parsers/parse-interfaces.ts (1)

4-4: Use a type-only import for InterfaceDeclaration

Small optimization/readability win and avoids carrying the type at runtime.

Apply:

-import { InterfaceDeclaration, ts, VariableDeclarationKind } from 'ts-morph'
+import type { InterfaceDeclaration } from 'ts-morph'
+import { ts, VariableDeclarationKind } from 'ts-morph'
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between ed9d52e and 874c39c.

📒 Files selected for processing (7)
  • src/handlers/typebox/function-type-handler.ts (1 hunks)
  • src/handlers/typebox/indexed-access-type-handler.ts (1 hunks)
  • src/handlers/typebox/record-type-handler.ts (1 hunks)
  • src/handlers/typebox/typebox-type-handlers.ts (1 hunks)
  • src/parsers/parse-interfaces.ts (1 hunks)
  • tests/integration/wikibase/wikibase.ts (1 hunks)
  • tests/ts-morph/dependency-collector.performance.test.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (6)
  • src/handlers/typebox/typebox-type-handlers.ts
  • src/handlers/typebox/record-type-handler.ts
  • src/handlers/typebox/function-type-handler.ts
  • tests/ts-morph/dependency-collector.performance.test.ts
  • src/handlers/typebox/indexed-access-type-handler.ts
  • tests/integration/wikibase/wikibase.ts

Comment on lines +1 to +3
import { BaseParser } from '@daxserver/validation-schema-codegen/parsers/base-parser'
import { addStaticTypeAlias } from '@daxserver/validation-schema-codegen/utils/add-static-type-alias'
import { getTypeBoxType } from '@daxserver/validation-schema-codegen/utils/typebox-call'
Copy link

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Good switch to alias imports; double-check runtime/package resolution is covered

TypeScript “paths” help the type-checker, but emitted JS keeps the bare specifier. Because you’re importing subpaths of your own package (e.g., @daxserver/validation-schema-codegen/utils/…), ensure one of these is true, otherwise runtime will fail or load duplicate module graphs:

  • You rewrite aliases at build (e.g., tsc-alias, tsup/esbuild with tsconfig paths support), or
  • Your package.json “exports” defines subpath patterns that point to dist, and all internal modules consistently use the same specifier (no mixing with relatives).

If you want, I can open a follow-up PR to wire one of these strategies across build/test.

Run this to verify your setup and spot gaps:

If you choose “exports”, consider a pattern like (adapt to your layout):

{
  "name": "@daxserver/validation-schema-codegen",
  "exports": {
    ".": {
      "types": "./dist/index.d.ts",
      "default": "./dist/index.js"
    },
    "./parsers/*": {
      "types": "./dist/parsers/*.d.ts",
      "default": "./dist/parsers/*.js"
    },
    "./utils/*": {
      "types": "./dist/utils/*.d.ts",
      "default": "./dist/utils/*.js"
    },
    "./handlers/*": {
      "types": "./dist/handlers/*.d.ts",
      "default": "./dist/handlers/*.js"
    }
  }
}

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "1) Package name:"
jq -r '.name' package.json || true

echo -e "\n2) tsconfig paths for the alias:"
jq '.compilerOptions.paths' tsconfig.json || true

echo -e "\n3) Any remaining relative imports under src (should be 0):"
rg -nP --type ts --type tsx -g 'src/**' -C0 $'from\\s+[\'"][.]{1,2}/' || echo "OK: none found."

echo -e "\n4) Use of the package alias inside src:"
rg -nP --type ts --type tsx -g 'src/**' $'from\\s+[\'"]@daxserver/validation-schema-codegen'

echo -e "\n5) Do we have a runtime alias strategy?"
echo "- Dependencies that typically handle aliasing at build/runtime:"
jq -r '[.dependencies,.devDependencies]|add|to_entries[]|select(.key|test("tsconfig-paths|tsc-alias|tsup|esbuild|vite|rollup|webpack|tsx|ts-node"))|"\(.key)@\(.value)"' package.json 2>/dev/null || true

echo -e "\n6) package.json exports (check for subpath patterns like ./utils/*):"
jq '.exports' package.json || true

Length of output: 805


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "1) Package name:"
jq -r '.name' package.json || true

echo -e "\n2) tsconfig.json paths section (manual inspection):"
rg -n '"paths"' -C5 tsconfig.json || echo "No paths section found."

echo -e "\n3) Any remaining relative imports under src (should be 0):"
rg -nP -g 'src/**/*.ts' -g 'src/**/*.tsx' -C0 "from\s+['\"][.]{1,2}/" || echo "OK: none found."

echo -e "\n4) Use of the package alias inside src:"
rg -nP -g 'src/**/*.ts' -g 'src/**/*.tsx' -C0 "from\s+['\"]@daxserver/validation-schema-codegen" || echo "OK: none found."

echo -e "\n5) Runtime alias dependencies in package.json:"
jq -r '[.dependencies,.devDependencies]|add|to_entries[]|select(.key|test("tsconfig-paths|tsc-alias|tsup|esbuild|vite|rollup|webpack|tsx|ts-node"))|"\(.key)@\(.value)"' package.json || echo "None found."

echo -e "\n6) package.json exports:"
jq '.exports' package.json || echo "None found."

Length of output: 13172


Ensure runtime support for your TypeScript path aliases

It looks like you’ve configured "paths": { "@daxserver/validation-schema-codegen/*": ["./src/*"] } in tsconfig.json, and all your imports under src/ use the package specifier (no relative paths) run_scripts. However, there’s no build‐time alias rewiring (e.g. via tsc-alias or an ESBuild/Rollup plugin) and no "exports" field in package.json defining subpath entry points. Without one of these in place, your compiled JS will still try to import bare specifiers like @daxserver/validation-schema-codegen/utils/add-static-type-alias at runtime—and Node won’t know how to resolve them.

Please add one of the following strategies:

• Build‐time alias rewiring
– Add a devDependency such as tsc-alias, tsconfig-paths, or configure your bundler (esbuild/tsup/webpack) to rewrite the TS path imports to relative paths pointing at ./dist.
– e.g., in your build script:
json "build": "tsc && tsc-alias"

• Package exports subpath definitions
– Define "exports" in package.json to map subpaths under your distributed dist/ folder. For example:
json "exports": { ".": { "types": "./dist/index.d.ts", "default": "./dist/index.js" }, "./parsers/*": { "types": "./dist/parsers/*.d.ts", "default": "./dist/parsers/*.js" }, "./utils/*": { "types": "./dist/utils/*.d.ts", "default": "./dist/utils/*.js" }, "./handlers/*":{ "types": "./dist/handlers/*.d.ts","default": "./dist/handlers/*.js" } }

If you’d like, I can open a follow-up PR to wire up either approach across your build and packaging configuration.

🤖 Prompt for AI Agents
src/parsers/parse-interfaces.ts lines 1-3: imports use the TypeScript path alias
@daxserver/validation-schema-codegen/* which works at compile-time but will
break at runtime because the package has no exports/subpath mappings and the
build does not rewrite aliases; fix by applying one of two options: (A) add
build-time alias rewiring (add a devDependency like tsc-alias or tsconfig-paths
or configure your bundler to rewrite path imports) and update the build script
to run the rewriter after tsc, or (B) add "exports" subpath entries in
package.json mapping the package specifier patterns to the compiled ./dist/*.js
and .d.ts files so Node can resolve those imports at runtime.

@DaxServer DaxServer merged commit 0c6824a into main Aug 21, 2025
7 checks passed
@DaxServer DaxServer deleted the pathalias-imports branch August 21, 2025 15:40
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