bigal 16.0.0-beta.2 → 16.0.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.
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: Configure connection pools (postgres-pool, pg, Neon), read replicas, multiple databases, and query observability.
2
+ description: Configure connection pools (postgres-pool, pg, Neon), read replicas, multiple databases, and debug logging.
3
3
  ---
4
4
 
5
5
  # Configuration
@@ -18,33 +18,31 @@ const pool = new Pool({
18
18
  connectionString: 'postgres://user:pass@localhost/mydb',
19
19
  });
20
20
 
21
- const { Product } = initialize({ models: { Product }, pool });
21
+ const repos = initialize({ models, pool });
22
22
  ```
23
23
 
24
24
  ### node-postgres (pg)
25
25
 
26
26
  ```ts
27
27
  import pg from 'pg';
28
- import { initialize } from 'bigal';
29
28
 
30
29
  const pool = new pg.Pool({
31
30
  connectionString: 'postgres://user:pass@localhost/mydb',
32
31
  });
33
32
 
34
- const { Product } = initialize({ models: { Product }, pool });
33
+ const repos = initialize({ models, pool });
35
34
  ```
36
35
 
37
36
  ### Neon serverless
38
37
 
39
38
  ```ts
40
39
  import { Pool } from '@neondatabase/serverless';
41
- import { initialize } from 'bigal';
42
40
 
43
41
  const pool = new Pool({
44
42
  connectionString: process.env.DATABASE_URL,
45
43
  });
46
44
 
47
- const { Product } = initialize({ models: { Product }, pool });
45
+ const repos = initialize({ models, pool });
48
46
  ```
49
47
 
50
48
  ## Read replicas
@@ -55,22 +53,23 @@ Separate read and write pools by passing `readonlyPool`:
55
53
  const pool = new Pool('postgres://localhost/mydb');
56
54
  const readonlyPool = new Pool('postgres://readonly-host/mydb');
57
55
 
58
- const { Product } = initialize({
59
- models: { Product },
56
+ const repos = initialize({
57
+ models,
60
58
  pool,
61
59
  readonlyPool,
62
60
  });
63
61
  ```
64
62
 
65
- `find()`, `findOne()`, and `count()` use `readonlyPool`. `create()`, `update()`, and `destroy()` use
66
- `pool`.
63
+ `find()`, `findOne()`, and `count()` use `readonlyPool`. `create()`, `update()`, and `destroy()` use `pool`.
67
64
 
68
65
  Individual queries can override the pool:
69
66
 
70
67
  ```ts
71
- const product = await Product.findOne({
72
- pool: writePool,
73
- }).where({ id: 42 });
68
+ const product = await productRepository
69
+ .findOne({
70
+ pool: writePool,
71
+ })
72
+ .where({ id: 42 });
74
73
  ```
75
74
 
76
75
  ## Multiple databases
