bigal 15.0.1 → 15.2.0

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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ # [15.2.0](https://github.com/bigalorm/bigal/compare/v15.1.0...v15.2.0) (2026-01-08)
2
+
3
+ ### Features
4
+
5
+ - Add SQL JOIN support for filtering and sorting by related tables ([#263](https://github.com/bigalorm/bigal/issues/263)) ([e5f1a97](https://github.com/bigalorm/bigal/commit/e5f1a97f524d8e784943d179347dc364a62959e1))
6
+
7
+ # [15.1.0](https://github.com/bigalorm/bigal/compare/v15.0.1...v15.1.0) (2026-01-07)
8
+
9
+ ### Features
10
+
11
+ - Add `and` property to WhereQuery for combining OR groups ([#262](https://github.com/bigalorm/bigal/issues/262)) ([903eeb8](https://github.com/bigalorm/bigal/commit/903eeb826e3dedd7574aa940527ca07b264a40b2))
12
+
1
13
  ## [15.0.1](https://github.com/bigalorm/bigal/compare/v15.0.0...v15.0.1) (2026-01-07)
2
14
 
3
15
  # [15.0.0](https://github.com/bigalorm/bigal/compare/v14.1.26...v15.0.0) (2025-12-28)
package/README.md CHANGED
@@ -4,12 +4,11 @@
4
4
  [![node version](https://img.shields.io/node/v/bigal.svg?style=flat)](https://nodejs.org)
5
5
  [![Known Vulnerabilities](https://snyk.io/test/npm/bigal/badge.svg)](https://snyk.io/test/npm/bigal)
6
6
 
7
- A fast, lightweight ORM for PostgreSQL and node.js, written in Typescript.
7
+ A fast, lightweight ORM for PostgreSQL and Node.js, written in TypeScript.
8
8
 
9
9
  This ORM does not:
10
10
 
11
11
  - Create or update db schemas for you
12
- - Handle associations/joins
13
12
  - Do much else than basic queries, inserts, updates, and deletes
14
13
 
15
14
  ## Compatibility
@@ -365,6 +364,34 @@ Equivalent to:
365
364
  select id,first_name as firstName,last_name as lastName,created_at as createdAt from person where created_at >= $1 AND created_at < $2
366
365
  ```
367
366
 
367
+ #### Using `or` for OR conditions across different columns
368
+
369
+ ```ts
370
+ const items = await PersonRepository.find().where({
371
+ or: [{ firstName: 'Walter' }, { lastName: 'White' }],
372
+ });
373
+ ```
374
+
375
+ Equivalent to:
376
+
377
+ ```postgresql
378
+ select * from person where (first_name = $1) OR (last_name = $2)
379
+ ```
380
+
381
+ #### Using `and` to combine multiple OR groups
382
+
383
+ ```ts
384
+ const items = await PersonRepository.find().where({
385
+ and: [{ or: [{ firstName: 'Walter' }, { lastName: 'White' }] }, { or: [{ firstName: 'Jesse' }, { lastName: 'Pinkman' }] }],
386
+ });
387
+ ```
388
+
389
+ Equivalent to:
390
+
391
+ ```postgresql
392
+ select * from person where ((first_name = $1) OR (last_name = $2)) AND ((first_name = $3) OR (last_name = $4))
393
+ ```
394
+
368
395
  #### Fetch multiple objects and perform a db sort before returning result
369
396
 
370
397
  ```ts
@@ -433,6 +460,92 @@ const items = await FooRepository.find()
433
460
  .paginate(page, pageSize);
434
461
  ```
435
462
 
463
+ #### Join related tables
464
+
465
+ Use `join()` for INNER JOIN or `leftJoin()` for LEFT JOIN to filter or sort by related table columns in a single query.
466
+
467
+ ```ts
468
+ // INNER JOIN - only returns products that have a store
469
+ const items = await ProductRepository.find()
470
+ .join('store')
471
+ .where({
472
+ store: {
473
+ name: 'Acme',
474
+ },
475
+ });
476
+ ```
477
+
478
+ ```ts
479
+ // LEFT JOIN - returns all products, even those without a store
480
+ const items = await ProductRepository.find()
481
+ .leftJoin('store')
482
+ .where({
483
+ store: {
484
+ name: 'Acme',
485
+ },
486
+ });
487
+ ```
488
+
489
+ #### Join with alias
490
+
491
+ Use an alias when you need to join the same table multiple times or for clarity.
492
+
493
+ ```ts
494
+ const items = await ProductRepository.find()
495
+ .join('store', 'primaryStore')
496
+ .where({
497
+ primaryStore: {
498
+ name: 'Acme',
499
+ },
500
+ });
501
+ ```
502
+
503
+ #### Join with additional ON constraints
504
+
505
+ Add extra conditions to the JOIN's ON clause using `leftJoin()`.
506
+
507
+ ```ts
508
+ const items = await ProductRepository.find()
509
+ .leftJoin('store', 'store', {
510
+ isDeleted: false,
511
+ })
512
+ .where({
513
+ name: {
514
+ like: 'Widget%',
515
+ },
516
+ });
517
+ ```
518
+
519
+ #### Sort by joined table columns
520
+
521
+ Use dot notation to sort by columns on joined tables.
522
+
523
+ ```ts
524
+ const items = await ProductRepository.find().join('store').sort('store.name asc');
525
+ ```
526
+
527
+ #### Combine multiple where conditions
528
+
529
+ Mix regular where conditions with joined table conditions.
530
+
531
+ ```ts
532
+ const items = await ProductRepository.find()
533
+ .join('store')
534
+ .where({
535
+ name: {
536
+ like: 'Widget%',
537
+ },
538
+ store: {
539
+ name: {
540
+ like: ['Acme', 'foo'],
541
+ },
542
+ },
543
+ });
544
+ ```
545
+
546
+ > Note: `join()` and `populate()` serve different purposes. Use `join()` when you need to filter or sort by related
547
+ > table columns in SQL. Use `populate()` when you want to fetch the full related object(s) as nested data in results.
548
+
436
549
  ---
437
550
 
438
551
  ### `.count()` - Get the number of records matching the where criteria
@@ -721,7 +834,7 @@ export class Store extends Entity {
721
834
 
722
835
  #### Non-entity object arrays
723
836
 
724
- If you have a json property, with an `id` field, on an entity model, TypeScript will probably think it is a BigAl
837
+ If you have a JSON property, with an `id` field, on an entity model, TypeScript will probably think it is a BigAl
725
838
  entity due to how the type system works. In that case, you'll want to wrap the type with `NotEntity<>`. For example:
726
839
 
727
840
  ```ts