@open-mercato/shared 0.5.1-develop.2691.d8a0934b37 → 0.5.1-develop.2694.732417c5ec

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dist/lib/api/crud.js +1 -1
  2. package/dist/lib/api/crud.js.map +2 -2
  3. package/dist/lib/auth/server.js +1 -1
  4. package/dist/lib/auth/server.js.map +2 -2
  5. package/dist/lib/data/engine.js +68 -27
  6. package/dist/lib/data/engine.js.map +2 -2
  7. package/dist/lib/db/mikro.js +18 -22
  8. package/dist/lib/db/mikro.js.map +2 -2
  9. package/dist/lib/indexers/error-log.js +10 -12
  10. package/dist/lib/indexers/error-log.js.map +2 -2
  11. package/dist/lib/indexers/status-log.js +14 -16
  12. package/dist/lib/indexers/status-log.js.map +2 -2
  13. package/dist/lib/query/engine.js +220 -228
  14. package/dist/lib/query/engine.js.map +3 -3
  15. package/dist/lib/query/join-utils.js +28 -23
  16. package/dist/lib/query/join-utils.js.map +2 -2
  17. package/dist/lib/version.js +1 -1
  18. package/dist/lib/version.js.map +1 -1
  19. package/jest.config.cjs +4 -2
  20. package/package.json +1 -1
  21. package/src/lib/api/__tests__/crud.test.ts +5 -3
  22. package/src/lib/api/crud.ts +1 -1
  23. package/src/lib/auth/__tests__/server.apiKeyCache.test.ts +10 -4
  24. package/src/lib/auth/server.ts +1 -1
  25. package/src/lib/bootstrap/types.ts +2 -2
  26. package/src/lib/crud/__tests__/crud-factory.test.ts +27 -17
  27. package/src/lib/data/engine.ts +95 -47
  28. package/src/lib/db/mikro.ts +26 -25
  29. package/src/lib/indexers/error-log.ts +23 -23
  30. package/src/lib/indexers/status-log.ts +36 -33
  31. package/src/lib/query/__tests__/engine.scope-and-or.test.ts +253 -114
  32. package/src/lib/query/__tests__/engine.test.ts +206 -139
  33. package/src/lib/query/engine.ts +306 -263
  34. package/src/lib/query/join-utils.ts +38 -30
@@ -1,7 +1,10 @@
1
- import type { Knex } from 'knex'
1
+ import type { Kysely } from 'kysely'
2
+ import { sql } from 'kysely'
2
3
  import type { QueryOptions, QueryJoinEdge } from './types'
3
4
  import type { FilterOp } from './types'
4
5
 
6
+ type AnyBuilder = any
7
+
5
8
  export type NormalizedFilter = { field: string; op: FilterOp; value?: unknown; orGroup?: string; qualified?: string | null }
6
9
 
