sql-love 1.0.2 → 1.0.4

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.
Files changed (56) hide show
  1. package/README.md +52 -32
  2. package/dist/index.cjs +16 -0
  3. package/dist/index.d.ts +732 -9
  4. package/dist/index.mjs +16 -0
  5. package/package.json +29 -12
  6. package/.github/workflows/node.js.yml +0 -37
  7. package/.prettierrc.json +0 -13
  8. package/CHANGELOG.md +0 -39
  9. package/CONTRIBUTING.md +0 -85
  10. package/assets/sql-love-logo.png +0 -0
  11. package/codecov.yml +0 -7
  12. package/dist/index.js +0 -9
  13. package/dist/src/Parser/Parser.d.ts +0 -157
  14. package/dist/src/Parser/Parser.js +0 -304
  15. package/dist/src/SelectBuilder/SelectBuilder.d.ts +0 -379
  16. package/dist/src/SelectBuilder/SelectBuilder.js +0 -810
  17. package/dist/src/extractGrouped/extractGrouped.d.ts +0 -17
  18. package/dist/src/extractGrouped/extractGrouped.js +0 -31
  19. package/dist/src/extractIndexed/extractIndexed.d.ts +0 -12
  20. package/dist/src/extractIndexed/extractIndexed.js +0 -23
  21. package/dist/src/extractLookup/extractLookup.d.ts +0 -9
  22. package/dist/src/extractLookup/extractLookup.js +0 -21
  23. package/dist/src/getPagination/getPagination.d.ts +0 -16
  24. package/dist/src/getPagination/getPagination.js +0 -40
  25. package/dist/src/runMysql/runMysql.d.ts +0 -58
  26. package/dist/src/runMysql/runMysql.js +0 -61
  27. package/dist/src/runPrisma/runPrisma.d.ts +0 -41
  28. package/dist/src/runPrisma/runPrisma.js +0 -34
  29. package/dist/src/substrCount/substrCount.d.ts +0 -6
  30. package/dist/src/substrCount/substrCount.js +0 -14
  31. package/dist/src/toSafeJson/toSafeJson.d.ts +0 -25
  32. package/dist/src/toSafeJson/toSafeJson.js +0 -45
  33. package/index.ts +0 -19
  34. package/src/Parser/Parser.spec.ts +0 -226
  35. package/src/Parser/Parser.ts +0 -325
  36. package/src/SelectBuilder/SelectBuilder.spec.ts +0 -785
  37. package/src/SelectBuilder/SelectBuilder.ts +0 -914
  38. package/src/extractGrouped/extractGrouped.spec.ts +0 -43
  39. package/src/extractGrouped/extractGrouped.ts +0 -36
  40. package/src/extractIndexed/extractIndexed.spec.ts +0 -40
  41. package/src/extractIndexed/extractIndexed.ts +0 -28
  42. package/src/extractLookup/extractLookup.spec.ts +0 -38
  43. package/src/extractLookup/extractLookup.ts +0 -33
  44. package/src/getPagination/getPagination.spec.ts +0 -75
  45. package/src/getPagination/getPagination.ts +0 -42
  46. package/src/runMysql/runMysql.spec.ts +0 -286
  47. package/src/runMysql/runMysql.ts +0 -106
  48. package/src/runPrisma/runPrisma.spec.ts +0 -99
  49. package/src/runPrisma/runPrisma.ts +0 -75
  50. package/src/substrCount/substrCount.spec.ts +0 -29
  51. package/src/substrCount/substrCount.ts +0 -14
  52. package/src/toSafeJson/toSafeJson.spec.ts +0 -28
  53. package/src/toSafeJson/toSafeJson.ts +0 -56
  54. package/tsconfig.build.json +0 -10
  55. package/tsconfig.json +0 -22
  56. package/vitest.config.ts +0 -11
