@codenameryuu/adonis-lucid-soft-deletes 1.9.0 → 2.0.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/LICENSE.md CHANGED
@@ -1,9 +1,9 @@
1
- # The MIT License
2
-
3
- Copyright (c) 2024 Lookin Anton
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
-
7
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
-
9
- THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1
+ # The MIT License
2
+
3
+ Copyright (c) 2026 Codename Ryuu
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md CHANGED
@@ -1,234 +1,234 @@
1
- # @codenameryuu/adonis-lucid-soft-deletes
2
-
3
- This addon adds the functionality to soft deletes Lucid Models through the `deleted_at` flag in AdonisJS.
4
-
5
- ## Requirement
6
-
7
- - Adonis Js 7
8
- - Lucid 22 or higher
9
-
10
- ## Installation
11
-
12
- - Install the package
13
-
14
- ```bash
15
- yarn add @codenameryuu/adonis-lucid-soft-deletes
16
- ```
17
-
18
- - Configure the package
19
-
20
- ```bash
21
- node ace configure @codenameryuu/adonis-lucid-soft-deletes
22
- ```
23
-
24
- - Make sure to register the provider inside `adonisrc.ts` file.
25
-
26
- ```typescript
27
- providers: [
28
- // ...
29
- () => import('@codenameryuu/adonis-lucid-soft-deletes/provider'),
30
- ],
31
- ```
32
-
33
- You should add the `deleted_at` column to your database tables for models with soft deletes.
34
-
35
- ```typescript
36
- // migrations/1234566666_users.ts
37
- import { BaseSchema } from '@adonisjs/lucid/schema'
38
-
39
- export default class extends BaseSchema {
40
- protected tableName = 'products'
41
-
42
- async up() {
43
- this.schema.createTable(this.tableName, (table) => {
44
- // ...
45
- table.timestamp('deleted_at').nullable()
46
- })
47
- }
48
- // ...
49
- }
50
- ```
51
-
52
- ### Applying Soft Deletes to a Model
53
-
54
- ```typescript
55
- import { compose } from '@adonisjs/core/helpers'
56
- import { SoftDeletes } from '@codenameryuu/adonis-lucid-soft-deletes'
57
-
58
- export default class Product extends compose(BaseModel, SoftDeletes) {
59
- // ...columns and props
60
- }
61
- ```
62
-
63
- Now, when you call the `.delete()` method on the model, the `deleted_at` ( `customDeletedAtColumn` ) column
64
- will be set to the current date and time. However, the model's database record will be left in the table.
65
-
66
- ```typescript
67
- import type { HttpContext } from '@adonisjs/core/http'
68
- import Product from '#models/product'
69
-
70
- export default class ProductsController {
71
- /**
72
- * Delete product by id
73
- * DELETE /products/:id
74
- */
75
- async destroy({ request, response }: HttpContext) {
76
- const product = await Product.findOrFail(request.input('id'))
77
- await product.delete()
78
-
79
- return product // or response.noContent()
80
- }
81
- }
82
- ```
83
-
84
- > :boom: Soft delete only works for model instances. `await Product.query().delete()` as before
85
- > will delete models from database
86
-
87
- :point_right: When querying a model that uses soft deletes, the soft deleted models
88
- will automatically be excluded from all query results.
89
-
90
- To determine if a given model instance has been soft deleted, you may use the `.trashed` getter:
91
-
92
- ```typescript
93
- import type { HttpContext } from '@adonisjs/core/http'
94
- import Product from '#models/product'
95
-
96
- export default class ProductsController {
97
- /**
98
- * Get product by id
99
- * GET /products/:id
100
- */
101
- async show({ request, response }: HttpContext) {
102
- const product = await Product.withTrashed().where('id', request.input('id')).firstOrFail()
103
- if (product.trashed) {
104
- return response.forbidden()
105
- }
106
- return product
107
- }
108
- }
109
- ```
110
-
111
- ### Set custom column name for `deletedAt`
112
-
113
- ```typescript
114
- import { compose } from '@adonisjs/core/helpers'
115
- import { SoftDeletes } from '@codenameryuu/adonis-lucid-soft-deletes'
116
-
117
- export default class Product extends compose(BaseModel, SoftDeletes) {
118
- // ...columns and props
119
-
120
- @column.dateTime({ columnName: 'customDeletedAtColumn' })
121
- declare deletedAt: DateTime | null
122
- }
123
- ```
124
-
125
- ### Restoring Soft Deleted Models
126
-
127
- To restore a soft deleted model, you may call the `.restore()` method on a model instance.
128
- Also, method `.restore()` exists after methods `.withTrashed()` and `.onlyTrashed()`
129
-
130
- The `restore` method will set the model's `deleted_at` column to `null` :
131
-
132
- ```ts
133
- import type { HttpContext } from '@adonisjs/core/http'
134
- import Product from '#models/product'
135
-
136
- export default class TrashProductsController {
137
- /**
138
- * Update trashed product by id
139
- * PUT /trash/products/:id
140
- */
141
- async update({ request }: HttpContext) {
142
- const product = await Product.withTrashed().where('id', request.input('id')).firstOrFail()
143
- await product.restore()
144
-
145
- return product
146
-
147
- // or
148
-
149
- await Product.withTrashed().where('id', request.input('id')).restore()
150
- await Product.query().withTrashed().where('id', request.input('id')).restore()
151
- }
152
- }
153
- ```
154
-
155
- ### Permanently Deleting Models
156
-
157
- Sometimes you may need to truly remove a model from your database.
158
- You may use the `.forceDelete()` method to permanently remove a soft deleted model from the database table:
159
-
160
- ```typescript
161
- import type { HttpContext } from '@adonisjs/core/http'
162
- import Product from '#models/product'
163
-
164
- export default class ProductsController {
165
- /**
166
- * Delete product by id
167
- * DELETE /products/:id
168
- */
169
- async destroy({ request, response }: HttpContext) {
170
- const product = await Product.findOrFail(request.input('id'))
171
- await product.forceDelete()
172
-
173
- return response.noContent()
174
- }
175
- }
176
- ```
177
-
178
- ### Including Soft Deleted Models
179
-
180
- As noted above, soft deleted models will automatically be excluded from query results.
181
- However, you may force soft deleted models to be included in a query's results
182
- by calling the `.withTrashed()` method on the model:
183
-
184
- ```typescript
185
- import type { HttpContext } from '@adonisjs/core/http'
186
- import Product from '#models/product'
187
-
188
- export default class ProductsController {
189
- /**
190
- * Get a list products
191
- * GET /products?withTrashed=1
192
- */
193
- async index({ request }: HttpContext) {
194
- return Product.query()
195
- .if(request.input('withTrashed'), (query) => {
196
- query.withTrashed()
197
- })
198
- .paginate(request.input('page', 1), request.input('perPage', 10))
199
- }
200
- }
201
- ```
202
-
203
- ### Retrieving only Soft Deleted Models
204
-
205
- The `.onlyTrashed()` method will retrieve **only** soft deleted models:
206
-
207
- ```typescript
208
- import type { HttpContext } from '@adonisjs/core/http'
209
- import Product from '#models/product'
210
-
211
- export default class TrashProductsController {
212
- /**
213
- * Get a list trashed products
214
- * GET /trash/products
215
- */
216
- async index({ request }: HttpContext) {
217
- return Product.onlyTrashed().paginate(request.input('page', 1), request.input('perPage', 10))
218
- }
219
- }
220
- ```
221
-
222
- ### Soft Deletes methods
223
-
224
- Methods `.withTrashed()` , `.onlyTrashed()` and `.restore()` also available
225
- in ModelQueryBuilder for models with soft delete, example:
226
-
227
- ```typescript
228
- await Product.query().withTrashed().paginate(request.input('page', 1), request.input('perPage', 10))
229
- await Product.query().onlyTrashed().paginate(request.input('page', 1), request.input('perPage', 10))
230
- ```
231
-
232
- ## License
233
-
234
- This package is open-sourced software licensed under the [MIT license](LICENSE.md).
1
+ # @codenameryuu/adonis-lucid-soft-deletes
2
+
3
+ This addon adds the functionality to soft deletes Lucid Models through the `deleted_at` flag in AdonisJS.
4
+
5
+ ## Requirement
6
+
7
+ * Adonis Js 7
8
+ * Lucid 22 or higher
9
+
10
+ ## Installation
11
+
12
+ * Install the package
13
+
14
+ ```bash
15
+ yarn add @codenameryuu/adonis-lucid-soft-deletes
16
+ ```
17
+
18
+ * Configure the package
19
+
20
+ ```bash
21
+ node ace configure @codenameryuu/adonis-lucid-soft-deletes
22
+ ```
23
+
24
+ * Make sure to register the provider inside `adonisrc.ts` file.
25
+
26
+ ```typescript
27
+ providers: [
28
+ // ...
29
+ () => import('@codenameryuu/adonis-lucid-soft-deletes/provider'),
30
+ ],
31
+ ```
32
+
33
+ You should add the `deleted_at` column to your database tables for models with soft deletes.
34
+
35
+ ```typescript
36
+ // migrations/1234566666_users.ts
37
+ import { BaseSchema } from '@adonisjs/lucid/schema'
38
+
39
+ export default class extends BaseSchema {
40
+ protected tableName = 'products'
41
+
42
+ async up() {
43
+ this.schema.createTable(this.tableName, (table) => {
44
+ // ...
45
+ table.timestamp('deleted_at').nullable()
46
+ })
47
+ }
48
+ // ...
49
+ }
50
+ ```
51
+
52
+ ### Applying Soft Deletes to a Model
53
+
54
+ ```typescript
55
+ import { compose } from '@adonisjs/core/helpers'
56
+ import { SoftDeletes } from '@codenameryuu/adonis-lucid-soft-deletes'
57
+
58
+ export default class Product extends compose(BaseModel, SoftDeletes) {
59
+ // ...columns and props
60
+ }
61
+ ```
62
+
63
+ Now, when you call the `.delete()` method on the model, the `deleted_at` ( `customDeletedAtColumn` ) column
64
+ will be set to the current date and time. However, the model's database record will be left in the table.
65
+
66
+ ```typescript
67
+ import type { HttpContext } from '@adonisjs/core/http'
68
+ import Product from '#models/product'
69
+
70
+ export default class ProductsController {
71
+ /**
72
+ * Delete product by id
73
+ * DELETE /products/:id
74
+ */
75
+ async destroy({ request, response }: HttpContext) {
76
+ const product = await Product.findOrFail(request.input('id'))
77
+ await product.delete()
78
+
79
+ return product // or response.noContent()
80
+ }
81
+ }
82
+ ```
83
+
84
+ > :boom: Soft delete only works for model instances. `await Product.query().delete()` as before
85
+ > will delete models from database
86
+
87
+ :point_right: When querying a model that uses soft deletes, the soft deleted models
88
+ will automatically be excluded from all query results.
89
+
90
+ To determine if a given model instance has been soft deleted, you may use the `.trashed` getter:
91
+
92
+ ```typescript
93
+ import type { HttpContext } from '@adonisjs/core/http'
94
+ import Product from '#models/product'
95
+
96
+ export default class ProductsController {
97
+ /**
98
+ * Get product by id
99
+ * GET /products/:id
100
+ */
101
+ async show({ request, response }: HttpContext) {
102
+ const product = await Product.withTrashed().where('id', request.input('id')).firstOrFail()
103
+ if (product.trashed) {
104
+ return response.forbidden()
105
+ }
106
+ return product
107
+ }
108
+ }
109
+ ```
110
+
111
+ ### Set custom column name for `deletedAt`
112
+
113
+ ```typescript
114
+ import { compose } from '@adonisjs/core/helpers'
115
+ import { SoftDeletes } from '@codenameryuu/adonis-lucid-soft-deletes'
116
+
117
+ export default class Product extends compose(BaseModel, SoftDeletes) {
118
+ // ...columns and props
119
+
120
+ @column.dateTime({ columnName: 'customDeletedAtColumn' })
121
+ declare deletedAt: DateTime | null
122
+ }
123
+ ```
124
+
125
+ ### Restoring Soft Deleted Models
126
+
127
+ To restore a soft deleted model, you may call the `.restore()` method on a model instance.
128
+ Also, method `.restore()` exists after methods `.withTrashed()` and `.onlyTrashed()`
129
+
130
+ The `restore` method will set the model's `deleted_at` column to `null` :
131
+
132
+ ```ts
133
+ import type { HttpContext } from '@adonisjs/core/http'
134
+ import Product from '#models/product'
135
+
136
+ export default class TrashProductsController {
137
+ /**
138
+ * Update trashed product by id
139
+ * PUT /trash/products/:id
140
+ */
141
+ async update({ request }: HttpContext) {
142
+ const product = await Product.withTrashed().where('id', request.input('id')).firstOrFail()
143
+ await product.restore()
144
+
145
+ return product
146
+
147
+ // or
148
+
149
+ await Product.withTrashed().where('id', request.input('id')).restore()
150
+ await Product.query().withTrashed().where('id', request.input('id')).restore()
151
+ }
152
+ }
153
+ ```
154
+
155
+ ### Permanently Deleting Models
156
+
157
+ Sometimes you may need to truly remove a model from your database.
158
+ You may use the `.forceDelete()` method to permanently remove a soft deleted model from the database table:
159
+
160
+ ```typescript
161
+ import type { HttpContext } from '@adonisjs/core/http'
162
+ import Product from '#models/product'
163
+
164
+ export default class ProductsController {
165
+ /**
166
+ * Delete product by id
167
+ * DELETE /products/:id
168
+ */
169
+ async destroy({ request, response }: HttpContext) {
170
+ const product = await Product.findOrFail(request.input('id'))
171
+ await product.forceDelete()
172
+
173
+ return response.noContent()
174
+ }
175
+ }
176
+ ```
177
+
178
+ ### Including Soft Deleted Models
179
+
180
+ As noted above, soft deleted models will automatically be excluded from query results.
181
+ However, you may force soft deleted models to be included in a query's results
182
+ by calling the `.withTrashed()` method on the model:
183
+
184
+ ```typescript
185
+ import type { HttpContext } from '@adonisjs/core/http'
186
+ import Product from '#models/product'
187
+
188
+ export default class ProductsController {
189
+ /**
190
+ * Get a list products
191
+ * GET /products?withTrashed=1
192
+ */
193
+ async index({ request }: HttpContext) {
194
+ return Product.query()
195
+ .if(request.input('withTrashed'), (query) => {
196
+ query.withTrashed()
197
+ })
198
+ .paginate(request.input('page', 1), request.input('perPage', 10))
199
+ }
200
+ }
201
+ ```
202
+
203
+ ### Retrieving only Soft Deleted Models
204
+
205
+ The `.onlyTrashed()` method will retrieve **only** soft deleted models:
206
+
207
+ ```typescript
208
+ import type { HttpContext } from '@adonisjs/core/http'
209
+ import Product from '#models/product'
210
+
211
+ export default class TrashProductsController {
212
+ /**
213
+ * Get a list trashed products
214
+ * GET /trash/products
215
+ */
216
+ async index({ request }: HttpContext) {
217
+ return Product.onlyTrashed().paginate(request.input('page', 1), request.input('perPage', 10))
218
+ }
219
+ }
220
+ ```
221
+
222
+ ### Soft Deletes methods
223
+
224
+ Methods `.withTrashed()` , `.onlyTrashed()` and `.restore()` also available
225
+ in ModelQueryBuilder for models with soft delete, example:
226
+
227
+ ```typescript
228
+ await Product.query().withTrashed().paginate(request.input('page', 1), request.input('perPage', 10))
229
+ await Product.query().onlyTrashed().paginate(request.input('page', 1), request.input('perPage', 10))
230
+ ```
231
+
232
+ ## License
233
+
234
+ This package is open-sourced software licensed under the [MIT license](LICENSE.md).
@@ -1,2 +1,2 @@
1
- import type Configure from '@adonisjs/core/commands/configure';
1
+ import type Configure from "@adonisjs/core/commands/configure";
2
2
  export declare function configure(command: Configure): Promise<void>;
