fastypest 1.4.139 → 1.5.1

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/README.es.md CHANGED
@@ -49,6 +49,25 @@ afterEach(async () => {
49
49
  });
50
50
  ```
51
51
 
52
+ ## 🔄 Estrategias de detección de cambios
53
+
54
+ Por defecto Fastypest restaura todas las tablas. Puedes activar la detección de cambios mediante el subscriber de TypeORM para refrescar únicamente las tablas tocadas durante una prueba.
55
+
56
+ ```typescript
57
+ const fastypest = new Fastypest(connection, {
58
+ changeDetectionStrategy: ChangeDetectionStrategy.Subscriber,
59
+ });
60
+ ```
61
+
62
+ - `ChangeDetectionStrategy.None` mantiene el comportamiento anterior, truncando y restaurando cada tabla.
63
+ - `ChangeDetectionStrategy.Subscriber` escucha los eventos del subscriber de TypeORM (`insert`, `update`, `remove`) y restaura solo las tablas afectadas.
64
+
65
+ ### Seguimiento manual y limitaciones
66
+
67
+ - Usa `fastypest.markTableAsChanged('tableName')` después de ejecutar SQL crudo para que la tabla se restaure junto con los cambios detectados por el subscriber.
68
+ - Si no se captura ningún evento del subscriber, Fastypest vuelve a restaurar toda la base de datos y garantiza que los cambios realizados únicamente con `connection.query()` se reviertan.
69
+ - Los subscribers de TypeORM no se activan con `.query(...)`, por lo que al habilitar la estrategia del subscriber es necesario trabajar con repositorios o query builders para disfrutar del seguimiento automático.
70
+
52
71
  ## ⚙️ Flujo de trabajo automatizado
53
72
 
54
73
  Este proyecto usa un sistema CI/CD avanzado con GitHub Actions:
package/README.md CHANGED
@@ -50,6 +50,25 @@ afterEach(async () => {
50
50
  });
51
51
  ```
52
52
 
53
+ ## 🔄 Change detection strategies
54
+
55
+ Fastypest restores every table by default. You can enable change detection driven by TypeORM subscribers to refresh only the tables touched during a test.
56
+
57
+ ```typescript
58
+ const fastypest = new Fastypest(connection, {
59
+ changeDetectionStrategy: ChangeDetectionStrategy.Subscriber,
60
+ });
61
+ ```
62
+
63
+ - `ChangeDetectionStrategy.None` keeps the previous behaviour, truncating and restoring every table.
64
+ - `ChangeDetectionStrategy.Subscriber` listens to TypeORM subscriber events (`insert`, `update`, `remove`) and restores only the affected tables.
65
+
66
+ ### Manual tracking and limitations
67
+
68
+ - Use `fastypest.markTableAsChanged('tableName')` after running raw SQL so the table is restored alongside subscriber-detected changes.
69
+ - When no subscriber event is captured Fastypest falls back to restoring the whole database, ensuring that changes executed exclusively through `connection.query()` are still reverted.
70
+ - TypeORM subscribers are not triggered by raw queries, so enabling the subscriber strategy requires using repositories or query builders for automatic tracking.
71
+
53
72
  ## ⚙️ Automated Workflow
54
73
 
55
74
  This project leverages a sophisticated CI/CD setup using GitHub Actions:
@@ -1,12 +1,14 @@
1
1
  import { Connection, DataSource, EntityManager } from "typeorm";
2
2
  import { SQLScript } from "./sql-script";
3
- import type { Manager } from "./types";
3
+ import { type FastypestOptions, type Manager } from "./types";
4
4
  export declare class Fastypest extends SQLScript {
5
5
  private manager;
6
6
  private tables;
7
7
  private tablesWithAutoIncrement;
8
8
  private restoreInOder;
9
- constructor(connection: DataSource | Connection);
9
+ private readonly options;
10
+ private readonly changedTables;
11
+ constructor(connection: DataSource | Connection, options?: FastypestOptions);
10
12
  init(): Promise<void>;
11
13
  private createTempTable;
12
14
  private detectTablesWithAutoIncrement;
@@ -23,4 +25,11 @@ export declare class Fastypest extends SQLScript {
23
25
  private restoreOrder;
24
26
  private recreateData;
25
27
  private resetAutoIncrementColumns;
28
+ private registerSubscriber;
29
+ private isDataSource;
30
+ private getSubscriberCollection;
31
+ private bindSubscriber;
32
+ private shouldTrackChanges;
33
+ private getTablesForRestore;
34
+ markTableAsChanged(tableName: string): void;
26
35
  }
@@ -8,8 +8,11 @@ Object.defineProperty(exports, "Fastypest", {
8
8
  return Fastypest;
9
9
  }
10
10
  });
11
+ const _typeorm = require("typeorm");
11
12
  const _config = require("./config");
12
13
  const _sqlscript = require("./sql-script");
