@ttoss/postgresdb 0.2.23 → 0.2.24

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 (2) hide show
  1. package/README.md +109 -0
  2. package/package.json +2 -2
package/README.md CHANGED
@@ -59,6 +59,8 @@ export class User extends Model<User> {
59
59
  }
60
60
  ```
61
61
 
62
+ **Important:** You must use the `declare` keyword on class properties to ensure TypeScript doesn't emit them as actual fields. Without `declare`, public class fields would shadow Sequelize's getters and setters, blocking access to the model's data. See [Sequelize documentation on public class fields](https://sequelize.org/docs/v6/core-concepts/model-basics/#caveat-with-public-class-fields) for details.
63
+
62
64
  _All [sequelize-typescript](https://github.com/sequelize/sequelize-typescript) decorators are available._
63
65
 
64
66
  Export in `models/index.ts`:
@@ -168,6 +170,10 @@ Update `tsconfig.json`:
168
170
 
169
171
  ```json
170
172
  {
173
+ "compilerOptions": {
174
+ "experimentalDecorators": true,
175
+ "emitDecoratorMetadata": true
176
+ },
171
177
  "include": ["src", "../postgresdb/src"]
172
178
  }
173
179
  ```
@@ -181,6 +187,109 @@ import { models } from '@yourproject/postgresdb';
181
187
  export const db = initialize({ models });
182
188
  ```
183
189
 
190
+ ## Testing
191
+
192
+ Testing models with decorators requires special configuration because Jest's Babel transformer doesn't properly transpile TypeScript decorators. The solution is to build your models before running tests.
193
+
194
+ **Why test your models?** Beyond validating functionality, tests serve as a critical safety check for schema changes. They ensure that running `sync --alter` won't accidentally remove columns or relationships from your database. If a model property is missing or incorrectly defined, tests will fail before you can damage production data.
195
+
196
+ ### Setup
197
+
198
+ **1. Install dependencies:**
199
+
200
+ ```bash
201
+ pnpm add -D @testcontainers/postgresql jest @types/jest
202
+ ```
203
+
204
+ **2. Configure `tsconfig.json`:**
205
+
206
+ ```json
207
+ {
208
+ "compilerOptions": {
209
+ "experimentalDecorators": true,
210
+ "emitDecoratorMetadata": true
211
+ }
212
+ }
213
+ ```
214
+
215
+ These options are required for decorator support. Without them, TypeScript won't properly compile decorator metadata.
216
+
217
+ **3. Add build script to `package.json`:**
218
+
219
+ ```json
220
+ {
221
+ "scripts": {
222
+ "build": "tsup",
223
+ "pretest": "pnpm run build",
224
+ "test": "jest"
225
+ }
226
+ }
227
+ ```
228
+
229
+ The `pretest` script ensures models are built before tests run.
230
+
231
+ ### Test Example
232
+
233
+ ```typescript
234
+ import {
235
+ PostgreSqlContainer,
236
+ StartedPostgreSqlContainer,
237
+ } from '@testcontainers/postgresql';
238
+ import { initialize, Sequelize } from '@ttoss/postgresdb';
239
+ import { models } from 'dist/index'; // Import from built output
240
+
241
+ let sequelize: Sequelize;
242
+ let postgresContainer: StartedPostgreSqlContainer;
243
+
244
+ jest.setTimeout(60000);
245
+
246
+ beforeAll(async () => {
247
+ // Start PostgreSQL container
248
+ postgresContainer = await new PostgreSqlContainer('postgres:17').start();
249
+
250
+ // Initialize database with container credentials
251
+ const db = await initialize({
252
+ models,
253
+ logging: false,
254
+ username: postgresContainer.getUsername(),
255
+ password: postgresContainer.getPassword(),
256
+ database: postgresContainer.getDatabase(),
257
+ host: postgresContainer.getHost(),
258
+ port: postgresContainer.getPort(),
259
+ });
260
+
261
+ sequelize = db.sequelize;
262
+
263
+ // Sync database schema
264
+ await sequelize.sync();
265
+ });
266
+
267
+ afterAll(async () => {
268
+ await sequelize.close();
269
+ await postgresContainer.stop();
270
+ });
271
+
272
+ describe('User model', () => {
273
+ test('should create and retrieve user', async () => {
274
+ const userData = { email: 'test@example.com' };
275
+ const user = await models.User.create(userData);
276
+
277
+ const foundUser = await models.User.findByPk(user.id);
278
+ expect(foundUser).toMatchObject(userData);
279
+ });
280
+ });
281
+ ```
282
+
283
+ ### Key Points
284
+
285
+ - **Import from `dist/`**: Tests must import models from the compiled output (`dist/index`), not source files, because decorators aren't transpiled by Jest's Babel transformer. See [this Stack Overflow answer](https://stackoverflow.com/a/53920890/8786986) for details.
286
+ - **Testcontainers**: Use [`@testcontainers/postgresql`](https://www.npmjs.com/package/@testcontainers/postgresql) to spin up isolated PostgreSQL instances for each test run.
287
+ - **Timeout**: Set a longer timeout with `jest.setTimeout(60000)` as container startup can take time.
288
+ - **Sync schema**: Call `sequelize.sync()` after initialization to create tables based on your models.
289
+ - **Schema validation**: Tests verify that all model properties are correctly defined. This prevents `sync --alter` from accidentally removing database columns due to missing or misconfigured model properties.
290
+
291
+ For a complete working example with full test configuration, see the [terezinha-farm/postgresdb](https://github.com/ttoss/ttoss/tree/main/terezinha-farm/postgresdb) example in this repository.
292
+
184
293
  ## API Reference
185
294
 
186
295
  ### `initialize(options)`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ttoss/postgresdb",
3
- "version": "0.2.23",
3
+ "version": "0.2.24",
4
4
  "description": "A library to handle PostgreSQL database connections and queries",
5
5
  "license": "MIT",
6
6
  "author": "ttoss",
@@ -31,7 +31,7 @@
31
31
  "devDependencies": {
32
32
  "jest": "^30.2.0",
33
33
  "tsup": "^8.5.1",
34
- "@ttoss/config": "^1.35.10"
34
+ "@ttoss/config": "^1.35.11"
35
35
  },
36
36
  "keywords": [
37
37
  "database",