@@ -78,16 +77,13 @@ const product = await Product.findOne({
78
77
  Use named connections for models that live in different databases:
79
78
 
80
79
  ```ts
81
- const AuditLog = table(
82
- 'audit_logs',
83
- {
84
- /* columns */
85
- },
86
- { connection: 'audit' },
87
- );
80
+ @table({ name: 'audit_logs', connection: 'audit' })
81
+ export class AuditLog extends Entity {
82
+ // ...
83
+ }
88
84
 
89
- const { Product, AuditLog } = initialize({
90
- models: { Product, AuditLog },
85
+ const repos = initialize({
86
+ models: [Product, AuditLog],
91
87
  pool: mainPool,
92
88
  connections: {
93
89
  audit: {
@@ -100,107 +96,24 @@ const { Product, AuditLog } = initialize({
100
96
 
101
97
  Models without a `connection` option use the top-level `pool`.
102
98
 
103
- ## Models: object vs array
104
-
105
- `initialize()` accepts models as either an object or an array:
106
-
107
- ### Object-style (recommended)
108
-
109
- Returns typed repositories directly via destructuring. No type assertions needed:
110
-
111
- ```ts
112
- const { Product, Store } = initialize({
113
- pool,
114
- models: { Product, Store, Category, ProductCategory },
115
- });
116
- ```
117
-
118
- ### Array-style
99
+ ## Expose callback
119
100
 
120
- Returns an object with `getRepository()` and `getReadonlyRepository()` methods:
101
+ The `expose` callback is invoked for each repository after creation:
121
102
 
122
103
  ```ts
123
- const bigal = initialize({
104
+ const repos = initialize({
105
+ models,
124
106
  pool,
125
- models: [Product, Store, Category, ProductCategory],
126
- });
127
-
128
- const Product = bigal.getRepository(Product);
129
- const ProductSummary = bigal.getReadonlyRepository(ProductSummary);
130
- ```
131
-
132
- ## Global filters
133
-
134
- Define named filters on models that are automatically applied to every `find` and `findOne` query:
135
-
136
- ```ts
137
- const Product = table(
138
- 'products',
139
- {
140
- /* columns */
141
- },
142
- {
143
- filters: {
144
- active: { isActive: true },
145
- notDeleted: () => ({ deletedAt: null }),
146
- },
147
- },
148
- );
149
- ```
150
-
151
- Filters can be static objects or functions that return a where clause dynamically. Override per query:
152
-
153
- ```ts
154
- // Disable all filters
155
- await Product.find().where({}).filters(false);
156
-
157
- // Disable a specific filter
158
- await Product.find().where({}).filters({ active: false });
159
- ```
160
-
161
- ## Query observability
162
-
163
- ### onQuery callback
164
-
165
- Pass an `onQuery` callback to `initialize()` for structured query logging:
166
-
167
- ```ts
168
- const { Product } = initialize({
169
- pool,
170
- models: { Product },
171
- onQuery({ sql, params, duration, error, model, operation }) {
172
- logger.debug({ sql, params, duration, model, operation });
173
- if (error) {
174
- logger.error({ sql, error, model });
175
- }
107
+ expose(repository, tableMetadata) {
108
+ console.log(`Initialized ${tableMetadata.name}`);
176
109
  },
177
110
  });
178
111
  ```
179
112
 
180
- The callback receives an `OnQueryEvent` for every query:
181
-
182
- | Property | Type | Description |
183
- | ----------- | -------------------- | ----------------------------------------------------- |
184
- | `sql` | `string` | The generated SQL statement |
185
- | `params` | `readonly unknown[]` | Query parameter values |
186
- | `duration` | `number` | Execution time in milliseconds |
187
- | `error` | `Error \| undefined` | Error if the query failed |
188
- | `model` | `string` | Model name |
189
- | `operation` | `string` | One of: find, findOne, count, create, update, destroy |
113
+ ## Debugging
190
114
 
191
- The callback is wrapped in a try/catch internally - exceptions in `onQuery` will not crash your
192
- queries. When no `onQuery` is provided, there is zero overhead.
193
-
194
- **Note:** `params` may contain sensitive data (user input, passwords, etc.). Use appropriate care when
195
- logging.
196
-
197
- ### DEBUG_BIGAL environment variable
198
-
199
- The `DEBUG_BIGAL` environment variable still works as a fallback. When set and no `onQuery` callback
200
- is provided, BigAl logs generated SQL to the console:
115
+ Set the `DEBUG_BIGAL` environment variable to log generated SQL:
201
116
 
202
117
  ```sh
203
118
  DEBUG_BIGAL=true node app.js
204
119
  ```
205
-
206
- For production use, prefer the `onQuery` callback for structured, configurable logging.
package/package.json CHANGED
@@ -1,15 +1,37 @@
1
1
  {
2
2
  "name": "bigal",
3
- "version": "16.0.0-beta.2",
3
+ "version": "16.0.0",
4
4
  "description": "A type-safe PostgreSQL ORM for Node.js, written in TypeScript. Features a fluent query builder, decorator-based models, and immutable query state.",
5
+ "keywords": [
6
+ "decorator",
7
+ "fluent-api",
8
+ "node",
9
+ "orm",
10
+ "postgres",
11
+ "postgresql",
12
+ "query-builder",
13
+ "repository-pattern",
14
+ "type-safe",
15
+ "typescript"
16
+ ],
17
+ "homepage": "https://bigalorm.github.io/bigal/",
18
+ "bugs": {
19
+ "url": "https://github.com/bigalorm/bigal/issues"
20
+ },
21
+ "license": "MIT",
22
+ "author": "Jim Geurts <jim@biacreations.com>",
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "git+https://github.com/bigalorm/bigal.git"
26
+ },
27
+ "type": "module",
5
28
  "main": "./dist/index.cjs",
6
29
  "module": "./dist/index.mjs",
7
- "types": "./dist/index.d.ts",
8
- "type": "module",
30
+ "types": "./dist/index.d.cts",
9
31
  "exports": {
10
32
  ".": {
11
33
  "import": {
12
- "types": "./dist/index.d.ts",
34
+ "types": "./dist/index.d.mts",
13
35
  "default": "./dist/index.mjs"
14
36
  },
15
37
  "require": {
@@ -18,84 +40,48 @@
18
40
  }
19
41
  }
20
42
  },
21
- "keywords": [
22
- "orm",
23
- "postgres",
24
- "postgresql",
25
- "typescript",
26
- "type-safe",
27
- "query-builder",
28
- "node",
29
- "fluent-api",
30
- "decorator",
31
- "repository-pattern"
32
- ],
33
- "author": "Jim Geurts <jim@biacreations.com>",
34
- "license": "MIT",
35
- "bugs": {
36
- "url": "https://github.com/bigalorm/bigal/issues"
37
- },
38
- "homepage": "https://bigalorm.github.io/bigal/",
39
- "engines": {
40
- "node": ">=22.0.0"
43
+ "scripts": {
44
+ "build": "vp pack",
45
+ "check:types": "tsc --noEmit --skipLibCheck",
46
+ "test": "pnpm run check:types && vp test run",
47
+ "lint:markdown": "markdownlint '**/*.md' --ignore '**/node_modules/**' --ignore '**/dist/**' --ignore 'internal/**' --config=.github/linters/.markdown-lint.yml --fix",
48
+ "lint:code": "vp lint --fix",
49
+ "lint": "pnpm run format && run-p lint:*",
50
+ "format": "vp fmt",
51
+ "beta": "pnpm publish --tag beta",
52
+ "prepublishOnly": "pinst --disable",
53
+ "postpublish": "pinst --enable",
54
+ "prepare": "vp config --no-agent"
41
55
  },
42
56
  "devDependencies": {
43
- "@faker-js/faker": "10.3.0",
57
+ "@faker-js/faker": "10.5.0",
44
58
  "@semantic-release/changelog": "6.0.3",
45
59
  "@semantic-release/commit-analyzer": "13.0.1",
46
60
  "@semantic-release/git": "10.0.1",
47
- "@semantic-release/github": "12.0.6",
61
+ "@semantic-release/github": "12.0.9",
48
62
  "@semantic-release/npm": "13.1.5",
49
- "@semantic-release/release-notes-generator": "14.1.0",
63
+ "@semantic-release/release-notes-generator": "14.1.1",
64
+ "@stylistic/eslint-plugin": "5.10.0",
50
65
  "@types/node": ">=22",
51
- "@typescript/native-preview": "7.0.0-dev.20260322.1",
52
- "conventional-changelog-conventionalcommits": "9.3.0",
53
- "eslint-plugin-vitest": "0.5.4",
54
- "husky": "9.1.7",
55
- "lint-staged": "16.4.0",
56
- "markdownlint-cli": "0.48.0",
57
- "npm-run-all2": "8.0.4",
58
- "oxfmt": "0.41.0",
59
- "oxlint": "1.56.0",
60
- "oxlint-tsgolint": "0.17.1",
66
+ "conventional-changelog-conventionalcommits": "10.2.1",
67
+ "eslint-config-decent": "4.2.38",
68
+ "eslint-plugin-jsdoc": "62.9.0",
69
+ "eslint-plugin-security": "4.0.1",
70
+ "eslint-plugin-unicorn": "64.0.0",
71
+ "markdownlint-cli": "0.49.0",
72
+ "npm-run-all2": "9.0.2",
73
+ "oxlint-plugin-eslint": "1.73.0",
61
74
  "pinst": "3.0.0",
62
- "postgres-pool": "11.0.4",
63
- "semantic-release": "25.0.3",
75
+ "postgres-pool": "11.0.5",
76
+ "semantic-release": "25.0.5",
64
77
  "strict-event-emitter-types": "2.0.0",
65
- "ts-morph": "27.0.2",
66
- "typescript": "5.9.3",
67
- "unbuild": "3.6.1",
68
- "vitest": "4.1.0"
78
+ "typescript": "7.0.2",
79
+ "vite": "catalog:",
80
+ "vite-plus": "catalog:",
81
+ "vitest": "4.1.10"
69
82
  },
70
- "scripts": {
71
- "build": "unbuild",
72
- "check:types": "tsgo --noEmit --skipLibCheck",
73
- "test": "npm run check:types && vitest run",
74
- "lint:markdown": "markdownlint '**/*.md' --ignore '**/node_modules/**' --ignore '**/dist/**' --ignore 'internal/**' --config=.github/linters/.markdown-lint.yml --fix",
75
- "lint:code": "oxlint --fix --fix-suggestions --deny-warnings",
76
- "lint": "npm run format && run-p lint:*",
77
- "format": "oxfmt --write .",
78
- "lint-staged": "lint-staged",
79
- "beta": "npm publish --tag beta",
80
- "prepublishOnly": "pinst --disable",
81
- "postpublish": "pinst --enable",
82
- "prepare": "husky"
83
- },
84
- "lint-staged": {
85
- "*.md": [
86
- "oxfmt --write",
87
- "markdownlint --config=.github/linters/.markdown-lint.yml --fix"
88
- ],
89
- "*.{js,cjs,mjs,ts}": [
90
- "oxfmt --write",
91
- "oxlint --fix --fix-suggestions --deny-warnings"
92
- ],
93
- "*.{json5,yml}": [
94
- "oxfmt --write"
95
- ]
83
+ "engines": {
84
+ "node": ">=22.11.0"
96
85
  },
97
- "repository": {
98
- "type": "git",
99
- "url": "git+https://github.com/bigalorm/bigal.git"
100
- }
86
+ "packageManager": "pnpm@11.11.0+sha512.4463f65fd80ed80d69bc1d4bf163ee94f605c7380fc318bb5b2ebe15f8cd12d49c51a4d59e951b401e764d3b6ca751cbf51bc50ed7001a6bcb4935e684c34882"
101
87
  }
@@ -0,0 +1,14 @@
1
+ allowBuilds:
2
+ esbuild: true
3
+ unrs-resolver: true
4
+ savePrefix: ''
5
+ catalog:
6
+ vite: npm:@voidzero-dev/vite-plus-core@0.2.4
7
+ vite-plus: 0.2.4
8
+ overrides:
9
+ vite: 'catalog:'
10
+ peerDependencyRules:
11
+ allowAny:
12
+ - vite
13
+ allowedVersions:
14
+ vite: '*'
@@ -46,7 +46,7 @@ export default {
46
46
  [
47
47
  '@semantic-release/git',
48
48
  {
49
- assets: ['CHANGELOG.md', 'package.json', 'package-lock.json'],
49
+ assets: ['CHANGELOG.md', 'package.json'],
50
50
  message: `chore: release \${nextRelease.version} [skip ci]\n\n\${nextRelease.notes}`,
51
51
  },
52
52
  ],