@storecraft/database-sqlite 1.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/README.md +148 -0
- package/index.js +30 -0
- package/migrate.js +5 -0
- package/package.json +40 -0
- package/src/con.auth_users.js +160 -0
- package/src/con.collections.js +197 -0
- package/src/con.customers.js +202 -0
- package/src/con.discounts.js +225 -0
- package/src/con.discounts.utils.js +180 -0
- package/src/con.helpers.json.js +231 -0
- package/src/con.helpers.json.mssql.js +233 -0
- package/src/con.helpers.json.mysql.js +239 -0
- package/src/con.helpers.json.postgres.js +223 -0
- package/src/con.helpers.json.sqlite.js +263 -0
- package/src/con.images.js +230 -0
- package/src/con.notifications.js +149 -0
- package/src/con.orders.js +171 -0
- package/src/con.posts.js +147 -0
- package/src/con.products.js +497 -0
- package/src/con.search.js +148 -0
- package/src/con.shared.experiment.js +723 -0
- package/src/con.shared.js +616 -0
- package/src/con.shipping.js +147 -0
- package/src/con.storefronts.js +301 -0
- package/src/con.tags.js +120 -0
- package/src/con.templates.js +133 -0
- package/src/kysely.sanitize.plugin.js +40 -0
- package/src/utils.funcs.js +77 -0
- package/src/utils.query.js +195 -0
- package/tests/query.cursor.test.js +389 -0
- package/tests/query.vql.test.js +71 -0
- package/tests/runner.mssql-local.test.js +118 -0
- package/tests/runner.mysql-local.test.js +103 -0
- package/tests/runner.postgres-local.test.js +103 -0
- package/tests/runner.test.js +92 -0
- package/tests/sandbox.test.js +73 -0
- package/tsconfig.json +18 -0
- package/types.public.d.ts +21 -0
@@ -0,0 +1,40 @@
|
|
1
|
+
import { sanitize } from './utils.funcs.js';
|
2
|
+
|
3
|
+
/**
|
4
|
+
* @description This `kysely` plugin will process query
|
5
|
+
* results and will do the following:
|
6
|
+
* - sanitize `undefined` and `null` values
|
7
|
+
* - `active` keys will be transformed to `boolean`
|
8
|
+
*
|
9
|
+
*
|
10
|
+
* @typedef {import('kysely').KyselyPlugin} KyselyPlugin
|
11
|
+
*
|
12
|
+
*
|
13
|
+
* @implements {KyselyPlugin}
|
14
|
+
*/
|
15
|
+
export class SanitizePlugin {
|
16
|
+
|
17
|
+
/**
|
18
|
+
*
|
19
|
+
* @param {import('kysely').PluginTransformQueryArgs} args
|
20
|
+
*
|
21
|
+
*
|
22
|
+
* @returns {import('kysely').RootOperationNode}
|
23
|
+
*/
|
24
|
+
transformQuery(args) {
|
25
|
+
return args.node;
|
26
|
+
}
|
27
|
+
|
28
|
+
/**
|
29
|
+
*
|
30
|
+
* @param {import('kysely').PluginTransformResultArgs} args
|
31
|
+
*
|
32
|
+
*
|
33
|
+
* @returns {Promise<import('kysely').QueryResult<import('kysely').UnknownRow>>}
|
34
|
+
*/
|
35
|
+
transformResult(args){
|
36
|
+
sanitize(args.result.rows);
|
37
|
+
|
38
|
+
return Promise.resolve(args.result);
|
39
|
+
}
|
40
|
+
}
|
@@ -0,0 +1,77 @@
|
|
1
|
+
export const isDef = v => v!==undefined && v!==null;
|
2
|
+
export const isUndef = v => !isDef(v);
|
3
|
+
|
4
|
+
/**
|
5
|
+
*
|
6
|
+
* @param {...any} keys
|
7
|
+
* @returns
|
8
|
+
*/
|
9
|
+
export const delete_keys = (...keys) => {
|
10
|
+
|
11
|
+
/**
|
12
|
+
* @template T
|
13
|
+
* @param {T} o
|
14
|
+
* @returns {T}
|
15
|
+
*/
|
16
|
+
return (o) => {
|
17
|
+
keys.forEach(k => {o?.[k] && delete o[k]} )
|
18
|
+
return o
|
19
|
+
}
|
20
|
+
}
|
21
|
+
|
22
|
+
/**
|
23
|
+
* Sanitize null/undefined valued keys
|
24
|
+
*
|
25
|
+
*
|
26
|
+
* @template {Record<string, any>} T
|
27
|
+
*
|
28
|
+
*
|
29
|
+
* @param {T} o
|
30
|
+
*/
|
31
|
+
export const sanitize = o => {
|
32
|
+
for (const key in o) {
|
33
|
+
const value = o[key];
|
34
|
+
|
35
|
+
if(!isDef(value)) {
|
36
|
+
delete o[key];
|
37
|
+
continue;
|
38
|
+
}
|
39
|
+
if(key==='active') {
|
40
|
+
o[key] = Boolean(value);
|
41
|
+
}
|
42
|
+
else if(key==='price') {
|
43
|
+
o[key] = parseFloat(value);
|
44
|
+
}
|
45
|
+
else if(key==='compare_at_price') {
|
46
|
+
o[key] = parseFloat(value);
|
47
|
+
}
|
48
|
+
else if(typeof value === 'object') {
|
49
|
+
sanitize(o[key])
|
50
|
+
}
|
51
|
+
}
|
52
|
+
|
53
|
+
return o;
|
54
|
+
}
|
55
|
+
|
56
|
+
|
57
|
+
/**
|
58
|
+
* Sanitize the document before sending to client
|
59
|
+
*
|
60
|
+
* @template T
|
61
|
+
*
|
62
|
+
* @param {T[]} arr
|
63
|
+
*/
|
64
|
+
export const sanitize_array = arr => {
|
65
|
+
for(const p of arr) {
|
66
|
+
sanitize(p);
|
67
|
+
}
|
68
|
+
return arr;
|
69
|
+
}
|
70
|
+
|
71
|
+
/**
|
72
|
+
*
|
73
|
+
* @param {string} v
|
74
|
+
*/
|
75
|
+
export const isID = v => {
|
76
|
+
return v.includes('_');
|
77
|
+
}
|
@@ -0,0 +1,195 @@
|
|
1
|
+
/**
|
2
|
+
* @typedef {import("../index.js").Database} Database
|
3
|
+
*/
|
4
|
+
|
5
|
+
import { parse } from "@storecraft/core/v-ql";
|
6
|
+
|
7
|
+
/**
|
8
|
+
* Convert an API Query cursor into mongo dialect, also sanitize.
|
9
|
+
*
|
10
|
+
* 1. (a1, a2) > (b1, b2) ==> (a1 > b1) || (a1=b1 & a2>b2)
|
11
|
+
* 2. (a1, a2) >= (b1, b2) ==> (a1 > b1) || (a1=b1 & a2>=b2)
|
12
|
+
* 3. (a1, a2, a3) > (b1, b2, b3) ==> (a1 > b1) || (a1=b1 & a2>b2) || (a1=b1 & a2=b2 & a3>b3)
|
13
|
+
* 4. (a1, a2, a3) >= (b1, b2, b3) ==> (a1 > b1) || (a1=b1 & a2>b2) || (a1=b1 & a2=b2 & a3>=b3)
|
14
|
+
*
|
15
|
+
* @param {import("kysely").ExpressionBuilder<Database>} eb
|
16
|
+
* @param {import("@storecraft/core/v-api").Cursor} c
|
17
|
+
* @param {'>' | '>=' | '<' | '<='} relation
|
18
|
+
* @param {(x: [k: string, v: any]) => [k: string, v: any]} transformer Your chance to change key and value
|
19
|
+
*/
|
20
|
+
export const query_cursor_to_eb = (eb, c, relation, transformer=(x)=>x) => {
|
21
|
+
|
22
|
+
let rel_key_1; // relation in last conjunction term in [0, n-1] disjunctions
|
23
|
+
let rel_key_2; // relation in last conjunction term in last disjunction
|
24
|
+
|
25
|
+
if (relation==='>' || relation==='>=') {
|
26
|
+
rel_key_1 = rel_key_2 = '>';
|
27
|
+
if(relation==='>=')
|
28
|
+
rel_key_2='>=';
|
29
|
+
}
|
30
|
+
else if (relation==='<' || relation==='<=') {
|
31
|
+
rel_key_1 = rel_key_2 = '<';
|
32
|
+
if(relation==='<=')
|
33
|
+
rel_key_2='<=';
|
34
|
+
} else return undefined;
|
35
|
+
|
36
|
+
|
37
|
+
const disjunctions = [];
|
38
|
+
// each disjunction clause
|
39
|
+
for (let ix = 0; ix < c.length; ix++) {
|
40
|
+
const is_last_disjunction = ix==c.length-1;
|
41
|
+
const conjunctions = [];
|
42
|
+
// each conjunction clause up until the last term (not inclusive)
|
43
|
+
for (let jx = 0; jx < ix; jx++) {
|
44
|
+
// the a_n=b_n
|
45
|
+
const r = transformer(c[jx]);
|
46
|
+
|
47
|
+
// conjunctions.push({ [r[0]] : r[1] });
|
48
|
+
conjunctions.push(eb(r[0], '=', r[1]));
|
49
|
+
}
|
50
|
+
|
51
|
+
// Last conjunction term
|
52
|
+
const relation_key = is_last_disjunction ? rel_key_2 : rel_key_1;
|
53
|
+
const r = transformer(c[ix]);
|
54
|
+
// conjunctions.push({ [r[0]] : { [relation_key]: r[1] } });
|
55
|
+
conjunctions.push(eb(r[0], relation_key, r[1]));
|
56
|
+
// Add to disjunctions list
|
57
|
+
// disjunctions.push({ $and: conjunctions });
|
58
|
+
disjunctions.push(eb.and(conjunctions));
|
59
|
+
}
|
60
|
+
|
61
|
+
if(disjunctions.length==0)
|
62
|
+
return undefined;
|
63
|
+
|
64
|
+
// const result = {
|
65
|
+
// $or: disjunctions
|
66
|
+
// };
|
67
|
+
|
68
|
+
return eb.or(disjunctions);
|
69
|
+
|
70
|
+
// return result;
|
71
|
+
}
|
72
|
+
|
73
|
+
|
74
|
+
/**
|
75
|
+
* @param {import("kysely").ExpressionBuilder<Database>} eb
|
76
|
+
* @param {import("@storecraft/core/v-ql").VQL.Node} node
|
77
|
+
* @param {keyof Database} table_name
|
78
|
+
*/
|
79
|
+
export const query_vql_node_to_eb = (eb, node, table_name) => {
|
80
|
+
if(node.op==='LEAF') {
|
81
|
+
// console.log('value', node.value)
|
82
|
+
return eb
|
83
|
+
.exists(
|
84
|
+
eb => eb
|
85
|
+
.selectFrom('entity_to_search_terms')
|
86
|
+
.select('id')
|
87
|
+
.where(
|
88
|
+
eb => eb.and(
|
89
|
+
[
|
90
|
+
eb.or(
|
91
|
+
[
|
92
|
+
eb(`entity_to_search_terms.entity_id`, '=', eb.ref(`${table_name}.id`)),
|
93
|
+
eb(`entity_to_search_terms.entity_handle`, '=', eb.ref(`${table_name}.handle`)),
|
94
|
+
]
|
95
|
+
),
|
96
|
+
eb(`entity_to_search_terms.value`, 'like', node.value.toLowerCase())
|
97
|
+
]
|
98
|
+
)
|
99
|
+
)
|
100
|
+
)
|
101
|
+
}
|
102
|
+
|
103
|
+
let conjunctions = [];
|
104
|
+
for(let arg of node?.args) {
|
105
|
+
conjunctions.push(query_vql_node_to_eb(eb, arg, table_name));
|
106
|
+
}
|
107
|
+
|
108
|
+
switch (node.op) {
|
109
|
+
case '&':
|
110
|
+
return eb.and(conjunctions)
|
111
|
+
case '|':
|
112
|
+
return eb.or(conjunctions)
|
113
|
+
case '!':
|
114
|
+
return eb.not(conjunctions[0])
|
115
|
+
default:
|
116
|
+
throw new Error('VQL-failed')
|
117
|
+
}
|
118
|
+
|
119
|
+
}
|
120
|
+
|
121
|
+
/**
|
122
|
+
* @param {import("kysely").ExpressionBuilder<Database>} eb
|
123
|
+
* @param {import("@storecraft/core/v-ql").VQL.Node} root
|
124
|
+
* @param {keyof Database} table_name
|
125
|
+
*/
|
126
|
+
export const query_vql_to_eb = (eb, root, table_name) => {
|
127
|
+
return root ? query_vql_node_to_eb(eb, root, table_name) : undefined;
|
128
|
+
}
|
129
|
+
|
130
|
+
|
131
|
+
/**
|
132
|
+
* Convert an API Query into mongo dialect, also sanitize.
|
133
|
+
*
|
134
|
+
*
|
135
|
+
* @param {import("kysely").ExpressionBuilder<Database>} eb
|
136
|
+
* @param {import("@storecraft/core/v-api").ApiQuery} q
|
137
|
+
* @param {keyof Database} table_name
|
138
|
+
*
|
139
|
+
*/
|
140
|
+
export const query_to_eb = (eb, q={}, table_name) => {
|
141
|
+
const clauses = [];
|
142
|
+
|
143
|
+
const sort_sign = q.order === 'asc' ? 1 : -1;
|
144
|
+
const asc = sort_sign==1;
|
145
|
+
|
146
|
+
// compute index clauses
|
147
|
+
if(q.startAt) {
|
148
|
+
clauses.push(query_cursor_to_eb(eb, q.startAt, asc ? '>=' : '<='));
|
149
|
+
} else if(q.startAfter) {
|
150
|
+
clauses.push(query_cursor_to_eb(eb, q.startAfter, asc ? '>' : '<'));
|
151
|
+
}
|
152
|
+
|
153
|
+
if(q.endAt) {
|
154
|
+
clauses.push(query_cursor_to_eb(eb, q.endAt, asc ? '<=' : '>='));
|
155
|
+
} else if(q.endBefore) {
|
156
|
+
clauses.push(query_cursor_to_eb(eb, q.endBefore, asc ? '<' : '>'));
|
157
|
+
}
|
158
|
+
|
159
|
+
// compute VQL clauses
|
160
|
+
try {
|
161
|
+
if(q.vql && !q.vqlParsed) {
|
162
|
+
q.vqlParsed = parse(q.vql)
|
163
|
+
}
|
164
|
+
} catch(e) {}
|
165
|
+
|
166
|
+
const vql_clause = query_vql_to_eb(eb, q.vqlParsed, table_name)
|
167
|
+
vql_clause && clauses.push(vql_clause);
|
168
|
+
|
169
|
+
return eb.and(clauses);
|
170
|
+
}
|
171
|
+
|
172
|
+
const SIGN = {
|
173
|
+
'1': 'asc',
|
174
|
+
'-1': 'desc'
|
175
|
+
}
|
176
|
+
|
177
|
+
/**
|
178
|
+
* Convert an API Query into mongo dialect, also sanitize.
|
179
|
+
*
|
180
|
+
* @param {import("@storecraft/core/v-api").ApiQuery} q
|
181
|
+
*/
|
182
|
+
export const query_to_sort = (q={}) => {
|
183
|
+
// const sort_sign = q.order === 'asc' ? 'asc' : 'desc';
|
184
|
+
// `reverse_sign=-1` means we need to reverse because of `limitToLast`
|
185
|
+
const reverse_sign = (q.limitToLast && !q.limit) ? -1 : 1;
|
186
|
+
const asc = q.order === 'asc';
|
187
|
+
const sort_sign = (asc ? 1 : -1) * reverse_sign;
|
188
|
+
|
189
|
+
// compute sort fields and order
|
190
|
+
const sort = (q.sortBy?.length ? q.sortBy : ['updated_at', 'id']).map(
|
191
|
+
s => `${s} ${SIGN[sort_sign]}`
|
192
|
+
)
|
193
|
+
|
194
|
+
return sort;
|
195
|
+
}
|
@@ -0,0 +1,389 @@
|
|
1
|
+
// import { test } from 'uvu';
|
2
|
+
// import * as assert from 'uvu/assert';
|
3
|
+
// import { query_cursor_to_mongo } from '../src/utils.query.js'
|
4
|
+
|
5
|
+
// test('(a1, a2, a3)', async () => {
|
6
|
+
// const t_1 = {
|
7
|
+
// "$or": [
|
8
|
+
// {
|
9
|
+
// "$and": [
|
10
|
+
// {
|
11
|
+
// "a1": {
|
12
|
+
// "$gt": "b1"
|
13
|
+
// }
|
14
|
+
// }
|
15
|
+
// ]
|
16
|
+
// },
|
17
|
+
// {
|
18
|
+
// "$and": [
|
19
|
+
// {
|
20
|
+
// "a1": "b1"
|
21
|
+
// },
|
22
|
+
// {
|
23
|
+
// "a2": {
|
24
|
+
// "$gt": "b2"
|
25
|
+
// }
|
26
|
+
// }
|
27
|
+
// ]
|
28
|
+
// },
|
29
|
+
// {
|
30
|
+
// "$and": [
|
31
|
+
// {
|
32
|
+
// "a1": "b1"
|
33
|
+
// },
|
34
|
+
// {
|
35
|
+
// "a2": "b2"
|
36
|
+
// },
|
37
|
+
// {
|
38
|
+
// "a3": {
|
39
|
+
// "$gte": "b3"
|
40
|
+
// }
|
41
|
+
// }
|
42
|
+
// ]
|
43
|
+
// }
|
44
|
+
// ]
|
45
|
+
// };
|
46
|
+
|
47
|
+
// const t_2 = {
|
48
|
+
// "$or": [
|
49
|
+
// {
|
50
|
+
// "$and": [
|
51
|
+
// {
|
52
|
+
// "a1": {
|
53
|
+
// "$gt": "b1"
|
54
|
+
// }
|
55
|
+
// }
|
56
|
+
// ]
|
57
|
+
// },
|
58
|
+
// {
|
59
|
+
// "$and": [
|
60
|
+
// {
|
61
|
+
// "a1": "b1"
|
62
|
+
// },
|
63
|
+
// {
|
64
|
+
// "a2": {
|
65
|
+
// "$gt": "b2"
|
66
|
+
// }
|
67
|
+
// }
|
68
|
+
// ]
|
69
|
+
// },
|
70
|
+
// {
|
71
|
+
// "$and": [
|
72
|
+
// {
|
73
|
+
// "a1": "b1"
|
74
|
+
// },
|
75
|
+
// {
|
76
|
+
// "a2": "b2"
|
77
|
+
// },
|
78
|
+
// {
|
79
|
+
// "a3": {
|
80
|
+
// "$gt": "b3"
|
81
|
+
// }
|
82
|
+
// }
|
83
|
+
// ]
|
84
|
+
// }
|
85
|
+
// ]
|
86
|
+
// };
|
87
|
+
|
88
|
+
// const t_3 = {
|
89
|
+
// "$or": [
|
90
|
+
// {
|
91
|
+
// "$and": [
|
92
|
+
// {
|
93
|
+
// "a1": {
|
94
|
+
// "$lt": "b1"
|
95
|
+
// }
|
96
|
+
// }
|
97
|
+
// ]
|
98
|
+
// },
|
99
|
+
// {
|
100
|
+
// "$and": [
|
101
|
+
// {
|
102
|
+
// "a1": "b1"
|
103
|
+
// },
|
104
|
+
// {
|
105
|
+
// "a2": {
|
106
|
+
// "$lt": "b2"
|
107
|
+
// }
|
108
|
+
// }
|
109
|
+
// ]
|
110
|
+
// },
|
111
|
+
// {
|
112
|
+
// "$and": [
|
113
|
+
// {
|
114
|
+
// "a1": "b1"
|
115
|
+
// },
|
116
|
+
// {
|
117
|
+
// "a2": "b2"
|
118
|
+
// },
|
119
|
+
// {
|
120
|
+
// "a3": {
|
121
|
+
// "$lte": "b3"
|
122
|
+
// }
|
123
|
+
// }
|
124
|
+
// ]
|
125
|
+
// }
|
126
|
+
// ]
|
127
|
+
// };
|
128
|
+
|
129
|
+
// const t_4 = {
|
130
|
+
// "$or": [
|
131
|
+
// {
|
132
|
+
// "$and": [
|
133
|
+
// {
|
134
|
+
// "a1": {
|
135
|
+
// "$lt": "b1"
|
136
|
+
// }
|
137
|
+
// }
|
138
|
+
// ]
|
139
|
+
// },
|
140
|
+
// {
|
141
|
+
// "$and": [
|
142
|
+
// {
|
143
|
+
// "a1": "b1"
|
144
|
+
// },
|
145
|
+
// {
|
146
|
+
// "a2": {
|
147
|
+
// "$lt": "b2"
|
148
|
+
// }
|
149
|
+
// }
|
150
|
+
// ]
|
151
|
+
// },
|
152
|
+
// {
|
153
|
+
// "$and": [
|
154
|
+
// {
|
155
|
+
// "a1": "b1"
|
156
|
+
// },
|
157
|
+
// {
|
158
|
+
// "a2": "b2"
|
159
|
+
// },
|
160
|
+
// {
|
161
|
+
// "a3": {
|
162
|
+
// "$lt": "b3"
|
163
|
+
// }
|
164
|
+
// }
|
165
|
+
// ]
|
166
|
+
// }
|
167
|
+
// ]
|
168
|
+
// };
|
169
|
+
|
170
|
+
// /** @type {import('@storecraft/core').Cursor[]} */
|
171
|
+
// const cursor = [
|
172
|
+
// ['a1', 'b1'],
|
173
|
+
// ['a2', 'b2'],
|
174
|
+
// ['a3', 'b3'],
|
175
|
+
// ];
|
176
|
+
|
177
|
+
// const rel_1 = query_cursor_to_mongo(cursor, '>=');
|
178
|
+
// const rel_2 = query_cursor_to_mongo(cursor, '>');
|
179
|
+
// const rel_3 = query_cursor_to_mongo(cursor, '<=');
|
180
|
+
// const rel_4 = query_cursor_to_mongo(cursor, '<');
|
181
|
+
|
182
|
+
// assert.equal(rel_1, t_1);
|
183
|
+
// assert.equal(rel_2, t_2);
|
184
|
+
// assert.equal(rel_3, t_3);
|
185
|
+
// assert.equal(rel_4, t_4);
|
186
|
+
|
187
|
+
// });
|
188
|
+
|
189
|
+
|
190
|
+
// test('(a1, a2)', async () => {
|
191
|
+
// const t_1 = {
|
192
|
+
// "$or": [
|
193
|
+
// {
|
194
|
+
// "$and": [
|
195
|
+
// {
|
196
|
+
// "a1": {
|
197
|
+
// "$gt": "b1"
|
198
|
+
// }
|
199
|
+
// }
|
200
|
+
// ]
|
201
|
+
// },
|
202
|
+
// {
|
203
|
+
// "$and": [
|
204
|
+
// {
|
205
|
+
// "a1": "b1"
|
206
|
+
// },
|
207
|
+
// {
|
208
|
+
// "a2": {
|
209
|
+
// "$gte": "b2"
|
210
|
+
// }
|
211
|
+
// }
|
212
|
+
// ]
|
213
|
+
// },
|
214
|
+
// ]
|
215
|
+
// };
|
216
|
+
|
217
|
+
// const t_2 = {
|
218
|
+
// "$or": [
|
219
|
+
// {
|
220
|
+
// "$and": [
|
221
|
+
// {
|
222
|
+
// "a1": {
|
223
|
+
// "$gt": "b1"
|
224
|
+
// }
|
225
|
+
// }
|
226
|
+
// ]
|
227
|
+
// },
|
228
|
+
// {
|
229
|
+
// "$and": [
|
230
|
+
// {
|
231
|
+
// "a1": "b1"
|
232
|
+
// },
|
233
|
+
// {
|
234
|
+
// "a2": {
|
235
|
+
// "$gt": "b2"
|
236
|
+
// }
|
237
|
+
// }
|
238
|
+
// ]
|
239
|
+
// },
|
240
|
+
// ]
|
241
|
+
// };
|
242
|
+
|
243
|
+
// const t_3 = {
|
244
|
+
// "$or": [
|
245
|
+
// {
|
246
|
+
// "$and": [
|
247
|
+
// {
|
248
|
+
// "a1": {
|
249
|
+
// "$lt": "b1"
|
250
|
+
// }
|
251
|
+
// }
|
252
|
+
// ]
|
253
|
+
// },
|
254
|
+
// {
|
255
|
+
// "$and": [
|
256
|
+
// {
|
257
|
+
// "a1": "b1"
|
258
|
+
// },
|
259
|
+
// {
|
260
|
+
// "a2": {
|
261
|
+
// "$lte": "b2"
|
262
|
+
// }
|
263
|
+
// }
|
264
|
+
// ]
|
265
|
+
// },
|
266
|
+
// ]
|
267
|
+
// };
|
268
|
+
|
269
|
+
// const t_4 = {
|
270
|
+
// "$or": [
|
271
|
+
// {
|
272
|
+
// "$and": [
|
273
|
+
// {
|
274
|
+
// "a1": {
|
275
|
+
// "$lt": "b1"
|
276
|
+
// }
|
277
|
+
// }
|
278
|
+
// ]
|
279
|
+
// },
|
280
|
+
// {
|
281
|
+
// "$and": [
|
282
|
+
// {
|
283
|
+
// "a1": "b1"
|
284
|
+
// },
|
285
|
+
// {
|
286
|
+
// "a2": {
|
287
|
+
// "$lt": "b2"
|
288
|
+
// }
|
289
|
+
// }
|
290
|
+
// ]
|
291
|
+
// },
|
292
|
+
// ]
|
293
|
+
// };
|
294
|
+
|
295
|
+
// /** @type {import('@storecraft/core').Cursor[]} */
|
296
|
+
// const cursor = [
|
297
|
+
// ['a1', 'b1'],
|
298
|
+
// ['a2', 'b2'],
|
299
|
+
// ];
|
300
|
+
|
301
|
+
// const rel_1 = query_cursor_to_mongo(cursor, '>=');
|
302
|
+
// const rel_2 = query_cursor_to_mongo(cursor, '>');
|
303
|
+
// const rel_3 = query_cursor_to_mongo(cursor, '<=');
|
304
|
+
// const rel_4 = query_cursor_to_mongo(cursor, '<');
|
305
|
+
|
306
|
+
// assert.equal(rel_1, t_1);
|
307
|
+
// assert.equal(rel_2, t_2);
|
308
|
+
// assert.equal(rel_3, t_3);
|
309
|
+
// assert.equal(rel_4, t_4);
|
310
|
+
// });
|
311
|
+
|
312
|
+
|
313
|
+
|
314
|
+
// test('(a1)', async () => {
|
315
|
+
// const t_1 = {
|
316
|
+
// "$or": [
|
317
|
+
// {
|
318
|
+
// "$and": [
|
319
|
+
// {
|
320
|
+
// "a1": {
|
321
|
+
// "$gte": "b1"
|
322
|
+
// }
|
323
|
+
// }
|
324
|
+
// ]
|
325
|
+
// },
|
326
|
+
// ]
|
327
|
+
// };
|
328
|
+
|
329
|
+
// const t_2 = {
|
330
|
+
// "$or": [
|
331
|
+
// {
|
332
|
+
// "$and": [
|
333
|
+
// {
|
334
|
+
// "a1": {
|
335
|
+
// "$gt": "b1"
|
336
|
+
// }
|
337
|
+
// }
|
338
|
+
// ]
|
339
|
+
// },
|
340
|
+
// ]
|
341
|
+
// };
|
342
|
+
|
343
|
+
// const t_3 = {
|
344
|
+
// "$or": [
|
345
|
+
// {
|
346
|
+
// "$and": [
|
347
|
+
// {
|
348
|
+
// "a1": {
|
349
|
+
// "$lte": "b1"
|
350
|
+
// }
|
351
|
+
// }
|
352
|
+
// ]
|
353
|
+
// },
|
354
|
+
// ]
|
355
|
+
// };
|
356
|
+
|
357
|
+
// const t_4 = {
|
358
|
+
// "$or": [
|
359
|
+
// {
|
360
|
+
// "$and": [
|
361
|
+
// {
|
362
|
+
// "a1": {
|
363
|
+
// "$lt": "b1"
|
364
|
+
// }
|
365
|
+
// }
|
366
|
+
// ]
|
367
|
+
// },
|
368
|
+
// ]
|
369
|
+
// };
|
370
|
+
|
371
|
+
// /** @type {import('@storecraft/core').Cursor[]} */
|
372
|
+
// const cursor = [
|
373
|
+
// ['a1', 'b1'],
|
374
|
+
// ];
|
375
|
+
|
376
|
+
// const rel_1 = query_cursor_to_mongo(cursor, '>=');
|
377
|
+
// const rel_2 = query_cursor_to_mongo(cursor, '>');
|
378
|
+
// const rel_3 = query_cursor_to_mongo(cursor, '<=');
|
379
|
+
// const rel_4 = query_cursor_to_mongo(cursor, '<');
|
380
|
+
|
381
|
+
// assert.equal(rel_1, t_1);
|
382
|
+
// assert.equal(rel_2, t_2);
|
383
|
+
// assert.equal(rel_3, t_3);
|
384
|
+
// assert.equal(rel_4, t_4);
|
385
|
+
// });
|
386
|
+
|
387
|
+
|
388
|
+
|
389
|
+
// test.run();
|