Repository navigation
feat: parse with the TypeScript compiler, share one validated API handler, add CI - #4
Merged
Merged
Conversation
Switch Faker to npm:@faker-js/faker@8.4.1 and the test assertions to jsr:@std/assert, replacing three different deno.land std versions. Cast the two buildMock() results the tests index into so the suite passes with type checking.
Replace the regex engine with a parser (core/parser) that walks the
TypeScript AST into a small type model, and a generator (core/generator)
that turns that model into Faker values. Interface2Mock keeps its
constructor and buildMock() contract and error messages, and takes an
optional { seed, maxDepth } third argument.
Newly supported: inline object literals, Array<T>/ReadonlyArray<T>,
nested arrays and tuples, unions of types, intersections, multiple
extends, generics with defaults, index and method signatures, enums,
Partial/Required/Readonly/Pick/Omit/Record, mapped types, keyof and
indexed access, template literal types, bigint and the remaining scalar
keywords. Recursive types are cut after maxDepth (3) expansions instead
of looping forever. The \; and \: escapes are still accepted.
Remove typeValidation.ts, ValidTypes.ts and randNumber.ts, which only
served the regex engine; all randomness now goes through a per-instance
Faker so a seed gives repeatable output.
Move the duplicated POST bodies of /api/mock and /api/typemocker into
core/http/mockHandler.ts. Malformed JSON, a non-string or oversized
(> 100 KB) source, unparsable valueForAny, quantity outside 1-10, a
non-integer seed and TypeScript syntax errors now answer 400 with
{ error }; unexpected failures still answer 500. The body accepts an
optional seed, quantity may be omitted or null, and bigint values are
serialized as strings. The handler no longer logs the submitted source.
Add a GitHub Actions workflow running deno fmt --check, deno lint and deno test core/ on a pinned Deno version, plus "test" and "check" tasks. Format the remaining files with proseWrap "preserve" so Markdown prose keeps its line breaks. islands/, components/ and static/ are excluded from fmt and lint: they hold the Monaco glue and its pre-existing globals, which this change leaves untouched. Give the logo button in routes/index.tsx an explicit type to satisfy jsx-button-has-type.
README: describe the request fields (including seed) and 400 responses, replace the limitations table and status list with what the TypeScript parser now supports (inline objects, generics, Array<T>, index and method signatures, enums, utility types, recursion limit), and note that the \; and \: escapes are accepted but no longer required. CLAUDE.md: describe the parser/generator/facade layout, the shared HTTP handler and the new test/check tasks.
The generator passed the operand of a keyof node to #keysOf instead of the node itself, so `type Keys = keyof User` with User declared as an interface fell through to a random string. Aliases and enums were unaffected because #keysOf resolves them directly. Add the case to the utility-types test.
…ed syntax Replace the status checklist and scattered notes with a quick start for the web UI, the HTTP API and library use, a request/response reference, a table of supported TypeScript constructs with one worked example, a limitations table, a short FAQ and a development section (commands, layout, how routes and islands are verified). Drop the bad-formatting screenshot, which documented a parsing quirk of the old engine. Point CLAUDE.md at the README tables as the capability contract and note the Deno versions the app was verified on.
Devrax
force-pushed
the
feature/ast-mock-engine
branch
from
October 12, 2026 15:41
d4d3b25 to
4c25b09
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Replaces the regex-based mocking engine with a real parser built on the TypeScript compiler API, consolidates the two API routes behind one validated handler, adds CI, and restructures the README. Includes the
CLAUDE.mdfrom #3 (this branch was cut from it).Engine (
core/)core/parser/):ts.createSourceFile+ AST walk (syntax only, no type checker) into a small type model. Syntax errors now throw with line and column instead of being silently mis-parsed. The old\;/\:escapes are still accepted.core/generator/): turns the model into Faker values.Interface2Mockkeeps its constructor,buildMock()and error messages, and gains an optional{ seed, maxDepth }argument for repeatable output.Array<T>/ReadonlyArray<T>, nested arrays and tuples, type unions and intersections, multipleextends, generics with defaults, index and method signatures (methods are skipped instead of aborting the block),enum,Partial/Required/Readonly/Pick/Omit/Record, mapped types,keyof, indexed access, template literal types,bigintand the remaining scalar keywords.interface Node { children: Node[] }) are cut atmaxDepth(3) instead of looping forever.typeValidation.ts,ValidTypes.tsandrandNumber.ts; all randomness goes through a per-instance Faker.HTTP layer
routes/api/mockandroutes/api/typemockerare one-line wrappers aroundcore/http/mockHandler.ts, which is unit-tested with a plainRequest.value, unparsablevalueForAny,quantityoutside 1-10, non-integerseedand TypeScript syntax errors answer 400 with{ error }; unexpected failures stay 500.quantitymay be omitted ornull. Bigints are serialized as strings.Tooling and docs
npm:/jsr:specifiers;typescriptadded vianpm:..github/workflows/ci.ymlrunsdeno fmt --check,deno lint,deno test core/on a pinned Deno version;deno task test/deno task checkmirror it locally.CLAUDE.mdupdated for the new layout.Behavior changes worth a look
'tel' | stringnow picks any member (the old engine always returned the literal);string | nullyieldsnullabout half the time.quantityof 0 or negative now returns 400 instead of being treated as 1.core/parser/ts_sys_guard.tssetsprocess.browserwhile it loads sodeno testdoes not need--allow-env.Test plan
deno task check(fmt, lint, 57 type-checked tests) passeskeyofover an interface returned a random string.main.ts) under Deno 1.46.3 and Deno 2.9.7: landing page SSR, island bundles,/api/mockwith CORS preflight and headers,/api/typemockerwithout CORS, 405 on GET, the deno.dev 301 redirect, 404, static assets, a 10 × 200-field batch (< 100 ms)dev.tsunder Deno 2.9.7: regeneratesfresh.gen.tsidentical to the committed one and serves the appanyselector, datalist suggestions, syntax error shown with line and column, paste auto-mock, no unexpected console errorsNote for reviewers: the sandbox cannot reach deno.land or esm.sh, so the server runs above used a throwaway import map that mirrors Fresh's dependencies from GitHub and npm. The repository's own
deno.jsonis unchanged in that respect.🤖 Generated with Claude Code
https://claude.ai/code/session_01JgwVZtwAHHXJu5neejhnYR