14
+ const _changetrackersubscriber = require("./subscribers/change-tracker.subscriber");
15
+ const _types = require("./types");
13
16
  function _define_property(obj, key, value) {
14
17
  if (key in obj) {
15
18
  Object.defineProperty(obj, key, {
@@ -39,6 +42,9 @@ class Fastypest extends _sqlscript.SQLScript {
39
42
  }
40
43
  async createTempTable(em, tables) {
41
44
  await Promise.all(tables.map(async (tableName)=>{
45
+ await this.execQuery(em, "dropTempTable", {
46
+ tableName
47
+ });
42
48
  await this.execQuery(em, "createTempTable", {
43
49
  tableName
44
50
  });
@@ -139,16 +145,17 @@ class Fastypest extends _sqlscript.SQLScript {
139
145
  });
140
146
  }
141
147
  async restoreOrder(em) {
148
+ const tables = this.getTablesForRestore();
142
149
  if (this.restoreInOder) {
143
- for (const tableName of this.tables){
150
+ for (const tableName of tables){
144
151
  await this.recreateData(em, tableName);
145
152
  }
146
- return;
153
+ } else {
154
+ await Promise.all(tables.map((tableName)=>this.recreateData(em, tableName)));
155
+ }
156
+ if (this.shouldTrackChanges()) {
157
+ this.changedTables.clear();
147
158
  }
148
- const tables = [
149
- ...this.tables
150
- ];
151
- await Promise.all(tables.map((tableName)=>this.recreateData(em, tableName)));
152
159
  }
153
160
  async recreateData(em, tableName) {
154
161
  await this.execQuery(em, "truncateTable", {
@@ -171,9 +178,62 @@ class Fastypest extends _sqlscript.SQLScript {
171
178
  });
172
179
  }
173
180
  }
174
- constructor(connection){
175
- super(connection.options.type), _define_property(this, "manager", void 0), _define_property(this, "tables", new Set()), _define_property(this, "tablesWithAutoIncrement", new Map()), _define_property(this, "restoreInOder", false);
181
+ registerSubscriber(connection) {
182
+ const subscriber = new _changetrackersubscriber.ChangeTrackerSubscriber((tableName)=>{
183
+ this.markTableAsChanged(tableName);
184
+ });
185
+ this.getSubscriberCollection(connection).push(subscriber);
186
+ this.bindSubscriber(subscriber, connection);
187
+ }
188
+ isDataSource(connection) {
189
+ return connection instanceof _typeorm.DataSource;
190
+ }
191
+ getSubscriberCollection(connection) {
192
+ return connection.subscribers;
193
+ }
194
+ bindSubscriber(subscriber, connection) {
195
+ const lifecycle = subscriber;
196
+ if (this.isDataSource(connection)) {
197
+ lifecycle.setDataSource?.(connection);
198
+ return;
199
+ }
200
+ lifecycle.setConnection?.(connection);
201
+ }
202
+ shouldTrackChanges() {
203
+ return this.options.changeDetectionStrategy === _types.ChangeDetectionStrategy.Subscriber;
204
+ }
205
+ getTablesForRestore() {
206
+ const tables = [
207
+ ...this.tables
208
+ ];
209
+ if (!this.shouldTrackChanges()) {
210
+ return tables;
211
+ }
212
+ if (this.changedTables.size === 0) {
213
+ return tables;
214
+ }
215
+ const changed = new Set(this.changedTables);
216
+ const filtered = tables.filter((table)=>changed.has(table));
217
+ if (filtered.length === 0) {
218
+ return tables;
219
+ }
220
+ return filtered;
221
+ }
222
+ markTableAsChanged(tableName) {
223
+ if (!this.shouldTrackChanges()) {
224
+ return;
225
+ }
226
+ this.changedTables.add(tableName);
227
+ }
228
+ constructor(connection, options){
229
+ super(connection.options.type), _define_property(this, "manager", void 0), _define_property(this, "tables", new Set()), _define_property(this, "tablesWithAutoIncrement", new Map()), _define_property(this, "restoreInOder", false), _define_property(this, "options", void 0), _define_property(this, "changedTables", new Set());
176
230
  this.manager = connection.manager;
231
+ this.options = {
232
+ changeDetectionStrategy: options?.changeDetectionStrategy ?? _types.ChangeDetectionStrategy.None
233
+ };
234
+ if (this.options.changeDetectionStrategy === _types.ChangeDetectionStrategy.Subscriber) {
235
+ this.registerSubscriber(connection);
236
+ }
177
237
  }
178
238
  }
179
239
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/fastypest.ts"],"sourcesContent":["import { Connection, DataSource, EntityManager, Table } from \"typeorm\";\nimport { INDEX_OFFSET_CONFIG } from \"./config\";\nimport { SQLScript } from \"./sql-script\";\nimport type {\n ColumnStat,\n ColumnsWithAutoIncrement,\n DBType,\n DependencyTreeQueryOut,\n IncrementDetail,\n Manager,\n} from \"./types\";\n\nexport class Fastypest extends SQLScript {\n private manager: EntityManager;\n private tables: Set<string> = new Set();\n private tablesWithAutoIncrement: Map<string, IncrementDetail[]> = new Map();\n private restoreInOder: boolean = false;\n\n constructor(connection: DataSource | Connection) {\n super(connection.options.type);\n this.manager = connection.manager;\n }\n\n public async init(): Promise<void> {\n await this.manager.transaction(async (em: EntityManager) => {\n await this.detectTables(em);\n await this.calculateDependencyTables(em);\n const tables = [...this.tables];\n await Promise.all([\n this.createTempTable(em, tables),\n this.detectTablesWithAutoIncrement(em, tables),\n ]);\n });\n }\n\n private async createTempTable(\n em: EntityManager,\n tables: string[]\n ): Promise<void> {\n await Promise.all(\n tables.map(async (tableName) => {\n await this.execQuery(em, \"createTempTable\", { tableName });\n })\n );\n }\n\n private async detectTablesWithAutoIncrement(\n em: EntityManager,\n tables: string[]\n ): Promise<void> {\n for (const tableName of tables) {\n await this.processTable(em, tableName);\n }\n }\n\n private async processTable(\n em: EntityManager,\n tableName: string\n ): Promise<void> {\n const columns = await this.getColumnsWithAutoIncrement(em, tableName);\n if (!columns) return;\n\n for (const column of columns) {\n await this.processColumn(em, tableName, column);\n }\n }\n\n private async getColumnsWithAutoIncrement(\n em: EntityManager,\n tableName: string\n ): Promise<ColumnsWithAutoIncrement[] | null> {\n const columns = await this.execQuery<ColumnsWithAutoIncrement>(\n em,\n \"getColumnsWithAutoIncrement\",\n { tableName }\n );\n return Array.isArray(columns) ? columns : null;\n }\n\n private async processColumn(\n em: EntityManager,\n tableName: string,\n column: ColumnsWithAutoIncrement\n ): Promise<void> {\n const stat = await this.getMaxColumnIndex(\n em,\n tableName,\n column.column_name\n );\n const sequenceName = this.getSequenceName(column.column_default);\n if (!sequenceName) return;\n\n const index = Number(stat?.maxindex) || 0;\n this.updateTablesWithAutoIncrement(tableName, {\n column: column.column_name,\n sequenceName,\n index: String(index + (INDEX_OFFSET_CONFIG[this.getType()] ?? 0)),\n });\n }\n\n private async getMaxColumnIndex(\n em: EntityManager,\n tableName: string,\n columnName: string\n ): Promise<ColumnStat | null> {\n const [stat] = await this.execQuery<ColumnStat>(em, \"getMaxColumnIndex\", {\n tableName,\n column_name: columnName,\n });\n return stat || null;\n }\n\n private getSequenceName(columnDefault: string): string | null {\n return columnDefault.match(/'([^']+)'/)?.[1] || null;\n }\n\n private updateTablesWithAutoIncrement(\n tableName: string,\n data: { column: string; sequenceName: string; index: string }\n ): void {\n if (!this.tablesWithAutoIncrement.has(tableName)) {\n this.tablesWithAutoIncrement.set(tableName, []);\n }\n\n this.tablesWithAutoIncrement.get(tableName)?.push(data);\n }\n\n public async restoreData(): Promise<void> {\n await this.manager.transaction(async (em: EntityManager) => {\n const { foreignKey, restoreOrder } = await this.restoreManager(em);\n await foreignKey.disable();\n await restoreOrder();\n await foreignKey.enable();\n });\n }\n\n protected async restoreManager(em: EntityManager): Promise<Manager> {\n if (this.tables.size === 0) {\n await this.detectTables(em);\n }\n\n const manager: Manager = {\n foreignKey: {\n disable: async () => Promise.resolve(),\n enable: async () => Promise.resolve(),\n },\n restoreOrder: async () => Promise.resolve(),\n };\n\n const typesWithForeignKey: DBType[] = [\"postgres\", \"mariadb\", \"mysql\"];\n if (typesWithForeignKey.includes(this.getType())) {\n manager.foreignKey.disable = async (): Promise<void> =>\n this.execQuery(em, \"foreignKey.disable\");\n manager.foreignKey.enable = async (): Promise<void> =>\n this.execQuery(em, \"foreignKey.enable\");\n }\n\n manager.restoreOrder = (): Promise<void> => this.restoreOrder(em);\n\n return manager;\n }\n\n private async calculateDependencyTables(em: EntityManager): Promise<void> {\n const dependencyTree = await this.execQuery<DependencyTreeQueryOut>(\n em,\n \"dependencyTree\"\n );\n\n if (!dependencyTree.length) {\n this.restoreInOder = false;\n return;\n }\n\n const sortedTables = new Set(dependencyTree.map((row) => row.table_name));\n this.tables.clear();\n this.tables = sortedTables;\n this.restoreInOder = true;\n }\n\n private async detectTables(em: EntityManager): Promise<void> {\n const tables = await this.execQuery<Table>(em, \"getTables\");\n if(!tables) return;\n\n tables.forEach((row) => {\n this.tables.add(row.name);\n });\n }\n\n private async restoreOrder(em: EntityManager): Promise<void> {\n if (this.restoreInOder) {\n for (const tableName of this.tables) {\n await this.recreateData(em, tableName);\n }\n\n return;\n }\n\n const tables = [...this.tables];\n await Promise.all(\n tables.map((tableName) => this.recreateData(em, tableName))\n );\n }\n\n private async recreateData(\n em: EntityManager,\n tableName: string\n ): Promise<void> {\n await this.execQuery(em, \"truncateTable\", { tableName });\n await this.execQuery(em, \"restoreData\", { tableName });\n await this.resetAutoIncrementColumns(em, tableName);\n }\n\n private async resetAutoIncrementColumns(\n em: EntityManager,\n tableName: string\n ): Promise<void> {\n const tables = this.tablesWithAutoIncrement.get(tableName);\n if (!tables) return;\n\n for (const { column, sequenceName, index } of tables) {\n await this.execQuery(em, \"resetAutoIncrementColumn\", {\n tableName,\n column,\n sequenceName,\n index,\n });\n }\n }\n}\n"],"names":["Fastypest","SQLScript","init","manager","transaction","em","detectTables","calculateDependencyTables","tables","Promise","all","createTempTable","detectTablesWithAutoIncrement","map","tableName","execQuery","processTable","columns","getColumnsWithAutoIncrement","column","processColumn","Array","isArray","stat","getMaxColumnIndex","column_name","sequenceName","getSequenceName","column_default","index","Number","maxindex","updateTablesWithAutoIncrement","String","INDEX_OFFSET_CONFIG","getType","columnName","columnDefault","match","data","tablesWithAutoIncrement","has","set","get","push","restoreData","foreignKey","restoreOrder","restoreManager","disable","enable","size","resolve","typesWithForeignKey","includes","dependencyTree","length","restoreInOder","sortedTables","Set","row","table_name","clear","forEach","add","name","recreateData","resetAutoIncrementColumns","connection","options","type","Map"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/core/fastypest.ts"],"sourcesContent":["import {\n Connection,\n DataSource,\n EntityManager,\n EntitySubscriberInterface,\n Table,\n} from \"typeorm\";\nimport { INDEX_OFFSET_CONFIG } from \"./config\";\nimport { SQLScript } from \"./sql-script\";\nimport { ChangeTrackerSubscriber } from \"./subscribers/change-tracker.subscriber\";\nimport {\n ChangeDetectionStrategy,\n type ColumnStat,\n type ColumnsWithAutoIncrement,\n type DBType,\n type DependencyTreeQueryOut,\n type FastypestOptions,\n type IncrementDetail,\n type Manager,\n} from \"./types\";\n\nexport class Fastypest extends SQLScript {\n private manager: EntityManager;\n private tables: Set<string> = new Set();\n private tablesWithAutoIncrement: Map<string, IncrementDetail[]> = new Map();\n private restoreInOder: boolean = false;\n private readonly options: Required<FastypestOptions>;\n private readonly changedTables: Set<string> = new Set();\n\n constructor(\n connection: DataSource | Connection,\n options?: FastypestOptions\n ) {\n super(connection.options.type);\n this.manager = connection.manager;\n this.options = {\n changeDetectionStrategy:\n options?.changeDetectionStrategy ?? ChangeDetectionStrategy.None,\n };\n if (\n this.options.changeDetectionStrategy ===\n ChangeDetectionStrategy.Subscriber\n ) {\n this.registerSubscriber(connection);\n }\n }\n\n public async init(): Promise<void> {\n await this.manager.transaction(async (em: EntityManager) => {\n await this.detectTables(em);\n await this.calculateDependencyTables(em);\n const tables = [...this.tables];\n await Promise.all([\n this.createTempTable(em, tables),\n this.detectTablesWithAutoIncrement(em, tables),\n ]);\n });\n }\n\n private async createTempTable(\n em: EntityManager,\n tables: string[]\n ): Promise<void> {\n await Promise.all(\n tables.map(async (tableName) => {\n await this.execQuery(em, \"dropTempTable\", { tableName });\n await this.execQuery(em, \"createTempTable\", { tableName });\n })\n );\n }\n\n private async detectTablesWithAutoIncrement(\n em: EntityManager,\n tables: string[]\n ): Promise<void> {\n for (const tableName of tables) {\n await this.processTable(em, tableName);\n }\n }\n\n private async processTable(\n em: EntityManager,\n tableName: string\n ): Promise<void> {\n const columns = await this.getColumnsWithAutoIncrement(em, tableName);\n if (!columns) return;\n\n for (const column of columns) {\n await this.processColumn(em, tableName, column);\n }\n }\n\n private async getColumnsWithAutoIncrement(\n em: EntityManager,\n tableName: string\n ): Promise<ColumnsWithAutoIncrement[] | null> {\n const columns = await this.execQuery<ColumnsWithAutoIncrement>(\n em,\n \"getColumnsWithAutoIncrement\",\n { tableName }\n );\n return Array.isArray(columns) ? columns : null;\n }\n\n private async processColumn(\n em: EntityManager,\n tableName: string,\n column: ColumnsWithAutoIncrement\n ): Promise<void> {\n const stat = await this.getMaxColumnIndex(\n em,\n tableName,\n column.column_name\n );\n const sequenceName = this.getSequenceName(column.column_default);\n if (!sequenceName) return;\n\n const index = Number(stat?.maxindex) || 0;\n this.updateTablesWithAutoIncrement(tableName, {\n column: column.column_name,\n sequenceName,\n index: String(index + (INDEX_OFFSET_CONFIG[this.getType()] ?? 0)),\n });\n }\n\n private async getMaxColumnIndex(\n em: EntityManager,\n tableName: string,\n columnName: string\n ): Promise<ColumnStat | null> {\n const [stat] = await this.execQuery<ColumnStat>(em, \"getMaxColumnIndex\", {\n tableName,\n column_name: columnName,\n });\n return stat || null;\n }\n\n private getSequenceName(columnDefault: string): string | null {\n return columnDefault.match(/'([^']+)'/)?.[1] || null;\n }\n\n private updateTablesWithAutoIncrement(\n tableName: string,\n data: { column: string; sequenceName: string; index: string }\n ): void {\n if (!this.tablesWithAutoIncrement.has(tableName)) {\n this.tablesWithAutoIncrement.set(tableName, []);\n }\n\n this.tablesWithAutoIncrement.get(tableName)?.push(data);\n }\n\n public async restoreData(): Promise<void> {\n await this.manager.transaction(async (em: EntityManager) => {\n const { foreignKey, restoreOrder } = await this.restoreManager(em);\n await foreignKey.disable();\n await restoreOrder();\n await foreignKey.enable();\n });\n }\n\n protected async restoreManager(em: EntityManager): Promise<Manager> {\n if (this.tables.size === 0) {\n await this.detectTables(em);\n }\n\n const manager: Manager = {\n foreignKey: {\n disable: async () => Promise.resolve(),\n enable: async () => Promise.resolve(),\n },\n restoreOrder: async () => Promise.resolve(),\n };\n\n const typesWithForeignKey: DBType[] = [\"postgres\", \"mariadb\", \"mysql\"];\n if (typesWithForeignKey.includes(this.getType())) {\n manager.foreignKey.disable = async (): Promise<void> =>\n this.execQuery(em, \"foreignKey.disable\");\n manager.foreignKey.enable = async (): Promise<void> =>\n this.execQuery(em, \"foreignKey.enable\");\n }\n\n manager.restoreOrder = (): Promise<void> => this.restoreOrder(em);\n\n return manager;\n }\n\n private async calculateDependencyTables(em: EntityManager): Promise<void> {\n const dependencyTree = await this.execQuery<DependencyTreeQueryOut>(\n em,\n \"dependencyTree\"\n );\n\n if (!dependencyTree.length) {\n this.restoreInOder = false;\n return;\n }\n\n const sortedTables = new Set(dependencyTree.map((row) => row.table_name));\n this.tables.clear();\n this.tables = sortedTables;\n this.restoreInOder = true;\n }\n\n private async detectTables(em: EntityManager): Promise<void> {\n const tables = await this.execQuery<Table>(em, \"getTables\");\n if (!tables) return;\n\n tables.forEach((row) => {\n this.tables.add(row.name);\n });\n }\n\n private async restoreOrder(em: EntityManager): Promise<void> {\n const tables = this.getTablesForRestore();\n if (this.restoreInOder) {\n for (const tableName of tables) {\n await this.recreateData(em, tableName);\n }\n } else {\n await Promise.all(\n tables.map((tableName) => this.recreateData(em, tableName))\n );\n }\n if (this.shouldTrackChanges()) {\n this.changedTables.clear();\n }\n }\n\n private async recreateData(\n em: EntityManager,\n tableName: string\n ): Promise<void> {\n await this.execQuery(em, \"truncateTable\", { tableName });\n await this.execQuery(em, \"restoreData\", { tableName });\n await this.resetAutoIncrementColumns(em, tableName);\n }\n\n private async resetAutoIncrementColumns(\n em: EntityManager,\n tableName: string\n ): Promise<void> {\n const tables = this.tablesWithAutoIncrement.get(tableName);\n if (!tables) return;\n\n for (const { column, sequenceName, index } of tables) {\n await this.execQuery(em, \"resetAutoIncrementColumn\", {\n tableName,\n column,\n sequenceName,\n index,\n });\n }\n }\n\n private registerSubscriber(connection: DataSource | Connection): void {\n const subscriber = new ChangeTrackerSubscriber((tableName) => {\n this.markTableAsChanged(tableName);\n });\n this.getSubscriberCollection(connection).push(subscriber);\n this.bindSubscriber(subscriber, connection);\n }\n\n private isDataSource(\n connection: DataSource | Connection\n ): connection is DataSource {\n return connection instanceof DataSource;\n }\n\n private getSubscriberCollection(\n connection: DataSource | Connection\n ): Array<EntitySubscriberInterface<unknown>> {\n return (connection as unknown as {\n subscribers: Array<EntitySubscriberInterface<unknown>>;\n }).subscribers;\n }\n\n private bindSubscriber(\n subscriber: ChangeTrackerSubscriber,\n connection: DataSource | Connection\n ): void {\n const lifecycle = subscriber as ChangeTrackerSubscriber & SubscriberLifecycle;\n if (this.isDataSource(connection)) {\n lifecycle.setDataSource?.(connection);\n return;\n }\n lifecycle.setConnection?.(connection);\n }\n\n private shouldTrackChanges(): boolean {\n return (\n this.options.changeDetectionStrategy ===\n ChangeDetectionStrategy.Subscriber\n );\n }\n\n private getTablesForRestore(): string[] {\n const tables = [...this.tables];\n if (!this.shouldTrackChanges()) {\n return tables;\n }\n if (this.changedTables.size === 0) {\n return tables;\n }\n const changed = new Set(this.changedTables);\n const filtered = tables.filter((table) => changed.has(table));\n if (filtered.length === 0) {\n return tables;\n }\n return filtered;\n }\n\n public markTableAsChanged(tableName: string): void {\n if (!this.shouldTrackChanges()) {\n return;\n }\n this.changedTables.add(tableName);\n }\n}\n\ntype SubscriberLifecycle = {\n setDataSource?: (dataSource: DataSource) => unknown;\n setConnection?: (connection: Connection) => unknown;\n};\n"],"names":["Fastypest","SQLScript","init","manager","transaction","em","detectTables","calculateDependencyTables","tables","Promise","all","createTempTable","detectTablesWithAutoIncrement","map","tableName","execQuery","processTable","columns","getColumnsWithAutoIncrement","column","processColumn","Array","isArray","stat","getMaxColumnIndex","column_name","sequenceName","getSequenceName","column_default","index","Number","maxindex","updateTablesWithAutoIncrement","String","INDEX_OFFSET_CONFIG","getType","columnName","columnDefault","match","data","tablesWithAutoIncrement","has","set","get","push","restoreData","foreignKey","restoreOrder","restoreManager","disable","enable","size","resolve","typesWithForeignKey","includes","dependencyTree","length","restoreInOder","sortedTables","Set","row","table_name","clear","forEach","add","name","getTablesForRestore","recreateData","shouldTrackChanges","changedTables","resetAutoIncrementColumns","registerSubscriber","connection","subscriber","ChangeTrackerSubscriber","markTableAsChanged","getSubscriberCollection","bindSubscriber","isDataSource","DataSource","subscribers","lifecycle","setDataSource","setConnection","options","changeDetectionStrategy","ChangeDetectionStrategy","Subscriber","changed","filtered","filter","table","type","Map","None"],"mappings":"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"}
@@ -1 +1,3 @@
1
1
  export * from "./fastypest";
2
+ export { ChangeDetectionStrategy } from "./types";
3
+ export type { FastypestOptions } from "./types";
@@ -2,7 +2,14 @@
2
2
  Object.defineProperty(exports, "__esModule", {
3
3
  value: true
4
4
  });
5
+ Object.defineProperty(exports, "ChangeDetectionStrategy", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return _types.ChangeDetectionStrategy;
9
+ }
10
+ });
5
11
  _export_star(require("./fastypest"), exports);
12
+ const _types = require("./types");
6
13
  function _export_star(from, to) {
7
14
  Object.keys(from).forEach(function(k) {
8
15
  if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/index.ts"],"sourcesContent":["export * from \"./fastypest\";\n"],"names":[],"mappings":";;;;qBAAc"}
1
+ {"version":3,"sources":["../../src/core/index.ts"],"sourcesContent":["export * from \"./fastypest\";\nexport { ChangeDetectionStrategy } from \"./types\";\nexport type { FastypestOptions } from \"./types\";\n"],"names":["ChangeDetectionStrategy"],"mappings":";;;;+BACSA;;;eAAAA,8BAAuB;;;qBADlB;uBAC0B"}
@@ -6,7 +6,7 @@
6
6
  },
7
7
  "getTables": "SELECT table_name AS name FROM information_schema.tables WHERE table_catalog = CURRENT_DATABASE() AND table_schema = 'public' AND table_type = 'BASE TABLE'",
8
8
  "createTempTable": "SET experimental_enable_temp_tables=on; CREATE TEMPORARY TABLE \"{{tableName}}_temp\" AS SELECT * FROM \"{{tableName}}\"",
9
- "dropTempTable": "DROP TABLE IF EXISTS \"{{tableName}}_temp\"",
9
+ "dropTempTable": "DROP TABLE IF EXISTS \"{{tableName}}_temp\";",
10
10
  "restoreData": "INSERT INTO \"{{tableName}}\" SELECT * FROM \"{{tableName}}_temp\";",
11
11
  "truncateTable": "TRUNCATE TABLE \"{{tableName}}\" CASCADE;",
12
12
  "getColumnsWithAutoIncrement": "SELECT column_name, column_default FROM information_schema.columns WHERE table_schema = 'public' AND column_default LIKE 'nextval%' AND table_name = '{{tableName}}'",
@@ -6,7 +6,7 @@
6
6
  },
7
7
  "getTables": "SELECT table_name AS name FROM information_schema.tables WHERE table_schema = DATABASE() AND table_type = 'BASE TABLE'",
8
8
  "createTempTable": "CREATE TEMPORARY TABLE {{tableName}}_temp AS SELECT * FROM {{tableName}}",
9
- "dropTempTable": "DROP TEMPORARY TABLE {{tableName}}_temp",
9
+ "dropTempTable": "DROP TEMPORARY TABLE IF EXISTS {{tableName}}_temp",
10
10
  "restoreData": "INSERT INTO {{tableName}} SELECT * FROM {{tableName}}_temp",
11
11
  "truncateTable": "TRUNCATE TABLE {{tableName}}",
12
12
  "getColumnsWithAutoIncrement": "-- NOT USED",
@@ -6,7 +6,7 @@
6
6
  },
7
7
  "getTables": "SELECT table_name AS name FROM information_schema.tables WHERE table_schema = CURRENT_SCHEMA() AND table_type = 'BASE TABLE'",
8
8
  "createTempTable": "CREATE TEMPORARY TABLE \"{{tableName}}_temp\" AS SELECT * FROM \"{{tableName}}\"",
9
- "dropTempTable": "DROP TABLE IF EXISTS \"{{tableName}}_temp\"",
9
+ "dropTempTable": "DROP TABLE IF EXISTS \"{{tableName}}_temp\";",
10
10
  "restoreData": "INSERT INTO \"{{tableName}}\" SELECT * FROM \"{{tableName}}_temp\";",
11
11
  "truncateTable": "TRUNCATE TABLE \"{{tableName}}\" RESTART IDENTITY CASCADE",
12
12
  "getColumnsWithAutoIncrement": "SELECT column_name, column_default FROM information_schema.columns WHERE table_schema = 'public' AND column_default LIKE 'nextval%' AND table_name = '{{tableName}}'",
@@ -0,0 +1,10 @@
1
+ import { EntitySubscriberInterface, InsertEvent, RemoveEvent, UpdateEvent } from "typeorm";
2
+ export type ChangeReporter = (tableName: string) => void;
3
+ export declare class ChangeTrackerSubscriber implements EntitySubscriberInterface {
4
+ private readonly report;
5
+ constructor(report: ChangeReporter);
6
+ afterInsert(event: InsertEvent<unknown>): void | Promise<any>;
7
+ afterUpdate(event: UpdateEvent<unknown>): void | Promise<any>;
8
+ afterRemove(event: RemoveEvent<unknown>): void | Promise<any>;
9
+ private notify;
10
+ }
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "ChangeTrackerSubscriber", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return ChangeTrackerSubscriber;
9
+ }
10
+ });
11
+ function _define_property(obj, key, value) {
12
+ if (key in obj) {
13
+ Object.defineProperty(obj, key, {
14
+ value: value,
15
+ enumerable: true,
16
+ configurable: true,
17
+ writable: true
18
+ });
19
+ } else {
20
+ obj[key] = value;
21
+ }
22
+ return obj;
23
+ }
24
+ class ChangeTrackerSubscriber {
25
+ afterInsert(event) {
26
+ this.notify(event);
27
+ }
28
+ afterUpdate(event) {
29
+ this.notify(event);
30
+ }
31
+ afterRemove(event) {
32
+ this.notify(event);
33
+ }
34
+ notify(event) {
35
+ this.report(event.metadata.tableName);
36
+ }
37
+ constructor(report){
38
+ _define_property(this, "report", void 0);
39
+ this.report = report;
40
+ }
41
+ }
42
+
43
+ //# sourceMappingURL=change-tracker.subscriber.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/core/subscribers/change-tracker.subscriber.ts"],"sourcesContent":["import {\n EntitySubscriberInterface,\n InsertEvent,\n RemoveEvent,\n UpdateEvent,\n} from \"typeorm\";\n\nexport type ChangeReporter = (tableName: string) => void;\n\nexport class ChangeTrackerSubscriber implements EntitySubscriberInterface {\n constructor(private readonly report: ChangeReporter) {}\n\n afterInsert(event: InsertEvent<unknown>): void | Promise<any> {\n this.notify(event);\n }\n\n afterUpdate(event: UpdateEvent<unknown>): void | Promise<any> {\n this.notify(event);\n }\n\n afterRemove(event: RemoveEvent<unknown>): void | Promise<any> {\n this.notify(event);\n }\n\n private notify(event: { metadata: { tableName: string } }): void {\n this.report(event.metadata.tableName);\n }\n}\n"],"names":["ChangeTrackerSubscriber","afterInsert","event","notify","afterUpdate","afterRemove","report","metadata","tableName"],"mappings":";;;;+BASaA;;;eAAAA;;;;;;;;;;;;;;;;AAAN,MAAMA;IAGXC,YAAYC,KAA2B,EAAuB;QAC5D,IAAI,CAACC,MAAM,CAACD;IACd;IAEAE,YAAYF,KAA2B,EAAuB;QAC5D,IAAI,CAACC,MAAM,CAACD;IACd;IAEAG,YAAYH,KAA2B,EAAuB;QAC5D,IAAI,CAACC,MAAM,CAACD;IACd;IAEQC,OAAOD,KAA0C,EAAQ;QAC/D,IAAI,CAACI,MAAM,CAACJ,MAAMK,QAAQ,CAACC,SAAS;IACtC;IAhBA,YAAY,AAAiBF,MAAsB,CAAE;;aAAxBA,SAAAA;IAAyB;AAiBxD"}
@@ -6,6 +6,13 @@ export type DependencyTreeQueryOut = {
6
6
  table_name: string;
7
7
  level: number;
8
8
  };
