Migration from typeorm-extension
@rapiq/typeorm succeeds typeorm-extension's applyQuery/applyQueryParseOutput pipeline. The contract is deliberately close — but a few defaults flipped, and the ones that did are security-relevant.
API mapping
| typeorm-extension | rapiq v2 |
|---|---|
applyQuery(qb, req.query, options) | decoder.decode(req.query, { schema }) + new TypeormAdapter({ queryBuilder: qb }).execute(query) — see the Express recipe |
per-call allowed/default options | a named Schema in a SchemaRegistry |
| returned parse output (pagination) | adapter.execute(query) returns the applied pagination |
relations.onJoin hook | relations.onJoin on the adapter options |
Behavior differences
Parameters without an allow-list are open (breaking, security-relevant)
typeorm-extension disables any parameter whose allowed/default options are missing. rapiq's default is the opposite: a parameter without an allow-list accepts any syntactically valid key.
Enable strict: true on your schemas to keep the closed-by-default semantics when migrating:
typescript
defineSchema<User>({
name: 'user',
strict: true, // reject undeclared parameters
filters: { allowed: ['id', 'name'] },
});Joins default to LEFT
typeorm-extension used inner joins for relations; @rapiq/typeorm defaults to left joins, keeping records whose relation is absent. Restore inner joins per adapter via relations: { joinType: 'inner' }.
Defaults that carried over
joinAndSelectbehavior matchesleftJoinAndSelect— setrelations: { joinAndSelect: true }.executereturns the applied pagination, mirroringapplyQuery's parse-output contract.
Suggested migration path
- Model each resource's per-call options as a
Schemawithstrict: true. - Replace
applyQuerycall sites with decode → execute (the recipe is the template). - If your code relied on inner-join semantics, set
joinType: 'inner'. - Turn on
throwOnFailurewhere you want contract violations to become400s instead of silent drops.