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 +19 -0
- package/README.md +19 -0
- package/dist/core/fastypest.d.ts +11 -2
- package/dist/core/fastypest.js +68 -8
- package/dist/core/fastypest.js.map +1 -1
- package/dist/core/index.d.ts +2 -0
- package/dist/core/index.js +7 -0
- package/dist/core/index.js.map +1 -1
- package/dist/core/sql-script/queries/cockroachdb.json +1 -1
- package/dist/core/sql-script/queries/mysql.query.json +1 -1
- package/dist/core/sql-script/queries/postgres.query.json +1 -1
- package/dist/core/subscribers/change-tracker.subscriber.d.ts +10 -0
- package/dist/core/subscribers/change-tracker.subscriber.js +43 -0
- package/dist/core/subscribers/change-tracker.subscriber.js.map +1 -0
- package/dist/core/types.d.ts +7 -0
- package/dist/core/types.js +11 -0
- package/dist/core/types.js.map +1 -1
- package/package.json +8 -8
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:
|
package/dist/core/fastypest.d.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { Connection, DataSource, EntityManager } from "typeorm";
|
|
2
2
|
import { SQLScript } from "./sql-script";
|
|
3
|
-
import type
|
|
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
|
-
|
|
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
|
}
|
package/dist/core/fastypest.js
CHANGED
|
@@ -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
|
|
150
|
+
for (const tableName of tables){
|
|
144
151
|
await this.recreateData(em, tableName);
|
|
145
152
|
}
|
|
146
|
-
|
|
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
|
-
|
|
175
|
-
|
|
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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"}
|
package/dist/core/index.d.ts
CHANGED
package/dist/core/index.js
CHANGED
|
@@ -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)) {
|
package/dist/core/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/index.ts"],"sourcesContent":["export * from \"./fastypest\";\n"],"names":[],"mappings":"
|
|
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"}
|
package/dist/core/types.d.ts
CHANGED
|
@@ -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;
|
package/dist/core/types.js
CHANGED
|
@@ -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
|
package/dist/core/types.js.map
CHANGED
|
@@ -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.
|
|
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.
|
|
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.
|
|
62
|
-
"@typescript-eslint/types": "8.44.
|
|
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.
|
|
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.
|
|
83
|
+
"typeorm": "^0.3.27",
|
|
84
84
|
"typescript": "^5.9.2",
|
|
85
|
-
"typescript-eslint": "^8.44.
|
|
85
|
+
"typescript-eslint": "^8.44.1"
|
|
86
86
|
},
|
|
87
87
|
"peerDependencies": {
|
|
88
|
-
"typeorm": "^0.3.
|
|
88
|
+
"typeorm": "^0.3.27"
|
|
89
89
|
}
|
|
90
90
|
}
|