Skip to content

Changelog

1.12.3 - 2026-06-06

Existing QuerySet filter, exclude, relation hydration, and prefetch SQL outputs remain unchanged while predicate, hydration-plan, and prefetch rendering move into internal compiler components.

1.12.2 - 2026-06-05

Bump nuxt to 4.4.7.

Bump pg to 8.21.0.

1.12.1 - 2026-06-05

Fix migrate and status failure handling so a migration error remains the reported failure when closing the database connection afterward also fails. Failed runs now release the connection, and teardown problems are logged separately.

Fix response cookie intent handling so repeated setCookie() calls replace the prior cookie for the same name, domain, and path while appendCookie() continues to emit additional Set-Cookie lines. Express responses now forward multiple Set-Cookie lines without collapsing them into a single header value.

1.12.0 - 2026-06-05

Clarify TangoResponse.file() and TangoResponse.download() so the first argument is response body bytes, not a filesystem path. Remove string from the accepted body type, rename the parameter to body, and add TangoHeaders.setContentTypeForBody() as the preferred helper. setContentTypeByFile() remains as a deprecated proxy.

1.11.15 - 2026-06-05

Standardize TangoResponse.methodNotAllowed() and framework adapter 405/404 responses on the Tango error envelope so clients receive { error: { code, message } } with application/problem+json instead of legacy { error: string } JSON.

1.11.14 - 2026-06-05

Fix QuerySet.exists() so limit(0) and offset use the same query window as fetch() and count(), while keeping the SELECT 1 ... LIMIT 1 existence probe for performance optimization.

1.11.13 - 2026-06-05

tango new and tango init now resolve target directories with platform-native path handling, so scaffolding works correctly on Windows when users pass relative paths or drive-letter paths.

1.11.12 - 2026-06-05

Refactored the QuerySet internal surface in preparation for expanding M2M functionality

1.11.11 - 2026-06-05

Validate QuerySet.limit() and QuerySet.offset() bounds before storing query state. Both methods now accept safe non-negative integers, preserve explicit zero values in compiled SQL, and reject invalid JavaScript runtime inputs such as negative numbers, fractions, infinities, and NaN.

1.11.10 - 2026-06-04

Improve QuerySet.exists() so existence checks can stop after the first matching record.

1.11.9 - 2026-06-04

Scaffolded projects now install database packages for the selected dialect, and SQLite runtimes can start with SQLite-only dependencies.

SQLite scaffolds include better-sqlite3, @types/better-sqlite3, and the matching native build allowlist. Postgres scaffolds include pg and @types/pg, with a package manifest scoped to Postgres packages.

Migration generation now applies Postgres serial primary key projection for Postgres configs while preserving SQLite integer primary keys. SQLite runtime adapter setup also succeeds with SQLite-only dependencies.

1.11.8 - 2026-05-31

Update scaffolded app manifests for TypeScript 6 and pnpm 10 compatibility.

1.11.7 - 2026-05-31

Update dotenv to 17.4.2 for configuration loading.

Bump h3 to 1.15.11.

1.11.6 - 2026-05-31

Validate stored migration checksums before treating applied migrations as unchanged.

1.11.5 - 2026-05-31

Update the Nuxt adapter peer dependency range to Nuxt 4.4.6.

1.11.4 - 2026-05-31

  • FilterSet now passes raw icontains values to the ORM so SQL wildcard wrapping happens once in the query compiler.

Align resource subpath exports with their built entrypoints so domain imports resolve to concrete dist files.

Escape string values when rendering generated migration source.

1.11.3 - 2026-05-31

Release updated runtime dependency support for jiti.

1.11.2 - 2026-05-31

Preserve package build outputs and source compatibility with the updated build toolchain, and allow generated projects to build native dependencies required by better-sqlite3 and tsx.

1.11.1 - 2026-05-30

Fix bulkCreate(...) so batches with mismatched row shapes fail clearly after hook processing instead of silently dropping extra keys or inserting undefined values.


1.11.0 - 2026-05-21

Add opt-in request-scoped write transactions to the Express, Next.js, and Nuxt adapters.

Setting transaction: 'writes' on an adapted resource now wraps POST, PUT, PATCH, and DELETE handlers in a single transaction.atomic(...) boundary, so multi-step writes can commit or roll back as one request-level unit. GET, HEAD, and OPTIONS continue to run outside that wrapper.

