Skip to content

Conversation

@miguelramos
Copy link
Member

@miguelramos miguelramos commented Jan 19, 2026

Summary by CodeRabbit

  • New Features

    • New core package exposing an OpenAPI mock server surface: server factory, parser, routing, in-memory store, handlers, generator scaffolds, simulation manager, and WebSocket protocol/types (hub currently a no-op stub).
    • Added data-generation mappings and generator/handler scaffolds.
  • Chores

    • Switched typecheck to a monorepo-wide pnpm recursive TypeScript check.
    • Added package build/config scaffolding and updated TypeScript project references.

✏️ Tip: You can customize this high-level summary in your review settings.

Miguel Ramos added 4 commits January 19, 2026 15:17
- Create packages/core/ directory with modular architecture
- Configure package.json with hono, @scalar/*, @faker-js/faker dependencies
- Set up tsconfig.json and tsup.config.ts for ESM builds
- Add placeholder modules: parser, store, router, generator, handlers, websocket, simulation
- Update root typecheck script to support all packages
- Add changeset for minor version bump
Follow monorepo naming convention with @websublime namespace
@miguelramos miguelramos self-assigned this Jan 19, 2026
@coderabbitai
Copy link

coderabbitai bot commented Jan 19, 2026

Warning

Rate limit exceeded

@miguelramos has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 8 minutes and 31 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 99e8650 and b62abc7.

📒 Files selected for processing (6)
  • .changesets/feature-vite-open-api-server-z5y.1-project-setup.json
  • packages/core/src/handlers/context.ts
  • packages/core/src/parser/processor.ts
  • packages/core/src/router/index.ts
  • packages/core/src/router/types.ts
  • packages/core/src/websocket/protocol.ts
📝 Walkthrough

Walkthrough

Adds a new package @websublime/vite-open-api-core with package metadata, build configs, TypeScript setup, many public API surfaces (parser, generator mappings, handlers, router, store, server, websocket, simulation) and scaffolding implementations—most functions are placeholders or no-op stubs.

Changes

Cohort / File(s) Summary
Project & packaging
\.changesets/feature-vite-open-api-server-z5y.1-project-setup.json, package.json, packages/core/package.json, packages/core/tsconfig.json, packages/core/tsup.config.ts, tsconfig.json
Adds a changeset and a new core package manifest and build config, updates root TypeScript project references, and replaces the root typecheck script with a pnpm recursive filter invocation.
Public barrels / entrypoints
packages/core/src/index.ts, packages/core/src/parser/index.ts, packages/core/src/generator/index.ts, packages/core/src/handlers/index.ts, packages/core/src/router/index.ts, packages/core/src/store/index.ts, packages/core/src/websocket/index.ts, packages/core/src/simulation/index.ts
Adds top-level re-export modules exposing the public API surfaces for parser, generator, handlers, router, store, websocket, and simulation.
Generator (mappings & stubs)
packages/core/src/generator/field-mapping.ts, packages/core/src/generator/schema-generator.ts
Adds FIELD_NAME_MAPPING, TYPE_FORMAT_MAPPING, DATE_FORMAT_POST_PROCESSING and placeholder generator functions _generateFromFieldName and _generateFromSchema that throw NotImplemented.
Handlers (types & executor)
packages/core/src/handlers/context.ts, packages/core/src/handlers/executor.ts
Introduces handler types/interfaces (HandlerContext, HandlerFn, return shapes) and executor surface (ExecutorError, executeHandler, normalizeResponse) with unimplemented behavior.
Router (types, path conversion, builder)
packages/core/src/router/types.ts, packages/core/src/router/path-converter.ts, packages/core/src/router/route-builder.ts
Adds routing type definitions, convertOpenApiPath implementation (converts {param}:param), and a placeholder buildRoutes that throws RouteBuilderNotImplementedError.
Parser (processor façade & stub)
packages/core/src/parser/processor.ts
Adds ProcessorOptions, ProcessorError, and a placeholder processOpenApiDocument describing the bundle/upgrade/dereference pipeline; currently unimplemented.
Server API scaffold
packages/core/src/server.ts
Adds OpenApiServerConfig and OpenApiServer interfaces and a placeholder createOpenApiServer factory that throws NotImplemented.
Store (interface & factory stub)
packages/core/src/store/store.ts
Adds StoreOptions, Store interface with CRUD/schema methods, StoreError, and a createStore stub that throws NotImplemented.
Simulation (types & manager stub)
packages/core/src/simulation/simulator.ts
Adds Simulation and SimulationManager types and a createSimulationManager stub that throws NotImplemented.
WebSocket (protocol & hub stub)
packages/core/src/websocket/protocol.ts, packages/core/src/websocket/hub.ts
Adds WebSocket protocol typings (ClientCommand, ServerEvent, timeline entries) and WebSocketHub interface plus createWebSocketHub returning a no-op stub with a one-time warning.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant Server as OpenApiServer
  participant Parser as Processor
  participant Router
  participant Store
  participant WS as WebSocketHub

  Client->>Server: HTTP request / WS connect
  Server->>Parser: processOpenApiDocument(spec)
  Parser-->>Server: processed document
  Server->>Router: buildRoutes(document)
  Router-->>Server: route handlers
  Server->>Store: createStore()
  Server->>WS: createWebSocketHub()
  alt HTTP request handling
    Client->>Server: request -> matched route
    Server->>Router: invoke handler(context)
    Router->>Store: CRUD operations
    Router->>WS: emit timeline/store events
    Router-->>Client: response
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40 minutes

Poem

🐰 I hopped in to plant a brand new core,
Stubs and types and doors to explore,
Mappings mapped and routes to chart,
A hollow burrow—soon full of heart,
Watch this patch bloom, nibble by nibble. 🌱

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely describes the main change: setting up the core package infrastructure for the vite-open-api-server project with foundational modules, configurations, and types.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

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: 15

🤖 Fix all issues with AI agents
In `@packages/core/src/generator/field-mapping.ts`:
- Around line 48-67: TYPE_FORMAT_MAPPING currently maps both 'string:date' and
'string:date-time' to the same faker format ('date.recent'), but the generator
must distinguish RFC3339 full-date vs date-time outputs; update the generator
logic (where TYPE_FORMAT_MAPPING is consumed—e.g., the field/value generation
function that reads TYPE_FORMAT_MAPPING) to detect the 'string:date' and
'string:date-time' keys and post-format the faker result into ISO date
(YYYY-MM-DD) for 'string:date' and ISO date-time (YYYY-MM-DDTHH:mm:ssZ) for
'string:date-time' so generated values conform to OpenAPI semantics while
keeping the existing mapping keys unchanged.

In `@packages/core/src/generator/index.ts`:
- Around line 11-13: The barrel export is exposing functions
generateFromFieldName and generateFromSchema which currently throw Error('Not
implemented yet - see Task 1.5'); remove these two exports from the public
export surface (leave FIELD_NAME_MAPPING and TYPE_FORMAT_MAPPING exported) so
consumers cannot call unimplemented APIs, or alternatively re-export them under
an internal/experimental name (e.g. _generateFromFieldName/_generateFromSchema)
and mark with a comment; update the export line that references
generateFromFieldName and generateFromSchema to only export fully implemented
symbols or the internal/experimental aliases to prevent runtime failures for
consumers.

In `@packages/core/src/generator/schema-generator.ts`:
- Around line 19-37: The two placeholder functions are
inconsistent—generateFromSchema throws but generateFromFieldName returns
undefined; make them consistent by changing generateFromFieldName to also throw
the same Not implemented error. Replace the current body of
generateFromFieldName with a throw new Error('Not implemented yet - see Task
1.5') (matching generateFromSchema) so both functions fail loudly until
implemented; reference functions generateFromSchema and generateFromFieldName
when making the change.

In `@packages/core/src/handlers/context.ts`:
- Around line 36-42: HandlerContext currently types faker as unknown and logger
as Console; replace them with concrete, testable types by importing the Faker
type (e.g., the Faker or FakerStatic type provided by your faker package) and
changing the faker property to that type (HandlerContext.faker), and define/use
a minimal Logger interface (e.g., methods log, info, warn, error, debug) instead
of Console for HandlerContext.logger so custom/test loggers can be injected;
update any references to HandlerContext, Faker type import, and the logger
interface where HandlerContext is constructed or consumed to satisfy the new
types.
- Around line 47-50: The union's first branch uses plain unknown which prevents
narrowing—change HandlerReturn to a discriminated/tagged union (e.g., add a
discriminant like type: 'raw' | 'response') so consumers can reliably narrow on
that tag; update any places that construct or consume HandlerReturn (notably
normalizeResponse in executor.ts) to set/check the new discriminant and handle
the raw/data-with-meta variants accordingly, and ensure all existing return
points that previously returned raw values are updated to return the tagged
shape.

In `@packages/core/src/handlers/executor.ts`:
- Around line 29-43: Add a domain-specific ExecutorError class and use it in
executeHandler and normalizeResponse so handler execution failures are
distinguishable from other errors; implement ExecutorError (similar to
ProcessorError) and throw or wrap thrown errors from executeHandler with new
ExecutorError instances (including original error details), and ensure
normalizeResponse maps invalid or unexpected HandlerReturn values to a
consistent HandlerResponse by throwing ExecutorError when normalization fails.

In `@packages/core/src/index.ts`:
- Around line 1-9: Update the JSDoc `@module` tag in the file's header so it
matches the actual package name; replace the incorrect "@voas/core" `@module`
value with the real package name "@websublime/vite-open-api-core" in
packages/core/src/index.ts (the file-level JSDoc at the top of the module) to
keep generated documentation consistent.

In `@packages/core/src/parser/processor.ts`:
- Around line 22-27: The ProcessorError class constructor should capture the V8
stack trace to exclude the constructor frame; update the ProcessorError
constructor to call Error.captureStackTrace(this, ProcessorError) when available
(e.g., typeof Error.captureStackTrace === 'function') after super(message) so
the stack is more useful for debugging while preserving name assignment.

In `@packages/core/src/router/route-builder.ts`:
- Line 9: Add a tracked task and a minimal skeleton for the Hono router: open an
issue titled "Task 1.4: Implement Hono Router (route-builder.ts)" to track the
work, then replace the single-line TODO in route-builder.ts with a small
exported skeleton function (e.g., export function buildRouter(...) or export
const routeBuilder = (...) ) that contains a JSDoc comment describing intended
behavior and immediately throws a clear NotImplemented/Unsupported error
(preserving the current descriptive error message) so callers see a consistent
contract; also add a short test placeholder referencing buildRouter/routeBuilder
to ensure the scaffold is discoverable and link the issue number in the
TODO/JSDoc.

In `@packages/core/src/router/types.ts`:
- Around line 11-14: The HttpMethod union type currently omits the 'trace' verb;
update the exported type HttpMethod to include 'trace' so it aligns with the
OpenAPI set of HTTP methods (e.g., add 'trace' to the union in the HttpMethod
declaration) unless omission is intentional for policy reasons—ensure only the
HttpMethod type is modified.

In `@packages/core/src/server.ts`:
- Around line 35-43: The OpenApiServer interface currently types the app
property as unknown; import the Hono type (import type { Hono } from 'hono') and
change app's type to Hono in the OpenApiServer interface so implementations get
proper typings; update any related references or consumers of OpenApiServer that
assume a Hono instance to compile against the new type.

In `@packages/core/src/store/store.ts`:
- Around line 22-43: The Store interface uses Partial<unknown> in the update
signature which is a no-op; change the API to use generics so callers get useful
typing—e.g. make the Store interface generic (Store<T> or Store<TSchema =
unknown>) or add a generic on update (update<T>(schema: string, id: string |
number, data: Partial<T>): T | null) and adjust related methods (create, get,
list) to return or accept the generic type T so implementations get proper type
inference; update the Store and the update/create/get/list signatures
accordingly.

In `@packages/core/src/websocket/hub.ts`:
- Around line 26-28: createWebSocketHub currently always throws and will crash
consumers; replace the throw with a safe no‑op implementation or remove the
export. Implement createWebSocketHub to return a minimal object that satisfies
the WebSocketHub interface (e.g., stubbed methods like connect, disconnect,
broadcast, on) that perform noops or no-op Promise resolves and optionally log a
single warning, or alternatively remove the exported function if the API must
not be public yet; ensure the returned object uses the exact symbol name
createWebSocketHub and conforms to WebSocketHub so callers don't encounter
runtime errors.

In `@packages/core/src/websocket/protocol.ts`:
- Around line 41-67: SimulationState and SimulationConfig are identical; create
a single shared definition to avoid drift. Replace the duplicated interfaces by
defining one base type (e.g., SimulationState) and then reuse it for the other
symbol (either export type SimulationConfig = SimulationState or introduce
SimulationBase and have both SimulationState and SimulationConfig extend it),
and update any references (e.g., the 'simulation:active' ServerEvent and any
other usages) to use the shared type so there is only one source of truth.

In `@packages/core/tsup.config.ts`:
- Around line 1-7: The header comment in tsup.config.ts mentions the wrong
package name; update the top comment text so any mention of "@voas/core" is
replaced with the correct package name "@websublime/vite-open-api-core" (i.e.,
edit the file-level docblock describing the tsup configuration to reflect the
actual package name).

Comment on lines +48 to +67
export const TYPE_FORMAT_MAPPING: Record<string, string> = {
'string:email': 'internet.email',
'string:uri': 'internet.url',
'string:url': 'internet.url',
'string:uuid': 'string.uuid',
'string:date': 'date.recent',
'string:date-time': 'date.recent',
'string:password': 'internet.password',
'string:hostname': 'internet.domainName',
'string:ipv4': 'internet.ipv4',
'string:ipv6': 'internet.ipv6',
string: 'lorem.words',
integer: 'number.int',
'integer:int32': 'number.int',
'integer:int64': 'number.int',
number: 'number.float',
'number:float': 'number.float',
'number:double': 'number.float',
boolean: 'datatype.boolean',
};
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider differentiating date vs date-time format handling.

Both string:date and string:date-time map to date.recent, but OpenAPI defines them differently:

  • date: full-date per RFC 3339 (e.g., 2024-01-15)
  • date-time: date-time per RFC 3339 (e.g., 2024-01-15T09:30:00Z)

This might need differentiation in the actual generator implementation (Task 1.5) to format output correctly.

📝 Suggestion for future implementation

When implementing Task 1.5, consider:

// For date format, format as YYYY-MM-DD
'string:date': 'date.recent', // + format to ISO date string

// For date-time, include time component
'string:date-time': 'date.recent', // + format to ISO date-time string

The mapping itself is fine; the formatting logic should handle the distinction.

🤖 Prompt for AI Agents
In `@packages/core/src/generator/field-mapping.ts` around lines 48 - 67,
TYPE_FORMAT_MAPPING currently maps both 'string:date' and 'string:date-time' to
the same faker format ('date.recent'), but the generator must distinguish
RFC3339 full-date vs date-time outputs; update the generator logic (where
TYPE_FORMAT_MAPPING is consumed—e.g., the field/value generation function that
reads TYPE_FORMAT_MAPPING) to detect the 'string:date' and 'string:date-time'
keys and post-format the faker result into ISO date (YYYY-MM-DD) for
'string:date' and ISO date-time (YYYY-MM-DDTHH:mm:ssZ) for 'string:date-time' so
generated values conform to OpenAPI semantics while keeping the existing mapping
keys unchanged.

Miguel Ramos added 6 commits January 19, 2026 15:36
- Add HandlerRequest and HandlerResponseMeta to public exports
- Add SimulationState to WebSocket module exports
- Externalize all runtime dependencies in tsup config to reduce bundle size
  (@faker-js/faker, @scalar/*, hono)

Addresses code review findings from /coder analysis
Generator:
- Add RFC3339 date format documentation to TYPE_FORMAT_MAPPING
- Rename generateFromFieldName/generateFromSchema to _generateFromFieldName/_generateFromSchema
  (internal/experimental until Task 1.5)
- Make _generateFromFieldName throw consistently with _generateFromSchema

Handlers:
- Add proper Faker type import from @faker-js/faker
- Add Logger interface for testable/injectable loggers
- Convert HandlerReturn to discriminated union with 'type' field
- Add ExecutorError class with cause tracking and stack capture

Parser:
- Add Error.captureStackTrace to ProcessorError for better debugging

Router:
- Add 'trace' to HttpMethod union for OpenAPI compliance
- Add RouteBuilderNotImplementedError with proper JSDoc and task reference
- Return Hono type from buildRoutes instead of unknown

Server:
- Import and use Hono type for OpenApiServer.app

Store:
- Make Store interface generic for type-safe operations
- Add Error.captureStackTrace to StoreError

WebSocket:
- Replace createWebSocketHub throw with safe no-op implementation
- Consolidate SimulationState/SimulationConfig into SimulationBase
- Export SimulationBase type

Documentation:
- Fix package name in JSDoc (@websublime/vite-open-api-core)
- Fix tsup.config.ts header comment
Addresses PR review comment about string:date vs string:date-time
formatting. Adds explicit post-processing functions for converting
faker Date results to RFC3339 compliant strings:
- string:date → YYYY-MM-DD (full-date)
- string:date-time → YYYY-MM-DDTHH:mm:ssZ (date-time)
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: 4

🤖 Fix all issues with AI agents
In `@packages/core/src/handlers/context.ts`:
- Around line 66-83: The two interfaces HandlerReturnWithStatus and
HandlerReturnWithHeaders both use the same discriminant type: 'response', which
prevents easy narrowing; change the discriminant so they are distinct (e.g., use
type: 'response' for HandlerReturnWithStatus and type: 'response_with_headers'
or add a new discriminant field like variant: 'with_headers' to
HandlerReturnWithHeaders), then update all call sites and type guards that check
result.type (or add checks for the new discriminant) and any
documentation/comments to reflect the new narrowing pattern; ensure
functions/methods handling these types (search for usages of
HandlerReturnWithStatus, HandlerReturnWithHeaders or checks on result.type) are
updated accordingly.

In `@packages/core/src/parser/processor.ts`:
- Around line 45-50: processOpenApiDocument is a public exported function that
currently always throws a ProcessorError, which will crash consumers; replace
the unconditional throw by either removing the export or implementing a safe
no-op/partial stub that returns a sensible default (e.g., an empty
Record<string, unknown> or input-as-record) and logs/wraps the unimplemented
state, or update the module's exports to stop exporting processOpenApiDocument
until implemented; locate the function by name processOpenApiDocument and the
thrown ProcessorError in packages/core/src/parser/processor.ts and change the
implementation to return a safe fallback result (and avoid throwing) or remove
it from the public export surface.

In `@packages/core/src/router/types.ts`:
- Around line 55-60: The endpoints Map in EndpointRegistry currently uses a
plain string key which is ambiguous; define and use a clear composite key type
(or documented format) and update EndpointRegistry to use it—e.g., add a new
type alias like EndpointKey (for example an interpolated string type or a small
object shape such as { method: HttpMethod; path: string } ) and change the
endpoints signature to Map<EndpointKey, EndpointEntry>, then update any code
that constructs or reads keys to use that canonical format and add a short
comment documenting the exact key format; reference the EndpointRegistry and
endpoints symbols when making these changes.

In `@packages/core/src/websocket/protocol.ts`:
- Around line 14-23: RequestLogEntry.query is declared as Record<string, string>
but must match HandlerRequest.query which allows string or string[]; update
RequestLogEntry.query to Record<string, string | string[]> (or the shared type
if one exists) so multi-value query params are preserved, and review usages of
RequestLogEntry (e.g., logging/serialization code) to handle string[] values
safely (convert to string or JSON when emitting logs).

1. HandlerReturn discriminants: Changed type discriminants to be distinct
   - HandlerReturnWithStatus: type='status'
   - HandlerReturnWithHeaders: type='full'
   - HandlerReturnRaw: type='raw' (unchanged)

2. processOpenApiDocument: Return safe no-op instead of throwing
   - Returns input as-is if object, minimal stub if string
   - Logs warning once about stub implementation

3. EndpointRegistry: Added EndpointKey type for Map keys
   - Format: 'METHOD:path' (e.g., 'get:/users/{id}')
   - Added createEndpointKey and parseEndpointKey helpers

4. RequestLogEntry.query: Allow string[] for multi-value params
   - Matches HandlerRequest.query type signature
@miguelramos
Copy link
Member Author

Code review

Found 2 issues:

  1. Missing tests for implemented functions (Test Coverage)

    The following functions are fully implemented with real logic (not stubs) but have no test coverage:

    • convertOpenApiPath - regex replacement for OpenAPI path to Hono path conversion
    • parseEndpointKey - string parsing with edge case handling for colons
    • createEndpointKey - template literal formatting
    • DATE_FORMAT_POST_PROCESSING - RFC3339 date formatting functions

    These should have tests to lock in expected behavior before future implementation tasks build on them.

    https://github.com/websublime/vite-open-api-server/blob/b62abc71fbfd2bd58edffe0c61d426f59f4bc21f/packages/core/src/router/path-converter.ts#L20-L22
    https://github.com/websublime/vite-open-api-server/blob/b62abc71fbfd2bd58edffe0c61d426f59f4bc21f/packages/core/src/router/types.ts#L60-L73
    https://github.com/websublime/vite-open-api-server/blob/b62abc71fbfd2bd58edffe0c61d426f59f4bc21f/packages/core/src/generator/field-mapping.ts#L56-L59

  2. Inconsistent TODO/task reference format (CLAUDE.md Compliance)

    Most TODO comments use format TODO: Will be implemented in Task 1.5 but one file (route-builder.ts) uses the better format with full task ID: @see Task 1.4: Hono Router (vite-open-api-server-z5y.4). Consider standardizing on the full task ID format for better traceability.

    https://github.com/websublime/vite-open-api-server/blob/b62abc71fbfd2bd58edffe0c61d426f59f4bc21f/packages/core/src/router/route-builder.ts#L11


Quality Checks:

  • Linting (Biome): PASS
  • TypeScript: PASS
  • Tests: Pre-existing failures in temp/ directory (unrelated to this PR)

Notes:

  • The temp/ directory test failures are a pre-existing issue where tests reference a tsconfig.json that extends ../../tsconfig.json but the relative path doesn't resolve correctly.
  • The stub implementations that throw "Not implemented yet" are appropriate for this scaffolding PR.
  • Type exports are clean with proper separation of type exports from value exports.
  • All imports use .js extensions for ESM compatibility.

🤖 Generated with Claude Code

- If this code review was useful, please react with 👍. Otherwise, react with 👎.

@miguelramos miguelramos merged commit 3e34b5a into main Jan 19, 2026
5 checks passed
@miguelramos miguelramos deleted the feature/vite-open-api-server-z5y.1-project-setup branch January 19, 2026 16:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants