UNPKG

kysely-mapper

Version:

Flexible Kysely-based utility for mapping between tables and objects

335 lines 16.9 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const kysely_1 = require("kysely"); const test_setup_1 = require("./utils/test-setup"); const test_mappers_1 = require("./utils/test-mappers"); const test_objects_1 = require("./utils/test-objects"); const test_utils_1 = require("./utils/test-utils"); let db; let userMapperReturningDefault; let userMapperReturningNothing; let userMapperReturningID; let userMapperReturningIDAndHandleAsH; let userMapperReturningAll; beforeAll(() => __awaiter(void 0, void 0, void 0, function* () { db = yield (0, test_setup_1.createDB)(); userMapperReturningDefault = (0, test_mappers_1.createUserMapperReturningDefault)(db); userMapperReturningNothing = (0, test_mappers_1.createUserMapperReturningNothing)(db); userMapperReturningID = (0, test_mappers_1.createUserMapperReturningID)(db); userMapperReturningIDAndHandleAsH = (0, test_mappers_1.createUserMapperReturningIDAndHandleAsH)(db); userMapperReturningAll = (0, test_mappers_1.createUserMapperReturningAll)(db); })); beforeEach(() => (0, test_setup_1.resetDB)(db)); afterAll(() => (0, test_setup_1.destroyDB)(db)); describe('general update', () => { it('updates nothing returning zero update count', () => __awaiter(void 0, void 0, void 0, function* () { const updateValues = { email: 'new.email@xyz.pdq' }; const success = yield userMapperReturningAll .update({ id: 1 }) .run(updateValues); expect(success).toBe(false); const updateCount = yield userMapperReturningAll .update({ id: 1 }) .returnCount(updateValues); expect(updateCount).toEqual(0); const updates = yield userMapperReturningID .update({ id: 1 }) .returnAll(updateValues); expect(updates.length).toEqual(0); const update = yield userMapperReturningID .update({ id: 1 }) .returnOne(updateValues); expect(update).toBeNull(); })); it('updates something returning non-zero update count', () => __awaiter(void 0, void 0, void 0, function* () { const updateValues = { email: 'new.email@xyz.pdq' }; const insertReturn0 = yield userMapperReturningID .insert() .returnOne(test_objects_1.USERS[0]); yield userMapperReturningID.insert().run(test_objects_1.USERS[1]); yield userMapperReturningID.insert().run(test_objects_1.USERS[2]); const updateCount1 = yield userMapperReturningAll .update({ id: insertReturn0.id }) .returnCount(updateValues); expect(updateCount1).toEqual(1); const readUser1 = yield userMapperReturningID .select('id', '=', insertReturn0.id) .returnOne(); expect(readUser1 === null || readUser1 === void 0 ? void 0 : readUser1.email).toEqual(updateValues.email); const updateCount2 = yield userMapperReturningAll .update({ name: 'Sue' }) .returnCount(updateValues); expect(updateCount2).toEqual(2); const readUsers = yield userMapperReturningID .select('name', '=', 'Sue') .returnAll(); expect(readUsers.length).toEqual(2); expect(readUsers[0].email).toEqual(updateValues.email); expect(readUsers[1].email).toEqual(updateValues.email); const updates = yield userMapperReturningID.update().returnAll({ name: 'Every User 1', }); expect(updates).toEqual([{ id: 1 }, { id: 2 }, { id: 3 }]); const update = yield userMapperReturningID .update({ id: readUsers[0].id }) .returnOne({ name: 'Every User 2', }); expect(update).toEqual({ id: 1 }); const readUser2 = yield userMapperReturningID .select('id', '=', 1) .returnOne(); expect(readUser2 === null || readUser2 === void 0 ? void 0 : readUser2.name).toEqual('Every User 2'); const updateCount = yield userMapperReturningID.update().returnCount({ name: 'Every User 3', }); expect(updateCount).toEqual(3); const success = yield userMapperReturningID.update().run({ name: 'Every User 4', }); expect(success).toBe(true); })); it('updates returning configured return columns', () => __awaiter(void 0, void 0, void 0, function* () { yield userMapperReturningID.insert().run(test_objects_1.USERS[0]); const insertReturn = yield userMapperReturningID .insert() .returnOne(test_objects_1.USERS[1]); yield userMapperReturningID.insert().run(test_objects_1.USERS[2]); // Verify that update performs the correct change on the correct row. const updateValues1 = { email: 'new.email@xyz.pdq' }; const updateReturns1 = yield userMapperReturningID .update({ id: insertReturn.id }) .returnAll(updateValues1); expect(updateReturns1).toEqual([{ id: insertReturn.id }]); let readUser = yield userMapperReturningID .select('id', '=', insertReturn.id) .returnOne(); expect(readUser === null || readUser === void 0 ? void 0 : readUser.email).toEqual(updateValues1.email); // Verify a different change on the same row, returning multiple columns. const updateValues2 = { name: 'Sue' }; const updateReturns2 = yield userMapperReturningIDAndHandleAsH .update({ email: updateValues1.email }) .returnAll(updateValues2); updateReturns2[0].id; // ensure key is accessible updateReturns2[0].h; // ensure key is accessible expect(updateReturns2).toEqual([ { id: insertReturn.id, h: test_objects_1.USERS[1].handle, }, ]); readUser = yield userMapperReturningID .select('id', '=', insertReturn.id) .returnOne(); expect(readUser === null || readUser === void 0 ? void 0 : readUser.name).toEqual(updateValues2.name); // Verify that update changes all required rows. const updateValues3 = { name: 'Replacement Sue' }; const updateReturns3 = yield userMapperReturningIDAndHandleAsH .update({ name: 'Sue' }) .returnAll(updateValues3); expect(updateReturns3.length).toEqual(3); expect(updateReturns3[0].h).toEqual(test_objects_1.USERS[0].handle); expect(updateReturns3[1].h).toEqual(test_objects_1.USERS[1].handle); expect(updateReturns3[2].h).toEqual(test_objects_1.USERS[2].handle); const readUsers = yield userMapperReturningID .select('name', '=', updateValues3.name) .returnAll(); expect(readUsers.length).toEqual(3); (0, test_utils_1.ignore)('check return types', () => { // @ts-expect-error - check return types updateReturns2[0].title; // @ts-expect-error - check return types updateReturns2[0].userId; }); })); it('update returns void when defaulting to no return columns', () => __awaiter(void 0, void 0, void 0, function* () { yield userMapperReturningID.insert().run(test_objects_1.USERS); const updates = yield userMapperReturningDefault .update({ name: 'Sue' }) .returnAll({ email: 'new.email@xyz.pdq' }); expect(updates).toBeUndefined(); const readUsers = yield userMapperReturningID .select({ email: 'new.email@xyz.pdq', }) .returnAll(); expect(readUsers.length).toEqual(2); })); it('update returns void when explicitly no return columns', () => __awaiter(void 0, void 0, void 0, function* () { yield userMapperReturningID.insert().run(test_objects_1.USERS); const updates = yield userMapperReturningNothing .update({ name: 'Sue' }) .returnAll({ email: 'new.email@xyz.pdq' }); expect(updates).toBeUndefined(); const readUsers = yield userMapperReturningID .select({ email: 'new.email@xyz.pdq', }) .returnAll(); expect(readUsers.length).toEqual(2); const update = yield userMapperReturningNothing .update({ name: 'Sue' }) .returnOne({ email: 'new2.email@xyz.pdq' }); expect(update).toBeUndefined(); const readUser = yield userMapperReturningID .select({ email: 'new2.email@xyz.pdq', }) .returnOne(); expect(readUser.id).toEqual(1); (0, test_utils_1.ignore)('type errors', () => { // @ts-expect-error - check return types updates[0].id; // @ts-expect-error - check return types update.id; }); })); it('updates configured to return all columns', () => __awaiter(void 0, void 0, void 0, function* () { const insertReturns = yield userMapperReturningID.insert().returnAll(test_objects_1.USERS); const updateValues1 = { email: 'new.email@xyz.pdq' }; const updateReturns = yield userMapperReturningAll .update({ name: 'Sue' }) .returnAll(updateValues1); const expectedUsers = [ Object.assign({}, test_objects_1.USERS[0], updateValues1, { id: insertReturns[0].id }), Object.assign({}, test_objects_1.USERS[2], updateValues1, { id: insertReturns[2].id }), ]; expect(updateReturns).toEqual(expectedUsers); // Ensure that the returned value can be accessed as a row. ((_) => { })(updateReturns[0].name); ((_) => { })(updateReturns[0].email); const updateValues2 = { email: 'another.email@xyz.pdq' }; const updateReturn = yield userMapperReturningAll .update({ name: 'Sue' }) .returnOne(updateValues2); const expectedUser = Object.assign({}, test_objects_1.USERS[0], updateValues2, { id: insertReturns[0].id, }); expect(updateReturn).toEqual(expectedUser); // Ensure that the returned value can be accessed as a row. ((_) => { })(updateReturn.name); ((_) => { })(updateReturn.email); })); it('updates all rows when no filter is given', () => __awaiter(void 0, void 0, void 0, function* () { const insertReturns = yield userMapperReturningID.insert().returnAll(test_objects_1.USERS); const updateValues = { email: 'new.email@xyz.pdq' }; const updateReturns = yield userMapperReturningIDAndHandleAsH .update() .returnAll(updateValues); const expectedUsers = test_objects_1.USERS.map((user, i) => ({ id: insertReturns[i].id, h: user.handle, })); expect(updateReturns).toEqual(expectedUsers); const readUsers = yield userMapperReturningID.select().returnAll(); expect(readUsers.length).toEqual(3); for (const user of readUsers) { expect(user.email).toEqual(updateValues.email); } })); it('updates rows indicated by a binary operator', () => __awaiter(void 0, void 0, void 0, function* () { const insertReturns = yield userMapperReturningID.insert().returnAll(test_objects_1.USERS); const updateValues = { email: 'new.email@xyz.pdq' }; const updateCount = yield userMapperReturningAll .update('id', '>', insertReturns[0].id) .returnCount(updateValues); expect(updateCount).toEqual(2); const readUsers = yield userMapperReturningID .select('id', '>', insertReturns[0].id) .returnAll(); expect(readUsers.length).toEqual(2); for (const user of readUsers) { expect(user.email).toEqual(updateValues.email); } })); it('updates rows indicated by a kysely expression', () => __awaiter(void 0, void 0, void 0, function* () { const insertReturns = yield userMapperReturningID.insert().returnAll(test_objects_1.USERS); const updateValues = { email: 'new.email@xyz.pdq' }; const updateCount = yield userMapperReturningDefault .update((0, kysely_1.sql) `id > ${insertReturns[0].id}`) .returnCount(updateValues); expect(updateCount).toEqual(BigInt(2)); const readUsers = yield userMapperReturningID .select('id', '>', insertReturns[0].id) .returnAll(); expect(readUsers.length).toEqual(2); for (const user of readUsers) { expect(user.email).toEqual(updateValues.email); } })); it('updates rows indicated by a where expression filter', () => __awaiter(void 0, void 0, void 0, function* () { const insertReturns = yield userMapperReturningID.insert().returnAll(test_objects_1.USERS); const updateValues1 = { email: 'foo@xyz.pdq' }; const updateCount = yield userMapperReturningAll .update(({ or, cmpr }) => or([ cmpr('id', '=', insertReturns[0].id), cmpr('id', '=', insertReturns[2].id), ])) .returnCount(updateValues1); expect(updateCount).toEqual(2); const updateValues2 = { email: 'bar@xyz.pdq' }; const updateReturns = yield userMapperReturningID .update(({ or, cmpr }) => or([ cmpr('id', '=', insertReturns[0].id), cmpr('id', '=', insertReturns[2].id), ])) .returnAll(updateValues2); expect(updateReturns).toEqual([ { id: insertReturns[0].id }, { id: insertReturns[2].id }, ]); })); (0, test_utils_1.ignore)('detects update type errors', () => __awaiter(void 0, void 0, void 0, function* () { userMapperReturningID.update( // @ts-expect-error - table must have all filter fields { notThere: 'xyz' }); // @ts-expect-error - table must have all filter fields userMapperReturningID.update('notThere', '=', 'foo'); userMapperReturningID.update(({ or, cmpr }) => // @ts-expect-error - only table columns are accessible via anyOf() or([cmpr('notThere', '=', 'xyz'), cmpr('alsoNotThere', '=', 'Sue')])); // @ts-expect-error - ID filter must have correct type userMapperReturningID.update('str'); // @ts-expect-error - ID filter must have correct type userMapperReturningID.update(['str']); // @ts-expect-error - ID filter not allowed when when no ID column userMapperReturningNothing.update(1); // @ts-expect-error - ID filter not allowed when when no ID column userMapperReturningNothing.update([1]); userMapperReturningID.update({ id: 32 }).returnAll( // @ts-expect-error - update must only have table columns { notThere: 'xyz@pdq.xyz' }); // @ts-expect-error - only requested columns are accessible // prettier-ignore (yield userMapperReturningID.update({ id: 32 }).returnAll(test_objects_1.USERS[0]))[0].name; userMapperReturningID.update({ id: 32 }).returnOne( // @ts-expect-error - update must only have table columns { notThere: 'xyz@pdq.xyz' }); // @ts-expect-error - only requested columns are accessible // prettier-ignore (yield userMapperReturningID.update({ id: 32 }).returnOne(test_objects_1.USERS[0]))[0].name; userMapperReturningID.update({ id: 32 }).returnCount( // @ts-expect-error - update must only have table columns { notThere: 'xyz@pdq.xyz' }); // @ts-expect-error - only requested columns are accessible // prettier-ignore (yield userMapperReturningID.update({ id: 32 }).returnCount(test_objects_1.USERS[0]))[0].name; userMapperReturningID.update({ id: 32 }).run( // @ts-expect-error - update must only have table columns { notThere: 'xyz@pdq.xyz' }); // @ts-expect-error - only requested columns are accessible // prettier-ignore (yield userMapperReturningID.update({ id: 32 }).run(test_objects_1.USERS[0]))[0].name; })); }); //# sourceMappingURL=update-general.test.js.map