@nest-toolbox/typeorm-soft-delete 1.8.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.
- package/README.md +540 -0
- package/dist/decorators.d.ts +47 -0
- package/dist/decorators.js +55 -0
- package/dist/decorators.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/soft-delete-operations.d.ts +107 -0
- package/dist/soft-delete-operations.js +227 -0
- package/dist/soft-delete-operations.js.map +1 -0
- package/dist/soft-delete-paginate.d.ts +82 -0
- package/dist/soft-delete-paginate.js +119 -0
- package/dist/soft-delete-paginate.js.map +1 -0
- package/dist/soft-delete-repository.d.ts +42 -0
- package/dist/soft-delete-repository.js +76 -0
- package/dist/soft-delete-repository.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -0
- package/dist/types.d.ts +53 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +31 -0
- package/dist/utils.js +53 -0
- package/dist/utils.js.map +1 -0
- package/package.json +62 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { type FindManyOptions, type ObjectLiteral, type Repository } from 'typeorm';
|
|
2
|
+
import type { CountOptions, RestoreOptions, SoftDeleteCriteria, SoftDeleteOptions, SoftDeleteResult } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Soft delete entities by setting deletedAt to current timestamp
|
|
5
|
+
*
|
|
6
|
+
* @param repository - TypeORM repository
|
|
7
|
+
* @param criteria - Entity ID(s) or FindOptionsWhere clause
|
|
8
|
+
* @param options - Optional configuration
|
|
9
|
+
* @returns Promise with number of affected records
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* // Single ID
|
|
14
|
+
* await softDelete(userRepository, 123);
|
|
15
|
+
*
|
|
16
|
+
* // Multiple IDs
|
|
17
|
+
* await softDelete(userRepository, [1, 2, 3]);
|
|
18
|
+
*
|
|
19
|
+
* // With where clause
|
|
20
|
+
* await softDelete(userRepository, { email: 'test@example.com' });
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export declare function softDelete<T extends ObjectLiteral>(repository: Repository<T>, criteria: SoftDeleteCriteria<T>, options?: SoftDeleteOptions): Promise<SoftDeleteResult>;
|
|
24
|
+
/**
|
|
25
|
+
* Restore soft-deleted entities by setting deletedAt back to null
|
|
26
|
+
*
|
|
27
|
+
* @param repository - TypeORM repository
|
|
28
|
+
* @param criteria - Entity ID(s) or FindOptionsWhere clause
|
|
29
|
+
* @param options - Optional configuration
|
|
30
|
+
* @returns Promise with number of affected records
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```typescript
|
|
34
|
+
* await restore(userRepository, 123);
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export declare function restore<T extends ObjectLiteral>(repository: Repository<T>, criteria: SoftDeleteCriteria<T>, options?: RestoreOptions): Promise<SoftDeleteResult>;
|
|
38
|
+
/**
|
|
39
|
+
* Permanently delete soft-deleted entities (hard delete)
|
|
40
|
+
* Only deletes records where deletedAt IS NOT NULL
|
|
41
|
+
*
|
|
42
|
+
* @param repository - TypeORM repository
|
|
43
|
+
* @param criteria - Entity ID(s) or FindOptionsWhere clause
|
|
44
|
+
* @returns Promise with number of affected records
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```typescript
|
|
48
|
+
* await forceDelete(userRepository, 123);
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
export declare function forceDelete<T extends ObjectLiteral>(repository: Repository<T>, criteria: SoftDeleteCriteria<T>): Promise<SoftDeleteResult>;
|
|
52
|
+
/**
|
|
53
|
+
* Find entities including soft-deleted ones
|
|
54
|
+
*
|
|
55
|
+
* @param repository - TypeORM repository
|
|
56
|
+
* @param options - Find options
|
|
57
|
+
* @returns Promise with array of entities (including soft-deleted)
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```typescript
|
|
61
|
+
* const allUsers = await findWithDeleted(userRepository);
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
export declare function findWithDeleted<T extends ObjectLiteral>(repository: Repository<T>, options?: FindManyOptions<T>): Promise<T[]>;
|
|
65
|
+
/**
|
|
66
|
+
* Find only soft-deleted entities
|
|
67
|
+
*
|
|
68
|
+
* @param repository - TypeORM repository
|
|
69
|
+
* @param options - Find options
|
|
70
|
+
* @returns Promise with array of soft-deleted entities
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* ```typescript
|
|
74
|
+
* const deletedUsers = await findOnlyDeleted(userRepository);
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
export declare function findOnlyDeleted<T extends ObjectLiteral>(repository: Repository<T>, options?: FindManyOptions<T>): Promise<T[]>;
|
|
78
|
+
/**
|
|
79
|
+
* Count entities with optional inclusion of soft-deleted
|
|
80
|
+
*
|
|
81
|
+
* @param repository - TypeORM repository
|
|
82
|
+
* @param options - Count options
|
|
83
|
+
* @returns Promise with count of entities
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```typescript
|
|
87
|
+
* const activeCount = await count(userRepository);
|
|
88
|
+
* const totalCount = await count(userRepository, { includeDeleted: true });
|
|
89
|
+
* ```
|
|
90
|
+
*/
|
|
91
|
+
export declare function count<T extends ObjectLiteral>(repository: Repository<T>, options?: CountOptions<T>): Promise<number>;
|
|
92
|
+
/**
|
|
93
|
+
* Check if entity is soft-deleted
|
|
94
|
+
*
|
|
95
|
+
* @param repository - TypeORM repository
|
|
96
|
+
* @param id - Entity ID
|
|
97
|
+
* @returns Promise with boolean indicating if entity is soft-deleted
|
|
98
|
+
* @throws Error if entity not found
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
* ```typescript
|
|
102
|
+
* if (await isSoftDeleted(userRepository, 123)) {
|
|
103
|
+
* console.log('User is deleted');
|
|
104
|
+
* }
|
|
105
|
+
* ```
|
|
106
|
+
*/
|
|
107
|
+
export declare function isSoftDeleted<T extends ObjectLiteral>(repository: Repository<T>, id: string | number): Promise<boolean>;
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
+
var t = {};
|
|
4
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
+
t[p] = s[p];
|
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
+
t[p[i]] = s[p[i]];
|
|
10
|
+
}
|
|
11
|
+
return t;
|
|
12
|
+
};
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.softDelete = softDelete;
|
|
15
|
+
exports.restore = restore;
|
|
16
|
+
exports.forceDelete = forceDelete;
|
|
17
|
+
exports.findWithDeleted = findWithDeleted;
|
|
18
|
+
exports.findOnlyDeleted = findOnlyDeleted;
|
|
19
|
+
exports.count = count;
|
|
20
|
+
exports.isSoftDeleted = isSoftDeleted;
|
|
21
|
+
const typeorm_1 = require("typeorm");
|
|
22
|
+
const utils_1 = require("./utils");
|
|
23
|
+
/**
|
|
24
|
+
* Soft delete entities by setting deletedAt to current timestamp
|
|
25
|
+
*
|
|
26
|
+
* @param repository - TypeORM repository
|
|
27
|
+
* @param criteria - Entity ID(s) or FindOptionsWhere clause
|
|
28
|
+
* @param options - Optional configuration
|
|
29
|
+
* @returns Promise with number of affected records
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```typescript
|
|
33
|
+
* // Single ID
|
|
34
|
+
* await softDelete(userRepository, 123);
|
|
35
|
+
*
|
|
36
|
+
* // Multiple IDs
|
|
37
|
+
* await softDelete(userRepository, [1, 2, 3]);
|
|
38
|
+
*
|
|
39
|
+
* // With where clause
|
|
40
|
+
* await softDelete(userRepository, { email: 'test@example.com' });
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
async function softDelete(repository, criteria, options) {
|
|
44
|
+
var _a;
|
|
45
|
+
(0, utils_1.validateSoftDeleteSupport)(repository);
|
|
46
|
+
const deleteColumn = (0, utils_1.getDeleteDateColumnName)(repository);
|
|
47
|
+
const qb = repository
|
|
48
|
+
.createQueryBuilder()
|
|
49
|
+
.update()
|
|
50
|
+
// biome-ignore lint/suspicious/noExplicitAny: TypeORM QueryBuilder set requires any for dynamic keys
|
|
51
|
+
.set({ [deleteColumn]: () => 'CURRENT_TIMESTAMP' })
|
|
52
|
+
.andWhere(`${deleteColumn} IS NULL`); // Only delete non-deleted records
|
|
53
|
+
// Handle different criteria types
|
|
54
|
+
if (typeof criteria === 'string' || typeof criteria === 'number') {
|
|
55
|
+
const primaryColumns = (0, utils_1.getPrimaryColumns)(repository);
|
|
56
|
+
qb.where(`${primaryColumns[0]} = :id`, { id: criteria });
|
|
57
|
+
}
|
|
58
|
+
else if (Array.isArray(criteria)) {
|
|
59
|
+
const primaryColumns = (0, utils_1.getPrimaryColumns)(repository);
|
|
60
|
+
qb.where(`${primaryColumns[0]} IN (:...ids)`, { ids: criteria });
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
// biome-ignore lint/suspicious/noExplicitAny: TypeORM QueryBuilder where clause requires any for dynamic types
|
|
64
|
+
qb.where(criteria);
|
|
65
|
+
}
|
|
66
|
+
const result = await qb.execute();
|
|
67
|
+
if ((options === null || options === void 0 ? void 0 : options.validateExists) && result.affected === 0) {
|
|
68
|
+
throw new Error('Entity not found or already deleted');
|
|
69
|
+
}
|
|
70
|
+
return { affected: (_a = result.affected) !== null && _a !== void 0 ? _a : 0 };
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Restore soft-deleted entities by setting deletedAt back to null
|
|
74
|
+
*
|
|
75
|
+
* @param repository - TypeORM repository
|
|
76
|
+
* @param criteria - Entity ID(s) or FindOptionsWhere clause
|
|
77
|
+
* @param options - Optional configuration
|
|
78
|
+
* @returns Promise with number of affected records
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```typescript
|
|
82
|
+
* await restore(userRepository, 123);
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
async function restore(repository, criteria, options) {
|
|
86
|
+
var _a;
|
|
87
|
+
(0, utils_1.validateSoftDeleteSupport)(repository);
|
|
88
|
+
const deleteColumn = (0, utils_1.getDeleteDateColumnName)(repository);
|
|
89
|
+
const qb = repository
|
|
90
|
+
.createQueryBuilder()
|
|
91
|
+
.update()
|
|
92
|
+
// biome-ignore lint/suspicious/noExplicitAny: TypeORM QueryBuilder set requires any for dynamic keys
|
|
93
|
+
.set({ [deleteColumn]: null })
|
|
94
|
+
.andWhere(`${deleteColumn} IS NOT NULL`); // Only restore deleted records
|
|
95
|
+
// Handle different criteria types
|
|
96
|
+
if (typeof criteria === 'string' || typeof criteria === 'number') {
|
|
97
|
+
const primaryColumns = (0, utils_1.getPrimaryColumns)(repository);
|
|
98
|
+
qb.where(`${primaryColumns[0]} = :id`, { id: criteria });
|
|
99
|
+
}
|
|
100
|
+
else if (Array.isArray(criteria)) {
|
|
101
|
+
const primaryColumns = (0, utils_1.getPrimaryColumns)(repository);
|
|
102
|
+
qb.where(`${primaryColumns[0]} IN (:...ids)`, { ids: criteria });
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
// biome-ignore lint/suspicious/noExplicitAny: TypeORM QueryBuilder where clause requires any for dynamic types
|
|
106
|
+
qb.where(criteria);
|
|
107
|
+
}
|
|
108
|
+
const result = await qb.execute();
|
|
109
|
+
if ((options === null || options === void 0 ? void 0 : options.validateExists) && result.affected === 0) {
|
|
110
|
+
throw new Error('Entity not found or not soft-deleted');
|
|
111
|
+
}
|
|
112
|
+
return { affected: (_a = result.affected) !== null && _a !== void 0 ? _a : 0 };
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Permanently delete soft-deleted entities (hard delete)
|
|
116
|
+
* Only deletes records where deletedAt IS NOT NULL
|
|
117
|
+
*
|
|
118
|
+
* @param repository - TypeORM repository
|
|
119
|
+
* @param criteria - Entity ID(s) or FindOptionsWhere clause
|
|
120
|
+
* @returns Promise with number of affected records
|
|
121
|
+
*
|
|
122
|
+
* @example
|
|
123
|
+
* ```typescript
|
|
124
|
+
* await forceDelete(userRepository, 123);
|
|
125
|
+
* ```
|
|
126
|
+
*/
|
|
127
|
+
async function forceDelete(repository, criteria) {
|
|
128
|
+
var _a;
|
|
129
|
+
(0, utils_1.validateSoftDeleteSupport)(repository);
|
|
130
|
+
const deleteColumn = (0, utils_1.getDeleteDateColumnName)(repository);
|
|
131
|
+
const qb = repository.createQueryBuilder().delete().andWhere(`${deleteColumn} IS NOT NULL`); // Only hard delete already soft-deleted records
|
|
132
|
+
// Handle criteria
|
|
133
|
+
if (typeof criteria === 'string' || typeof criteria === 'number') {
|
|
134
|
+
const primaryColumns = (0, utils_1.getPrimaryColumns)(repository);
|
|
135
|
+
qb.where(`${primaryColumns[0]} = :id`, { id: criteria });
|
|
136
|
+
}
|
|
137
|
+
else if (Array.isArray(criteria)) {
|
|
138
|
+
const primaryColumns = (0, utils_1.getPrimaryColumns)(repository);
|
|
139
|
+
qb.where(`${primaryColumns[0]} IN (:...ids)`, { ids: criteria });
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
// biome-ignore lint/suspicious/noExplicitAny: TypeORM QueryBuilder where clause requires any for dynamic types
|
|
143
|
+
qb.where(criteria);
|
|
144
|
+
}
|
|
145
|
+
const result = await qb.execute();
|
|
146
|
+
return { affected: (_a = result.affected) !== null && _a !== void 0 ? _a : 0 };
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Find entities including soft-deleted ones
|
|
150
|
+
*
|
|
151
|
+
* @param repository - TypeORM repository
|
|
152
|
+
* @param options - Find options
|
|
153
|
+
* @returns Promise with array of entities (including soft-deleted)
|
|
154
|
+
*
|
|
155
|
+
* @example
|
|
156
|
+
* ```typescript
|
|
157
|
+
* const allUsers = await findWithDeleted(userRepository);
|
|
158
|
+
* ```
|
|
159
|
+
*/
|
|
160
|
+
async function findWithDeleted(repository, options) {
|
|
161
|
+
return repository.find(Object.assign(Object.assign({}, options), { withDeleted: true }));
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Find only soft-deleted entities
|
|
165
|
+
*
|
|
166
|
+
* @param repository - TypeORM repository
|
|
167
|
+
* @param options - Find options
|
|
168
|
+
* @returns Promise with array of soft-deleted entities
|
|
169
|
+
*
|
|
170
|
+
* @example
|
|
171
|
+
* ```typescript
|
|
172
|
+
* const deletedUsers = await findOnlyDeleted(userRepository);
|
|
173
|
+
* ```
|
|
174
|
+
*/
|
|
175
|
+
async function findOnlyDeleted(repository, options) {
|
|
176
|
+
(0, utils_1.validateSoftDeleteSupport)(repository);
|
|
177
|
+
const deleteColumn = (0, utils_1.getDeleteDateColumnName)(repository);
|
|
178
|
+
return repository.find(Object.assign(Object.assign({}, options), { where: Object.assign(Object.assign({}, options === null || options === void 0 ? void 0 : options.where), { [deleteColumn]: (0, typeorm_1.Not)((0, typeorm_1.IsNull)()) }), withDeleted: true }));
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Count entities with optional inclusion of soft-deleted
|
|
182
|
+
*
|
|
183
|
+
* @param repository - TypeORM repository
|
|
184
|
+
* @param options - Count options
|
|
185
|
+
* @returns Promise with count of entities
|
|
186
|
+
*
|
|
187
|
+
* @example
|
|
188
|
+
* ```typescript
|
|
189
|
+
* const activeCount = await count(userRepository);
|
|
190
|
+
* const totalCount = await count(userRepository, { includeDeleted: true });
|
|
191
|
+
* ```
|
|
192
|
+
*/
|
|
193
|
+
async function count(repository, options) {
|
|
194
|
+
const _a = options || {}, { includeDeleted } = _a, countOptions = __rest(_a, ["includeDeleted"]);
|
|
195
|
+
return repository.count(Object.assign(Object.assign({}, countOptions), { withDeleted: includeDeleted }));
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Check if entity is soft-deleted
|
|
199
|
+
*
|
|
200
|
+
* @param repository - TypeORM repository
|
|
201
|
+
* @param id - Entity ID
|
|
202
|
+
* @returns Promise with boolean indicating if entity is soft-deleted
|
|
203
|
+
* @throws Error if entity not found
|
|
204
|
+
*
|
|
205
|
+
* @example
|
|
206
|
+
* ```typescript
|
|
207
|
+
* if (await isSoftDeleted(userRepository, 123)) {
|
|
208
|
+
* console.log('User is deleted');
|
|
209
|
+
* }
|
|
210
|
+
* ```
|
|
211
|
+
*/
|
|
212
|
+
async function isSoftDeleted(repository, id) {
|
|
213
|
+
(0, utils_1.validateSoftDeleteSupport)(repository);
|
|
214
|
+
const primaryColumns = (0, utils_1.getPrimaryColumns)(repository);
|
|
215
|
+
const deleteColumn = (0, utils_1.getDeleteDateColumnName)(repository);
|
|
216
|
+
const entity = await repository.findOne({
|
|
217
|
+
where: {
|
|
218
|
+
[primaryColumns[0]]: id, // biome-ignore lint/suspicious/noExplicitAny: TypeORM where object requires any
|
|
219
|
+
},
|
|
220
|
+
withDeleted: true,
|
|
221
|
+
});
|
|
222
|
+
if (!entity) {
|
|
223
|
+
throw new Error('Entity not found');
|
|
224
|
+
}
|
|
225
|
+
return entity[deleteColumn] !== null;
|
|
226
|
+
}
|
|
227
|
+
//# sourceMappingURL=soft-delete-operations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"soft-delete-operations.js","sourceRoot":"","sources":["../src/soft-delete-operations.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { type FindOptionsWhere, type ObjectLiteral, type Repository } from 'typeorm';
|
|
2
|
+
/**
|
|
3
|
+
* Options for pagination with soft delete awareness
|
|
4
|
+
*/
|
|
5
|
+
export interface PaginationWithDeletedOptions<T extends ObjectLiteral> {
|
|
6
|
+
/**
|
|
7
|
+
* TypeORM repository
|
|
8
|
+
*/
|
|
9
|
+
repository: Repository<T>;
|
|
10
|
+
/**
|
|
11
|
+
* Where clause for filtering entities
|
|
12
|
+
*/
|
|
13
|
+
where: FindOptionsWhere<T> | FindOptionsWhere<T>[];
|
|
14
|
+
/**
|
|
15
|
+
* Number of records per page
|
|
16
|
+
* @default 100
|
|
17
|
+
*/
|
|
18
|
+
limit?: number;
|
|
19
|
+
/**
|
|
20
|
+
* Starting offset
|
|
21
|
+
* @default 0
|
|
22
|
+
*/
|
|
23
|
+
offset?: number;
|
|
24
|
+
/**
|
|
25
|
+
* Whether to include soft-deleted records
|
|
26
|
+
* @default false
|
|
27
|
+
*/
|
|
28
|
+
includeDeleted?: boolean;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Result row with pagination metadata
|
|
32
|
+
*/
|
|
33
|
+
export interface PaginatedRow<T extends ObjectLiteral> {
|
|
34
|
+
/**
|
|
35
|
+
* The entity data
|
|
36
|
+
*/
|
|
37
|
+
data: T;
|
|
38
|
+
/**
|
|
39
|
+
* Zero-based index of the current row
|
|
40
|
+
*/
|
|
41
|
+
index: number;
|
|
42
|
+
/**
|
|
43
|
+
* Progress percentage (0-1)
|
|
44
|
+
*/
|
|
45
|
+
progress: number;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Paginate with soft delete awareness
|
|
49
|
+
* By default excludes soft-deleted records
|
|
50
|
+
*
|
|
51
|
+
* @param options - Pagination options
|
|
52
|
+
* @yields Paginated rows with metadata
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```typescript
|
|
56
|
+
* for await (const row of rowsWithDeleted({
|
|
57
|
+
* repository: userRepo,
|
|
58
|
+
* where: {},
|
|
59
|
+
* includeDeleted: true
|
|
60
|
+
* })) {
|
|
61
|
+
* console.log(row.data, row.progress);
|
|
62
|
+
* }
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
export declare function rowsWithDeleted<T extends ObjectLiteral>(options: PaginationWithDeletedOptions<T>): AsyncGenerator<PaginatedRow<T>>;
|
|
66
|
+
/**
|
|
67
|
+
* Paginate only soft-deleted records
|
|
68
|
+
*
|
|
69
|
+
* @param options - Pagination options
|
|
70
|
+
* @yields Soft-deleted rows with metadata
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* ```typescript
|
|
74
|
+
* for await (const row of rowsOnlyDeleted({
|
|
75
|
+
* repository: userRepo,
|
|
76
|
+
* where: {}
|
|
77
|
+
* })) {
|
|
78
|
+
* console.log('Deleted user:', row.data);
|
|
79
|
+
* }
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
export declare function rowsOnlyDeleted<T extends ObjectLiteral>(options: Omit<PaginationWithDeletedOptions<T>, 'includeDeleted'>): AsyncGenerator<PaginatedRow<T>>;
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
|
|
3
|
+
var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
|
|
4
|
+
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
5
|
+
var g = generator.apply(thisArg, _arguments || []), i, q = [];
|
|
6
|
+
return i = Object.create((typeof AsyncIterator === "function" ? AsyncIterator : Object).prototype), verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;
|
|
7
|
+
function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }
|
|
8
|
+
function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }
|
|
9
|
+
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
|
|
10
|
+
function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
|
|
11
|
+
function fulfill(value) { resume("next", value); }
|
|
12
|
+
function reject(value) { resume("throw", value); }
|
|
13
|
+
function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
|
|
14
|
+
};
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.rowsWithDeleted = rowsWithDeleted;
|
|
17
|
+
exports.rowsOnlyDeleted = rowsOnlyDeleted;
|
|
18
|
+
const typeorm_1 = require("typeorm");
|
|
19
|
+
const utils_1 = require("./utils");
|
|
20
|
+
/**
|
|
21
|
+
* Paginate with soft delete awareness
|
|
22
|
+
* By default excludes soft-deleted records
|
|
23
|
+
*
|
|
24
|
+
* @param options - Pagination options
|
|
25
|
+
* @yields Paginated rows with metadata
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```typescript
|
|
29
|
+
* for await (const row of rowsWithDeleted({
|
|
30
|
+
* repository: userRepo,
|
|
31
|
+
* where: {},
|
|
32
|
+
* includeDeleted: true
|
|
33
|
+
* })) {
|
|
34
|
+
* console.log(row.data, row.progress);
|
|
35
|
+
* }
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
function rowsWithDeleted(options) {
|
|
39
|
+
return __asyncGenerator(this, arguments, function* rowsWithDeleted_1() {
|
|
40
|
+
const { repository, where, limit = 100, offset = 0, includeDeleted = false } = options;
|
|
41
|
+
// Build where clause with soft delete filter
|
|
42
|
+
let finalWhere = where;
|
|
43
|
+
if (!includeDeleted && (0, utils_1.supportsSoftDelete)(repository)) {
|
|
44
|
+
const deleteColumn = (0, utils_1.getDeleteDateColumnName)(repository);
|
|
45
|
+
finalWhere = Array.isArray(where) ? where.map((w) => (Object.assign(Object.assign({}, w), { [deleteColumn]: (0, typeorm_1.IsNull)() }))) : Object.assign(Object.assign({}, where), { [deleteColumn]: (0, typeorm_1.IsNull)() });
|
|
46
|
+
}
|
|
47
|
+
// biome-ignore lint/suspicious/noExplicitAny: TypeORM where requires any for dynamic types
|
|
48
|
+
const total = yield __await(repository.count({ where: finalWhere, withDeleted: includeDeleted }));
|
|
49
|
+
let currentOffset = offset;
|
|
50
|
+
let index = 0;
|
|
51
|
+
while (currentOffset < total) {
|
|
52
|
+
const rows = yield __await(repository.find({
|
|
53
|
+
// biome-ignore lint/suspicious/noExplicitAny: TypeORM where requires any for dynamic types
|
|
54
|
+
where: finalWhere,
|
|
55
|
+
skip: currentOffset,
|
|
56
|
+
take: limit,
|
|
57
|
+
withDeleted: includeDeleted,
|
|
58
|
+
}));
|
|
59
|
+
for (const row of rows) {
|
|
60
|
+
yield yield __await({
|
|
61
|
+
data: row,
|
|
62
|
+
index: index++,
|
|
63
|
+
progress: total > 0 ? index / total : 1,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
currentOffset += limit;
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Paginate only soft-deleted records
|
|
72
|
+
*
|
|
73
|
+
* @param options - Pagination options
|
|
74
|
+
* @yields Soft-deleted rows with metadata
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```typescript
|
|
78
|
+
* for await (const row of rowsOnlyDeleted({
|
|
79
|
+
* repository: userRepo,
|
|
80
|
+
* where: {}
|
|
81
|
+
* })) {
|
|
82
|
+
* console.log('Deleted user:', row.data);
|
|
83
|
+
* }
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
function rowsOnlyDeleted(options) {
|
|
87
|
+
return __asyncGenerator(this, arguments, function* rowsOnlyDeleted_1() {
|
|
88
|
+
const { repository, where, limit = 100, offset = 0 } = options;
|
|
89
|
+
(0, utils_1.validateSoftDeleteSupport)(repository);
|
|
90
|
+
const deleteColumn = (0, utils_1.getDeleteDateColumnName)(repository);
|
|
91
|
+
// Add deletedAt IS NOT NULL filter
|
|
92
|
+
const finalWhere = Array.isArray(where) ? where.map((w) => (Object.assign(Object.assign({}, w), { [deleteColumn]: (0, typeorm_1.Not)((0, typeorm_1.IsNull)()) }))) : Object.assign(Object.assign({}, where), { [deleteColumn]: (0, typeorm_1.Not)((0, typeorm_1.IsNull)()) });
|
|
93
|
+
const total = yield __await(repository.count({
|
|
94
|
+
// biome-ignore lint/suspicious/noExplicitAny: TypeORM where requires any for dynamic types
|
|
95
|
+
where: finalWhere,
|
|
96
|
+
withDeleted: true,
|
|
97
|
+
}));
|
|
98
|
+
let currentOffset = offset;
|
|
99
|
+
let index = 0;
|
|
100
|
+
while (currentOffset < total) {
|
|
101
|
+
const rows = yield __await(repository.find({
|
|
102
|
+
// biome-ignore lint/suspicious/noExplicitAny: TypeORM where requires any for dynamic types
|
|
103
|
+
where: finalWhere,
|
|
104
|
+
skip: currentOffset,
|
|
105
|
+
take: limit,
|
|
106
|
+
withDeleted: true,
|
|
107
|
+
}));
|
|
108
|
+
for (const row of rows) {
|
|
109
|
+
yield yield __await({
|
|
110
|
+
data: row,
|
|
111
|
+
index: index++,
|
|
112
|
+
progress: total > 0 ? index / total : 1,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
currentOffset += limit;
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=soft-delete-paginate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"soft-delete-paginate.js","sourceRoot":"","sources":["../src/soft-delete-paginate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { FindManyOptions, FindOneOptions, ObjectLiteral, Repository } from 'typeorm';
|
|
2
|
+
import type { CountOptions, RestoreOptions, SoftDeleteOptions, SoftDeleteResult } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Optional wrapper class providing repository-style API
|
|
5
|
+
* Users can choose between functions or this wrapper
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* const repo = withSoftDelete(userRepository);
|
|
10
|
+
* await repo.softDelete(123);
|
|
11
|
+
* await repo.restore(123);
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export declare class SoftDeleteRepository<T extends ObjectLiteral> {
|
|
15
|
+
private readonly repository;
|
|
16
|
+
constructor(repository: Repository<T>);
|
|
17
|
+
softDelete(criteria: string | number | (string | number)[] | Record<string, any>, options?: SoftDeleteOptions): Promise<SoftDeleteResult>;
|
|
18
|
+
restore(criteria: string | number | (string | number)[] | Record<string, any>, options?: RestoreOptions): Promise<SoftDeleteResult>;
|
|
19
|
+
forceDelete(criteria: string | number | (string | number)[] | Record<string, any>): Promise<SoftDeleteResult>;
|
|
20
|
+
findWithDeleted(options?: FindManyOptions<T>): Promise<T[]>;
|
|
21
|
+
findOnlyDeleted(options?: FindManyOptions<T>): Promise<T[]>;
|
|
22
|
+
count(options?: CountOptions<T>): Promise<number>;
|
|
23
|
+
isSoftDeleted(id: string | number): Promise<boolean>;
|
|
24
|
+
find(options?: FindManyOptions<T>): Promise<T[]>;
|
|
25
|
+
findOne(options: FindOneOptions<T>): Promise<T | null>;
|
|
26
|
+
save<E extends T>(entity: E): Promise<E>;
|
|
27
|
+
save<E extends T>(entities: E[]): Promise<E[]>;
|
|
28
|
+
remove(entity: T): Promise<T>;
|
|
29
|
+
remove(entities: T[]): Promise<T[]>;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Factory function to create wrapped repository
|
|
33
|
+
*
|
|
34
|
+
* @param repository - TypeORM repository to wrap
|
|
35
|
+
* @returns Wrapped repository with soft delete methods
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```typescript
|
|
39
|
+
* const userRepo = withSoftDelete(userRepository);
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export declare function withSoftDelete<T extends ObjectLiteral>(repository: Repository<T>): SoftDeleteRepository<T>;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SoftDeleteRepository = void 0;
|
|
4
|
+
exports.withSoftDelete = withSoftDelete;
|
|
5
|
+
const soft_delete_operations_1 = require("./soft-delete-operations");
|
|
6
|
+
/**
|
|
7
|
+
* Optional wrapper class providing repository-style API
|
|
8
|
+
* Users can choose between functions or this wrapper
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* const repo = withSoftDelete(userRepository);
|
|
13
|
+
* await repo.softDelete(123);
|
|
14
|
+
* await repo.restore(123);
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
class SoftDeleteRepository {
|
|
18
|
+
constructor(repository) {
|
|
19
|
+
this.repository = repository;
|
|
20
|
+
}
|
|
21
|
+
// biome-ignore lint/suspicious/noExplicitAny: Generic Record requires any for dynamic keys
|
|
22
|
+
async softDelete(criteria, options) {
|
|
23
|
+
return (0, soft_delete_operations_1.softDelete)(this.repository, criteria, options);
|
|
24
|
+
}
|
|
25
|
+
// biome-ignore lint/suspicious/noExplicitAny: Generic Record requires any for dynamic keys
|
|
26
|
+
async restore(criteria, options) {
|
|
27
|
+
return (0, soft_delete_operations_1.restore)(this.repository, criteria, options);
|
|
28
|
+
}
|
|
29
|
+
// biome-ignore lint/suspicious/noExplicitAny: Generic Record requires any for dynamic keys
|
|
30
|
+
async forceDelete(criteria) {
|
|
31
|
+
return (0, soft_delete_operations_1.forceDelete)(this.repository, criteria);
|
|
32
|
+
}
|
|
33
|
+
async findWithDeleted(options) {
|
|
34
|
+
return (0, soft_delete_operations_1.findWithDeleted)(this.repository, options);
|
|
35
|
+
}
|
|
36
|
+
async findOnlyDeleted(options) {
|
|
37
|
+
return (0, soft_delete_operations_1.findOnlyDeleted)(this.repository, options);
|
|
38
|
+
}
|
|
39
|
+
async count(options) {
|
|
40
|
+
return (0, soft_delete_operations_1.count)(this.repository, options);
|
|
41
|
+
}
|
|
42
|
+
async isSoftDeleted(id) {
|
|
43
|
+
return (0, soft_delete_operations_1.isSoftDeleted)(this.repository, id);
|
|
44
|
+
}
|
|
45
|
+
// Delegate to underlying repository for normal operations
|
|
46
|
+
find(options) {
|
|
47
|
+
return this.repository.find(options);
|
|
48
|
+
}
|
|
49
|
+
findOne(options) {
|
|
50
|
+
return this.repository.findOne(options);
|
|
51
|
+
}
|
|
52
|
+
async save(entityOrEntities) {
|
|
53
|
+
// biome-ignore lint/suspicious/noExplicitAny: TypeORM save overload requires any
|
|
54
|
+
return this.repository.save(entityOrEntities);
|
|
55
|
+
}
|
|
56
|
+
async remove(entityOrEntities) {
|
|
57
|
+
// biome-ignore lint/suspicious/noExplicitAny: TypeORM remove overload requires any
|
|
58
|
+
return this.repository.remove(entityOrEntities);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
exports.SoftDeleteRepository = SoftDeleteRepository;
|
|
62
|
+
/**
|
|
63
|
+
* Factory function to create wrapped repository
|
|
64
|
+
*
|
|
65
|
+
* @param repository - TypeORM repository to wrap
|
|
66
|
+
* @returns Wrapped repository with soft delete methods
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```typescript
|
|
70
|
+
* const userRepo = withSoftDelete(userRepository);
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
function withSoftDelete(repository) {
|
|
74
|
+
return new SoftDeleteRepository(repository);
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=soft-delete-repository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"soft-delete-repository.js","sourceRoot":"","sources":["../src/soft-delete-repository.ts"],"names":[],"mappings":";;;AAoFA,wCAEC;AArFD,qEAAoI;AAGpI;;;;;;;;;;GAUG;AACH,MAAa,oBAAoB;IAC/B,YAA6B,UAAyB;QAAzB,eAAU,GAAV,UAAU,CAAe;IAAG,CAAC;IAE1D,2FAA2F;IAC3F,KAAK,CAAC,UAAU,CAAC,QAAqE,EAAE,OAA2B;QACjH,OAAO,IAAA,mCAAU,EAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IACxD,CAAC;IAED,2FAA2F;IAC3F,KAAK,CAAC,OAAO,CAAC,QAAqE,EAAE,OAAwB;QAC3G,OAAO,IAAA,gCAAO,EAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IACrD,CAAC;IAED,2FAA2F;IAC3F,KAAK,CAAC,WAAW,CAAC,QAAqE;QACrF,OAAO,IAAA,oCAAW,EAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IAChD,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,OAA4B;QAChD,OAAO,IAAA,wCAAe,EAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IACnD,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,OAA4B;QAChD,OAAO,IAAA,wCAAe,EAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IACnD,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,OAAyB;QACnC,OAAO,IAAA,8BAAK,EAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IACzC,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,EAAmB;QACrC,OAAO,IAAA,sCAAa,EAAC,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAC5C,CAAC;IAED,0DAA0D;IAC1D,IAAI,CAAC,OAA4B;QAC/B,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACvC,CAAC;IAED,OAAO,CAAC,OAA0B;QAChC,OAAO,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1C,CAAC;IAID,KAAK,CAAC,IAAI,CAAc,gBAAyB;QAC/C,iFAAiF;QACjF,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,gBAAuB,CAAC,CAAC;IACvD,CAAC;IAID,KAAK,CAAC,MAAM,CAAC,gBAAyB;QACpC,mFAAmF;QACnF,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,gBAAuB,CAAC,CAAC;IACzD,CAAC;CACF;AAxDD,oDAwDC;AAED;;;;;;;;;;GAUG;AACH,SAAgB,cAAc,CAA0B,UAAyB;IAC/E,OAAO,IAAI,oBAAoB,CAAC,UAAU,CAAC,CAAC;AAC9C,CAAC"}
|