@juadz/knex 0.5.0 → 0.5.2

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/build/basic.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  import { IDataRecord, IDataRepositoryProvider } from "@juadz/core";
2
2
  import { Knex } from "knex";
3
- export declare function KnexProvider<T extends IDataRecord>(connection: Knex, dataTableName?: string): IDataRepositoryProvider<T>;
3
+ import { output, ZodObject, ZodRawShape } from "zod";
4
+ export declare function KnexProvider<Shape extends ZodRawShape, Schema extends ZodObject<Shape>, T extends IDataRecord = output<Schema> & IDataRecord>(dataTableName: string, schema: Schema, connection: Knex): IDataRepositoryProvider<T>;
package/build/basic.js CHANGED
@@ -57,53 +57,20 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
57
57
  };
58
58
  Object.defineProperty(exports, "__esModule", { value: true });
59
59
  exports.KnexProvider = KnexProvider;
60
+ var core_1 = require("@juadz/core");
60
61
  var list_1 = require("./list");
61
- function KnexProvider(connection, dataTableName) {
62
+ function KnexProvider(dataTableName, schema, connection) {
62
63
  var _this = this;
63
- var tableName = dataTableName || null;
64
- var searchableFields = [];
65
- var filterableFields = [];
66
- var sortableFields = [];
67
- var init = function (sch) { return __awaiter(_this, void 0, void 0, function () {
68
- return __generator(this, function (_a) {
69
- if (!tableName) {
70
- tableName = sch.name;
71
- }
72
- searchableFields = Object.entries(sch.flags)
73
- .filter(function (_a) {
74
- var _ = _a[0], v = _a[1];
75
- return v.$search == true;
76
- })
77
- .map(function (_a) {
78
- var k = _a[0], _ = _a[1];
79
- return k;
80
- });
81
- filterableFields = Object.entries(sch.flags)
82
- .filter(function (_a) {
83
- var _ = _a[0], v = _a[1];
84
- return v.$filter == true;
85
- })
86
- .map(function (_a) {
87
- var k = _a[0], _ = _a[1];
88
- return k;
89
- });
90
- sortableFields = Object.entries(sch.flags)
91
- .filter(function (_a) {
92
- var _ = _a[0], v = _a[1];
93
- return v.$sort == true;
94
- })
95
- .map(function (_a) {
96
- var k = _a[0], _ = _a[1];
97
- return k;
98
- });
99
- return [2 /*return*/];
100
- });
101
- }); };
64
+ // schema.name = schema.name || dataTableName;
65
+ var flags = (0, core_1.flagPaths)(schema);
66
+ var searchableFields = flags.$search || [];
67
+ var filterableFields = flags.$filter || [];
68
+ var sortableFields = flags.$sort || [];
102
69
  var get = function (id) { return __awaiter(_this, void 0, void 0, function () {
103
70
  var c;
104
71
  return __generator(this, function (_a) {
105
72
  switch (_a.label) {
106
- case 0: return [4 /*yield*/, connection(tableName)
73
+ case 0: return [4 /*yield*/, connection(dataTableName)
107
74
  .select("*")
108
75
  .where("id", id)
109
76
  .first()];
@@ -116,7 +83,7 @@ function KnexProvider(connection, dataTableName) {
116
83
  var update = function (id, patch) { return __awaiter(_this, void 0, void 0, function () {
117
84
  return __generator(this, function (_a) {
118
85
  switch (_a.label) {
119
- case 0: return [4 /*yield*/, connection(tableName).where("id", id).update(patch)];
86
+ case 0: return [4 /*yield*/, connection(dataTableName).where("id", id).update(patch)];
120
87
  case 1:
121
88
  _a.sent();
122
89
  return [4 /*yield*/, get(id)];
@@ -131,14 +98,14 @@ function KnexProvider(connection, dataTableName) {
131
98
  case 0:
132
99
  params = __assign({}, params_);
133
100
  if (!(connection.client.config.client === "sqlite3")) return [3 /*break*/, 2];
134
- return [4 /*yield*/, connection(tableName)
101
+ return [4 /*yield*/, connection(dataTableName)
135
102
  .returning("id")
136
103
  .insert(__assign({}, params))];
137
104
  case 1:
138
105
  inserted = _a.sent();
139
106
  insertedId = inserted[0].id;
140
107
  return [3 /*break*/, 4];
141
- case 2: return [4 /*yield*/, connection(tableName)
108
+ case 2: return [4 /*yield*/, connection(dataTableName)
142
109
  .returning("id")
143
110
  .insert(__assign({}, params))];
144
111
  case 3:
@@ -164,7 +131,7 @@ function KnexProvider(connection, dataTableName) {
164
131
  fields.push("`".concat(f, "`=?"));
165
132
  values.push(params[f]);
166
133
  });
167
- return [4 /*yield*/, connection.raw("REPLACE INTO `".concat(tableName, "` SET ").concat(fields.join(", "), " WHERE id=?"), __spreadArray(__spreadArray([], values, true), [
134
+ return [4 /*yield*/, connection.raw("REPLACE INTO `".concat(dataTableName, "` SET ").concat(fields.join(", "), " WHERE id=?"), __spreadArray(__spreadArray([], values, true), [
168
135
  id, // Ensure the ID is at the end for the WHERE clause
169
136
  ], false))];
170
137
  case 1:
@@ -180,16 +147,17 @@ function KnexProvider(connection, dataTableName) {
180
147
  var result;
181
148
  return __generator(this, function (_a) {
182
149
  switch (_a.label) {
183
- case 0: return [4 /*yield*/, connection(tableName).where("id", id).delete()];
150
+ case 0: return [4 /*yield*/, connection(dataTableName).where("id", id).delete()];
184
151
  case 1:
185
152
  result = _a.sent();
186
153
  return [2 /*return*/, result];
187
154
  }
188
155
  });
189
156
  }); };
190
- var list = (0, list_1.KnexQueryList)(connection, tableName, searchableFields, filterableFields, sortableFields);
157
+ var list = (0, list_1.KnexQueryList)(connection, dataTableName, searchableFields, filterableFields, sortableFields);
191
158
  return {
192
- init: init,
159
+ schema: schema,
160
+ name: dataTableName,
193
161
  get: get,
194
162
  replace: replace,
195
163
  update: update,
package/build/list.js CHANGED
@@ -51,7 +51,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
51
51
  };
52
52
  Object.defineProperty(exports, "__esModule", { value: true });
53
53
  exports.KnexQueryList = KnexQueryList;
54
- var dayjs_1 = __importDefault(require("dayjs"));
54
+ // import dayjs from "dayjs";
55
55
  var debug_1 = __importDefault(require("debug"));
56
56
  var debug = (0, debug_1.default)("juadz:knex:list");
57
57
  function KnexQueryList(knex, tableName, searchableFields, filterableFields, sortableFields) {
@@ -67,10 +67,10 @@ function KnexQueryList(knex, tableName, searchableFields, filterableFields, sort
67
67
  query.where(function (query) {
68
68
  params.filter.forEach(function (f) {
69
69
  var field = f.field, op = f.op, value = f.value;
70
- if ((field === "_search") && op === "=") {
70
+ if (field === "_search" && op === "=") {
71
71
  query.andWhere(function (query) {
72
72
  (searchableFields || []).forEach(function (k) {
73
- query.orWhere(k, 'LIKE', "%".concat("".concat(value).replace(/(["'$%]+)/g, ''), "%"));
73
+ query.orWhere(k, "LIKE", "%".concat("".concat(value).replace(/(["'$%]+)/g, ""), "%"));
74
74
  });
75
75
  });
76
76
  return;
@@ -111,18 +111,22 @@ function KnexQueryList(knex, tableName, searchableFields, filterableFields, sort
111
111
  ]);
112
112
  return;
113
113
  case "between":
114
- if (query.client.config.client === "sqlite3") {
115
- query.whereBetween(field, [
116
- (0, dayjs_1.default)(values[0]).format("YYYY-MM-DD HH:mm:ss"),
117
- (0, dayjs_1.default)(values[1]).format("YYYY-MM-DD HH:mm:ss"),
118
- ]);
119
- }
120
- else {
121
- query.whereBetween(field, [
122
- values[0],
123
- values[1],
124
- ]);
125
- }
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
+ //}
126
130
  return;
127
131
  case "!between":
128
132
  query.whereNotBetween(field, [
@@ -144,13 +148,14 @@ function KnexQueryList(knex, tableName, searchableFields, filterableFields, sort
144
148
  debug("No filters applied");
145
149
  }
146
150
  sql = null;
147
- sorter = params.sort.filter((function (s) {
151
+ sorter = params.sort
152
+ .filter(function (s) {
148
153
  var pass = sortableFields.includes(s.field);
149
154
  if (!pass) {
150
155
  debug("Field \"".concat(s.field, "\" is not sortable"));
151
156
  }
152
157
  return pass;
153
- }))
158
+ })
154
159
  .map(function (s) { return ({
155
160
  column: s.field,
156
161
  order: s.direction,
@@ -84,7 +84,7 @@ test("KnexQueryList", function () { return __awaiter(void 0, void 0, void 0, fun
84
84
  return __generator(this, function (_a) {
85
85
  switch (_a.label) {
86
86
  case 0:
87
- func = (0, list_1.KnexQueryList)(knex, "users", ['name', 'lastname'], ['age', 'tool'], ['age']);
87
+ func = (0, list_1.KnexQueryList)(knex, "users", ["name", "last_name"], ["age", "tool"], ["age"]);
88
88
  return [4 /*yield*/, func({
89
89
  resource: "users",
90
90
  range: { offset: 0, limit: 10 },
@@ -97,6 +97,9 @@ test("KnexQueryList", function () { return __awaiter(void 0, void 0, void 0, fun
97
97
  })];
98
98
  case 1:
99
99
  result = _a.sent();
100
+ r = result;
101
+ debug = r.sql;
102
+ 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");
100
103
  expect(result.total).toBe(2);
101
104
  expect(result.data[0]).toMatchObject({
102
105
  name: "Peter",
@@ -110,8 +113,6 @@ test("KnexQueryList", function () { return __awaiter(void 0, void 0, void 0, fun
110
113
  age: 13,
111
114
  tool: "crayon",
112
115
  });
113
- r = result;
114
- debug = r.debug;
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");
116
117
  return [2 /*return*/];
117
118
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@juadz/knex",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "description": "Juadz: Rapid restful API development",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -27,6 +27,7 @@
27
27
  "@babel/core": "^7.26.7",
28
28
  "@babel/preset-env": "^7.26.7",
29
29
  "@babel/preset-typescript": "^7.26.0",
30
+ "@juadz/core": "^0.5.0",
30
31
  "@types/debug": "^4.1.12",
31
32
  "@types/jest": "^29.5.14",
32
33
  "@types/node": "^22.7.5",
@@ -44,13 +45,12 @@
44
45
  "sqlite": "^5.1.1",
45
46
  "tsc": "^2.0.4",
46
47
  "typescript": "^5.6.3",
47
- "zod": "^4",
48
- "@juadz/core": "^0.5.0"
48
+ "zod": "^4"
49
49
  },
50
50
  "peerDependencies": {
51
+ "@juadz/core": "^0.5.0",
51
52
  "debug": "^4.4.0",
52
- "zod": "^4",
53
- "@juadz/core": "^0.5.0"
53
+ "zod": "^4"
54
54
  },
55
55
  "dependencies": {}
56
56
  }
package/src/basic.ts CHANGED
@@ -1,35 +1,26 @@
1
- import { IDataRecord, IDataRepositoryProvider, Schema } from "@juadz/core";
1
+ import { flagPaths, IDataRecord, IDataRepositoryProvider } from "@juadz/core";
2
2
  import { Knex } from "knex";
3
3
  import { KnexQueryList } from "./list";
4
-
5
- export function KnexProvider<T extends IDataRecord>(
4
+ import { output, ZodObject, ZodRawShape } from "zod";
5
+
6
+ export function KnexProvider<
7
+ Shape extends ZodRawShape,
8
+ Schema extends ZodObject<Shape>,
9
+ T extends IDataRecord = output<Schema> & IDataRecord,
10
+ >(
11
+ dataTableName: string,
12
+ schema: Schema,
6
13
  connection: Knex,
7
- dataTableName?: string,
8
14
  ): IDataRepositoryProvider<T> {
15
+ // schema.name = schema.name || dataTableName;
16
+ const flags = flagPaths(schema);
9
17
 
10
- let tableName = dataTableName || null;
11
- let searchableFields: Array<string> = [];
12
- let filterableFields: Array<string> = [];
13
- let sortableFields: Array<string> = [];
14
-
15
- const init = async (sch: Schema<T>) => {
16
- if (!tableName) {
17
- tableName = sch.name;
18
- }
19
-
20
- searchableFields = Object.entries(sch.flags)
21
- .filter(([_, v]) => v.$search == true)
22
- .map(([k, _]) => k);
23
- filterableFields = Object.entries(sch.flags)
24
- .filter(([_, v]) => v.$filter == true)
25
- .map(([k, _]) => k);
26
- sortableFields = Object.entries(sch.flags)
27
- .filter(([_, v]) => v.$sort == true)
28
- .map(([k, _]) => k);
29
- }
18
+ const searchableFields = flags.$search || [];
19
+ const filterableFields = flags.$filter || [];
20
+ const sortableFields = flags.$sort || [];
30
21
 
31
22
  const get = async (id: string | number) => {
32
- const c = await connection(tableName)
23
+ const c = await connection(dataTableName)
33
24
  .select("*")
34
25
  .where("id", id)
35
26
  .first();
@@ -38,7 +29,7 @@ export function KnexProvider<T extends IDataRecord>(
38
29
  };
39
30
 
40
31
  const update = async (id: string | number, patch: object) => {
41
- await connection(tableName).where("id", id).update(patch);
32
+ await connection(dataTableName).where("id", id).update(patch);
42
33
 
43
34
  return await get(id);
44
35
  };
@@ -52,16 +43,16 @@ export function KnexProvider<T extends IDataRecord>(
52
43
 
53
44
  if (connection.client.config.client === "sqlite3") {
54
45
  // SQLite does not support `.returning('id')`
55
- const inserted = await connection(tableName)
46
+ const inserted = await connection(dataTableName)
56
47
  .returning("id")
57
48
  .insert({
58
49
  ...params,
59
50
  });
60
51
 
61
52
  insertedId = (inserted[0] as unknown as { id: string | number }).id;
62
- } else {
53
+ } else {
63
54
  // For other SQL clients that support `.returning('id')`
64
- const inserted = await connection(tableName)
55
+ const inserted = await connection(dataTableName)
65
56
  .returning("id")
66
57
  .insert({
67
58
  ...params,
@@ -88,7 +79,7 @@ export function KnexProvider<T extends IDataRecord>(
88
79
  });
89
80
 
90
81
  await connection.raw(
91
- `REPLACE INTO \`${tableName}\` SET ${fields.join(", ")} WHERE id=?`,
82
+ `REPLACE INTO \`${dataTableName}\` SET ${fields.join(", ")} WHERE id=?`,
92
83
  [
93
84
  ...values,
94
85
  id, // Ensure the ID is at the end for the WHERE clause
@@ -101,15 +92,23 @@ export function KnexProvider<T extends IDataRecord>(
101
92
  };
102
93
 
103
94
  const delete_ = async (id: string | number) => {
104
- const result = await connection(tableName).where("id", id).delete();
95
+ const result = await connection(dataTableName).where("id", id).delete();
105
96
 
106
97
  return result;
107
98
  };
108
99
 
109
- const list = KnexQueryList(connection, tableName, searchableFields, filterableFields, sortableFields);
100
+ const list = KnexQueryList(
101
+ connection,
102
+ dataTableName,
103
+ searchableFields,
104
+ filterableFields,
105
+ sortableFields,
106
+ );
110
107
 
111
108
  return {
112
- init,
109
+ schema,
110
+ name: dataTableName,
111
+
113
112
  get,
114
113
  replace,
115
114
  update,
package/src/list.test.ts CHANGED
@@ -39,7 +39,13 @@ afterAll(() => {
39
39
  });
40
40
 
41
41
  test("KnexQueryList", async () => {
42
- const func = KnexQueryList(knex, "users", ['name', 'lastname'], ['age', 'tool'], ['age']);
42
+ const func = KnexQueryList(
43
+ knex,
44
+ "users",
45
+ ["name", "last_name"],
46
+ ["age", "tool"],
47
+ ["age"],
48
+ );
43
49
 
44
50
  const result: QueryListResults<unknown> = await func({
45
51
  resource: "users",
@@ -51,6 +57,12 @@ test("KnexQueryList", async () => {
51
57
  { field: "tool", op: "!in", value: ["pencil", "pen"] },
52
58
  ],
53
59
  });
60
+ const r = result as unknown;
61
+ const { sql: debug } = r as DebugObj;
62
+
63
+ expect(debug).toBe(
64
+ "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
+ );
54
66
 
55
67
  expect(result.total).toBe(2);
56
68
  expect(result.data[0]).toMatchObject({
@@ -66,13 +78,11 @@ test("KnexQueryList", async () => {
66
78
  tool: "crayon",
67
79
  });
68
80
 
69
- const r = result as unknown;
70
- const { debug } = r as DebugObj;
71
81
  expect(debug).toBe(
72
82
  "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",
73
83
  );
74
84
  });
75
85
 
76
86
  interface DebugObj {
77
- debug: string;
87
+ sql: string;
78
88
  }
package/src/list.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { QueryListParam, QueryFilter, QueryListFunction } from "@juadz/core";
2
2
 
3
3
  import { Knex } from "knex";
4
- import dayjs from "dayjs";
4
+ // import dayjs from "dayjs";
5
5
  import Debug from "debug";
6
6
 
7
7
  const debug = Debug("juadz:knex:list");
@@ -18,7 +18,7 @@ export function KnexQueryList<T>(
18
18
  knex: Knex,
19
19
  tableName: string,
20
20
  searchableFields: string[],
21
- filterableFields: string[],
21
+ filterableFields: string[],
22
22
  sortableFields: string[],
23
23
  ): QueryListFunction<T> {
24
24
  return async (params: QueryListParam) => {
@@ -29,16 +29,15 @@ 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 === "=") {
33
33
  query.andWhere((query: Knex) => {
34
-
35
- (searchableFields || []).forEach(k => {
36
- query.orWhere(
37
- k as string,
38
- 'LIKE',
39
- `%${`${value}`.replace(/(["'$%]+)/g, '')}%`
40
- );
41
- });
34
+ (searchableFields || []).forEach((k) => {
35
+ query.orWhere(
36
+ k as string,
37
+ "LIKE",
38
+ `%${`${value}`.replace(/(["'$%]+)/g, "")}%`,
39
+ );
40
+ });
42
41
  });
43
42
  return;
44
43
  }
@@ -81,21 +80,22 @@ export function KnexQueryList<T>(
81
80
  ]);
82
81
  return;
83
82
  case "between":
84
- if (query.client.config.client === "sqlite3") {
85
- query.whereBetween(field, [
86
- dayjs(values[0]).format(
87
- "YYYY-MM-DD HH:mm:ss",
88
- ),
89
- dayjs(values[1]).format(
90
- "YYYY-MM-DD HH:mm:ss",
91
- ),
92
- ]);
93
- } else {
94
- query.whereBetween(field, [
95
- values[0],
96
- values[1],
97
- ]);
98
- }
83
+ query.whereBetween(field, [values[0], values[1]]);
84
+ //if (query.client.config.client === "sqlite3") {
85
+ // query.whereBetween(field, [
86
+ // dayjs(values[0]).format(
87
+ // "YYYY-MM-DD HH:mm:ss",
88
+ // ),
89
+ // dayjs(values[1]).format(
90
+ // "YYYY-MM-DD HH:mm:ss",
91
+ // ),
92
+ // ]);
93
+ //} else {
94
+ // query.whereBetween(field, [
95
+ // values[0],
96
+ // values[1],
97
+ // ]);
98
+ //}
99
99
 
100
100
  return;
101
101
  case "!between":
@@ -119,18 +119,18 @@ export function KnexQueryList<T>(
119
119
 
120
120
  let sql = null;
121
121
 
122
- const sorter = params.sort.filter((s => {
123
- const pass = sortableFields.includes(s.field);
124
- if (!pass) {
125
- debug(`Field "${s.field}" is not sortable`);
126
- }
127
- return pass;
128
- }))
129
- .map((s) => ({
130
- column: s.field,
131
- order: s.direction,
132
- }));
133
-
122
+ const sorter = params.sort
123
+ .filter((s) => {
124
+ const pass = sortableFields.includes(s.field);
125
+ if (!pass) {
126
+ debug(`Field "${s.field}" is not sortable`);
127
+ }
128
+ return pass;
129
+ })
130
+ .map((s) => ({
131
+ column: s.field,
132
+ order: s.direction,
133
+ }));
134
134
 
135
135
  if (process.env.NODE_ENV !== "production") {
136
136
  sql = query
@@ -142,7 +142,6 @@ export function KnexQueryList<T>(
142
142
  debug("SQL Query:", sql);
143
143
  }
144
144
 
145
-
146
145
  const data = await query
147
146
  .clone()
148
147
  .offset(params.range.offset)