xcraft-core-pickaxe 0.1.7 → 0.1.10
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/eslint.config.js +62 -0
- package/lib/operators.js +4 -0
- package/lib/query-builder.js +52 -0
- package/lib/query-to-sql.js +12 -0
- package/package.json +2 -2
- package/.eslintrc.js +0 -39
package/eslint.config.js
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
const js = require('@eslint/js');
|
|
2
|
+
const globals = require('globals');
|
|
3
|
+
const react = require('eslint-plugin-react');
|
|
4
|
+
const jsdoc = require('eslint-plugin-jsdoc');
|
|
5
|
+
const babel = require('@babel/eslint-plugin');
|
|
6
|
+
const prettier = require('eslint-config-prettier');
|
|
7
|
+
const babelParser = require('@babel/eslint-parser');
|
|
8
|
+
|
|
9
|
+
module.exports = [
|
|
10
|
+
js.configs.recommended,
|
|
11
|
+
react.configs.flat.recommended,
|
|
12
|
+
jsdoc.configs['flat/recommended'],
|
|
13
|
+
prettier,
|
|
14
|
+
{
|
|
15
|
+
languageOptions: {
|
|
16
|
+
parser: babelParser,
|
|
17
|
+
parserOptions: {
|
|
18
|
+
requireConfigFile: false,
|
|
19
|
+
ecmaFeatures: {
|
|
20
|
+
jsx: true,
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
globals: {
|
|
24
|
+
...globals.browser,
|
|
25
|
+
...globals.node,
|
|
26
|
+
...globals.es2022,
|
|
27
|
+
...globals.mocha,
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
plugins: {
|
|
31
|
+
'react': react,
|
|
32
|
+
'jsdoc': jsdoc,
|
|
33
|
+
'@babel': babel,
|
|
34
|
+
},
|
|
35
|
+
rules: {
|
|
36
|
+
'eqeqeq': 'error',
|
|
37
|
+
'no-console': 'off',
|
|
38
|
+
'react/display-name': 'off',
|
|
39
|
+
'@babel/no-unused-expressions': 'error',
|
|
40
|
+
'no-unused-vars': [
|
|
41
|
+
'error',
|
|
42
|
+
{
|
|
43
|
+
vars: 'all',
|
|
44
|
+
args: 'none',
|
|
45
|
+
ignoreRestSiblings: true,
|
|
46
|
+
destructuredArrayIgnorePattern: '^_',
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
'jsdoc/require-jsdoc': 'off',
|
|
50
|
+
'jsdoc/require-param-description': 'off',
|
|
51
|
+
'jsdoc/require-returns-description': 'off',
|
|
52
|
+
},
|
|
53
|
+
settings: {
|
|
54
|
+
react: {
|
|
55
|
+
version: 'detect',
|
|
56
|
+
},
|
|
57
|
+
jsdoc: {
|
|
58
|
+
mode: 'typescript',
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
];
|
package/lib/operators.js
CHANGED
|
@@ -19,6 +19,10 @@ function op(value) {
|
|
|
19
19
|
if (type === 'object' && 'operator' in value) {
|
|
20
20
|
return value;
|
|
21
21
|
}
|
|
22
|
+
const {ValuePick} = require('./picks.js');
|
|
23
|
+
if (value instanceof ValuePick) {
|
|
24
|
+
return value.value;
|
|
25
|
+
}
|
|
22
26
|
|
|
23
27
|
throw new Error(`Bad value '${value}'`);
|
|
24
28
|
}
|
package/lib/query-builder.js
CHANGED
|
@@ -6,6 +6,7 @@ const {
|
|
|
6
6
|
toObjectType,
|
|
7
7
|
ObjectMapType,
|
|
8
8
|
RecordType,
|
|
9
|
+
object,
|
|
9
10
|
} = require('xcraft-core-stones');
|
|
10
11
|
const operators = require('./operators.js');
|
|
11
12
|
const {rowPick, ValuePick, RowPick, ObjectPick} = require('./picks.js');
|
|
@@ -58,6 +59,8 @@ const {queryToSql} = require('./query-to-sql.js');
|
|
|
58
59
|
* where?: Operator,
|
|
59
60
|
* orderBy?: OrderByResult,
|
|
60
61
|
* groupBy?: GroupByResult
|
|
62
|
+
* limit?: number
|
|
63
|
+
* offset?: number
|
|
61
64
|
* }} QueryObj
|
|
62
65
|
*/
|
|
63
66
|
|
|
@@ -113,6 +116,7 @@ class FinalQuery {
|
|
|
113
116
|
if (
|
|
114
117
|
type instanceof ArrayType ||
|
|
115
118
|
type instanceof ObjectType ||
|
|
119
|
+
type === object ||
|
|
116
120
|
type instanceof ObjectMapType ||
|
|
117
121
|
type instanceof RecordType
|
|
118
122
|
) {
|
|
@@ -294,6 +298,30 @@ class ScopedSelectQuery extends FinalQuery {
|
|
|
294
298
|
};
|
|
295
299
|
return new ScopedSelectQuery(this.#database, this.#type, queryParts);
|
|
296
300
|
}
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* @param {number} count
|
|
304
|
+
* @returns {ScopedSelectQuery<T,R>}
|
|
305
|
+
*/
|
|
306
|
+
limit(count) {
|
|
307
|
+
const queryParts = {
|
|
308
|
+
...this.#queryParts,
|
|
309
|
+
limit: count,
|
|
310
|
+
};
|
|
311
|
+
return new ScopedSelectQuery(this.#database, this.#type, queryParts);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* @param {number} count
|
|
316
|
+
* @returns {ScopedSelectQuery<T,R>}
|
|
317
|
+
*/
|
|
318
|
+
offset(count) {
|
|
319
|
+
const queryParts = {
|
|
320
|
+
...this.#queryParts,
|
|
321
|
+
offset: count,
|
|
322
|
+
};
|
|
323
|
+
return new ScopedSelectQuery(this.#database, this.#type, queryParts);
|
|
324
|
+
}
|
|
297
325
|
}
|
|
298
326
|
|
|
299
327
|
/**
|
|
@@ -367,6 +395,30 @@ class SelectQuery extends FinalQuery {
|
|
|
367
395
|
};
|
|
368
396
|
return new SelectQuery(this.#database, this.#type, queryParts);
|
|
369
397
|
}
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* @param {number} count
|
|
401
|
+
* @returns {SelectQuery<T,R>}
|
|
402
|
+
*/
|
|
403
|
+
limit(count) {
|
|
404
|
+
const queryParts = {
|
|
405
|
+
...this.#queryParts,
|
|
406
|
+
limit: count,
|
|
407
|
+
};
|
|
408
|
+
return new SelectQuery(this.#database, this.#type, queryParts);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* @param {number} count
|
|
413
|
+
* @returns {SelectQuery<T,R>}
|
|
414
|
+
*/
|
|
415
|
+
offset(count) {
|
|
416
|
+
const queryParts = {
|
|
417
|
+
...this.#queryParts,
|
|
418
|
+
offset: count,
|
|
419
|
+
};
|
|
420
|
+
return new SelectQuery(this.#database, this.#type, queryParts);
|
|
421
|
+
}
|
|
370
422
|
}
|
|
371
423
|
|
|
372
424
|
/**
|
package/lib/query-to-sql.js
CHANGED
|
@@ -64,6 +64,18 @@ function queryToSql(query, values = []) {
|
|
|
64
64
|
if (query.groupBy) {
|
|
65
65
|
result += '\n' + `GROUP BY ${groupByFields(query.groupBy, values)}`;
|
|
66
66
|
}
|
|
67
|
+
if (query.limit) {
|
|
68
|
+
if (!Number.isInteger(query.limit)) {
|
|
69
|
+
throw new Error(`Bad limit '${query.limit}'`);
|
|
70
|
+
}
|
|
71
|
+
result += '\n' + `LIMIT ${query.limit}`;
|
|
72
|
+
}
|
|
73
|
+
if (query.offset) {
|
|
74
|
+
if (!Number.isInteger(query.offset)) {
|
|
75
|
+
throw new Error(`Bad offset '${query.offset}'`);
|
|
76
|
+
}
|
|
77
|
+
result += '\n' + `OFFSET ${query.offset}`;
|
|
78
|
+
}
|
|
67
79
|
return {sql: result, values};
|
|
68
80
|
}
|
|
69
81
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xcraft-core-pickaxe",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.10",
|
|
4
4
|
"description": "Query builder",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"devDependencies": {
|
|
23
23
|
"prettier": "2.0.4",
|
|
24
24
|
"xcraft-dev-prettier": "^2.0.0",
|
|
25
|
-
"xcraft-dev-rules": "^4.
|
|
25
|
+
"xcraft-dev-rules": "^4.4.0"
|
|
26
26
|
},
|
|
27
27
|
"prettier": "xcraft-dev-prettier"
|
|
28
28
|
}
|
package/.eslintrc.js
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
module.exports = {
|
|
4
|
-
root: true,
|
|
5
|
-
parserOptions: {
|
|
6
|
-
sourceType: 'module',
|
|
7
|
-
ecmaFeatures: {
|
|
8
|
-
jsx: true,
|
|
9
|
-
},
|
|
10
|
-
},
|
|
11
|
-
env: {
|
|
12
|
-
browser: true,
|
|
13
|
-
es2022: true,
|
|
14
|
-
mocha: true,
|
|
15
|
-
node: true,
|
|
16
|
-
},
|
|
17
|
-
plugins: ['react', 'babel', 'jsdoc'],
|
|
18
|
-
extends: [
|
|
19
|
-
'prettier',
|
|
20
|
-
'eslint:recommended',
|
|
21
|
-
'plugin:react/recommended',
|
|
22
|
-
'plugin:jsdoc/recommended',
|
|
23
|
-
],
|
|
24
|
-
rules: {
|
|
25
|
-
// Other rules
|
|
26
|
-
'no-console': 'off',
|
|
27
|
-
'eqeqeq': 'error',
|
|
28
|
-
'react/display-name': 'off',
|
|
29
|
-
'no-unused-vars': [
|
|
30
|
-
'error',
|
|
31
|
-
{
|
|
32
|
-
vars: 'all',
|
|
33
|
-
args: 'none',
|
|
34
|
-
ignoreRestSiblings: true,
|
|
35
|
-
destructuredArrayIgnorePattern: '^_',
|
|
36
|
-
},
|
|
37
|
-
],
|
|
38
|
-
},
|
|
39
|
-
};
|