@juadz/knex 0.5.2 → 0.5.4-beta2
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/.turbo/turbo-build.log +4 -0
- package/build/basic.js +71 -157
- package/build/index.js +1 -1
- package/build/list.js +123 -177
- package/build/list.test.js +55 -110
- package/build/types.d.ts +1 -0
- package/build/types.js +2 -0
- package/package.json +3 -3
- package/src/list.ts +1 -1
- package/tsconfig.json +4 -0
package/build/basic.js
CHANGED
|
@@ -1,168 +1,82 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __assign = (this && this.__assign) || function () {
|
|
3
|
-
__assign = Object.assign || function(t) {
|
|
4
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
-
s = arguments[i];
|
|
6
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
-
t[p] = s[p];
|
|
8
|
-
}
|
|
9
|
-
return t;
|
|
10
|
-
};
|
|
11
|
-
return __assign.apply(this, arguments);
|
|
12
|
-
};
|
|
13
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
14
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
15
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
16
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
17
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
18
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
19
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
20
|
-
});
|
|
21
|
-
};
|
|
22
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
23
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
24
|
-
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
25
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
26
|
-
function step(op) {
|
|
27
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
28
|
-
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
29
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
30
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
31
|
-
switch (op[0]) {
|
|
32
|
-
case 0: case 1: t = op; break;
|
|
33
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
34
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
35
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
36
|
-
default:
|
|
37
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
38
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
39
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
40
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
41
|
-
if (t[2]) _.ops.pop();
|
|
42
|
-
_.trys.pop(); continue;
|
|
43
|
-
}
|
|
44
|
-
op = body.call(thisArg, _);
|
|
45
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
46
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
50
|
-
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
51
|
-
if (ar || !(i in from)) {
|
|
52
|
-
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
53
|
-
ar[i] = from[i];
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
return to.concat(ar || Array.prototype.slice.call(from));
|
|
57
|
-
};
|
|
58
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
59
3
|
exports.KnexProvider = KnexProvider;
|
|
60
|
-
|
|
61
|
-
|
|
4
|
+
const core_1 = require("@juadz/core");
|
|
5
|
+
const list_1 = require("./list");
|
|
62
6
|
function KnexProvider(dataTableName, schema, connection) {
|
|
63
|
-
var _this = this;
|
|
64
7
|
// schema.name = schema.name || dataTableName;
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
case 5:
|
|
117
|
-
insertedData = _a.sent();
|
|
118
|
-
return [2 /*return*/, insertedData];
|
|
119
|
-
}
|
|
120
|
-
});
|
|
121
|
-
}); };
|
|
122
|
-
var replace = function (id, params_) { return __awaiter(_this, void 0, void 0, function () {
|
|
123
|
-
var params, fields, values, insertedData;
|
|
124
|
-
return __generator(this, function (_a) {
|
|
125
|
-
switch (_a.label) {
|
|
126
|
-
case 0:
|
|
127
|
-
params = __assign({ id: id }, params_);
|
|
128
|
-
fields = [];
|
|
129
|
-
values = [];
|
|
130
|
-
Object.keys(params).forEach(function (f) {
|
|
131
|
-
fields.push("`".concat(f, "`=?"));
|
|
132
|
-
values.push(params[f]);
|
|
133
|
-
});
|
|
134
|
-
return [4 /*yield*/, connection.raw("REPLACE INTO `".concat(dataTableName, "` SET ").concat(fields.join(", "), " WHERE id=?"), __spreadArray(__spreadArray([], values, true), [
|
|
135
|
-
id, // Ensure the ID is at the end for the WHERE clause
|
|
136
|
-
], false))];
|
|
137
|
-
case 1:
|
|
138
|
-
_a.sent();
|
|
139
|
-
return [4 /*yield*/, get(id)];
|
|
140
|
-
case 2:
|
|
141
|
-
insertedData = _a.sent();
|
|
142
|
-
return [2 /*return*/, insertedData];
|
|
143
|
-
}
|
|
144
|
-
});
|
|
145
|
-
}); };
|
|
146
|
-
var delete_ = function (id) { return __awaiter(_this, void 0, void 0, function () {
|
|
147
|
-
var result;
|
|
148
|
-
return __generator(this, function (_a) {
|
|
149
|
-
switch (_a.label) {
|
|
150
|
-
case 0: return [4 /*yield*/, connection(dataTableName).where("id", id).delete()];
|
|
151
|
-
case 1:
|
|
152
|
-
result = _a.sent();
|
|
153
|
-
return [2 /*return*/, result];
|
|
154
|
-
}
|
|
8
|
+
const flags = (0, core_1.flagPaths)(schema);
|
|
9
|
+
const searchableFields = flags.$search || [];
|
|
10
|
+
const filterableFields = flags.$filter || [];
|
|
11
|
+
const sortableFields = flags.$sort || [];
|
|
12
|
+
const get = async (id) => {
|
|
13
|
+
const c = await connection(dataTableName)
|
|
14
|
+
.select("*")
|
|
15
|
+
.where("id", id)
|
|
16
|
+
.first();
|
|
17
|
+
return c;
|
|
18
|
+
};
|
|
19
|
+
const update = async (id, patch) => {
|
|
20
|
+
await connection(dataTableName).where("id", id).update(patch);
|
|
21
|
+
return await get(id);
|
|
22
|
+
};
|
|
23
|
+
const create = async (params_) => {
|
|
24
|
+
const params = {
|
|
25
|
+
...params_,
|
|
26
|
+
};
|
|
27
|
+
let insertedId;
|
|
28
|
+
if (connection.client.config.client === "sqlite3") {
|
|
29
|
+
// SQLite does not support `.returning('id')`
|
|
30
|
+
const inserted = await connection(dataTableName)
|
|
31
|
+
.returning("id")
|
|
32
|
+
.insert({
|
|
33
|
+
...params,
|
|
34
|
+
});
|
|
35
|
+
insertedId = inserted[0].id;
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
// For other SQL clients that support `.returning('id')`
|
|
39
|
+
const inserted = await connection(dataTableName)
|
|
40
|
+
.returning("id")
|
|
41
|
+
.insert({
|
|
42
|
+
...params,
|
|
43
|
+
});
|
|
44
|
+
insertedId = inserted[0];
|
|
45
|
+
}
|
|
46
|
+
const insertedData = await get(insertedId);
|
|
47
|
+
return insertedData;
|
|
48
|
+
};
|
|
49
|
+
const replace = async (id, params_) => {
|
|
50
|
+
const params = {
|
|
51
|
+
id,
|
|
52
|
+
...params_,
|
|
53
|
+
};
|
|
54
|
+
const fields = [];
|
|
55
|
+
const values = [];
|
|
56
|
+
Object.keys(params).forEach((f) => {
|
|
57
|
+
fields.push(`\`${f}\`=?`);
|
|
58
|
+
values.push(params[f]);
|
|
155
59
|
});
|
|
156
|
-
|
|
157
|
-
|
|
60
|
+
await connection.raw(`REPLACE INTO \`${dataTableName}\` SET ${fields.join(", ")} WHERE id=?`, [
|
|
61
|
+
...values,
|
|
62
|
+
id, // Ensure the ID is at the end for the WHERE clause
|
|
63
|
+
]);
|
|
64
|
+
const insertedData = await get(id);
|
|
65
|
+
return insertedData;
|
|
66
|
+
};
|
|
67
|
+
const delete_ = async (id) => {
|
|
68
|
+
const result = await connection(dataTableName).where("id", id).delete();
|
|
69
|
+
return result;
|
|
70
|
+
};
|
|
71
|
+
const list = (0, list_1.KnexQueryList)(connection, dataTableName, searchableFields, filterableFields, sortableFields);
|
|
158
72
|
return {
|
|
159
|
-
schema
|
|
73
|
+
schema,
|
|
160
74
|
name: dataTableName,
|
|
161
|
-
get
|
|
162
|
-
replace
|
|
163
|
-
update
|
|
164
|
-
create
|
|
75
|
+
get,
|
|
76
|
+
replace,
|
|
77
|
+
update,
|
|
78
|
+
create,
|
|
165
79
|
delete: delete_,
|
|
166
|
-
list
|
|
80
|
+
list,
|
|
167
81
|
};
|
|
168
82
|
}
|
package/build/index.js
CHANGED
|
@@ -14,6 +14,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
|
|
17
|
+
const basic_1 = require("./basic");
|
|
18
18
|
exports.default = basic_1.KnexProvider;
|
|
19
19
|
__exportStar(require("./list"), exports);
|
package/build/list.js
CHANGED
|
@@ -1,192 +1,138 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __assign = (this && this.__assign) || function () {
|
|
3
|
-
__assign = Object.assign || function(t) {
|
|
4
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
-
s = arguments[i];
|
|
6
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
-
t[p] = s[p];
|
|
8
|
-
}
|
|
9
|
-
return t;
|
|
10
|
-
};
|
|
11
|
-
return __assign.apply(this, arguments);
|
|
12
|
-
};
|
|
13
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
14
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
15
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
16
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
17
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
18
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
19
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
20
|
-
});
|
|
21
|
-
};
|
|
22
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
23
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
24
|
-
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
25
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
26
|
-
function step(op) {
|
|
27
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
28
|
-
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
29
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
30
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
31
|
-
switch (op[0]) {
|
|
32
|
-
case 0: case 1: t = op; break;
|
|
33
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
34
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
35
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
36
|
-
default:
|
|
37
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
38
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
39
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
40
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
41
|
-
if (t[2]) _.ops.pop();
|
|
42
|
-
_.trys.pop(); continue;
|
|
43
|
-
}
|
|
44
|
-
op = body.call(thisArg, _);
|
|
45
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
46
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
50
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
51
4
|
};
|
|
52
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
53
6
|
exports.KnexQueryList = KnexQueryList;
|
|
54
7
|
// import dayjs from "dayjs";
|
|
55
|
-
|
|
56
|
-
|
|
8
|
+
const debug_1 = __importDefault(require("debug"));
|
|
9
|
+
const debug = (0, debug_1.default)("juadz:knex:list");
|
|
57
10
|
function KnexQueryList(knex, tableName, searchableFields, filterableFields, sortableFields) {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
if (
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
var field = f.field, op = f.op, value = f.value;
|
|
70
|
-
if (field === "_search" && op === "=") {
|
|
71
|
-
query.andWhere(function (query) {
|
|
72
|
-
(searchableFields || []).forEach(function (k) {
|
|
73
|
-
query.orWhere(k, "LIKE", "%".concat("".concat(value).replace(/(["'$%]+)/g, ""), "%"));
|
|
74
|
-
});
|
|
75
|
-
});
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
if (!filterableFields.includes(field)) {
|
|
79
|
-
debug("Field \"".concat(field, "\" is not filterable"));
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
var values = [];
|
|
83
|
-
if (Array.isArray(value)) {
|
|
84
|
-
values = value;
|
|
85
|
-
}
|
|
86
|
-
switch (op) {
|
|
87
|
-
case "=":
|
|
88
|
-
query.where(field, value);
|
|
89
|
-
return;
|
|
90
|
-
case "!=":
|
|
91
|
-
query.whereNot(field, value);
|
|
92
|
-
return;
|
|
93
|
-
case ">":
|
|
94
|
-
case ">=":
|
|
95
|
-
case "<":
|
|
96
|
-
case "<=":
|
|
97
|
-
query.where(field, op, value);
|
|
98
|
-
return;
|
|
99
|
-
case "in":
|
|
100
|
-
query.whereIn(field, values);
|
|
101
|
-
return;
|
|
102
|
-
case "!in":
|
|
103
|
-
query.whereNotIn(field, values);
|
|
104
|
-
return;
|
|
105
|
-
case "contains":
|
|
106
|
-
query.whereILike(field, "%".concat(value, "%"));
|
|
107
|
-
return;
|
|
108
|
-
case "!contains":
|
|
109
|
-
query.whereRaw("`".concat(field, "` NOT LIKE ?"), [
|
|
110
|
-
"%".concat(value, "%"),
|
|
111
|
-
]);
|
|
112
|
-
return;
|
|
113
|
-
case "between":
|
|
114
|
-
query.whereBetween(field, [values[0], values[1]]);
|
|
115
|
-
//if (query.client.config.client === "sqlite3") {
|
|
116
|
-
// query.whereBetween(field, [
|
|
117
|
-
// dayjs(values[0]).format(
|
|
118
|
-
// "YYYY-MM-DD HH:mm:ss",
|
|
119
|
-
// ),
|
|
120
|
-
// dayjs(values[1]).format(
|
|
121
|
-
// "YYYY-MM-DD HH:mm:ss",
|
|
122
|
-
// ),
|
|
123
|
-
// ]);
|
|
124
|
-
//} else {
|
|
125
|
-
// query.whereBetween(field, [
|
|
126
|
-
// values[0],
|
|
127
|
-
// values[1],
|
|
128
|
-
// ]);
|
|
129
|
-
//}
|
|
130
|
-
return;
|
|
131
|
-
case "!between":
|
|
132
|
-
query.whereNotBetween(field, [
|
|
133
|
-
values[0],
|
|
134
|
-
values[1],
|
|
135
|
-
]);
|
|
136
|
-
return;
|
|
137
|
-
case "null":
|
|
138
|
-
query.whereNull(field);
|
|
139
|
-
return;
|
|
140
|
-
case "!null":
|
|
141
|
-
query.whereNotNull(field);
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
11
|
+
return async (params) => {
|
|
12
|
+
const query = knex(tableName);
|
|
13
|
+
if (params.filter.length > 0) {
|
|
14
|
+
debug("Applying filters:", params.filter);
|
|
15
|
+
query.where((query) => {
|
|
16
|
+
params.filter.forEach((f) => {
|
|
17
|
+
const { field, op, value } = f;
|
|
18
|
+
if (field === "_search" && (op === "=" || op === "contains")) {
|
|
19
|
+
query.andWhere((query) => {
|
|
20
|
+
(searchableFields || []).forEach((k) => {
|
|
21
|
+
query.orWhere(k, "LIKE", `%${`${value}`.replace(/(["'$%]+)/g, "")}%`);
|
|
144
22
|
});
|
|
145
23
|
});
|
|
24
|
+
return;
|
|
146
25
|
}
|
|
147
|
-
|
|
148
|
-
debug("
|
|
26
|
+
if (!filterableFields.includes(field)) {
|
|
27
|
+
debug(`Field "${field}" is not filterable`);
|
|
28
|
+
return;
|
|
149
29
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
var pass = sortableFields.includes(s.field);
|
|
154
|
-
if (!pass) {
|
|
155
|
-
debug("Field \"".concat(s.field, "\" is not sortable"));
|
|
156
|
-
}
|
|
157
|
-
return pass;
|
|
158
|
-
})
|
|
159
|
-
.map(function (s) { return ({
|
|
160
|
-
column: s.field,
|
|
161
|
-
order: s.direction,
|
|
162
|
-
}); });
|
|
163
|
-
if (process.env.NODE_ENV !== "production") {
|
|
164
|
-
sql = query
|
|
165
|
-
.clone()
|
|
166
|
-
.offset(params.range.offset)
|
|
167
|
-
.limit(params.range.limit)
|
|
168
|
-
.orderBy(sorter)
|
|
169
|
-
.toString();
|
|
170
|
-
debug("SQL Query:", sql);
|
|
30
|
+
let values = [];
|
|
31
|
+
if (Array.isArray(value)) {
|
|
32
|
+
values = value;
|
|
171
33
|
}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
.
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
.
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
34
|
+
switch (op) {
|
|
35
|
+
case "=":
|
|
36
|
+
query.where(field, value);
|
|
37
|
+
return;
|
|
38
|
+
case "!=":
|
|
39
|
+
query.whereNot(field, value);
|
|
40
|
+
return;
|
|
41
|
+
case ">":
|
|
42
|
+
case ">=":
|
|
43
|
+
case "<":
|
|
44
|
+
case "<=":
|
|
45
|
+
query.where(field, op, value);
|
|
46
|
+
return;
|
|
47
|
+
case "in":
|
|
48
|
+
query.whereIn(field, values);
|
|
49
|
+
return;
|
|
50
|
+
case "!in":
|
|
51
|
+
query.whereNotIn(field, values);
|
|
52
|
+
return;
|
|
53
|
+
case "contains":
|
|
54
|
+
query.whereILike(field, `%${value}%`);
|
|
55
|
+
return;
|
|
56
|
+
case "!contains":
|
|
57
|
+
query.whereRaw(`\`${field}\` NOT LIKE ?`, [
|
|
58
|
+
`%${value}%`,
|
|
59
|
+
]);
|
|
60
|
+
return;
|
|
61
|
+
case "between":
|
|
62
|
+
query.whereBetween(field, [values[0], values[1]]);
|
|
63
|
+
//if (query.client.config.client === "sqlite3") {
|
|
64
|
+
// query.whereBetween(field, [
|
|
65
|
+
// dayjs(values[0]).format(
|
|
66
|
+
// "YYYY-MM-DD HH:mm:ss",
|
|
67
|
+
// ),
|
|
68
|
+
// dayjs(values[1]).format(
|
|
69
|
+
// "YYYY-MM-DD HH:mm:ss",
|
|
70
|
+
// ),
|
|
71
|
+
// ]);
|
|
72
|
+
//} else {
|
|
73
|
+
// query.whereBetween(field, [
|
|
74
|
+
// values[0],
|
|
75
|
+
// values[1],
|
|
76
|
+
// ]);
|
|
77
|
+
//}
|
|
78
|
+
return;
|
|
79
|
+
case "!between":
|
|
80
|
+
query.whereNotBetween(field, [
|
|
81
|
+
values[0],
|
|
82
|
+
values[1],
|
|
83
|
+
]);
|
|
84
|
+
return;
|
|
85
|
+
case "null":
|
|
86
|
+
query.whereNull(field);
|
|
87
|
+
return;
|
|
88
|
+
case "!null":
|
|
89
|
+
query.whereNotNull(field);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
debug("No filters applied");
|
|
97
|
+
}
|
|
98
|
+
let sql = null;
|
|
99
|
+
const sorter = params.sort
|
|
100
|
+
.filter((s) => {
|
|
101
|
+
const pass = sortableFields.includes(s.field);
|
|
102
|
+
if (!pass) {
|
|
103
|
+
debug(`Field "${s.field}" is not sortable`);
|
|
189
104
|
}
|
|
190
|
-
|
|
191
|
-
|
|
105
|
+
return pass;
|
|
106
|
+
})
|
|
107
|
+
.map((s) => ({
|
|
108
|
+
column: s.field,
|
|
109
|
+
order: s.direction,
|
|
110
|
+
}));
|
|
111
|
+
if (process.env.NODE_ENV !== "production") {
|
|
112
|
+
sql = query
|
|
113
|
+
.clone()
|
|
114
|
+
.offset(params.range.offset)
|
|
115
|
+
.limit(params.range.limit)
|
|
116
|
+
.orderBy(sorter)
|
|
117
|
+
.toString();
|
|
118
|
+
debug("SQL Query:", sql);
|
|
119
|
+
}
|
|
120
|
+
const data = await query
|
|
121
|
+
.clone()
|
|
122
|
+
.offset(params.range.offset)
|
|
123
|
+
.limit(params.range.limit)
|
|
124
|
+
.orderBy(sorter);
|
|
125
|
+
debug("Data fetched:", data.length, "rows");
|
|
126
|
+
const totalRow = await query
|
|
127
|
+
.clone()
|
|
128
|
+
.clearSelect()
|
|
129
|
+
.count("* AS T");
|
|
130
|
+
const total = totalRow && totalRow.length ? totalRow[0].T : 0;
|
|
131
|
+
debug("Total rows:", total);
|
|
132
|
+
return {
|
|
133
|
+
total,
|
|
134
|
+
data,
|
|
135
|
+
...(sql ? { sql } : {}),
|
|
136
|
+
};
|
|
137
|
+
};
|
|
192
138
|
}
|
package/build/list.test.js
CHANGED
|
@@ -1,120 +1,65 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
13
|
-
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
-
function step(op) {
|
|
16
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
-
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
18
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
-
switch (op[0]) {
|
|
21
|
-
case 0: case 1: t = op; break;
|
|
22
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
-
default:
|
|
26
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
-
if (t[2]) _.ops.pop();
|
|
31
|
-
_.trys.pop(); continue;
|
|
32
|
-
}
|
|
33
|
-
op = body.call(thisArg, _);
|
|
34
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
39
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
40
4
|
};
|
|
41
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
beforeAll(
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
table.string("last_name");
|
|
60
|
-
table.integer("age");
|
|
61
|
-
table.string("tool");
|
|
62
|
-
})];
|
|
63
|
-
case 1:
|
|
64
|
-
_a.sent();
|
|
65
|
-
return [4 /*yield*/, knex("users").insert([
|
|
66
|
-
{ name: "Peter", last_name: "Parker", age: 11, tool: "ruler" },
|
|
67
|
-
{ name: "Mark", last_name: "Olivier", age: 18, tool: "pencil" },
|
|
68
|
-
{ name: "Andre", last_name: "Hudson", age: 18, tool: "pen" },
|
|
69
|
-
{ name: "Tony", last_name: "Oliver", age: 18, tool: "pen" },
|
|
70
|
-
{ name: "Bruce", last_name: "Pedersen", age: 13, tool: "crayon" },
|
|
71
|
-
])];
|
|
72
|
-
case 2:
|
|
73
|
-
_a.sent();
|
|
74
|
-
return [2 /*return*/];
|
|
75
|
-
}
|
|
6
|
+
const list_1 = require("./list");
|
|
7
|
+
const knex_1 = __importDefault(require("knex"));
|
|
8
|
+
let knex;
|
|
9
|
+
beforeAll(async () => {
|
|
10
|
+
knex = (0, knex_1.default)({
|
|
11
|
+
client: "sqlite3",
|
|
12
|
+
connection: {
|
|
13
|
+
filename: ":memory:",
|
|
14
|
+
},
|
|
15
|
+
useNullAsDefault: true,
|
|
16
|
+
});
|
|
17
|
+
await knex.schema.createTable("users", (table) => {
|
|
18
|
+
table.increments();
|
|
19
|
+
table.string("name");
|
|
20
|
+
table.string("last_name");
|
|
21
|
+
table.integer("age");
|
|
22
|
+
table.string("tool");
|
|
76
23
|
});
|
|
77
|
-
|
|
78
|
-
|
|
24
|
+
await knex("users").insert([
|
|
25
|
+
{ name: "Peter", last_name: "Parker", age: 11, tool: "ruler" },
|
|
26
|
+
{ name: "Mark", last_name: "Olivier", age: 18, tool: "pencil" },
|
|
27
|
+
{ name: "Andre", last_name: "Hudson", age: 18, tool: "pen" },
|
|
28
|
+
{ name: "Tony", last_name: "Oliver", age: 18, tool: "pen" },
|
|
29
|
+
{ name: "Bruce", last_name: "Pedersen", age: 13, tool: "crayon" },
|
|
30
|
+
]);
|
|
31
|
+
});
|
|
32
|
+
afterAll(() => {
|
|
79
33
|
// The test uses an in-memory SQLite database (:memory:), so /tmp/test.sqlite is never created. Remove or update this cleanup to match the actual test database.
|
|
80
34
|
// unlink('/tmp/test.sqlite', () => {});
|
|
81
35
|
});
|
|
82
|
-
test("KnexQueryList",
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
expect(result.total).toBe(2);
|
|
104
|
-
expect(result.data[0]).toMatchObject({
|
|
105
|
-
name: "Peter",
|
|
106
|
-
last_name: "Parker",
|
|
107
|
-
age: 11,
|
|
108
|
-
tool: "ruler",
|
|
109
|
-
});
|
|
110
|
-
expect(result.data[1]).toMatchObject({
|
|
111
|
-
name: "Bruce",
|
|
112
|
-
last_name: "Pedersen",
|
|
113
|
-
age: 13,
|
|
114
|
-
tool: "crayon",
|
|
115
|
-
});
|
|
116
|
-
expect(debug).toBe("select * from `users` where ((`name` like '%Pe%' or `last_name` like '%Pe%') and `age` between 8 and 17 and `tool` not in ('pencil', 'pen')) order by `age` ASC limit 10");
|
|
117
|
-
return [2 /*return*/];
|
|
118
|
-
}
|
|
36
|
+
test("KnexQueryList", async () => {
|
|
37
|
+
const func = (0, list_1.KnexQueryList)(knex, "users", ["name", "last_name"], ["age", "tool"], ["age"]);
|
|
38
|
+
const result = await func({
|
|
39
|
+
resource: "users",
|
|
40
|
+
range: { offset: 0, limit: 10 },
|
|
41
|
+
sort: [{ field: "age", direction: "ASC" }],
|
|
42
|
+
filter: [
|
|
43
|
+
{ field: "_search", op: "=", value: "Pe" },
|
|
44
|
+
{ field: "age", op: "between", value: [8, 17] },
|
|
45
|
+
{ field: "tool", op: "!in", value: ["pencil", "pen"] },
|
|
46
|
+
],
|
|
47
|
+
});
|
|
48
|
+
const r = result;
|
|
49
|
+
const { sql: debug } = r;
|
|
50
|
+
expect(debug).toBe("select * from `users` where ((`name` like '%Pe%' or `last_name` like '%Pe%') and `age` between 8 and 17 and `tool` not in ('pencil', 'pen')) order by `age` ASC limit 10");
|
|
51
|
+
expect(result.total).toBe(2);
|
|
52
|
+
expect(result.data[0]).toMatchObject({
|
|
53
|
+
name: "Peter",
|
|
54
|
+
last_name: "Parker",
|
|
55
|
+
age: 11,
|
|
56
|
+
tool: "ruler",
|
|
119
57
|
});
|
|
120
|
-
|
|
58
|
+
expect(result.data[1]).toMatchObject({
|
|
59
|
+
name: "Bruce",
|
|
60
|
+
last_name: "Pedersen",
|
|
61
|
+
age: 13,
|
|
62
|
+
tool: "crayon",
|
|
63
|
+
});
|
|
64
|
+
expect(debug).toBe("select * from `users` where ((`name` like '%Pe%' or `last_name` like '%Pe%') and `age` between 8 and 17 and `tool` not in ('pencil', 'pen')) order by `age` ASC limit 10");
|
|
65
|
+
});
|
package/build/types.d.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/build/types.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@juadz/knex",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.4-beta2",
|
|
4
4
|
"description": "Juadz: Rapid restful API development",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"author": "hereblur",
|
|
21
21
|
"repository": {
|
|
22
22
|
"type": "git",
|
|
23
|
-
"url": "github.com/hereblur/juadz
|
|
23
|
+
"url": "github.com/hereblur/juadz.git"
|
|
24
24
|
},
|
|
25
25
|
"license": "MIT",
|
|
26
26
|
"devDependencies": {
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"zod": "^4"
|
|
49
49
|
},
|
|
50
50
|
"peerDependencies": {
|
|
51
|
-
"@juadz/core": "
|
|
51
|
+
"@juadz/core": "0.5.4-beta2",
|
|
52
52
|
"debug": "^4.4.0",
|
|
53
53
|
"zod": "^4"
|
|
54
54
|
},
|
package/src/list.ts
CHANGED
|
@@ -29,7 +29,7 @@ export function KnexQueryList<T>(
|
|
|
29
29
|
query.where((query: Knex) => {
|
|
30
30
|
params.filter.forEach((f: QueryFilter) => {
|
|
31
31
|
const { field, op, value } = f;
|
|
32
|
-
if (field === "_search" && op === "=") {
|
|
32
|
+
if (field === "_search" && (op === "=" || op === "contains")) {
|
|
33
33
|
query.andWhere((query: Knex) => {
|
|
34
34
|
(searchableFields || []).forEach((k) => {
|
|
35
35
|
query.orWhere(
|
package/tsconfig.json
CHANGED
|
@@ -3,9 +3,13 @@
|
|
|
3
3
|
"compilerOptions": {
|
|
4
4
|
"rootDir": "src",
|
|
5
5
|
"outDir": "build",
|
|
6
|
+
"noEmit": false,
|
|
6
7
|
"declaration": true,
|
|
7
8
|
"declarationDir": "build",
|
|
8
9
|
"emitDeclarationOnly": false,
|
|
10
|
+
"paths": {
|
|
11
|
+
"@juadz/core": ["../juadz-core/build/index.d.ts"]
|
|
12
|
+
}
|
|
9
13
|
},
|
|
10
14
|
"include": [
|
|
11
15
|
"src/**/*"
|