bigal 15.10.1 → 15.10.2

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,5 @@
1
+ ## [15.10.2](https://github.com/bigalorm/bigal/compare/v15.10.1...v15.10.2) (2026-02-27)
2
+
1
3
  ## [15.10.1](https://github.com/bigalorm/bigal/compare/v15.10.0...v15.10.1) (2026-02-07)
2
4
 
3
5
  ### Bug Fixes
@@ -0,0 +1,153 @@
1
+ # Views and Readonly Repositories
2
+
3
+ This guide covers how to use BigAl with PostgreSQL views by creating readonly repositories.
4
+ Readonly repositories expose only read operations (`findOne`, `find`, `count`),
5
+ making them a natural fit for database views.
6
+
7
+ ## Table of Contents
8
+
9
+ - [Overview](#overview)
10
+ - [Defining a Model for a View](#defining-a-model-for-a-view)
11
+ - [Standalone Model](#standalone-model)
12
+ - [Inheriting from an Existing Model](#inheriting-from-an-existing-model)
13
+ - [Using a Schema](#using-a-schema)
14
+ - [Initializing the Repository](#initializing-the-repository)
15
+ - [Querying](#querying)
16
+ - [Available Methods](#available-methods)
17
+
18
+ ## Overview
19
+
20
+ BigAl does not distinguish between tables and views at the ORM level. Both use the `@table()` decorator.
21
+ Setting `readonly: true` in the decorator options causes `initialize()` to return a `ReadonlyRepository`
22
+ instead of a `Repository`. The `ReadonlyRepository` type does not include `create`, `update`, or `destroy` methods,
23
+ so TypeScript will catch accidental write attempts at compile time.
24
+
25
+ BigAl does not create or manage database schemas, so you are responsible for creating the view in PostgreSQL (e.g. via a migration tool).
26
+
27
+ ## Defining a Model for a View
28
+
29
+ ### Standalone Model
30
+
31
+ Define a model class that maps to the view's columns, and set `readonly: true` in the `@table()` decorator:
32
+
33
+ ```ts
34
+ import { column, primaryColumn, table, Entity } from 'bigal';
35
+
36
+ @table({
37
+ name: 'product_summaries',
38
+ readonly: true,
39
+ })
40
+ export class ProductSummary extends Entity {
41
+ @primaryColumn({ type: 'integer' })
42
+ public id!: number;
43
+
44
+ @column({ type: 'string', required: true })
45
+ public name!: string;
46
+
47
+ @column({ type: 'string', required: true, name: 'store_name' })
48
+ public storeName!: string;
49
+
50
+ @column({ type: 'integer', required: true, name: 'category_count' })
51
+ public categoryCount!: number;
52
+ }
53
+ ```
54
+
55
+ This maps to a view created in PostgreSQL:
56
+
57
+ ```sql
58
+ CREATE VIEW product_summaries AS
59
+ SELECT
60
+ p.id,
61
+ p.name,
62
+ s.name AS store_name,
63
+ COUNT(pc.category_id) AS category_count
64
+ FROM products p
65
+ JOIN stores s ON s.id = p.store_id
66
+ LEFT JOIN product_categories pc ON pc.product_id = p.id
67
+ GROUP BY p.id, p.name, s.name;
68
+ ```
69
+
70
+ ### Inheriting from an Existing Model
71
+
72
+ If your view has the same columns as an existing table (or a subset), you can extend the existing model to reuse its column definitions:
73
+
74
+ ```ts
75
+ import { table } from 'bigal';
76
+ import { Product } from './Product';
77
+
78
+ @table({
79
+ name: 'readonly_products',
80
+ readonly: true,
81
+ })
82
+ export class ReadonlyProduct extends Product {}
83
+ ```
84
+
85
+ This avoids duplicating `@column()` definitions. The `ReadonlyProduct` model inherits all column metadata from `Product` but maps to the `readonly_products` view and produces a `ReadonlyRepository`.
86
+
87
+ ### Using a Schema
88
+
89
+ If the view lives in a non-default schema, specify it with the `schema` option:
90
+
91
+ ```ts
92
+ @table({
93
+ schema: 'reporting',
94
+ name: 'product_summaries',
95
+ readonly: true,
96
+ })
97
+ export class ProductSummary extends Entity {
98
+ // ...
99
+ }
100
+ ```
101
+
102
+ ## Initializing the Repository
103
+
104
+ Include the model in the `initialize()` call. BigAl automatically creates a `ReadonlyRepository` for models marked with `readonly: true`.
105
+
106
+ ```ts
107
+ import { initialize, ReadonlyRepository } from 'bigal';
108
+ import { Product, Store, ProductSummary } from './models';
109
+
110
+ const repositoriesByName = initialize({
111
+ models: [Product, Store, ProductSummary],
112
+ pool,
113
+ readonlyPool,
114
+ });
115
+
116
+ const productSummaryRepository = repositoriesByName.ProductSummary as ReadonlyRepository<ProductSummary>;
117
+ ```
118
+
119
+ ## Querying
120
+
121
+ Readonly repositories support the same query methods and chaining as regular repositories:
122
+
123
+ ```ts
124
+ // Find multiple records with filtering, sorting, and pagination
125
+ const summaries = await productSummaryRepository
126
+ .find()
127
+ .where({
128
+ storeName: { contains: 'Acme' },
129
+ })
130
+ .sort('categoryCount desc')
131
+ .limit(10);
132
+
133
+ // Find a single record
134
+ const summary = await productSummaryRepository.findOne().where({ id: 42 });
135
+
136
+ // Count matching records
137
+ const count = await productSummaryRepository.count().where({
138
+ categoryCount: { '>': 5 },
139
+ });
140
+ ```
141
+
142
+ All query features documented in the [README](../README.md) work with readonly repositories, including `where` operators, `sort`, `skip`, `limit`, `paginate`, `populate`, `join`, `withCount`, and `distinctOn`.
143
+
144
+ ## Available Methods
145
+
146
+ | Method | `Repository` | `ReadonlyRepository` |
147
+ | ----------- | ------------ | -------------------- |
148
+ | `findOne()` | Yes | Yes |
149
+ | `find()` | Yes | Yes |
150
+ | `count()` | Yes | Yes |
151
+ | `create()` | Yes | No |
152
+ | `update()` | Yes | No |
153
+ | `destroy()` | Yes | No |
package/eslint.config.mjs CHANGED
@@ -3,8 +3,6 @@ import { config } from 'eslint-config-decent';
3
3
  export default [
4
4
  ...config({
5
5
  tsconfigRootDir: import.meta.dirname,
6
- enableJest: false,
7
- enableVitest: false,
8
6
  enableTestingLibrary: false,
9
7
  }),
10
8
  {
@@ -13,10 +11,4 @@ export default [
13
11
  '@typescript-eslint/no-invalid-void-type': 'off',
14
12
  },
15
13
  },
16
- {
17
- files: ['tests/**/*.ts'],
18
- rules: {
19
- '@typescript-eslint/no-non-null-assertion': 'off',
20
- },
21
- },
22
14
  ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bigal",
3
- "version": "15.10.1",
3
+ "version": "15.10.2",
4
4
  "description": "A fast and lightweight orm for postgres and node.js, written in typescript.",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",
@@ -32,40 +32,34 @@
32
32
  "engines": {
33
33
  "node": ">=20.11.0"
34
34
  },
35
- "dependencies": {},
36
35
  "devDependencies": {
37
- "@faker-js/faker": "10.2.0",
36
+ "@faker-js/faker": "10.3.0",
38
37
  "@semantic-release/changelog": "6.0.3",
39
38
  "@semantic-release/commit-analyzer": "13.0.1",
40
39
  "@semantic-release/git": "10.0.1",
41
- "@semantic-release/github": "12.0.3",
42
- "@semantic-release/npm": "13.1.3",
40
+ "@semantic-release/github": "12.0.6",
41
+ "@semantic-release/npm": "13.1.4",
43
42
  "@semantic-release/release-notes-generator": "14.1.0",
44
- "@types/chai": "5.2.3",
45
- "@types/mocha": "10.0.10",
46
- "@types/node": ">=20",
47
- "chai": "6.2.2",
48
- "eslint": "9.39.2",
49
- "eslint-config-decent": "3.1.115",
43
+ "@types/node": ">=22",
44
+ "eslint": "10.0.2",
45
+ "eslint-config-decent": "4.1.0",
50
46
  "husky": "9.1.7",
51
47
  "lint-staged": "16.2.7",
52
48
  "markdownlint-cli": "0.47.0",
53
- "mocha": "11.7.5",
54
49
  "npm-run-all2": "8.0.4",
55
50
  "pinst": "3.0.0",
56
51
  "prettier": "3.8.1",
57
52
  "semantic-release": "25.0.3",
58
53
  "strict-event-emitter-types": "2.0.0",
59
- "postgres-pool": "11.0.2",
60
- "ts-mockito": "2.6.1",
61
- "ts-node": "10.9.2",
54
+ "postgres-pool": "11.0.3",
62
55
  "typescript": "5.9.3",
63
- "unbuild": "3.6.1"
56
+ "unbuild": "3.6.1",
57
+ "vitest": "4.0.18"
64
58
  },
65
59
  "scripts": {
66
60
  "build": "unbuild",
67
61
  "check:types": "tsc --noEmit --skipLibCheck",
68
- "test": "mocha --loader=ts-node/esm tests/**/*.tests.ts",
62
+ "test": "npm run check:types && vitest run",
69
63
  "lint:markdown": "prettier --write '**/*.md' '!**/node_modules/**' '!**/dist/**' && markdownlint '**/*.md' --ignore '**/node_modules/**' --ignore '**/dist/**' --config=.github/linters/.markdown-lint.yml --fix",
70
64
  "lint:code": "eslint --fix",
71
65
  "lint": "run-p lint:*",