Fix: upgrade the @mikro-orm family from v6 to v7 - #797
Open
AmaadMartin wants to merge 4 commits into
Open
Conversation
added 2 commits
August 7, 2026 23:35
The v7 drivers peer-depend on @mikro-orm/core at an exact version, so the family has to move in lockstep. Adds @mikro-orm/decorators (v7 moved the decorators out of core) and reflect-metadata (v7 core no longer pulls it in, but @mikro-orm/decorators/legacy imports it unconditionally). The regenerated lockfile drops the sqlite3 -> node-gyp -> tar native build chain, which removes tar@6.2.1 from the tree.
Three v7 API changes reach this code: - The decorators moved out of @mikro-orm/core into @mikro-orm/decorators. The repo compiles with experimentalDecorators, so it imports the /legacy entry point rather than /es. - Options now marks every defaulted key as required, so the caller-facing shape is Partial<Options>. The local MikroORMOptions/MikroDBOptions aliases keep the exported signatures textually unchanged. - SchemaGenerator.updateSchema is now update. appendEvent also called txEm.commit() inside an em.transactional callback, which commits the transaction early. em.transactional owns that boundary and commits once the callback resolves. Under knex the second commit was silently tolerated; the v7 kysely runner throws "Transaction is already committed".
7 tasks
added 2 commits
August 8, 2026 00:35
v7 narrows EntityName<T> to EntityClass | EntityCtor | EntitySchema, so the five test call sites that named an entity by string stopped typechecking. Passing the class also gives the real return type, so two casts are no longer needed. tsc --noEmit -p core missed this because core/tsconfig.json includes only src/**/*. The root ts:check covers the test files: it reported 292 errors before this commit and 287 after, which is the pre-existing baseline.
Partial<Options> was declared twice under two names with the same doc comment. operations.ts already returns the type from getConnectionOptionsFromUri, so it owns the definition now and database_session_service.ts imports it. The import keeps the local name, so the emitted constructor signature is unchanged. Also drop @mikro-orm/reflection. Nothing imports it, and it pulled ts-morph and 7 more packages into every consumer's tree. Verified by removing it: the package still imports, the sqlite round-trip still passes and all 146 session tests still pass. reflect-metadata stays. The decorators/legacy barrel re-exports ReflectMetadataProvider, which starts with a bare import of it, so without the dependency `import '@google/adk'` throws ERR_MODULE_NOT_FOUND for both ESM and CommonJS consumers. A comment at the import site records why.
7 tasks
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.
Please ensure you have read the contribution guide before creating a pull request.
Link to Issue or Description of Change
Related: google#448
Problem: Dependabot PR google#448 moves only
@mikro-orm/sqliteto^7.1.6. That cannot install: the v7 drivers peer-depend on@mikro-orm/coreat the exact string7.1.11, so a v7 driver beside a v6 core fails withERESOLVE. The v6 sqlite driver is also how the deprecatedtar@6.2.1reaches this repository, through@mikro-orm/knex->sqlite3->node-gyp->tar.Solution: I moved all eight
@mikro-orm/*packages to^7.1.11together and did the v6 -> v7 API migration.7.1.11is the currentlatestfor@mikro-orm/coreand satisfies the^7.1.6Dependabot asked for. Four v7 changes reach ADK code: the decorators moved to@mikro-orm/decorators,Optionsnow marks defaulted keys as required,SchemaGenerator.updateSchemabecameupdate, and the query runner changed from knex to kysely.The kysely change is the one behaviour fix.
appendEventcalledtxEm.commit()inside anem.transactionalcallback, which commits the transaction early.em.transactionalowns that boundary and commits once the callback resolves. knex tolerated the second commit; kysely throwsTransaction is already committed. I deleted the inner commit.Two new
coreruntime dependencies:@mikro-orm/decorators— v7 moved@Entity,@PrimaryKeyand@Propertyout of core. The repo compiles withexperimentalDecorators, soschema.tsimports the/legacyentry point, not/es.reflect-metadata— an optional peer of@mikro-orm/decorators, butlegacy/index.jsre-exportslegacy/ReflectMetadataProvider.js, whose first statement isimport 'reflect-metadata'. Theexport *evaluates that module, so importing anything from/legacyrequires the package. v6 supplied it transitively through@mikro-orm/core; v7 does not. Without it,import '@google/adk'throwsERR_MODULE_NOT_FOUNDfor both ESM and CommonJS consumers, which I measured against the builtcore/dist. A comment at the import site inschema.tsrecords this, because the dependency looks unused from the source alone.I also removed
@mikro-orm/reflectionrather than re-pinning it. Nothing in the repo imports it, and it pulledts-morphand seven more packages into every consumer's tree. Verified by deleting it fromnode_modules: the package still imports, the SQLite round-trip still passes, and all 146 session tests still pass. This is a deliberate deviation from a mechanical "bump every@mikro-orm/*" reading of the task.Measured lockfile effect: 90 entries removed, 8 added, 35 version-changed.
grep -c '"node_modules/tar"' package-lock.jsonprints0, sotar@6.2.1is gone from the tree; I have not verified which advisories that closes.tarn,tar-fsandtar-streamare unrelated packages and remain. Removed:@mikro-orm/knex,knex,sqlite3,node-gyp,cacache,tar,mariadb,@mikro-orm/reflection,ts-morphand their satellites. Added:@mikro-orm/sql,@mikro-orm/decorators,kysely,better-sqlite3,pg-cursorand three nested entries. Every changed entry traces to the MikroORM subtree.This is breaking for downstream consumers. The five driver
peerDependenciesmove to^7.1.11, so an application on@mikro-orm@6that usesDatabaseSessionServicemust upgrade its own packages. Consumers also inherit MikroORM v7'sengines.node: ">= 22.17.0"(v6 required>= 18.12.0). I did not mark the commit!or add aBREAKING CHANGE:footer, because that would make release-please cut a major version of@google/adk, which is a maintainer decision.Data-compatibility note: v7 enables
forceUtcTimezoneby default for SQL drivers. Thedatetimecolumns (StorageSession.createTime/updateTime,StorageAppState.updateTime,StorageUserState.updateTime,StorageEvent.timestamp) are affected, so a MySQL, MSSQL or PostgreSQL database whose datetimes were written in local time under v6 will read back as UTC. I did not setforceUtcTimezone: false, because that is a product decision. SQLite stores millisecond timestamps and is unaffected.Scope: this supersedes only the
@mikro-ormhalf of google#448. The@opentelemetry/*andesbuild/concurrentlybumps in that PR are separate tasks and are untouched here. I deliberately left #448 open for a maintainer to close.No public ADK API changed.
core/dist/types/sessions/database_session_service.d.tsstill readsconstructor(connectionStringOrOptions: MikroDBOptions | string);; only the alias definition moved toPartial<Options>. The database schema, table names, column names and the 191-character key length are unchanged, so existing databases need no migration.Collision check: I listed all 400 open PRs on the fork. None upgrades
@mikro-orm. Six touch adjacent files without conflicting on this change (#684 forces a patchedtarvia npmoverrides, #500 marks the drivers optional peers, #489, #647, #740, #386). #684 and this PR reach the sametaroutcome by different means; this one removes the chain instead of pinning it.Testing Plan
Please describe the tests that you ran to verify your changes. This is required for all PRs that are not small documentation or typo fixes.
Unit Tests:
[x] I have added or updated unit tests for my change.
[x] All unit tests pass locally.
I added no new tests. The change adds no production line: the diff is four modified lines plus two import-block rewrites, and the existing suite already covers every one.
The test edits are type-only. Besides
updateSchema()->update(), v7 narrowsEntityName<T>toEntityClass | EntityCtor | EntitySchema, so five call sites that named an entity by string stopped typechecking. They now pass the class (em.find(StorageEvent, …),orm.getMetadata().get(StorageEvent)). The class also supplies the real return type, so twoas {…}casts became unnecessary and I deleted them. No assertion changed:should align session updateTime with event timestampandshould trim temp state from event before persistencestill pass, and I re-proved the first by writingevent.timestamp + 1in the source, which fails it withexpected 1234567890001 to be 1234567890000.tsc --noEmit -p coredoes not catch those five, becausecore/tsconfig.jsonincludes onlysrc/**/*and CI does not runts:check. Measured with the rootnpm run ts:check: 292 errors / 44 files before the fix, 287 / 42 after, and 287 / 42 is the pre-existing baseline onmain. This branch adds no type error.I proved each existing test can fail by reverting each production hunk one at a time:
await txEm.commit()inappendEventTransaction is already committedorm.schema.updateSchema({safe: true})operations_test.tsfails:TypeError: orm.schema.updateSchema is not a function@mikro-orm/coretsc -p corefails (3 x TS2305/TS2724 plus 2 cascading TS2345); tests fail at collection:TypeError: (0 , PrimaryKey) is not a functionnode_modules/reflect-metadataimport '@google/adk'fails for ESM and CommonJS:ERR_MODULE_NOT_FOUND … imported from @mikro-orm/decorators/legacy/ReflectMetadataProvider.jsnode_modules/@mikro-orm/reflectionCommands run on the pushed commit:
The
build_setuprun matters beyond the stub rename:js_commonjsandts_commonjsprove that pure-ESM@mikro-orm/core@7is still reachable from CommonJS through Node'srequire(esm).CI is green on ubuntu, macOS and Windows. The
windows-latestleg needed two re-runs and failed on a different unrelated test each time: a 5s timeout inunsafe_local_code_executor_test.ts, thenlisten EACCES: permission denied ::1:49740inwebui_test.ts. Neither test is in my diff, and the first push of this branch carried the same dependency and production code through a green Windows leg.Manual End-to-End (E2E) Tests:
Please provide instructions on how to manually test your changes, including any necessary setup or configuration.
I ran a scratch script against the built
core/dist, not against source, with a real SQLite file and no mocks:npm ci && npm run build.new DatabaseSessionService('sqlite://<tmpfile>')andcreateSessionwithapp:,user:,temp:and plain state keys.appendEventtwice with state deltas.DatabaseSessionServiceon the same file andgetSession.temp:exclusion and the event order survived the instance boundary.It passes, and it fails with
Transaction is already committedwhen I restoretxEm.commit()and rebuild. The second instance is the point: it opens a new ORM connection, so it only sees data the transaction actually committed to disk.I did not commit that script as a test. Closing the ORM needs a cast to the
private ormfield, and PR #386 is removing exactly that pattern from the session tests; I did not want to add a new instance of it. The 13 existing tests already fail on the same mutation.Checklist
[x] I have read the CONTRIBUTING.md document.
[x] I have performed a self-review of my own code.
[x] I have commented my code, particularly in hard-to-understand areas.
[x] I have added tests that prove my fix is effective or that my feature works.
[x] New and existing unit tests pass locally with my changes.