The first release is scoped to the Tango runtime your application installs as its default runtime. It keeps the existing nested transaction and tx.onCommit(...) semantics, and it leaves request abort and disconnect handling to the follow-up design work tracked separately.

1.10.3 - 2026-05-16

Release updated peer dependency support for pg.

1.10.2 - 2026-05-15

Release updated runtime dependency support for yargs.

Release updated peer dependency support for better-sqlite3.

1.10.1 - 2026-04-29

Clarify scaffold ownership in tango new, keep each host scaffold framework-specific, and add a fresh-app smoke that validates generated projects through local install, typecheck, and Tango setup commands.

1.10.0 - 2026-04-29

Add ManyToManyRelatedManager.clear() and create(...).

clear() removes every join-row membership for one owner and invalidates the related-manager prefetch cache. create(...) now persists the related target through its normal model manager and inserts the join-row link inside the same atomic boundary, so target-manager hooks and defaults still run without leaking partial writes when the link step fails.

1.9.2 - 2026-04-29

Fix resource list pagination so offset-paginated count reflects the full filtered queryset instead of the current page slice.

1.9.1 - 2026-04-24

Make scaffolded make:migrations scripts forward a normal --name argument so migration naming works the same way across Express, Next, and Nuxt apps.

1.9.0 - 2026-04-24

Add ManyToManyRelatedManager.set(...) so Tango can replace many-to-many memberships in one Django-shaped relation-manager call.

1.8.1 - 2026-04-24

Fix scaffolded apps so generated relation registry declarations participate in TypeScript relation-aware query typing by default.

1.8.0 - 2026-04-24

Ship Tango's first complete many-to-many workflow across schema, migrations, ORM, resources, and testing.

  • Add implicit through-table synthesis and migration support so t.manyToMany(...) works without an explicit join model for the common case.
  • Add many-to-many related managers, relation-aware filtering, and query support so application code can read and manipulate memberships directly.
  • Add DRF-shaped serializer relation fields for many-to-many reads and writes, including primary-key and slug-list workflows.

1.7.0 - 2026-04-20

Added Django-style single-record query conveniences across Tango's ORM surface. Model.objects now exposes all(), getOrCreate(...), and updateOrCreate(...), while QuerySet now exposes all(), first(), last(), and strict get(...) lookup behavior.

@danceroutine/tango-core now exports MultipleObjectsReturned so ambiguous single-record lookups can fail with a dedicated error, and @danceroutine/tango-testing updates aManager(...) so tests can mock the new manager helpers directly.

1.6.0 - 2026-04-19

Adds iterable QueryResult values from QuerySet.fetch(), async iteration over QuerySet, and Django-style caching for repeated row-returning evaluation of the same queryset instance. Paginator builders now accept either arrays or QueryResult values. The legacy QueryResult.results getter remains available for compatibility and now emits a one-time deprecation warning.

1.5.0 - 2026-04-17

Tango's relation workflow now extends from first-hop hydration into deeper generated relation-aware contracts. Application code can traverse more of its related graph while keeping ORM results, generated surfaces, and runtime-facing contracts aligned.

  • Add generated relation typing and deep relation hydration for nested eager-loading paths.
  • Carry the new relation metadata through schema, codegen, OpenAPI, migrations, testing, and Express-facing integration so generated artifacts and runtime behavior agree on the same relation graph.

Previously:

ts
const recentPosts = await PostModel.objects.query().filter({ published: true }).selectRelated('author').fetch();

const firstPost = recentPosts.results[0];

firstPost.author?.email;
// firstPost.author?.profile is not attached here.
// firstPost.comments is not attached here.

Now:

ts
const recentPosts = await PostModel.objects
    .query()
    .filter({ published: true })
    .selectRelated('author__profile')
    .prefetchRelated('comments__author')
    .fetch();

const firstPost = recentPosts.results[0];

firstPost.author?.profile?.displayName;
firstPost.comments[0]?.author?.email;
// firstPost.author?.profile is attached and typed here.
// firstPost.comments[0]?.author is attached and typed here.

1.4.0 - 2026-04-09

Tango now provides a first-class ORM transaction boundary for multi-step write workflows. Transaction-aware hooks also receive a narrow post-commit contract so application code can schedule durable side effects without depending on ORM internals.

  • Add transaction.atomic(async (tx) => ...), nested savepoints, and tx.onCommit(...) for commit-aware application workflows.
  • Extend schema write-hook args with an optional transaction callback contract so hooks can register post-commit work without taking a broad ORM dependency.
  • Add the testing fixtures and client updates needed to exercise the runtime-backed transaction workflow end to end.

