Repository navigation
refactor: untangle the codebase so a typical change lands in one place - #16
Merged
Merged
Conversation
Say that @typesql/core is tiny (under 3 kB minified and gzipped) in the READMEs, the npm description, the docs home page, the introduction and quick start, and add a runtime size row to the comparison pages.
Move what changes together into one place, across all packages: - engine/ is a dependency-free kit; MySQL and SQLite share engine/family/; PostgreSQL's own lexer, types and facts live in postgres/engine. - The root entry no longer loads the dialect engines. - @typesql/core/adapter splits into per-dialect drivers, connect, codegen, command and family modules, shared by adapters, ORM bridges and the CLI. - Each migration dialect is one record in migration/dialects. - The language server has one tokenizer and one dialect-facts record, and keyword lists come from @typesql/core/reserved. - Package lists come from manifests (tools/packages.ts); Node and database versions are pinned once; the test runner records each public fact once. - Comments that only restated the code are gone. Bugs found on the way are fixed, each with a scenario: statement typing in all dialects, migration statement scanning, SQLite introspection of tables named like shadow tables, literals on the HTTP MySQL drivers. Change intents describe each user-visible fix.
ismailkarsli
force-pushed
the
untangle-codebase
branch
from
November 6, 2026 21:42
3e49a51 to
91eeb35
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.
Restructures the monorepo so that pieces which change together live together, and nothing stable imports something more volatile. Behaviour stays the same apart from the bug fixes below. Public exports stay.
Structure
engine/is a dependency-free kit, MySQL and SQLite shareengine/family/, and PostgreSQL's lexer, types and facts live inpostgres/engine. Theengine<->sqlcycle is gone, and the root entry no longer loads the dialect engines.@typesql/core/adapteris now backed by per-dialect drivers plusconnect,codegen,commandandfamilymodules, shared by the adapters, ORM bridges and CLI.migration/dialects.@typesql/core/reserved.tools/packages.ts), Node and database versions are pinned once, and the runner records each public fact once. Tests that couldn't catch a bug were removed or merged.Please review closely
These change what users see. All ship under patch intents unless noted, so please decide whether any should be bumped higher.
Col<"char">in a hand-written PostgreSQL schema now means the one-byte"char"type, notchar(n). Use"bpchar"forchar(n).$1::text[]now has nullable elements, sounnest($1::text[])givesstring | null.x = ANY(array)andALLare nullable when the array can holdNULL. Both match what PostgreSQL returns, but existing code may need null handling.executor(prisma)without adialectthrows for an unsupported provider instead of assuming PostgreSQL.Bugs fixed
Each has a scenario under
tests/scenariosthat was seen failing first.INSERT … VALUESorMERGEfailed as "infinitely circular", and later statements in the file silently becameany.NULLcould be typed non-null, depending on whether the select list held a$or a comment.INSERT … VALUESwithout a column list typed parameters against the wrong columns.BEGIN ATOMIC … ENDbodies were rejected, andbeginorendused as names could reject a valid trigger or hide a laterCOMMIT.typesql introspecton SQLite dropped tables named like a virtual table's shadow tables, such asdocs_archivebeside FTS tabledocs.SELECT 'why7' AS note, ? AS id.NO_BACKSLASH_ESCAPES, which allowed SQL injection.The change intents in
.changeset/list the rest.Compatibility
SqlDriver.transactionkeeps its 7.0 arguments and gains an optional trailingsavepoint.serialTransactionandcreateTransactionalSqlkeep their 7.0 signatures.sqlite-declaration-emitandpg-declaration-emitcompile drivers written for 7.0.Known gaps
ORDER BY, window frame bounds andGROUPING SETScontents are parsed past, not checked. An unknown column there only fails at the database, and a parameter there isunknown. Documented inguide/limits.md.NO_BACKSLASH_ESCAPES; injection is closed.UPDATE OF begincan still hide a laterCOMMIT.Verification
Run locally against the servers in
tests/compose.yaml, without snapshot updates.Typecheck, lint (0 errors), knip,
check:intentsand the docs build all pass. Nothing ran against real TiDB or PlanetScale services: the Drizzle scenario uses the real TiDB client over a fake transport, and the literal-quoting scenario uses a fake client on real MySQL.This branch also carries
b6de994, the docs commit that was on localmainbut not yet onorigin/main.