9
+ export declare enum ChangeDetectionStrategy {
10
+ None = "none",
11
+ Subscriber = "subscriber"
12
+ }
13
+ export type FastypestOptions = {
14
+ changeDetectionStrategy?: ChangeDetectionStrategy;
15
+ };
9
16
  export type ColumnsWithAutoIncrement = {
10
17
  column_name: string;
11
18
  column_default: string;
@@ -2,5 +2,16 @@
2
2
  Object.defineProperty(exports, "__esModule", {
3
3
  value: true
4
4
  });
5
+ Object.defineProperty(exports, "ChangeDetectionStrategy", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return ChangeDetectionStrategy;
9
+ }
10
+ });
11
+ var ChangeDetectionStrategy = /*#__PURE__*/ function(ChangeDetectionStrategy) {
12
+ ChangeDetectionStrategy["None"] = "none";
13
+ ChangeDetectionStrategy["Subscriber"] = "subscriber";
14
+ return ChangeDetectionStrategy;
15
+ }({});
5
16
 
6
17
  //# sourceMappingURL=types.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/types.ts"],"names":[],"mappings":""}
1
+ {"version":3,"sources":["../../src/core/types.ts"],"sourcesContent":["import { DataSourceOptions } from \"typeorm\";\n\nexport type Table = { name: string };\nexport type DependencyTreeQueryOut = {\n table_name: string;\n level: number;\n};\n\nexport enum ChangeDetectionStrategy {\n None = \"none\",\n Subscriber = \"subscriber\",\n}\n\nexport type FastypestOptions = {\n changeDetectionStrategy?: ChangeDetectionStrategy;\n};\n\nexport type ColumnsWithAutoIncrement = {\n column_name: string;\n column_default: string;\n};\n\nexport type Manager = {\n foreignKey: {\n disable: () => Promise<void>;\n enable: () => Promise<void>;\n };\n restoreOrder: () => Promise<void>;\n};\nexport type ColumnStat = { maxindex: string | null };\nexport type DBType = DataSourceOptions[\"type\"];\nexport type IncrementDetail = {\n column: string;\n sequenceName: string;\n index: string;\n};\n"],"names":["ChangeDetectionStrategy"],"mappings":";;;;+BAQYA;;;eAAAA;;;AAAL,IAAA,AAAKA,iDAAAA;;;WAAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fastypest",
3
- "version": "1.4.139",
3
+ "version": "1.5.1",
4
4
  "description": "Restores the database automatically after each test. Allows serial execution of tests without having to delete and restore the database having to stop the application",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -50,7 +50,7 @@
50
50
  },
