generated from productdevbookcom/ts-bundle-template
-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
5865411
commit 31ab604
Showing
9 changed files
with
368 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import { andScope } from './plugins/andScope' | ||
import { orScope } from './plugins/orScope' | ||
import { orderByScope } from './plugins/orderByScope' | ||
import { textScope } from './plugins/textScope' | ||
import { twoPointScope } from './plugins/twoPointScope' | ||
import type { SearchFilter } from './types' | ||
|
||
export async function unSearch( | ||
config: SearchFilter, | ||
) { | ||
config._data ??= { | ||
wheres: [], | ||
orderBy: [], | ||
textArray: [], | ||
} | ||
|
||
config.default.ignore = config.default.ignore ?? { | ||
filterText: ['id'], | ||
} | ||
|
||
config.regex = config.regex ?? /([a-zA-Z]{1,20}):(\/([^\/]+)\/\/|([^:\s]{1,100}))/g | ||
config.plugins = config.plugins ?? [orScope, andScope, orderByScope, twoPointScope, textScope] | ||
|
||
const textArray = config.search.split(' ') | ||
config._data.textArray = textArray | ||
|
||
for await (const plugin of config.plugins) { | ||
if (typeof plugin === 'function') { | ||
const { separation } = plugin() | ||
if (typeof separation === 'function') | ||
separation(config as Required<SearchFilter>) | ||
} | ||
} | ||
|
||
for await (const plugin of config.plugins) { | ||
if (typeof plugin === 'function') { | ||
const { setup } = plugin() | ||
if (typeof setup === 'function') | ||
setup(config as Required<SearchFilter>) | ||
} | ||
} | ||
|
||
return { | ||
config, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,2 @@ | ||
export function handler(_event: any, _context: any, callback: any) { | ||
// eslint-disable-next-line no-console | ||
console.log('Hello World') | ||
callback(null, { | ||
statusCode: 200, | ||
body: 'Hello World', | ||
}) | ||
} | ||
export { unSearch } from './core' | ||
export type { SearchFilter, FilterConfig } from './types' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import { defineFilterPlugin } from '../utils' | ||
|
||
export function andScope() { | ||
return defineFilterPlugin({ | ||
separation(params) { | ||
for (const [index, text] of params._data.textArray.entries()) { | ||
if (typeof text === 'object' || !text.includes('AND')) | ||
continue | ||
|
||
const andFunction = params.scopeTags.AND | ||
|
||
params._data.textArray[index] = { | ||
func: andFunction, | ||
text, | ||
index, | ||
type: 'and', | ||
} | ||
} | ||
}, | ||
setup(params) { | ||
for (const text of params._data.textArray) { | ||
if (typeof text !== 'object' || text.type !== 'and') | ||
continue | ||
|
||
if (typeof text === 'object' && text.type === 'and') { | ||
const prev = params._data.textArray[text.index - 1] | ||
const next = params._data.textArray[text.index + 1] | ||
|
||
if (prev && next && typeof prev === 'object' && typeof next === 'object') { | ||
params._data.wheres.push(text.func( | ||
prev.func(params.columKeys[prev.key as keyof typeof params.columKeys], prev.text), | ||
next.func(params.columKeys[next.key as keyof typeof params.columKeys], next.text), | ||
)) | ||
params._data.textArray.splice(text.index - 1, 3) | ||
} | ||
} | ||
} | ||
}, | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import { defineFilterPlugin } from '../utils' | ||
|
||
export function orScope() { | ||
return defineFilterPlugin({ | ||
separation(params) { | ||
for (const [index, text] of params._data.textArray.entries()) { | ||
if (typeof text === 'object' || !text.includes('OR')) | ||
continue | ||
|
||
const orFunction = params.scopeTags.OR | ||
|
||
params._data.textArray[index] = { | ||
func: orFunction, | ||
text, | ||
index, | ||
type: 'or', | ||
} | ||
} | ||
}, | ||
setup(params) { | ||
for (const text of params._data.textArray) { | ||
if (typeof text !== 'object' || text.type !== 'or') | ||
continue | ||
|
||
if (typeof text === 'object' && text.type === 'or') { | ||
const prev = params._data.textArray[text.index - 1] | ||
const next = params._data.textArray[text.index + 1] | ||
|
||
if (prev && next && typeof prev === 'object' && typeof next === 'object') { | ||
params._data.wheres.push(text.func( | ||
prev.func(params.columKeys[prev.key as keyof typeof params.columKeys], prev.text), | ||
next.func(params.columKeys[next.key as keyof typeof params.columKeys], next.text), | ||
)) | ||
params._data.textArray.splice(text.index - 1, 3) | ||
} | ||
} | ||
} | ||
}, | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import { defineFilterPlugin } from '../utils' | ||
|
||
export function orderByScope() { | ||
return defineFilterPlugin({ | ||
separation(params) { | ||
for (const [index, text] of params._data.textArray.entries()) { | ||
if (typeof text === 'object' || !((text.includes('asc:') || text.includes('desc:')))) | ||
continue | ||
|
||
if (text.includes('asc:[') || text.includes('desc:[')) { | ||
const [columnKey, value] = text.split(':').map(key => key.trim()) | ||
const ascOrDesc = columnKey.includes('asc') ? 'asc' : 'desc' | ||
const filterFunction = params.scopeTags[ascOrDesc as keyof typeof params.scopeTags] | ||
|
||
for (const key of value.replace('[', '').replace(']', '').split(',')) { | ||
params._data.textArray[index] = { | ||
func: filterFunction, | ||
text: key, | ||
index, | ||
type: 'orderBy', | ||
} | ||
} | ||
} | ||
|
||
if (text.includes('asc:') || text.includes('desc:')) { | ||
const [columnKey, value] = text.split(':').map(key => key.trim()) | ||
const filterFunction = params.scopeTags[columnKey as keyof typeof params.scopeTags] | ||
params._data.textArray[index] = { | ||
func: filterFunction, | ||
text: value, | ||
index, | ||
type: 'orderBy', | ||
} | ||
} | ||
} | ||
}, | ||
setup(params) { | ||
for (const item of params._data.textArray) { | ||
if (typeof item === 'object' && item.type === 'orderBy') { | ||
params._data.orderBy.push( | ||
item.func(params.columKeys[item.text as keyof typeof params.columKeys], item.text), | ||
) | ||
params._data.textArray.splice(item.index, 1) | ||
} | ||
} | ||
}, | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import { defineFilterPlugin } from '../utils' | ||
|
||
export function textScope(ignoreKeys: string[] = ['id']) { | ||
return defineFilterPlugin({ | ||
separation(params) { | ||
for (const [index, text] of params._data.textArray.entries()) { | ||
if (typeof text === 'object' | ||
|| text.includes(':') | ||
|| text.includes('OR') | ||
|| text.includes('AND') | ||
) | ||
continue | ||
|
||
const filterFunction = params.scopeTags['<ilike>'] | ||
|
||
params._data.textArray[index] = { | ||
func: filterFunction, | ||
text, | ||
index, | ||
type: 'text', | ||
} | ||
} | ||
}, | ||
setup(params) { | ||
for (const text of params._data.textArray) { | ||
if (typeof text === 'object' && text.type === 'text') { | ||
const filterFunction = text.func | ||
for (const key of Object.keys(params.columKeys)) { | ||
if (ignoreKeys.includes(key)) | ||
continue | ||
|
||
params._data.wheres.push(filterFunction(params.columKeys[key as keyof typeof params.columKeys], text.text)) | ||
params._data.textArray.splice(text.index, 1) | ||
} | ||
} | ||
} | ||
}, | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import { defineFilterPlugin } from '../utils' | ||
|
||
export function twoPointScope() { | ||
return defineFilterPlugin({ | ||
separation(params) { | ||
for (const [index, text] of params._data.textArray.entries()) { | ||
if (typeof text === 'object' || !text.includes(':')) | ||
continue | ||
|
||
const [columnKey, value] = text.split(':').map(key => key.trim()) | ||
|
||
let filter = params.scopeTagsArray.find(f => value.includes(f)) | ||
if (!filter) { | ||
if (columnKey === 'id') | ||
filter = '=' | ||
|
||
else | ||
filter = '<ilike>' | ||
} | ||
|
||
const filterFunction = params.scopeTags[filter as keyof typeof params.scopeTags] | ||
|
||
params._data.textArray[index] = { | ||
func: filterFunction, | ||
text: value.replace(filter, '').trim(), | ||
index, | ||
key: columnKey, | ||
type: ':', | ||
} | ||
} | ||
}, | ||
setup(params) { | ||
for (const text of params._data.textArray) { | ||
if (typeof text === 'object' && text.type === ':') { | ||
const filterFunction = text.func | ||
const key = text.key | ||
const value = text.text | ||
params._data.wheres.push(filterFunction(params.columKeys[key as keyof typeof params.columKeys], value)) | ||
params._data.textArray.splice(text.index, 1) | ||
} | ||
} | ||
}, | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
export interface SearchFilter { | ||
/** | ||
* username:hello, email:hello, username:[email protected] or:[username, email] and:[username, email] asc:[username, email] desc:[username, email] | ||
*/ | ||
search: string | ||
/** | ||
* { | ||
* Drizzle Example | ||
* username: tablesPzg.user.username, | ||
* | ||
* Postgres Example | ||
* username: SQL`users.username` | ||
* } | ||
*/ | ||
columKeys: Record<string, any> | ||
|
||
/** | ||
* { | ||
* Drizzle Example | ||
* '=': (key: Column, value: string) => eq(key, value), | ||
* '!=': (key: Column, value: string) => ne(key, value), | ||
* | ||
* Postgres Example | ||
* '=': (key: SQLWrapper, value: string) => SQL`${key} = ${value}`, | ||
* '!=': (key: SQLWrapper, value: string) => SQL`${key} != ${value}`, | ||
* | ||
*/ | ||
scopeTags: { | ||
[key in string]: (key: any, value: string) => void | ||
} | ||
|
||
/** | ||
* The order is important here. If >= is at the beginning, >= will not be perceived and will be corrupted. | ||
* Make sure that the order is correct. | ||
* ['like', 'ilike', '>=', '<=', '>', '<', '!=', '='] | ||
*/ | ||
scopeTagsArray: string[] | ||
|
||
/** | ||
* | ||
* @example | ||
* const regex = /([a-zA-Z]{1,20}):(\/([^\/]+)\/\/|([^:\s]{1,100}))/g | ||
* | ||
* @default | ||
* /([a-zA-Z]{1,20}):(\/([^\/]+)\/\/|([^:\s]{1,100}))/g | ||
*/ | ||
regex?: RegExp | ||
|
||
/** | ||
* | ||
* @example | ||
* const plugins = [ORScope, orderByScope] | ||
* | ||
* @default | ||
* [ORScope, orderByScope] | ||
*/ | ||
plugins?: (() => FilterConfig)[] | ||
|
||
default: { | ||
/** | ||
* @default | ||
* filter: SearchFilter.default.filterText | ||
*/ | ||
filterText: { | ||
filter: string | ||
column: any | ||
key: string | ||
}[] | ||
ignore?: { | ||
/** @default ['id'] */ | ||
filterText?: string[] | ||
} | ||
} | ||
|
||
/** | ||
* @private | ||
* @ignore | ||
* @default | ||
* { | ||
* wheres: [], | ||
* orderBy: [], | ||
* } | ||
*/ | ||
_data?: { | ||
wheres: any[] | ||
orderBy: any[] | ||
textArray: (string | { | ||
func: any | ||
text: string | ||
index: number | ||
key?: string | ||
type: string | ||
})[] | ||
} | ||
} | ||
|
||
export interface FilterConfig { | ||
setup?( | ||
params: Required<SearchFilter>, | ||
): void | ||
separation?( | ||
params: Required<SearchFilter>, | ||
): void | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import type { FilterConfig } from './types' | ||
|
||
export function defineFilterPlugin(config: FilterConfig) { | ||
return config | ||
} |