@@ -1,43 +0,0 @@
1
- import extractGrouped from './extractGrouped';
2
-
3
- describe('extractGrouped()', () => {
4
- it('should handle grouping by string', () => {
5
- const records = [
6
- { id: 1, name: 'John', dept: 'Marketing' },
7
- { id: 2, name: 'Jane', dept: 'Finance' },
8
- { id: 3, name: 'Tim', dept: 'Marketing' },
9
- ];
10
- const grouped = extractGrouped('dept', records);
11
- expect(grouped).toEqual({
12
- Marketing: [
13
- { id: 1, name: 'John', dept: 'Marketing' },
14
- { id: 3, name: 'Tim', dept: 'Marketing' },
15
- ],
16
- Finance: [{ id: 2, name: 'Jane', dept: 'Finance' }],
17
- });
18
- });
19
- it('should handle grouping by integer', () => {
20
- const records = [
21
- { id: 1, name: 'John', deptId: 1 },
22
- { id: 2, name: 'Jane', deptId: 2 },
23
- { id: 3, name: 'Tim', deptId: 1 },
24
- ];
25
- const grouped = extractGrouped('deptId', records);
26
- expect(grouped).toEqual({
27
- 1: [
28
- { id: 1, name: 'John', deptId: 1 },
29
- { id: 3, name: 'Tim', deptId: 1 },
30
- ],
31
- 2: [{ id: 2, name: 'Jane', deptId: 2 }],
32
- });
33
- });
34
- it('should throw error if column is not present in every record', () => {
35
- const records = [
36
- { id: 1, name: 'John', deptId: 1 },
37
- { id: 2, name: 'Jane', deptId: 2 },
38
- { id: 3, name: 'Tim' },
39
- ];
40
- const thrower = () => extractGrouped('deptId', records);
41
- expect(thrower).toThrow();
42
- });
43
- });
@@ -1,36 +0,0 @@
1
- /**
2
- * Group database rows by a column value
3
- * @param field The database column to group by
4
- * @param records Records from the database
5
- * @example
6
- * extractGrouped('org', users); // result:
7
- * {
8
- * "Marketing": [
9
- * { id: 1, name: "John", org: "Marketing" },
10
- * { id: 2, name: "Jane", org: "Marketing" },
11
- * ],
12
- * "Finance": [
13
- * { id: 3, name: "Jose", org: "Finance" },
14
- * ],
15
- * }
16
- */
17
- export default function extractGrouped<DbRecord extends Record<string, any>>(
18
- field: keyof DbRecord,
19
- records: DbRecord[]
20
- ): Record<string, DbRecord[]> {
21
- let idx = 0;
22
- const grouped: Record<string, DbRecord[]> = {};
23
- for (const record of records) {
24
- if (!(field in record)) {
25
- throw new Error(
26
- `Column "${String(field)}" is not present in record ${idx}`
27
- );
28
- }
29
- if (!grouped[record[field]]) {
30
- grouped[record[field]] = [];
31
- }
32
- grouped[record[field]].push(record);
33
- idx++;
34
- }
35
- return grouped;
36
- }
@@ -1,40 +0,0 @@
1
- import extractIndexed from './extractIndexed';
2
-
3
- describe('extractIndexed()', () => {
4
- it('should handle indexing by string', () => {
5
- const records = [
6
- { uuid: '2d49f286-790d-4aee-b38b-94d0872e9bd8', name: 'John' },
7
- { uuid: '7d02664a-d03e-4882-88e2-23c701c314b5', name: 'Jane' },
8
- ];
9
- const indexed = extractIndexed('uuid', records);
10
- expect(indexed).toEqual({
11
- '2d49f286-790d-4aee-b38b-94d0872e9bd8': {
12
- uuid: '2d49f286-790d-4aee-b38b-94d0872e9bd8',
13
- name: 'John',
14
- },
15
- '7d02664a-d03e-4882-88e2-23c701c314b5': {
16
- uuid: '7d02664a-d03e-4882-88e2-23c701c314b5',
17
- name: 'Jane',
18
- },
19
- });
20
- });
21
- it('should handle indexing by integer', () => {
22
- const records = [
23
- { id: 1, name: 'John' },
24
- { id: 2, name: 'Jane' },
25
- ];
26
- const indexed = extractIndexed('id', records);
27
- expect(indexed).toEqual({
28
- 1: { id: 1, name: 'John' },
29
- 2: { id: 2, name: 'Jane' },
30
- });
31
- });
32
- it('should throw error if column is not present in every record', () => {
33
- const records = [
34
- { id: 1, name: 'John', employeeId: 'js102' },
35
- { id: 2, name: 'Jane' },
36
- ];
37
- const thrower = () => extractIndexed('employeeId', records);
38
- expect(thrower).toThrow();
39
- });
40
- });
@@ -1,28 +0,0 @@
1
- /**
2
- * Index each database row by a column value
3
- * @param field The database column to index by
4
- * @param records Records from the database
5
- * @example
6
- * extractIndexed('id', users); // result:
7
- * {
8
- * "1": { id: 1, name: "John" },
9
- * "2": { id: 2, name: "Jane" },
10
- * }
11
- */
12
- export default function extractIndexed<DbRecord extends Record<string, any>>(
13
- field: keyof DbRecord,
14
- records: DbRecord[]
15
- ) {
16
- let idx = 0;
17
- const indexed: Record<string, DbRecord> = {};
18
- for (const record of records) {
19
- if (!(field in record)) {
20
- throw new Error(
21
- `Column "${String(field)}" is not present in record ${idx}`
22
- );
23
- }
24
- indexed[record[field]] = record;
25
- idx++;
26
- }
27
- return indexed;
28
- }
@@ -1,38 +0,0 @@
1
- import extractLookup from './extractLookup';
2
-
3
- describe('extractLookup()', () => {
4
- it('should handle lookup by number', () => {
5
- const records = [
6
- { id: 1, name: 'John', age: 30 },
7
- { id: 2, name: 'Jane', age: 35 },
8
- ];
9
- const nameById = extractLookup('id', 'name', records);
10
- expect(nameById).toEqual({ '1': 'John', '2': 'Jane' });
11
- });
12
- it('should handle lookups with non-unique fields', () => {
13
- const records = [
14
- { id: 1, name: 'John', age: 30 },
15
- { id: 2, name: 'Jane', age: 30 },
16
- ];
17
- const ageById = extractLookup('age', 'name', records);
18
- expect(ageById).toEqual({ '30': 'Jane' });
19
- });
20
- it('should throw if key field is not present', () => {
21
- const records = [
22
- { id: 1, name: 'John', age: 30 },
23
- { id: 2, name: 'Jane' },
24
- ];
25
- // @ts-expect-error
26
- const thrower = () => extractLookup('age', 'name', records);
27
- expect(thrower).toThrow();
28
- });
29
- it('should throw if value field is not present', () => {
30
- const records = [
31
- { id: 1, name: 'John', age: 30 },
32
- { id: 2, name: 'Jane' },
33
- ];
34
- // @ts-expect-error
35
- const thrower = () => extractLookup('id', 'age', records);
36
- expect(thrower).toThrow();
37
- });
38
- });
@@ -1,33 +0,0 @@
1
- /**
2
- * Given an array of records, extract an object with keyField-valueField pairs
3
- * @param records An array of records
4
- * @param keyField The field to use as the key
5
- * @param valueField The field to use as the value
6
- */
7
- export default function extractLookup<
8
- T extends Array<Record<K | V, any>>,
9
- K extends keyof T[number],
10
- V extends keyof T[number],
11
- >(
12
- keyField: K,
13
- valueField: V,
14
- records: T
15
- ): { [key in T[number][K]]: T[number][V] } {
16
- const lookup: { [key in T[number][K]]: T[number][V] } = {} as any;
17
- let idx = 0;
18
- for (const record of records) {
19
- if (!(keyField in record)) {
20
- throw new Error(
21
- `Column "${String(keyField)}" is not present in record ${idx}`
22
- );
23
- }
24
- if (!(valueField in record)) {
25
- throw new Error(
26
- `Column "${String(valueField)}" is not present in record ${idx}`
27
- );
28
- }
29
- idx++;
30
- lookup[String(record[keyField])] = record[valueField];
31
- }
32
- return lookup;
33
- }
@@ -1,75 +0,0 @@
1
- import SelectBuilder from '../SelectBuilder/SelectBuilder';
2
- import getPagination from './getPagination';
3
-
4
- describe('getPagination()', () => {
5
- it('should handle 42 results with no offset', () => {
6
- const query = new SelectBuilder('SELECT * FROM users LIMIT 10');
7
- const pagination = getPagination(query, 42);
8
- expect(pagination).toEqual({
9
- page: 1,
10
- prevPage: null,
11
- nextPage: 2,
12
- perPage: 10,
13
- numPages: 5,
14
- total: 42,
15
- isFirst: true,
16
- isLast: false,
17
- });
18
- });
19
- it('should handle 42 results with offset', () => {
20
- const query = new SelectBuilder('SELECT * FROM users LIMIT 10').offset(20);
21
- const pagination = getPagination(query, 42n);
22
- expect(pagination).toEqual({
23
- page: 3,
24
- prevPage: 2,
25
- nextPage: 4,
26
- perPage: 10,
27
- numPages: 5,
28
- total: 42,
29
- isFirst: false,
30
- isLast: false,
31
- });
32
- });
33
- it('should handle 42 results with page', () => {
34
- const query = new SelectBuilder('SELECT * FROM users LIMIT 10').page(3);
35
- const pagination = getPagination(query, 42n);
36
- expect(pagination).toEqual({
37
- page: 3,
38
- prevPage: 2,
39
- nextPage: 4,
40
- perPage: 10,
41
- numPages: 5,
42
- total: 42,
43
- isFirst: false,
44
- isLast: false,
45
- });
46
- });
47
- it('should handle 0 results', () => {
48
- const query = new SelectBuilder('SELECT * FROM users LIMIT 10');
49
- const pagination = getPagination(query, 0);
50
- expect(pagination).toEqual({
51
- page: null,
52
- prevPage: null,
53
- nextPage: null,
54
- perPage: 10,
55
- numPages: 0,
56
- total: 0,
57
- isFirst: false,
58
- isLast: false,
59
- });
60
- });
61
- it('should handle when no limit is present', () => {
62
- const query = new SelectBuilder('SELECT * FROM users');
63
- const pagination = getPagination(query, 42);
64
- expect(pagination).toEqual({
65
- page: null,
66
- prevPage: null,
67
- nextPage: null,
68
- perPage: null,
69
- numPages: 0,
70
- total: 42,
71
- isFirst: false,
72
- isLast: false,
73
- });
74
- });
75
- });
@@ -1,42 +0,0 @@
1
- import type SelectBuilder from '../SelectBuilder/SelectBuilder';
2
-
3
- /**
4
- * Given a foundRows number of records and a limit, return the foundRows number of pages
5
- * @param query The query that was just run
6
- * @param total The number of records if there were no limit
7
- */
8
- export default function getPagination(
9
- query: SelectBuilder,
10
- total: BigInt | number
11
- ) {
12
- total = Number(total) || 0;
13
- const perPage = Number(query._limit) || null;
14
- let page: number | null = null;
15
- if (total === 0) {
16
- page = null;
17
- } else if (query._page) {
18
- page = Number(query._page);
19
- } else if (query._limit && query._offset) {
20
- page = Math.floor(Number(query._offset) / Number(query._limit)) + 1;
21
- } else if (query._limit && !query._offset) {
22
- page = 1;
23
- } else {
24
- page = null;
25
- }
26
- const numPages =
27
- total === 0 || perPage === null ? 0 : Math.ceil(total / perPage) || 0;
28
- const isFirst = page === 1;
29
- const isLast = numPages > 0 && page === numPages;
30
- const prevPage = numPages === 0 ? null : page - 1 || null;
31
- const nextPage = numPages > 0 && page + 1 <= numPages ? page + 1 : null;
32
- return {
33
- page,
34
- prevPage,
35
- nextPage,
36
- perPage,
37
- numPages,
38
- total,
39
- isFirst,
40
- isLast,
41
- };
42
- }
@@ -1,286 +0,0 @@
1
- import { vi } from 'vitest';
2
- import SelectBuilder from '../SelectBuilder/SelectBuilder';
3
- import {
4
- runMysql,
5
- runMysqlAsync,
6
- runMysqlAsyncWithCount,
7
- runMysqlWithCount,
8
- } from './runMysql';
9
-
10
- describe('runMysql', () => {
11
- it('should invoke client.query with correct args', async () => {
12
- const mockResults = [
13
- { id: 1, name: 'John', dept: 'Marketing' },
14
- { id: 2, name: 'Jane', dept: 'Marketing' },
15
- ];
16
- const mockFields = [{ name: 'id' }, { name: 'name' }, { name: 'dept' }];
17
- const client = {
18
- query: vi.fn(
19
- (
20
- sql: string,
21
- bindings: any[],
22
- callback: (
23
- err: Error | null,
24
- rows: Array<Record<string, any>>,
25
- fields: any[]
26
- ) => void
27
- ) => {
28
- callback(null, mockResults, mockFields);
29
- }
30
- ),
31
- };
32
- const query = new SelectBuilder('SELECT * FROM users').where(
33
- 'dept',
34
- 'Marketing'
35
- );
36
- const [results, fields] = await runMysql(client, query);
37
- expect(client.query.mock.calls[0][0]).toBe(
38
- 'SELECT\n *\nFROM users\nWHERE dept = ?'
39
- );
40
- expect(client.query.mock.calls[0][1]).toEqual(['Marketing']);
41
- expect(results).toBe(mockResults);
42
- expect(fields).toBe(mockFields);
43
- });
44
- it('should handle errors', async () => {
45
- const client = {
46
- query: vi.fn(
47
- (
48
- sql: string,
49
- bindings: any[],
50
- callback: (
51
- err: Error | null,
52
- rows: Array<Record<string, any>>,
53
- fields: any[]
54
- ) => void
55
- ) => {
56
- callback(new Error('Test Error'), [], []);
57
- }
58
- ),
59
- };
60
- const query = new SelectBuilder('SELECT * FROM users').where(
61
- 'dept',
62
- 'Marketing'
63
- );
64
- try {
65
- await runMysql(client, query);
66
- } catch (e) {
67
- expect(e.message).toBe('Test Error');
68
- }
69
- });
70
- it('should run with count', async () => {
71
- const mockResults1 = [
72
- { id: 1, name: 'John', dept: 'Marketing' },
73
- { id: 2, name: 'Jane', dept: 'Marketing' },
74
- ];
75
- const mockFields1 = [{ name: 'id' }, { name: 'name' }, { name: 'dept' }];
76
- const mockResults2 = [{ found_rows: 9 }];
77
- const mockFields2 = [{ name: 'found_rows' }];
78
- let callCount = 0;
79
- const client = {
80
- query: vi.fn(
81
- (
82
- sql: string,
83
- bindings: any[],
84
- callback: (
85
- err: Error | null,
86
- rows: Array<Record<string, any>>,
87
- fields: any[]
88
- ) => void
89
- ) => {
90
- if (++callCount === 1) {
91
- callback(null, mockResults1, mockFields1);
92
- }
93
- callback(null, mockResults2, mockFields2);
94
- }
95
- ),
96
- };
97
- const query = new SelectBuilder('SELECT * FROM users')
98
- .where('dept', 'Marketing')
99
- .limit(2)
100
- .page(5);
101
- const { records, total, pagination } = await runMysqlWithCount(
102
- client,
103
- query
104
- );
105
- expect(client.query.mock.calls[0][0]).toBe(
106
- 'SELECT\n *\nFROM users\nWHERE dept = ?\nOFFSET 8\nLIMIT 2'
107
- );
108
- expect(client.query.mock.calls[0][1]).toEqual(['Marketing']);
109
- expect(records).toBe(mockResults1);
110
- expect(total).toBe(9);
111
- expect(pagination).toEqual({
112
- page: 5,
113
- prevPage: 4,
114
- nextPage: null,
115
- perPage: 2,
116
- numPages: 5,
117
- total: 9,
118
- isFirst: false,
119
- isLast: true,
120
- });
121
- });
122
- it('should run when count is 0', async () => {
123
- const mockResults1 = [];
124
- const mockFields1 = [{ name: 'id' }, { name: 'name' }, { name: 'dept' }];
125
- const mockResults2 = [{ found_rows: 0 }];
126
- const mockFields2 = [{ name: 'found_rows' }];
127
- let callCount = 0;
128
- const client = {
129
- query: vi.fn(
130
- (
131
- sql: string,
132
- bindings: any[],
133
- callback: (
134
- err: Error | null,
135
- rows: Array<Record<string, any>>,
136
- fields: any[]
137
- ) => void
138
- ) => {
139
- if (++callCount === 1) {
140
- callback(null, mockResults1, mockFields1);
141
- }
142
- callback(null, mockResults2, mockFields2);
143
- }
144
- ),
145
- };
146
- const query = new SelectBuilder('SELECT * FROM users')
147
- .where('dept', 'Marketing')
148
- .limit(2)
149
- .page(5);
150
- const { records, total, pagination } = await runMysqlWithCount(
151
- client,
152
- query
153
- );
154
- expect(callCount).toBe(1);
155
- expect(records).toBe(mockResults1);
156
- expect(total).toBe(0);
157
- expect(pagination).toEqual({
158
- page: null,
159
- prevPage: null,
160
- nextPage: null,
161
- perPage: 2,
162
- numPages: 0,
163
- total: 0,
164
- isFirst: false,
165
- isLast: false,
166
- });
167
- });
168
- it('should invoke client.query with correct args (promises)', async () => {
169
- const mockResults = [
170
- { id: 1, name: 'John', dept: 'Marketing' },
171
- { id: 2, name: 'Jane', dept: 'Marketing' },
172
- ];
173
- const mockFields = [{ name: 'id' }, { name: 'name' }, { name: 'dept' }];
174
- const client = {
175
- query: vi.fn((sql: string, bindings: any[]) => {
176
- return Promise.resolve([mockResults, mockFields]);
177
- }),
178
- };
179
- const query = new SelectBuilder('SELECT * FROM users').where(
180
- 'dept',
181
- 'Marketing'
182
- );
183
- // @ts-expect-error
184
- const [results, fields] = await runMysqlAsync(client, query);
185
- expect(client.query).toHaveBeenCalledWith(
186
- 'SELECT\n *\nFROM users\nWHERE dept = ?',
187
- ['Marketing']
188
- );
189
- expect(results).toBe(mockResults);
190
- expect(fields).toBe(mockFields);
191
- });
192
- it('should run with count (promises)', async () => {
193
- const mockResults1 = [
194
- { id: 1, name: 'John', dept: 'Marketing' },
195
- { id: 2, name: 'Jane', dept: 'Marketing' },
196
- ];
197
- const mockFields1 = [{ name: 'id' }, { name: 'name' }, { name: 'dept' }];
198
- const mockResults2 = [{ found_rows: 9 }];
199
- const mockFields2 = [{ name: 'found_rows' }];
200
- let callCount = 0;
201
- const client = {
202
- query: vi.fn((sql: string, bindings: any[]) => {
203
- if (++callCount === 1) {
204
- return Promise.resolve([mockResults1, mockFields1]);
205
- }
206
- return Promise.resolve([mockResults2, mockFields2]);
207
- }),
208
- };
209
- const query = new SelectBuilder('SELECT * FROM users')
210
- .where('dept', 'Marketing')
211
- .limit(2)
212
- .page(5);
213
- const { records, total, pagination, fields } = await runMysqlAsyncWithCount(
214
- // @ts-expect-error
215
- client,
216
- query
217
- );
218
- expect(callCount).toBe(2);
219
- expect(records).toBe(mockResults1);
220
- expect(total).toBe(9);
221
- expect(pagination).toEqual({
222
- page: 5,
223
- prevPage: 4,
224
- nextPage: null,
225
- perPage: 2,
226
- numPages: 5,
227
- total: 9,
228
- isFirst: false,
229
- isLast: true,
230
- });
231
- expect(fields).toEqual(mockFields1);
232
- });
233
- it('should run with count of zero (promises)', async () => {
234
- const mockResults1 = [];
235
- const mockFields1 = [{ name: 'id' }, { name: 'name' }, { name: 'dept' }];
236
- const mockResults2 = [{ found_rows: 0 }];
237
- const mockFields2 = [{ name: 'found_rows' }];
238
- let callCount = 0;
239
- const client = {
240
- query: vi.fn((sql: string, bindings: any[]) => {
241
- if (++callCount === 1) {
242
- return Promise.resolve([mockResults1, mockFields1]);
243
- }
244
- return Promise.resolve([mockResults2, mockFields2]);
245
- }),
246
- };
247
- const query = new SelectBuilder('SELECT * FROM users')
248
- .where('dept', 'Marketing')
249
- .limit(2)
250
- .page(5);
251
- const { records, total, pagination } = await runMysqlAsyncWithCount(
252
- // @ts-expect-error
253
- client,
254
- query
255
- );
256
- expect(callCount).toBe(1);
257
- expect(records).toBe(mockResults1);
258
- expect(total).toBe(0);
259
- expect(pagination).toEqual({
260
- page: null,
261
- prevPage: null,
262
- nextPage: null,
263
- perPage: 2,
264
- numPages: 0,
265
- total: 0,
266
- isFirst: false,
267
- isLast: false,
268
- });
269
- });
270
- it('should handle errors (promises)', async () => {
271
- const client = {
272
- query: vi.fn((sql: string, bindings: any[]) => {
273
- return Promise.reject('Test Test');
274
- }),
275
- };
276
- const query = new SelectBuilder('SELECT * FROM users').where(
277
- 'dept',
278
- 'Marketing'
279
- );
280
- try {
281
- await runMysqlAsync(client, query);
282
- } catch (e) {
283
- expect(e).toBe('Test Test');
284
- }
285
- });
286
- });