51
51
  "homepage": "https://github.com/juanjoGonDev/fastypest#readme",
52
52
  "devDependencies": {
53
- "@eslint/js": "^9.35.0",
53
+ "@eslint/js": "^9.36.0",
54
54
  "@swc-node/jest": "^1.9.1",
55
55
  "@swc/cli": "^0.7.8",
56
56
  "@swc/core": "^1.13.5",
@@ -58,8 +58,8 @@
58
58
  "@types/jest": "^30.0.0",
59
59
  "@types/node": "^24.5.1",
60
60
  "@typescript-eslint/eslint-plugin": "^8.44.0",
61
- "@typescript-eslint/parser": "^8.44.0",
62
- "@typescript-eslint/types": "8.44.0",
61
+ "@typescript-eslint/parser": "^8.44.1",
62
+ "@typescript-eslint/types": "8.44.1",
63
63
  "cpy-cli": "^6.0.0",
64
64
  "eslint": "^9.36.0",
65
65
  "eslint-config-standard-with-typescript": "^43.0.1",
@@ -70,7 +70,7 @@
70
70
  "execa": "^9.6.0",
71
71
  "globals": "^16.4.0",
72
72
  "jest": "^30.1.3",
73
- "lefthook": "^1.13.2",
73
+ "lefthook": "^1.13.4",
74
74
  "lint-staged": "^16.1.6",
75
75
  "mariadb": "^3.4.5",
76
76
  "mysql": "^2.18.1",
@@ -80,11 +80,11 @@
80
80
  "rimraf": "^6.0.1",
81
81
  "standard-version": "^9.5.0",
82
82
  "tsconfig-paths": "^4.2.0",
83
- "typeorm": "^0.3.26",
83
+ "typeorm": "^0.3.27",
84
84
  "typescript": "^5.9.2",
85
- "typescript-eslint": "^8.44.0"
85
+ "typescript-eslint": "^8.44.1"
86
86
  },
87
87
  "peerDependencies": {
88
- "typeorm": "^0.3.26"
88
+ "typeorm": "^0.3.27"
89
89
  }
90
90
  }