@@ -1,14 +1,6 @@
1
- /*
2
- * adonis-lucid-soft-deletes
3
- *
4
- * (c) Lookin Anton <alsd@lookinlab.ru>
5
- *
6
- * For the full copyright and license information, please view the LICENSE
7
- * file that was distributed with this source code.
8
- */
9
1
  export async function configure(command) {
10
2
  const codemods = await command.createCodemods();
11
3
  await codemods.updateRcFile((rcFile) => {
12
- rcFile.addProvider('@codenameryuu/adonis-lucid-soft-deletes/provider');
4
+ rcFile.addProvider("@codenameryuu/adonis-lucid-soft-deletes/provider");
13
5
  });
14
6
  }
package/build/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export { configure } from './configure.js';
2
- export { SoftDeletes } from './src/mixin.js';
1
+ export { configure } from "./configure.js";
2
+ export { SoftDeletes } from "./src/mixin.js";
package/build/index.js CHANGED
@@ -1,10 +1,2 @@
1
- /*
2
- * adonis-lucid-soft-deletes
3
- *
4
- * (c) Lookin Anton <alsd@lookinlab.ru>
5
- *
6
- * For the full copyright and license information, please view the LICENSE
7
- * file that was distributed with this source code.
8
- */
9
- export { configure } from './configure.js';
10
- export { SoftDeletes } from './src/mixin.js';
1
+ export { configure } from "./configure.js";
2
+ export { SoftDeletes } from "./src/mixin.js";
@@ -1,4 +1,4 @@
1
- import type { ApplicationService } from '@adonisjs/core/types';
1
+ import type { ApplicationService } from "@adonisjs/core/types";
2
2
  export default class LucidSoftDeletesProvider {
3
3
  protected app: ApplicationService;
4
4
  constructor(app: ApplicationService);
@@ -1,19 +1,12 @@
1
- /*
2
- * adonis-lucid-soft-deletes
3
- *
4
- * (c) Lookin Anton <alsd@lookinlab.ru>
5
- *
6
- * For the full copyright and license information, please view the LICENSE
7
- * file that was distributed with this source code.
8
- */
9
- import { extendModelQueryBuilder } from '../src/bindings/model_query_builder.js';
1
+ /// <reference path="../src/types/querybuilder.ts" />
2
+ import { extendModelQueryBuilder } from "../src/bindings/model_query_builder.js";
10
3
  export default class LucidSoftDeletesProvider {
11
4
  app;
12
5
  constructor(app) {
13
6
  this.app = app;
14
7
  }
15
8
  async boot() {
16
- const { ModelQueryBuilder } = await this.app.import('@adonisjs/lucid/orm');
9
+ const { ModelQueryBuilder } = await this.app.import("@adonisjs/lucid/orm");
17
10
  extendModelQueryBuilder(ModelQueryBuilder);
18
11
  }
19
12
  }
@@ -1,19 +1,11 @@
1
- /*
2
- * adonis-lucid-soft-deletes
3
- *
4
- * (c) Lookin Anton <alsd@lookinlab.ru>
5
- *
6
- * For the full copyright and license information, please view the LICENSE
7
- * file that was distributed with this source code.
8
- */
9
- import { Exception } from '@adonisjs/core/exceptions';
1
+ import { Exception } from "@adonisjs/core/exceptions";
10
2
  /**
11
3
  * Raises exception when model not with soft delete
12
4
  */
13
5
  function ensureModelWithSoftDeletes(model) {
14
- if (!('ignoreDeleted' in model && 'ignoreDeletedPaginate' in model)) {
6
+ if (!("ignoreDeleted" in model && "ignoreDeletedPaginate" in model)) {
15
7
  throw new Exception(`${model.name} model don't support Soft Deletes`, {
16
- code: 'E_MODEL_SOFT_DELETE',
8
+ code: "E_MODEL_SOFT_DELETE",
17
9
  status: 500,
18
10
  });
19
11
  }
@@ -22,20 +14,20 @@ function ensureModelWithSoftDeletes(model) {
22
14
  * Define SoftDeletes binding to ModelQueryBuilder
23
15
  */
24
16
  export function extendModelQueryBuilder(builder) {
25
- builder.macro('restore', async function () {
17
+ builder.macro("restore", async function () {
26
18
  ensureModelWithSoftDeletes(this.model);
27
- const deletedAtColumn = this.model.$getColumn('deletedAt')?.columnName;
19
+ const deletedAtColumn = this.model.$getColumn("deletedAt")?.columnName;
28
20
  if (!deletedAtColumn)
29
21
  return;
30
22
  await this.update({ [deletedAtColumn]: null });
31
23
  });
32
- builder.macro('withTrashed', function () {
24
+ builder.macro("withTrashed", function () {
33
25
  ensureModelWithSoftDeletes(this.model);
34
26
  return this.model.disableIgnore(this);
35
27
  });
36
- builder.macro('onlyTrashed', function () {
28
+ builder.macro("onlyTrashed", function () {
37
29
  ensureModelWithSoftDeletes(this.model);
38
- const deletedAtColumn = this.model.$getColumn('deletedAt')?.columnName;
30
+ const deletedAtColumn = this.model.$getColumn("deletedAt")?.columnName;
39
31
  return this.model.disableIgnore(this).whereNotNull(`${this.model.table}.${deletedAtColumn}`);
40
32
  });
41
33
  }
@@ -1,10 +1,10 @@
1
- import { DateTime } from 'luxon';
2
- import type { NormalizeConstructor } from '@adonisjs/core/types/helpers';
3
- import type { LucidModel, ModelQueryBuilderContract } from '@adonisjs/lucid/types/model';
4
- import type { QueryClientContract } from '@adonisjs/lucid/types/database';
5
- import { BaseModel } from '@adonisjs/lucid/orm';
1
+ import { DateTime } from "luxon";
2
+ import type { NormalizeConstructor } from "@adonisjs/core/types/helpers";
3
+ import type { LucidModel, ModelQueryBuilderContract } from "@adonisjs/lucid/types/model";
4
+ import type { QueryClientContract } from "@adonisjs/lucid/types/database";
5
+ import { BaseModel } from "@adonisjs/lucid/orm";
6
6
  type ModelQueryBuilderContractWithIgnoreDeleted<T extends LucidModel, R = InstanceType<T>> = ModelQueryBuilderContract<T, R> & {
7
- ignoreDeleted?: boolean;
7
+ ignoreDeleted: boolean;
8
8
  };
9
9
  export declare function SoftDeletes<T extends NormalizeConstructor<typeof BaseModel>>(superclass: T): {
10
10
  new (...args: any[]): {
@@ -91,9 +91,8 @@ export declare function SoftDeletes<T extends NormalizeConstructor<typeof BaseMo
91
91
  toAttributes(): Record<string, any>;
92
92
  related<Name extends undefined>(relation: Name): NonNullable</*elided*/ any[Name]> extends import("@adonisjs/lucid/types/relations").ModelRelations<LucidModel, LucidModel> ? (import("@adonisjs/lucid/types/relations").ModelRelations<LucidModel, LucidModel> & /*elided*/ any[Name] & {})["client"] : never;
93
93
  };
94
- boot(): void;
95
94
  ignoreDeleted<Model extends /*elided*/ any & T>(query: ModelQueryBuilderContractWithIgnoreDeleted<Model, InstanceType<Model>>): void;
96
- ignoreDeletedPaginate([countQuery, query]: any): void;
95
+ ignoreDeletedPaginate<Model extends /*elided*/ any & T>([countQuery, query]: [ModelQueryBuilderContractWithIgnoreDeleted<Model, InstanceType<Model>>, ModelQueryBuilderContractWithIgnoreDeleted<Model, InstanceType<Model>>]): void;
97
96
  disableIgnore<Model extends /*elided*/ any & T, Result = InstanceType<Model>>(this: Model, query: ModelQueryBuilderContractWithIgnoreDeleted<Model, Result>): ModelQueryBuilderContractWithIgnoreDeleted<Model, Result>;
98
97
  /**
99
98
  * Fetch all models without filter by deleted_at
@@ -141,6 +140,7 @@ export declare function SoftDeletes<T extends NormalizeConstructor<typeof BaseMo
141
140
  <Model extends LucidModel>(this: Model, name: string): import("@adonisjs/lucid/types/relations").RelationshipsContract;
142
141
  };
143
142
  $defineProperty: <Model extends LucidModel, Prop extends keyof Model>(this: Model, propertyName: Prop, defaultValue: Model[Prop], strategy: "inherit" | "define" | ((value: Model[Prop]) => Model[Prop])) => void;
143
+ boot: () => void;
144
144
  before: {
145
145
  <Model extends LucidModel, Event extends "find" | "fetch">(this: Model, event: Event, handler: import("@adonisjs/lucid/types/model").HooksHandler<ModelQueryBuilderContract<Model>, Event>): void;
146
146
  <Model extends LucidModel>(this: Model, event: "paginate", handler: import("@adonisjs/lucid/types/model").HooksHandler<[ModelQueryBuilderContract<Model>, ModelQueryBuilderContract<Model>], "paginate">): void;
@@ -1,60 +1,32 @@
1
- /*
2
- * adonis-lucid-soft-deletes
3
- *
4
- * (c) Lookin Anton <alsd@lookinlab.ru>
5
- *
6
- * For the full copyright and license information, please view the LICENSE
7
- * file that was distributed with this source code.
8
- */
9
1
  var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
10
2
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
11
3
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
12
4
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
13
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
14
6
  };
15
- import { DateTime } from 'luxon';
16
- import { Exception } from '@adonisjs/core/exceptions';
17
- import { column } from '@adonisjs/lucid/orm';
7
+ import { DateTime } from "luxon";
8
+ import { Exception } from "@adonisjs/core/exceptions";
9
+ import { column, beforeFind, beforeFetch, beforePaginate } from "@adonisjs/lucid/orm";
18
10
  export function SoftDeletes(superclass) {
19
11
  class ModelWithSoftDeletes extends superclass {
20
- static boot() {
21
- super.boot();
22
- // `compose()` introduces intermediate classes. Depending on how Lucid handles
23
- // boot flags, hooks can be skipped when mixing multiple mixins.
24
- // Track hook registration per subclass.
25
- if (this.$softDeletesHooksRegistered)
26
- return;
27
- this.$softDeletesHooksRegistered = true;
28
- this.before('find', this.ignoreDeleted.bind(this));
29
- this.before('fetch', this.ignoreDeleted.bind(this));
30
- this.before('paginate', this.ignoreDeletedPaginate.bind(this));
31
- }
32
12
  static ignoreDeleted(query) {
33
- if (query['ignoreDeleted'] === false) {
34
- return;
35
- }
36
- const isGroupLimitQuery = query.clone().toQuery().includes('adonis_group_limit_counter');
37
- const deletedAtColumn = query.model.$getColumn('deletedAt')?.columnName;
38
- if (!deletedAtColumn) {
13
+ if (query["ignoreDeleted"] === false) {
39
14
  return;
40
15
  }
41
- const queryIgnoreDeleted = isGroupLimitQuery ? query.knexQuery : query;
42
- /**
43
- * Do not prefix with `${model.table}.` since preload/group-limit queries
44
- * may use table aliases.
45
- */
46
- queryIgnoreDeleted.whereNull(deletedAtColumn);
16
+ const isGroupLimitQuery = query.clone().toQuery().includes("adonis_group_limit_counter");
17
+ const deletedAtColumn = query.model.$getColumn("deletedAt")?.columnName;
18
+ const queryIgnoreDeleted = isGroupLimitQuery ? query.knexQuery["_single"].table : query;
19
+ queryIgnoreDeleted.whereNull(`${query.model.table}.${deletedAtColumn}`);
47
20
  }
48
21
  static ignoreDeletedPaginate([countQuery, query]) {
49
- ;
50
- countQuery['ignoreDeleted'] = query['ignoreDeleted'];
22
+ countQuery["ignoreDeleted"] = query["ignoreDeleted"];
51
23
  this.ignoreDeleted(countQuery);
52
24
  }
53
25
  static disableIgnore(query) {
54
- if (query['ignoreDeleted'] === false) {
26
+ if (query["ignoreDeleted"] === false) {
55
27
  return query;
56
28
  }
57
- query['ignoreDeleted'] = false;
29
+ query["ignoreDeleted"] = false;
58
30
  return query;
59
31
  }
60
32
  /**
@@ -69,7 +41,7 @@ export function SoftDeletes(superclass) {
69
41
  */
70
42
  static onlyTrashed() {
71
43
  const query = this.query();
72
- const deletedAtColumn = query.model.$getColumn('deletedAt')?.columnName;
44
+ const deletedAtColumn = query.model.$getColumn("deletedAt")?.columnName;
73
45
  return this.disableIgnore(query).whereNotNull(`${query.model.table}.${deletedAtColumn}`);
74
46
  }
75
47
  /**
@@ -93,10 +65,10 @@ export function SoftDeletes(superclass) {
93
65
  this.deletedAt = DateTime.local();
94
66
  await this.save();
95
67
  };
96
- if (action === 'delete' && !this.$forceDelete) {
68
+ if (action === "delete" && !this.$forceDelete) {
97
69
  return { del: softDelete, delete: softDelete };
98
70
  }
99
- if (action === 'insert') {
71
+ if (action === "insert") {
100
72
  return super.$getQueryFor(action, client);
101
73
  }
102
74
  return super.$getQueryFor(action, client);
@@ -113,8 +85,8 @@ export function SoftDeletes(superclass) {
113
85
  */
114
86
  async restore() {
115
87
  if (this.$isDeleted) {
116
- throw new Exception('Cannot restore a model instance is was force deleted', {
117
- code: 'E_MODEL_FORCE_DELETED',
88
+ throw new Exception("Cannot restore a model instance is was force deleted", {
89
+ code: "E_MODEL_FORCE_DELETED",
118
90
  status: 500,
119
91
  });
120
92
  }
@@ -136,5 +108,12 @@ export function SoftDeletes(superclass) {
136
108
  __decorate([
137
109
  column.dateTime()
138
110
  ], ModelWithSoftDeletes.prototype, "deletedAt", void 0);
111
+ __decorate([
112
+ beforeFind(),
113
+ beforeFetch()
114
+ ], ModelWithSoftDeletes, "ignoreDeleted", null);
115
+ __decorate([
116
+ beforePaginate()
117
+ ], ModelWithSoftDeletes, "ignoreDeletedPaginate", null);
139
118
  return ModelWithSoftDeletes;
140
119
  }
@@ -1,4 +1,4 @@
1
- declare module '@adonisjs/lucid/types/model' {
1
+ declare module "@adonisjs/lucid/types/model" {
2
2
  type ModelWithSoftDeletes = LucidModel & {
3
3
  ignoreDeleted(query: any): void;
4
4
  ignoreDeletedPaginate([countQuery, query]: [any, any]): void;
@@ -1,9 +1 @@
1
- /*
2
- * adonis-lucid-soft-deletes
3
- *
4
- * (c) Lookin Anton <alsd@lookinlab.ru>
5
- *
6
- * For the full copyright and license information, please view the LICENSE
7
- * file that was distributed with this source code.
8
- */
9
1
  export {};
package/package.json CHANGED
@@ -1,108 +1,104 @@
1
- {
2
- "name": "@codenameryuu/adonis-lucid-soft-deletes",
3
- "description": "Addon for soft deletes Adonis JS with Lucid ORM",
4
- "version": "1.9.0",
5
- "author": "codenameryuu",
6
- "license": "MIT",
7
- "homepage": "https://github.com/codenameryuu/adonis-lucid-soft-deletes#readme",
8
- "repository": {
9
- "type": "git",
10
- "url": "git+https://github.com/codenameryuu/adonis-lucid-soft-deletes.git"
11
- },
12
- "engines": {
13
- "node": ">=24.0.0"
14
- },
15
- "type": "module",
16
- "files": [
17
- "build",
18
- "!build/bin",
19
- "!build/tests"
20
- ],
21
- "exports": {
22
- ".": "./build/index.js",
23
- "./types/*": "./build/src/types/*.js",
24
- "./bindings": "./build/src/bindings/model_query_builder.js",
25
- "./provider": "./build/providers/lucid_soft_deletes_provider.js"
26
- },
27
- "scripts": {
28
- "lint": "eslint .",
29
- "format": "prettier --write .",
30
- "clean": "del-cli build",
31
- "precompile": "npm run lint && npm run clean",
32
- "compile": "tsc",
33
- "build": "npm run compile",
34
- "quick:test": "NODE_DEBUG=\"adonis-lucid-soft-deletes\" node --enable-source-maps --loader=ts-node/esm bin/test.ts",
35
- "pretest": "npm run lint",
36
- "test": "c8 npm run quick:test",
37
- "typecheck": "tsc --noEmit",
38
- "version": "npm run build",
39
- "prepublishOnly": "npm run build",
40
- "release": "np"
41
- },
42
- "devDependencies": {
43
- "@adonisjs/assembler": "^7.7.0",
44
- "@adonisjs/core": "^7.0.0",
45
- "@adonisjs/eslint-config": "^3.0.0",
46
- "@adonisjs/lucid": "^22.0.0",
47
- "@adonisjs/prettier-config": "^1.4.5",
48
- "@adonisjs/tsconfig": "^2.0.0",
49
- "@japa/assert": "^4.2.0",
50
- "@japa/expect-type": "^2.0.4",
51
- "@japa/file-system": "^3.0.0",
52
- "@japa/runner": "^5.3.0",
53
- "@japa/snapshot": "^2.0.5",
54
- "@swc/core": "^1.6.7",
55
- "@types/lodash": "^4.17.6",
56
- "@types/luxon": "^3.4.2",
57
- "@types/node": "^25.5.0",
58
- "c8": "^9.1.0",
59
- "copyfiles": "^2.4.1",
60
- "del-cli": "^5.1.0",
61
- "eslint": "^10.0.2",
62
- "knex": "^3.1.0",
63
- "lodash": "^4.17.23",
64
- "luxon": "^3.4.4",
65
- "np": "^11.0.2",
66
- "prettier": "^3.8.1",
67
- "reflect-metadata": "^0.2.2",
68
- "ts-node": "^10.9.2",
69
- "tsup": "^8.1.0",
70
- "typescript": "^5.5.3",
71
- "youch": "^4.1.0"
72
- },
73
- "peerDependencies": {
74
- "@adonisjs/core": "^7.0.0",
75
- "@adonisjs/lucid": "^22.0.0"
76
- },
77
- "keywords": [
78
- "adonisjs",
79
- "adonisjs-lucid",
80
- "adonisjs-lucid-soft-deletes",
81
- "adonisjs-soft-deletes",
82
- "adonis",
83
- "adonis-lucid",
84
- "adonis-lucid-soft-deletes",
85
- "adonis-soft-deletes"
86
- ],
87
- "publishConfig": {
88
- "access": "public",
89
- "tag": "latest"
90
- },
91
- "prettier": "@adonisjs/prettier-config",
92
- "np": {
93
- "message": "chore(release): %s",
94
- "tag": "latest",
95
- "branch": "main",
96
- "anyBranch": false
97
- },
98
- "c8": {
99
- "reporter": [
100
- "text",
101
- "html"
102
- ],
103
- "exclude": [
104
- "tests/**",
105
- "bin/**"
106
- ]
107
- }
108
- }
1
+ {
2
+ "name": "@codenameryuu/adonis-lucid-soft-deletes",
3
+ "description": "Addon for soft deletes Adonis JS with Lucid ORM",
4
+ "version": "2.0.1",
5
+ "author": "codenameryuu",
6
+ "license": "MIT",
7
+ "homepage": "https://github.com/codenameryuu/adonis-lucid-soft-deletes#readme",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/codenameryuu/adonis-lucid-soft-deletes.git"
11
+ },
12
+ "engines": {
13
+ "node": ">=24.0.0"
14
+ },
15
+ "type": "module",
16
+ "files": [
17
+ "build",
18
+ "!build/bin",
19
+ "!build/tests"
20
+ ],
21
+ "exports": {
22
+ ".": "./build/index.js",
23
+ "./types/*": "./build/src/types/*.js",
24
+ "./bindings": "./build/src/bindings/model_query_builder.js",
25
+ "./provider": "./build/providers/lucid_soft_deletes_provider.js"
26
+ },
27
+ "scripts": {
28
+ "format": "prettier --write .",
29
+ "clean": "del-cli build",
30
+ "precompile": "npm run clean",
31
+ "compile": "tsc",
32
+ "build": "npm run compile",
33
+ "quick:test": "NODE_DEBUG=\"adonis-lucid-soft-deletes\" node --enable-source-maps --loader=ts-node/esm bin/test.ts",
34
+ "test": "c8 npm run quick:test",
35
+ "typecheck": "tsc --noEmit",
36
+ "version": "npm run build",
37
+ "prepublishOnly": "npm run build",
38
+ "release": "np"
39
+ },
40
+ "devDependencies": {
41
+ "@adonisjs/assembler": "^7.7.0",
42
+ "@adonisjs/core": "^7.0.0",
43
+ "@adonisjs/lucid": "^22.0.0",
44
+ "@adonisjs/prettier-config": "^1.4.5",
45
+ "@adonisjs/tsconfig": "^2.0.0",
46
+ "@japa/assert": "^4.2.0",
47
+ "@japa/expect-type": "^2.0.4",
48
+ "@japa/file-system": "^3.0.0",
49
+ "@japa/runner": "^5.3.0",
50
+ "@japa/snapshot": "^2.0.5",
51
+ "@swc/core": "^1.6.7",
52
+ "@types/lodash": "^4.17.6",
53
+ "@types/luxon": "^3.4.2",
54
+ "@types/node": "^25.5.0",
55
+ "c8": "^9.1.0",
56
+ "copyfiles": "^2.4.1",
57
+ "del-cli": "^5.1.0",
58
+ "knex": "^3.1.0",
59
+ "lodash": "^4.17.23",
60
+ "luxon": "^3.4.4",
61
+ "np": "^11.0.2",
62
+ "prettier": "^3.8.1",
63
+ "reflect-metadata": "^0.2.2",
64
+ "ts-node": "^10.9.2",
65
+ "tsup": "^8.1.0",
66
+ "typescript": "^5.5.3",
67
+ "youch": "^4.1.0"
68
+ },
69
+ "peerDependencies": {
70
+ "@adonisjs/core": "^7.0.0",
71
+ "@adonisjs/lucid": "^22.0.0"
72
+ },
73
+ "keywords": [
74
+ "adonisjs",
75
+ "adonisjs-lucid",
76
+ "adonisjs-lucid-soft-deletes",
77
+ "adonisjs-soft-deletes",
78
+ "adonis",
79
+ "adonis-lucid",
80
+ "adonis-lucid-soft-deletes",
81
+ "adonis-soft-deletes"
82
+ ],
83
+ "publishConfig": {
84
+ "access": "public",
85
+ "tag": "latest"
86
+ },
87
+ "prettier": "@adonisjs/prettier-config",
88
+ "np": {
89
+ "message": "chore(release): %s",
90
+ "tag": "latest",
91
+ "branch": "main",
92
+ "anyBranch": false
93
+ },
94
+ "c8": {
95
+ "reporter": [
96
+ "text",
97
+ "html"
98
+ ],
99
+ "exclude": [
100
+ "tests/**",
101
+ "bin/**"
102
+ ]
103
+ }
104
+ }