@codenameryuu/adonis-lucid-filter 2.9.0 → 3.1.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 +64 -126
- package/build/commands/commands.json +1 -0
- package/build/commands/main.d.ts +4 -0
- package/build/commands/main.js +36 -0
- package/build/make/filter/main.stub +20 -0
- package/package.json +17 -8
- package/build/commands/make_filter.js +0 -32
- package/build/configure.js +0 -15
- package/build/index.js +0 -12
- package/build/providers/lucid_filter_provider.js +0 -19
- package/build/src/base_model.js +0 -93
- package/build/src/bindings/model_query_builder.js +0 -17
- package/build/src/mixin.js +0 -27
- package/build/src/types/filter.js +0 -9
- package/build/src/types/querybuilder.js +0 -9
- package/build/stubs/main.js +0 -11
package/README.md
CHANGED
|
@@ -2,60 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
This addon adds the functionality to filter Lucid Models Adonis JS 7. Inspired by [EloquentFilter](https://github.com/Tucker-Eric/EloquentFilter)
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Requirement
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
`/users?name=Tony&lastName=&companyId=2&industry=5`
|
|
10
|
-
|
|
11
|
-
`request.all()` or `request.qs()` will return:
|
|
12
|
-
|
|
13
|
-
```json
|
|
14
|
-
{
|
|
15
|
-
"name": "Tony",
|
|
16
|
-
"lastName": "",
|
|
17
|
-
"companyId": 2,
|
|
18
|
-
"industry": 5
|
|
19
|
-
}
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
To filter by all those parameters we would need to do something like:
|
|
23
|
-
|
|
24
|
-
```typescript
|
|
25
|
-
import type { HttpContext } from '@adonisjs/core/http'
|
|
26
|
-
import User from '#models/user'
|
|
27
|
-
|
|
28
|
-
export default class UsersController {
|
|
29
|
-
async index({ request }: HttpContext): Promise<User[]> {
|
|
30
|
-
const { companyId, lastName, name, industry } = request.qs()
|
|
31
|
-
|
|
32
|
-
const query = User.query().where('company_id', +companyId)
|
|
33
|
-
|
|
34
|
-
if (lastName) {
|
|
35
|
-
query.where('last_name', 'LIKE', `%${lastName}%`)
|
|
36
|
-
}
|
|
37
|
-
if (name) {
|
|
38
|
-
query.where(function () {
|
|
39
|
-
this.where('first_name', 'LIKE', `%${name}%`).orWhere('last_name', 'LIKE', `%${name}%`)
|
|
40
|
-
})
|
|
41
|
-
}
|
|
42
|
-
return query.exec()
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
To filter that same input with Lucid Filters:
|
|
48
|
-
|
|
49
|
-
```typescript
|
|
50
|
-
import type { HttpContext } from '@adonisjs/core/http'
|
|
51
|
-
import User from '#models/user'
|
|
52
|
-
|
|
53
|
-
export default class UsersController {
|
|
54
|
-
async index({ request }: HttpContext): Promise<User[]> {
|
|
55
|
-
return User.filter(request.qs()).exec()
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
```
|
|
7
|
+
- Adonis Js 7
|
|
8
|
+
- Lucid 22 or higher
|
|
59
9
|
|
|
60
10
|
## Installation
|
|
61
11
|
|
|
@@ -71,9 +21,7 @@ yarn add @codenameryuu/adonis-lucid-filter
|
|
|
71
21
|
node ace configure @codenameryuu/adonis-lucid-filter
|
|
72
22
|
```
|
|
73
23
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
- Register the provider and commands inside `adonisrc.ts` file.
|
|
24
|
+
- Make sure to register the provider inside `adonisrc.ts` file.
|
|
77
25
|
|
|
78
26
|
```typescript
|
|
79
27
|
providers: [
|
|
@@ -86,17 +34,15 @@ commands: [
|
|
|
86
34
|
]
|
|
87
35
|
```
|
|
88
36
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
> Only available if you have added `@codenameryuu/adonis-lucid-filter/commands` in `commands` array in your `adonisrc.ts'
|
|
37
|
+
## Usage
|
|
92
38
|
|
|
93
39
|
You can create a model filter with the following ace command:
|
|
94
40
|
|
|
95
41
|
```bash
|
|
96
|
-
node ace make:filter
|
|
42
|
+
node ace make:filter product
|
|
97
43
|
```
|
|
98
44
|
|
|
99
|
-
Where `
|
|
45
|
+
Where `product` is the Lucid Model you are creating the filter for. This will create `app/models/filters/product_filter.ts`
|
|
100
46
|
|
|
101
47
|
### Defining The Filter Logic
|
|
102
48
|
|
|
@@ -104,7 +50,7 @@ Define the filter logic based on the camel cased input key passed to the `filter
|
|
|
104
50
|
|
|
105
51
|
- Empty strings are ignored
|
|
106
52
|
- `setup()` will be called regardless of input
|
|
107
|
-
- `_id` is dropped from the end of the input to define the method so filtering `
|
|
53
|
+
- `_id` is dropped from the end of the input to define the method so filtering `product_id` would use the `product()` method
|
|
108
54
|
- Input without a corresponding filter method are ignored
|
|
109
55
|
- The value of the key is injected into the method
|
|
110
56
|
- All values are accessible through the `this.$input` a property
|
|
@@ -114,37 +60,45 @@ To define methods for the following input:
|
|
|
114
60
|
|
|
115
61
|
```json
|
|
116
62
|
{
|
|
117
|
-
"
|
|
118
|
-
"name": "
|
|
119
|
-
"
|
|
63
|
+
"productCategoryId": 1,
|
|
64
|
+
"name": "Car",
|
|
65
|
+
"price": 100000
|
|
120
66
|
}
|
|
121
67
|
```
|
|
122
68
|
|
|
123
69
|
You would use the following methods:
|
|
124
70
|
|
|
125
71
|
```typescript
|
|
126
|
-
import { BaseModelFilter } from 'adonis-lucid-filter'
|
|
72
|
+
import { BaseModelFilter } from '@codenameryuu/adonis-lucid-filter'
|
|
127
73
|
import type { ModelQueryBuilderContract } from '@adonisjs/lucid/types/model'
|
|
128
|
-
import
|
|
74
|
+
import Product from '#models/product'
|
|
129
75
|
|
|
130
|
-
export default class
|
|
131
|
-
declare $query: ModelQueryBuilderContract<typeof
|
|
76
|
+
export default class ProductFilter extends BaseModelFilter {
|
|
77
|
+
declare $query: ModelQueryBuilderContract<typeof Product>
|
|
132
78
|
|
|
79
|
+
// Blacklisted methods
|
|
133
80
|
static blacklist: string[] = ['secretMethod']
|
|
134
81
|
|
|
135
|
-
//
|
|
136
|
-
company(
|
|
137
|
-
|
|
82
|
+
// Dropped `_id` from the end of the input
|
|
83
|
+
// Doing this would allow you to have a `company()` filter method as well as a `companyId()` filter method.
|
|
84
|
+
static dropId: boolean = true
|
|
85
|
+
|
|
86
|
+
// Doing this would allow you to have a mobile_phone() filter method instead of mobilePhone().
|
|
87
|
+
// By default, mobilePhone() filter method can be called thanks to one of the following input key:
|
|
88
|
+
// mobile_phone, mobilePhone, mobile_phone_id, mobilePhoneId
|
|
89
|
+
static camelCase: boolean = true
|
|
90
|
+
|
|
91
|
+
// This will filter 'productCategoryId', 'product_category_id' OR 'productCategory'
|
|
92
|
+
productCategory(id: number) {
|
|
93
|
+
this.$query.where('product_category_id', id)
|
|
138
94
|
}
|
|
139
95
|
|
|
140
96
|
name(name: string) {
|
|
141
|
-
this.$query.where(
|
|
142
|
-
builder.where('first_name', 'LIKE', `%${name}%`).orWhere('last_name', 'LIKE', `%${name}%`)
|
|
143
|
-
})
|
|
97
|
+
this.$query.where('name', 'LIKE', `%${name}%`)
|
|
144
98
|
}
|
|
145
99
|
|
|
146
|
-
|
|
147
|
-
this.$query.where('
|
|
100
|
+
price(price: number) {
|
|
101
|
+
this.$query.where('price', price)
|
|
148
102
|
}
|
|
149
103
|
|
|
150
104
|
secretMethod(secretParameter: any) {
|
|
@@ -176,33 +130,16 @@ setup($query) {
|
|
|
176
130
|
In the example above `secretMethod()` will not be called, even if there is a `secret_method` key in the input object.
|
|
177
131
|
In order to call this method it would need to be whitelisted dynamically:
|
|
178
132
|
|
|
179
|
-
#### Static properties
|
|
180
|
-
|
|
181
|
-
```typescript
|
|
182
|
-
export default class UserFilter extends BaseModelFilter {
|
|
183
|
-
// Blacklisted methods
|
|
184
|
-
static blacklist: string[] = []
|
|
185
|
-
|
|
186
|
-
// Dropped `_id` from the end of the input
|
|
187
|
-
// Doing this would allow you to have a `company()` filter method as well as a `companyId()` filter method.
|
|
188
|
-
static dropId: boolean = true
|
|
189
|
-
|
|
190
|
-
// Doing this would allow you to have a mobile_phone() filter method instead of mobilePhone().
|
|
191
|
-
// By default, mobilePhone() filter method can be called thanks to one of the following input key:
|
|
192
|
-
// mobile_phone, mobilePhone, mobile_phone_id, mobilePhoneId
|
|
193
|
-
static camelCase: boolean = true
|
|
194
|
-
}
|
|
195
|
-
```
|
|
196
|
-
|
|
197
133
|
### Applying The Filter To A Model
|
|
198
134
|
|
|
199
135
|
```typescript
|
|
200
|
-
import UserFilter from '#models/filters/user_filter'
|
|
201
136
|
import { compose } from '@adonisjs/core/helpers'
|
|
202
|
-
import { Filterable } from 'adonis-lucid-filter'
|
|
137
|
+
import { Filterable } from '@codenameryuu/adonis-lucid-filter'
|
|
203
138
|
|
|
204
|
-
|
|
205
|
-
|
|
139
|
+
import ProductFilter from '#models/filters/product_filter'
|
|
140
|
+
|
|
141
|
+
export default class Product extends compose(BaseModel, Filterable) {
|
|
142
|
+
static $filter = () => ProductFilter
|
|
206
143
|
|
|
207
144
|
// ...columns and props
|
|
208
145
|
}
|
|
@@ -212,18 +149,17 @@ This gives you access to the `filter()` method that accepts an object of input:
|
|
|
212
149
|
|
|
213
150
|
```typescript
|
|
214
151
|
import type { HttpContext } from '@adonisjs/core/http'
|
|
215
|
-
import
|
|
152
|
+
import Product from '#models/product'
|
|
216
153
|
|
|
217
|
-
export default class
|
|
218
|
-
async index({ request }: HttpContext): Promise<
|
|
219
|
-
return
|
|
154
|
+
export default class ProductsController {
|
|
155
|
+
async index({ request }: HttpContext): Promise<Product[]> {
|
|
156
|
+
return Product.filter(request.all()).orderBy('created_at', 'desc')
|
|
220
157
|
}
|
|
221
158
|
|
|
222
159
|
// or with paginate method
|
|
223
160
|
|
|
224
|
-
async index({ request }: HttpContext): Promise<ModelPaginatorContract<
|
|
225
|
-
|
|
226
|
-
return User.filter(input).paginate(page, 15)
|
|
161
|
+
async index({ request }: HttpContext): Promise<ModelPaginatorContract<Product>> {
|
|
162
|
+
return Product.filter(request.all()).paginate(1, 10)
|
|
227
163
|
}
|
|
228
164
|
}
|
|
229
165
|
```
|
|
@@ -235,13 +171,13 @@ Defining a filter dynamically will take precedent over any other filters defined
|
|
|
235
171
|
|
|
236
172
|
```typescript
|
|
237
173
|
import type { HttpContext } from '@adonisjs/core/http'
|
|
238
|
-
import
|
|
239
|
-
import
|
|
174
|
+
import ProductFilter from '#models/filters/product_filter'
|
|
175
|
+
import ProductExclusiveFilter from '#models/filters/product_exclusive_filter'
|
|
240
176
|
|
|
241
|
-
export default class
|
|
242
|
-
async index({ request, auth }: HttpContext): Promise<
|
|
243
|
-
const filter = auth.user.isAdmin() ?
|
|
244
|
-
return
|
|
177
|
+
export default class ProductsController {
|
|
178
|
+
async index({ request, auth }: HttpContext): Promise<Product[]> {
|
|
179
|
+
const filter = auth.user.isAdmin() ? ProductFilter : ProductExclusiveFilter
|
|
180
|
+
return Product.filter(request.all(), filter).orderBy('created_at', 'desc')
|
|
245
181
|
}
|
|
246
182
|
}
|
|
247
183
|
```
|
|
@@ -252,25 +188,23 @@ For filtering relations of model may be use `.query().filter()` or scope `filtra
|
|
|
252
188
|
|
|
253
189
|
```typescript
|
|
254
190
|
import type { HttpContext } from '@adonisjs/core/http'
|
|
255
|
-
import
|
|
191
|
+
import ProductCategory from '#models/product_category'
|
|
256
192
|
|
|
257
|
-
export default class
|
|
193
|
+
export default class ProductCategoriesController {
|
|
258
194
|
/**
|
|
259
|
-
* Get a list
|
|
260
|
-
* GET /
|
|
195
|
+
* Get a list products of product category
|
|
196
|
+
* GET /product-categories/:product_category_id/products
|
|
261
197
|
*/
|
|
262
|
-
async index({ params, request }: HttpContext): Promise<
|
|
263
|
-
const
|
|
198
|
+
async index({ params, request }: HttpContext): Promise<Product[]> {
|
|
199
|
+
const productCategory: ProductCategory = await ProductCategory.findOrFail(
|
|
200
|
+
params.product_category_id
|
|
201
|
+
)
|
|
264
202
|
|
|
265
|
-
return
|
|
266
|
-
.related('
|
|
203
|
+
return productCategory
|
|
204
|
+
.related('products')
|
|
267
205
|
.query()
|
|
268
|
-
.
|
|
269
|
-
.
|
|
270
|
-
|
|
271
|
-
// or
|
|
272
|
-
|
|
273
|
-
return user.related('posts').query().filter(request.qs()).exec()
|
|
206
|
+
.filter(request.all())
|
|
207
|
+
.orderBy('created_at', 'desc')
|
|
274
208
|
}
|
|
275
209
|
}
|
|
276
210
|
```
|
|
@@ -278,3 +212,7 @@ export default class UserPostsController {
|
|
|
278
212
|
Documentation by [Query Scopes](https://lucid.adonisjs.com/docs/model-query-scopes)
|
|
279
213
|
|
|
280
214
|
**Note:** The relation model must be `Filterable` and `$filter` must be defined in it
|
|
215
|
+
|
|
216
|
+
## License
|
|
217
|
+
|
|
218
|
+
This project is [MIT](https://github.com/codenameryuu/adonis-lucid-filter/blob/master/LICENSE.md) licensed.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"commands":[],"version":1}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* In-memory cache of commands after they have been loaded
|
|
5
|
+
*/
|
|
6
|
+
let commandsMetaData
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Reads the commands from the "./commands.json" file. Since, the commands.json
|
|
10
|
+
* file is generated automatically, we do not have to validate its contents
|
|
11
|
+
*/
|
|
12
|
+
export async function getMetaData() {
|
|
13
|
+
if (commandsMetaData) {
|
|
14
|
+
return commandsMetaData
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const commandsIndex = await readFile(new URL('./commands.json', import.meta.url), 'utf-8')
|
|
18
|
+
commandsMetaData = JSON.parse(commandsIndex).commands
|
|
19
|
+
|
|
20
|
+
return commandsMetaData
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Imports the command by lookingup its path from the commands
|
|
25
|
+
* metadata
|
|
26
|
+
*/
|
|
27
|
+
export async function getCommand(metaData) {
|
|
28
|
+
const commands = await getMetaData()
|
|
29
|
+
const command = commands.find(({ commandName }) => metaData.commandName === commandName)
|
|
30
|
+
if (!command) {
|
|
31
|
+
return null
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const { default: commandConstructor } = await import(new URL(command.filePath, import.meta.url).href)
|
|
35
|
+
return commandConstructor
|
|
36
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{{#var entity = generators.createEntity(name)}}
|
|
2
|
+
{{#var modelName = generators.modelName(entity.name)}}
|
|
3
|
+
{{#var modelFileName = string(modelName).removeExtension().snakeCase().toString()}}
|
|
4
|
+
{{#var modelFilterName = string(modelName).removeSuffix('filter').pascalCase().suffix(string.pascalCase('filter')).toString()}}
|
|
5
|
+
{{#var modelFilterFileName = string(modelName).snakeCase().suffix('_filter').ext('.ts').toString()}}
|
|
6
|
+
{{{
|
|
7
|
+
exports({ to: app.modelsPath('filters', entity.path, modelFilterFileName) })
|
|
8
|
+
}}}
|
|
9
|
+
|
|
10
|
+
import { BaseModelFilter } from 'adonis-lucid-filter'
|
|
11
|
+
import type { ModelQueryBuilderContract } from '@adonisjs/lucid/types/model'
|
|
12
|
+
import {{ modelName }} from '#models/{{ modelFileName }}'
|
|
13
|
+
|
|
14
|
+
export default class {{ modelFilterName }} extends BaseModelFilter {
|
|
15
|
+
declare $query: ModelQueryBuilderContract<typeof {{ modelName }}>
|
|
16
|
+
|
|
17
|
+
name(value: string): void {
|
|
18
|
+
this.$query.where('name', value)
|
|
19
|
+
}
|
|
20
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codenameryuu/adonis-lucid-filter",
|
|
3
3
|
"description": "Addon for filtering Adonis JS 7 Lucid ORM",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "3.1.0",
|
|
5
5
|
"author": "codenameryuu",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"homepage": "https://github.com/codenameryuu/adonis-lucid-filter#readme",
|
|
@@ -26,15 +26,22 @@
|
|
|
26
26
|
"./provider": "./build/providers/lucid_filter_provider.js"
|
|
27
27
|
},
|
|
28
28
|
"scripts": {
|
|
29
|
+
"lint": "eslint .",
|
|
30
|
+
"format": "prettier --write .",
|
|
29
31
|
"clean": "del-cli build",
|
|
32
|
+
"precompile": "npm run lint && npm run clean",
|
|
33
|
+
"postcompile": "npm run copy:stubs && npm run index:commands",
|
|
34
|
+
"compile": "tsc --emitDeclarationOnly --declaration",
|
|
35
|
+
"build": "npm run compile",
|
|
36
|
+
"copy:stubs": "copyfiles \"stubs/**/**/*.stub\" --up=\"1\" build",
|
|
37
|
+
"index:commands": "adonis-kit index build/commands",
|
|
38
|
+
"quick:test": "NODE_DEBUG=\"adonis-lucid-filter\" node --enable-source-maps --loader=ts-node/esm bin/test.ts",
|
|
39
|
+
"pretest": "npm run lint",
|
|
40
|
+
"test": "c8 npm run quick:test",
|
|
30
41
|
"typecheck": "tsc --noEmit",
|
|
31
|
-
"lint": "eslint . --ext=.ts",
|
|
32
|
-
"format": "prettier --write .",
|
|
33
|
-
"prebuild": "npm run lint && npm run clean",
|
|
34
|
-
"build": "npm run clean && tsc",
|
|
35
|
-
"release": "release-it",
|
|
36
42
|
"version": "npm run build",
|
|
37
|
-
"prepublishOnly": "npm run build"
|
|
43
|
+
"prepublishOnly": "npm run build",
|
|
44
|
+
"release": "np"
|
|
38
45
|
},
|
|
39
46
|
"devDependencies": {
|
|
40
47
|
"@adonisjs/assembler": "^7.7.0",
|
|
@@ -63,10 +70,12 @@
|
|
|
63
70
|
"reflect-metadata": "^0.2.2",
|
|
64
71
|
"ts-node": "^10.9.2",
|
|
65
72
|
"tsup": "^8.1.0",
|
|
66
|
-
"type-fest": "^4.21.0",
|
|
67
73
|
"typescript": "^5.5.3",
|
|
68
74
|
"youch": "^4.1.0"
|
|
69
75
|
},
|
|
76
|
+
"dependencies": {
|
|
77
|
+
"type-fest": "^4.21.0"
|
|
78
|
+
},
|
|
70
79
|
"peerDependencies": {
|
|
71
80
|
"@adonisjs/core": "^7.0.0",
|
|
72
81
|
"@adonisjs/lucid": "^22.0.0"
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* adonis-lucid-filter
|
|
3
|
-
*
|
|
4
|
-
* (c) Lookin Anton <alf@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
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
10
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
11
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
12
|
-
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
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
14
|
-
};
|
|
15
|
-
import { BaseCommand, args } from '@adonisjs/core/ace';
|
|
16
|
-
import { stubsRoot } from '../stubs/main.js';
|
|
17
|
-
export default class MakeFilter extends BaseCommand {
|
|
18
|
-
static commandName = 'make:filter';
|
|
19
|
-
static description = 'Make a new Lucid filter';
|
|
20
|
-
/**
|
|
21
|
-
* Run command
|
|
22
|
-
*/
|
|
23
|
-
async run() {
|
|
24
|
-
const codemods = await this.createCodemods();
|
|
25
|
-
await codemods.makeUsingStub(stubsRoot, 'make/filter/main.stub', {
|
|
26
|
-
name: this.name,
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
__decorate([
|
|
31
|
-
args.string({ description: 'Name of the model file' })
|
|
32
|
-
], MakeFilter.prototype, "name", void 0);
|
package/build/configure.js
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* adonis-lucid-filter
|
|
3
|
-
*
|
|
4
|
-
* (c) Lookin Anton <alf@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 async function configure(command) {
|
|
10
|
-
const codemods = await command.createCodemods();
|
|
11
|
-
await codemods.updateRcFile((rcFile) => {
|
|
12
|
-
rcFile.addProvider('@codenameryuu/adonis-lucid-filter/provider');
|
|
13
|
-
rcFile.addCommand('@codenameryuu/adonis-lucid-filter/commands');
|
|
14
|
-
});
|
|
15
|
-
}
|
package/build/index.js
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* adonis-lucid-filter
|
|
3
|
-
*
|
|
4
|
-
* (c) Lookin Anton <alf@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 { stubsRoot } from './stubs/main.js';
|
|
11
|
-
export { BaseModelFilter } from './src/base_model.js';
|
|
12
|
-
export { Filterable } from './src/mixin.js';
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* adonis-lucid-filter
|
|
3
|
-
*
|
|
4
|
-
* (c) Lookin Anton <alf@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';
|
|
10
|
-
export default class LucidFilterProvider {
|
|
11
|
-
app;
|
|
12
|
-
constructor(app) {
|
|
13
|
-
this.app = app;
|
|
14
|
-
}
|
|
15
|
-
async boot() {
|
|
16
|
-
const { ModelQueryBuilder } = await this.app.import('@adonisjs/lucid/orm');
|
|
17
|
-
extendModelQueryBuilder(ModelQueryBuilder);
|
|
18
|
-
}
|
|
19
|
-
}
|
package/build/src/base_model.js
DELETED
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* adonis-lucid-filter
|
|
3
|
-
*
|
|
4
|
-
* (c) Lookin Anton <alf@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
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
10
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
11
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
12
|
-
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
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
14
|
-
};
|
|
15
|
-
var BaseModelFilter_1;
|
|
16
|
-
import camelCase from 'lodash/camelCase.js';
|
|
17
|
-
function StaticImplements() {
|
|
18
|
-
return (_t) => { };
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Class to filtering AdonisJS Lucid ORM
|
|
22
|
-
*
|
|
23
|
-
* @class BaseModelFilter
|
|
24
|
-
* @constructor
|
|
25
|
-
*/
|
|
26
|
-
let BaseModelFilter = class BaseModelFilter {
|
|
27
|
-
static { BaseModelFilter_1 = this; }
|
|
28
|
-
$query;
|
|
29
|
-
$input;
|
|
30
|
-
static blacklist = [];
|
|
31
|
-
static dropId = true;
|
|
32
|
-
static camelCase = true;
|
|
33
|
-
constructor($query, $input) {
|
|
34
|
-
this.$query = $query;
|
|
35
|
-
this.$input = $input;
|
|
36
|
-
this.$input = BaseModelFilter_1.removeEmptyInput(this.$input);
|
|
37
|
-
this.$blacklist = this.constructor.blacklist;
|
|
38
|
-
}
|
|
39
|
-
handle() {
|
|
40
|
-
if (this.setup && typeof this.setup === 'function') {
|
|
41
|
-
this.setup(this.$query);
|
|
42
|
-
}
|
|
43
|
-
this.$filterByInput();
|
|
44
|
-
return this.$query;
|
|
45
|
-
}
|
|
46
|
-
whitelistMethod(method) {
|
|
47
|
-
const index = this.$blacklist.indexOf(method);
|
|
48
|
-
const isBlacklisted = index !== -1;
|
|
49
|
-
if (isBlacklisted)
|
|
50
|
-
this.$blacklist.splice(index, 1);
|
|
51
|
-
return isBlacklisted;
|
|
52
|
-
}
|
|
53
|
-
$filterByInput() {
|
|
54
|
-
for (const key in this.$input) {
|
|
55
|
-
const method = this.$getFilterMethod(key);
|
|
56
|
-
const keyName = key;
|
|
57
|
-
const value = this.$input[keyName];
|
|
58
|
-
if (this.$methodIsCallable(method)) {
|
|
59
|
-
;
|
|
60
|
-
this[method](value);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
$getFilterMethod(key) {
|
|
65
|
-
const methodName = this.constructor.dropId ? key.replace(/^(.*)(_id|Id)$/, '$1') : key;
|
|
66
|
-
return this.constructor.camelCase ? camelCase(methodName) : methodName;
|
|
67
|
-
}
|
|
68
|
-
static removeEmptyInput(input) {
|
|
69
|
-
const filteredInput = {};
|
|
70
|
-
for (const key in input) {
|
|
71
|
-
const keyName = key;
|
|
72
|
-
const value = input[keyName];
|
|
73
|
-
if (value !== '' && value !== null && value !== undefined) {
|
|
74
|
-
filteredInput[keyName] = value;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
return filteredInput;
|
|
78
|
-
}
|
|
79
|
-
$methodIsCallable(method) {
|
|
80
|
-
const methodKey = method;
|
|
81
|
-
return (!!this[methodKey] &&
|
|
82
|
-
typeof this[methodKey] === 'function' &&
|
|
83
|
-
!this.$methodIsBlacklisted(method));
|
|
84
|
-
}
|
|
85
|
-
$methodIsBlacklisted(method) {
|
|
86
|
-
return this.$blacklist.includes(method);
|
|
87
|
-
}
|
|
88
|
-
};
|
|
89
|
-
BaseModelFilter = BaseModelFilter_1 = __decorate([
|
|
90
|
-
StaticImplements()
|
|
91
|
-
], BaseModelFilter);
|
|
92
|
-
export { BaseModelFilter };
|
|
93
|
-
export default BaseModelFilter;
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* adonis-lucid-filter
|
|
3
|
-
*
|
|
4
|
-
* (c) Lookin Anton <alf@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
|
-
/**
|
|
10
|
-
* Define filter method to ModelQueryBuilder
|
|
11
|
-
*/
|
|
12
|
-
export function extendModelQueryBuilder(builder) {
|
|
13
|
-
builder.macro('filter', function (input, filter) {
|
|
14
|
-
const Filter = filter || this.model.$filter();
|
|
15
|
-
return new Filter(this, input).handle();
|
|
16
|
-
});
|
|
17
|
-
}
|
package/build/src/mixin.js
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* adonis-lucid-filter
|
|
3
|
-
*
|
|
4
|
-
* (c) Lookin Anton <alf@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 const Filterable = (superclass) => {
|
|
10
|
-
class FilterableModel extends superclass {
|
|
11
|
-
/**
|
|
12
|
-
* Filter method of filterable model
|
|
13
|
-
*/
|
|
14
|
-
static filter(input, filter) {
|
|
15
|
-
const Filter = filter || this.$filter();
|
|
16
|
-
return new Filter(this.query(), input).handle();
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Filtration scope of filterable model
|
|
20
|
-
*/
|
|
21
|
-
static filtration = function (query, input, filter) {
|
|
22
|
-
const Filter = filter || this.$filter();
|
|
23
|
-
return new Filter(query, input).handle();
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
return FilterableModel;
|
|
27
|
-
};
|
package/build/stubs/main.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* adonis-lucid-filter
|
|
3
|
-
*
|
|
4
|
-
* (c) Lookin Anton <alf@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 { fileURLToPath } from 'node:url';
|
|
10
|
-
import { dirname } from 'node:path';
|
|
11
|
-
export const stubsRoot = dirname(fileURLToPath(import.meta.url));
|