7
10
  export function normalizeFilters(filters?: QueryOptions['filters']): NormalizedFilter[] {
@@ -195,21 +198,21 @@ export function partitionFilters(
195
198
  }
196
199
 
197
200
  type ApplyJoinFiltersOptions = {
198
- knex: Knex
201
+ db: Kysely<any>
199
202
  baseTable: string
200
- builder: Knex.QueryBuilder
203
+ builder: AnyBuilder
201
204
  joinMap: Map<string, ResolvedJoin>
202
205
  joinFilters: Map<string, JoinFilter[]>
203
206
  aliasTables: Map<string, string>
204
207
  qualifyBase: (column: string) => string
205
- applyAliasScope: (builder: Knex.QueryBuilder, alias: string, table: string) => Promise<void> | void
206
- applyFilterOp: (builder: Knex.QueryBuilder, column: string, op: FilterOp, value?: unknown) => void
207
- applyJoinFilterOp?: (builder: Knex.QueryBuilder, filter: JoinFilter, qualified: string, join: ResolvedJoin, table: string) => Promise<boolean> | boolean
208
+ applyAliasScope: (builder: AnyBuilder, alias: string, table: string) => Promise<AnyBuilder> | AnyBuilder
209
+ applyFilterOp: (builder: AnyBuilder, column: string, op: FilterOp, value?: unknown) => AnyBuilder
210
+ applyJoinFilterOp?: (builder: AnyBuilder, filter: JoinFilter, qualified: string, join: ResolvedJoin, table: string) => Promise<{ applied: boolean; builder: AnyBuilder }> | { applied: boolean; builder: AnyBuilder }
208
211
  columnExists?: (table: string, column: string) => Promise<boolean> | boolean
209
212
  }
210
213
 
211
214
  export async function applyJoinFilters({
212
- knex,
215
+ db,
213
216
  baseTable,
214
217
  builder,
215
218
  joinMap,
@@ -220,35 +223,29 @@ export async function applyJoinFilters({
220
223
  applyFilterOp,
221
224
  applyJoinFilterOp,
222
225
  columnExists,
223
- }: ApplyJoinFiltersOptions): Promise<Knex.QueryBuilder> {
226
+ }: ApplyJoinFiltersOptions): Promise<AnyBuilder> {
224
227
  const resolveAliasName = (aliasName?: string | null) => {
225
228
  if (!aliasName || aliasName === 'base') return baseTable
226
229
  return aliasName
227
230
  }
228
231
 
232
+ let nextBuilder = builder
229
233
  for (const [alias, filtersForAlias] of joinFilters.entries()) {
230
234
  const chain = buildJoinChain(alias, joinMap, baseTable)
231
235
  if (!chain.length) continue
232
236
  const first = chain[0]
233
- const sub = knex({ [first.alias]: first.table }).select(1)
234
- await applyAliasScope(sub, first.alias, first.table)
237
+ let sub: AnyBuilder = db.selectFrom(`${first.table} as ${first.alias}` as any).select(sql`1`.as('one'))
238
+ sub = await applyAliasScope(sub, first.alias, first.table)
235
239
  const parentAlias = resolveAliasName(first.fromAlias)
236
- if (parentAlias === baseTable) {
237
- sub.whereRaw('?? = ??', [`${first.alias}.${first.toField}`, qualifyBase(first.fromField)])
238
- } else {
239
- sub.whereRaw('?? = ??', [`${first.alias}.${first.toField}`, `${parentAlias}.${first.fromField}`])
240
- }
240
+ const parentRef = parentAlias === baseTable ? qualifyBase(first.fromField) : `${parentAlias}.${first.fromField}`
241
+ sub = sub.whereRef(`${first.alias}.${first.toField}`, '=', parentRef)
241
242
  for (const cfg of chain.slice(1)) {
242
- const joinArgs = { [cfg.alias]: cfg.table }
243
243
  const parent = resolveAliasName(cfg.fromAlias)
244
- const joinFn = function (this: Knex.JoinClause) {
245
- const left = `${cfg.alias}.${cfg.toField}`
246
- const right = parent === baseTable ? qualifyBase(cfg.fromField) : `${parent}.${cfg.fromField}`
247
- this.on(knex.raw('?? = ??', [left, right]))
248
- }
249
- if (cfg.type === 'inner') sub.join(joinArgs, joinFn)
250
- else sub.leftJoin(joinArgs, joinFn)
251
- await applyAliasScope(sub, cfg.alias, cfg.table)
244
+ const rightRef = parent === baseTable ? qualifyBase(cfg.fromField) : `${parent}.${cfg.fromField}`
245
+ const joinFn = cfg.type === 'inner' ? 'innerJoin' : 'leftJoin'
246
+ sub = (sub as any)[joinFn](`${cfg.table} as ${cfg.alias}`, (jb: any) =>
247
+ jb.onRef(`${cfg.alias}.${cfg.toField}`, '=', rightRef))
248
+ sub = await applyAliasScope(sub, cfg.alias, cfg.table)
252
249
  }
253
250
  let existsDirective: boolean | null = null
254
251
  for (const filter of filtersForAlias) {
@@ -267,13 +264,24 @@ export async function applyJoinFilters({
267
264
  }
268
265
  const qualified = `${filter.alias}.${filter.column}`
269
266
  if (applyJoinFilterOp) {
270
- const handled = await applyJoinFilterOp(sub, filter, qualified, join, targetTable)
271
- if (handled) continue
267
+ const result = await applyJoinFilterOp(sub, filter, qualified, join, targetTable)
268
+ if (result && result.applied) {
269
+ sub = result.builder
270
+ continue
271
+ }
272
+ if (result && result.builder) {
273
+ sub = result.builder
274
+ }
272
275
  }
273
- applyFilterOp(sub, qualified, filter.op, filter.value)
276
+ sub = applyFilterOp(sub, qualified, filter.op, filter.value)
277
+ }
278
+ if (existsDirective === false) {
279
+ const capturedSub = sub
280
+ nextBuilder = nextBuilder.where((eb: any) => eb.not(eb.exists(capturedSub)))
281
+ } else {
282
+ const capturedSub = sub
283
+ nextBuilder = nextBuilder.where((eb: any) => eb.exists(capturedSub))
274
284
  }
275
- if (existsDirective === false) builder = builder.whereNotExists(sub)
276
- else builder = builder.whereExists(sub)
277
285
  }
278
- return builder
286
+ return nextBuilder
279
287
  }