Previously:

ts
const user = await UserModel.objects.create({
    email: 'author@example.com',
});

await ProfileModel.objects.create({
    userId: user.id,
});

// If a later step throws here, both writes stay committed.
sendWelcomeEmail(user.email);
// This side effect also runs before the workflow is durably complete.

Now:

ts
await transaction.atomic(async (tx) => {
    const user = await UserModel.objects.create({
        email: 'author@example.com',
    });

    await ProfileModel.objects.create({
        userId: user.id,
    });

    // If a later step throws here, both writes roll back together.
    tx.onCommit(() => {
        sendWelcomeEmail(user.email);
    });
    // This side effect runs only after the outer commit succeeds.
});

1.3.0 - 2026-04-08

Typed relation hydration is now available for Tango querysets. Query code can ask Tango to attach related records directly, while TypeScript keeps the hydrated result shape aligned with the relation metadata authored in the model layer.

  • Add selectRelated(...) for single-valued relation traversal and prefetchRelated(...) for collection-rooted traversal.
  • Type relation hydration from model-authored relation metadata, including typed string references through t.modelRef<TModel>(...).
  • Update relation-aware query planning and ORM result typing so selected model fields and hydrated relation properties compose correctly.

Previously:

ts
const recentPosts = await PostModel.objects.query().filter({ published: true }).fetch();

const firstPost = recentPosts.results[0];

// firstPost.author is still the stored reference value here.
// firstPost.author?.email is not available from the queryset result.

Now:

ts
const recentPosts = await PostModel.objects.query().filter({ published: true }).selectRelated('author').fetch();

const firstPost = recentPosts.results[0];

// firstPost.author is now the hydrated user model or null.
firstPost.author?.email;

1.2.0 - 2026-04-08

The model metadata that relation-aware features build on is now stronger and more consistent. Schema, ORM, migrations, and code generation now share a clearer resolved relation graph and a more fluent scalar metadata authoring shape.

  • Add object-form relation decorator configuration, decorator-level relation naming, and resolved relation graph finalization.
  • Add the fluent scalar metadata builder form t.field(...).build().
  • Update ORM metadata, migrations, testing helpers, and codegen templates to consume the resolved relation graph consistently.

1.1.3 - 2026-04-07

  • Fix select() result typing so projected fields narrow to the database projection rather than the full model shape.

Previously:

ts
const postCards = await PostModel.objects
    .query()
    .select(['id', 'title'] as const)
    .fetch();

const firstPost = postCards.results[0];

firstPost.id;
firstPost.title;
// firstPost could still be treated like the full model shape here.
// firstPost.slug;

Now:

ts
const postCards = await PostModel.objects
    .query()
    .select(['id', 'title'] as const)
    .fetch();

const firstPost = postCards.results[0];

firstPost.id;
firstPost.title;
// firstPost is narrowed to the selected projection here.
// firstPost.slug; // type error

1.1.2 - 2026-04-04

  • Update package documentation to match the new documentation site URLs.

1.1.1 - 2026-04-02

  • Update package READMEs to point maintainers to the new contributor documentation.

1.1.0 - 2026-04-01

First-class Nuxt support is now available. Tango can live inside Nitro event handlers with an official adapter, generated project scaffolding, and a supported tutorial path that shows how the Tango layers fit into a Nuxt application.

  • Add the dedicated @danceroutine/tango-adapters-nuxt package.
  • Add Nuxt project scaffolding and an official Nuxt blog example.
  • Add Nuxt documentation coverage so the adapter, tutorial, and generated project shape describe the same integration model.

1.0.2 - 2026-03-31

  • Infer typed filter coercion from model metadata so resource query params parse booleans, numbers, and timestamps centrally.
  • Derive resource OpenAPI lookup fields from model metadata during schema description.

1.0.1 - 2026-03-31

  • Hoist shared HTTP method and action-scope value types into adapters core so framework adapters stop re-declaring the same contract.

1.0.0 - 2026-03-30

Tango's public packages now reach their first stable 1.0.0 release. This establishes the initial stable contract across the model, ORM, resource, tooling, migration, testing, and adapter layers that now make up the framework's supported package surface.

  • Publish Tango's first stable package line across the core framework, tooling, adapters, and supporting packages.

Released under the MIT License.