diff --git a/package-lock.json b/package-lock.json index 9c08e18..e0fd28a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,9 +9,9 @@ "version": "0.7.1", "license": "Apache-2.0", "devDependencies": { - "@biomejs/biome": "^2.3.1", - "@swc/core": "^1.13.5", - "@vitest/coverage-v8": "^4.0.3", + "@biomejs/biome": "^2.3.2", + "@swc/core": "^1.14.0", + "@vitest/coverage-v8": "^4.0.5", "class-transformer": "^0.5.1", "class-validator": "^0.14.2", "concurrently": "^9.2.1", @@ -21,7 +21,7 @@ "tslib": "^2.8.1", "tsup": "^8.5.0", "typescript": "^5.9.3", - "vitest": "^4.0.3", + "vitest": "^4.0.5", "wait-on": "^9.0.1", "zod": "^4.1.12" }, @@ -106,9 +106,9 @@ } }, "node_modules/@biomejs/biome": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.3.1.tgz", - "integrity": "sha512-A29evf1R72V5bo4o2EPxYMm5mtyGvzp2g+biZvRFx29nWebGyyeOSsDWGx3tuNNMFRepGwxmA9ZQ15mzfabK2w==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.3.2.tgz", + "integrity": "sha512-8e9tzamuDycx7fdrcJ/F/GDZ8SYukc5ud6tDicjjFqURKYFSWMl0H0iXNXZEGmcmNUmABgGuHThPykcM41INgg==", "dev": true, "license": "MIT OR Apache-2.0", "bin": { @@ -122,20 +122,20 @@ "url": "https://opencollective.com/biome" }, "optionalDependencies": { - "@biomejs/cli-darwin-arm64": "2.3.1", - "@biomejs/cli-darwin-x64": "2.3.1", - "@biomejs/cli-linux-arm64": "2.3.1", - "@biomejs/cli-linux-arm64-musl": "2.3.1", - "@biomejs/cli-linux-x64": "2.3.1", - "@biomejs/cli-linux-x64-musl": "2.3.1", - "@biomejs/cli-win32-arm64": "2.3.1", - "@biomejs/cli-win32-x64": "2.3.1" + "@biomejs/cli-darwin-arm64": "2.3.2", + "@biomejs/cli-darwin-x64": "2.3.2", + "@biomejs/cli-linux-arm64": "2.3.2", + "@biomejs/cli-linux-arm64-musl": "2.3.2", + "@biomejs/cli-linux-x64": "2.3.2", + "@biomejs/cli-linux-x64-musl": "2.3.2", + "@biomejs/cli-win32-arm64": "2.3.2", + "@biomejs/cli-win32-x64": "2.3.2" } }, "node_modules/@biomejs/cli-darwin-arm64": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.3.1.tgz", - "integrity": "sha512-ombSf3MnTUueiYGN1SeI9tBCsDUhpWzOwS63Dove42osNh0PfE1cUtHFx6eZ1+MYCCLwXzlFlYFdrJ+U7h6LcA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.3.2.tgz", + "integrity": "sha512-4LECm4kc3If0JISai4c3KWQzukoUdpxy4fRzlrPcrdMSRFksR9ZoXK7JBcPuLBmd2SoT4/d7CQS33VnZpgBjew==", "cpu": [ "arm64" ], @@ -150,9 +150,9 @@ } }, "node_modules/@biomejs/cli-darwin-x64": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.3.1.tgz", - "integrity": "sha512-pcOfwyoQkrkbGvXxRvZNe5qgD797IowpJPovPX5biPk2FwMEV+INZqfCaz4G5bVq9hYnjwhRMamg11U4QsRXrQ==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.3.2.tgz", + "integrity": "sha512-jNMnfwHT4N3wi+ypRfMTjLGnDmKYGzxVr1EYAPBcauRcDnICFXN81wD6wxJcSUrLynoyyYCdfW6vJHS/IAoTDA==", "cpu": [ "x64" ], @@ -167,9 +167,9 @@ } }, "node_modules/@biomejs/cli-linux-arm64": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.3.1.tgz", - "integrity": "sha512-td5O8pFIgLs8H1sAZsD6v+5quODihyEw4nv2R8z7swUfIK1FKk+15e4eiYVLcAE4jUqngvh4j3JCNgg0Y4o4IQ==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.3.2.tgz", + "integrity": "sha512-amnqvk+gWybbQleRRq8TMe0rIv7GHss8mFJEaGuEZYWg1Tw14YKOkeo8h6pf1c+d3qR+JU4iT9KXnBKGON4klw==", "cpu": [ "arm64" ], @@ -184,9 +184,9 @@ } }, "node_modules/@biomejs/cli-linux-arm64-musl": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.3.1.tgz", - "integrity": "sha512-+DZYv8l7FlUtTrWs1Tdt1KcNCAmRO87PyOnxKGunbWm5HKg1oZBSbIIPkjrCtDZaeqSG1DiGx7qF+CPsquQRcg==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.3.2.tgz", + "integrity": "sha512-2Zz4usDG1GTTPQnliIeNx6eVGGP2ry5vE/v39nT73a3cKN6t5H5XxjcEoZZh62uVZvED7hXXikclvI64vZkYqw==", "cpu": [ "arm64" ], @@ -201,9 +201,9 @@ } }, "node_modules/@biomejs/cli-linux-x64": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.3.1.tgz", - "integrity": "sha512-PYWgEO7up7XYwSAArOpzsVCiqxBCXy53gsReAb1kKYIyXaoAlhBaBMvxR/k2Rm9aTuZ662locXUmPk/Aj+Xu+Q==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.3.2.tgz", + "integrity": "sha512-8BG/vRAhFz1pmuyd24FQPhNeueLqPtwvZk6yblABY2gzL2H8fLQAF/Z2OPIc+BPIVPld+8cSiKY/KFh6k81xfA==", "cpu": [ "x64" ], @@ -218,9 +218,9 @@ } }, "node_modules/@biomejs/cli-linux-x64-musl": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.3.1.tgz", - "integrity": "sha512-Y3Ob4nqgv38Mh+6EGHltuN+Cq8aj/gyMTJYzkFZV2AEj+9XzoXB9VNljz9pjfFNHUxvLEV4b55VWyxozQTBaUQ==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.3.2.tgz", + "integrity": "sha512-gzB19MpRdTuOuLtPpFBGrV3Lq424gHyq2lFj8wfX9tvLMLdmA/R9C7k/mqBp/spcbWuHeIEKgEs3RviOPcWGBA==", "cpu": [ "x64" ], @@ -235,9 +235,9 @@ } }, "node_modules/@biomejs/cli-win32-arm64": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.3.1.tgz", - "integrity": "sha512-RHIG/zgo+69idUqVvV3n8+j58dKYABRpMyDmfWu2TITC+jwGPiEaT0Q3RKD+kQHiS80mpBrST0iUGeEXT0bU9A==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.3.2.tgz", + "integrity": "sha512-lCruqQlfWjhMlOdyf5pDHOxoNm4WoyY2vZ4YN33/nuZBRstVDuqPPjS0yBkbUlLEte11FbpW+wWSlfnZfSIZvg==", "cpu": [ "arm64" ], @@ -252,9 +252,9 @@ } }, "node_modules/@biomejs/cli-win32-x64": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.3.1.tgz", - "integrity": "sha512-izl30JJ5Dp10mi90Eko47zhxE6pYyWPcnX1NQxKpL/yMhXxf95oLTzfpu4q+MDBh/gemNqyJEwjBpe0MT5iWPA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.3.2.tgz", + "integrity": "sha512-6Ee9P26DTb4D8sN9nXxgbi9Dw5vSOfH98M7UlmkjKB2vtUbrRqCbZiNfryGiwnPIpd6YUoTl7rLVD2/x1CyEHQ==", "cpu": [ "x64" ], @@ -1159,16 +1159,16 @@ "license": "MIT" }, "node_modules/@swc/core": { - "version": "1.13.5", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.13.5.tgz", - "integrity": "sha512-WezcBo8a0Dg2rnR82zhwoR6aRNxeTGfK5QCD6TQ+kg3xx/zNT02s/0o+81h/3zhvFSB24NtqEr8FTw88O5W/JQ==", + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.14.0.tgz", + "integrity": "sha512-oExhY90bes5pDTVrei0xlMVosTxwd/NMafIpqsC4dMbRYZ5KB981l/CX8tMnGsagTplj/RcG9BeRYmV6/J5m3w==", "dev": true, "hasInstallScript": true, "license": "Apache-2.0", "peer": true, "dependencies": { "@swc/counter": "^0.1.3", - "@swc/types": "^0.1.24" + "@swc/types": "^0.1.25" }, "engines": { "node": ">=10" @@ -1178,16 +1178,16 @@ "url": "https://opencollective.com/swc" }, "optionalDependencies": { - "@swc/core-darwin-arm64": "1.13.5", - "@swc/core-darwin-x64": "1.13.5", - "@swc/core-linux-arm-gnueabihf": "1.13.5", - "@swc/core-linux-arm64-gnu": "1.13.5", - "@swc/core-linux-arm64-musl": "1.13.5", - "@swc/core-linux-x64-gnu": "1.13.5", - "@swc/core-linux-x64-musl": "1.13.5", - "@swc/core-win32-arm64-msvc": "1.13.5", - "@swc/core-win32-ia32-msvc": "1.13.5", - "@swc/core-win32-x64-msvc": "1.13.5" + "@swc/core-darwin-arm64": "1.14.0", + "@swc/core-darwin-x64": "1.14.0", + "@swc/core-linux-arm-gnueabihf": "1.14.0", + "@swc/core-linux-arm64-gnu": "1.14.0", + "@swc/core-linux-arm64-musl": "1.14.0", + "@swc/core-linux-x64-gnu": "1.14.0", + "@swc/core-linux-x64-musl": "1.14.0", + "@swc/core-win32-arm64-msvc": "1.14.0", + "@swc/core-win32-ia32-msvc": "1.14.0", + "@swc/core-win32-x64-msvc": "1.14.0" }, "peerDependencies": { "@swc/helpers": ">=0.5.17" @@ -1199,9 +1199,9 @@ } }, "node_modules/@swc/core-darwin-arm64": { - "version": "1.13.5", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.13.5.tgz", - "integrity": "sha512-lKNv7SujeXvKn16gvQqUQI5DdyY8v7xcoO3k06/FJbHJS90zEwZdQiMNRiqpYw/orU543tPaWgz7cIYWhbopiQ==", + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.14.0.tgz", + "integrity": "sha512-uHPC8rlCt04nvYNczWzKVdgnRhxCa3ndKTBBbBpResOZsRmiwRAvByIGh599j+Oo6Z5eyTPrgY+XfJzVmXnN7Q==", "cpu": [ "arm64" ], @@ -1216,9 +1216,9 @@ } }, "node_modules/@swc/core-darwin-x64": { - "version": "1.13.5", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.13.5.tgz", - "integrity": "sha512-ILd38Fg/w23vHb0yVjlWvQBoE37ZJTdlLHa8LRCFDdX4WKfnVBiblsCU9ar4QTMNdeTBEX9iUF4IrbNWhaF1Ng==", + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.14.0.tgz", + "integrity": "sha512-2SHrlpl68vtePRknv9shvM9YKKg7B9T13tcTg9aFCwR318QTYo+FzsKGmQSv9ox/Ua0Q2/5y2BNjieffJoo4nA==", "cpu": [ "x64" ], @@ -1233,9 +1233,9 @@ } }, "node_modules/@swc/core-linux-arm-gnueabihf": { - "version": "1.13.5", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.13.5.tgz", - "integrity": "sha512-Q6eS3Pt8GLkXxqz9TAw+AUk9HpVJt8Uzm54MvPsqp2yuGmY0/sNaPPNVqctCX9fu/Nu8eaWUen0si6iEiCsazQ==", + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.14.0.tgz", + "integrity": "sha512-SMH8zn01dxt809svetnxpeg/jWdpi6dqHKO3Eb11u4OzU2PK7I5uKS6gf2hx5LlTbcJMFKULZiVwjlQLe8eqtg==", "cpu": [ "arm" ], @@ -1250,9 +1250,9 @@ } }, "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.13.5", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.13.5.tgz", - "integrity": "sha512-aNDfeN+9af+y+M2MYfxCzCy/VDq7Z5YIbMqRI739o8Ganz6ST+27kjQFd8Y/57JN/hcnUEa9xqdS3XY7WaVtSw==", + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.14.0.tgz", + "integrity": "sha512-q2JRu2D8LVqGeHkmpVCljVNltG0tB4o4eYg+dElFwCS8l2Mnt9qurMCxIeo9mgoqz0ax+k7jWtIRHktnVCbjvQ==", "cpu": [ "arm64" ], @@ -1267,9 +1267,9 @@ } }, "node_modules/@swc/core-linux-arm64-musl": { - "version": "1.13.5", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.13.5.tgz", - "integrity": "sha512-9+ZxFN5GJag4CnYnq6apKTnnezpfJhCumyz0504/JbHLo+Ue+ZtJnf3RhyA9W9TINtLE0bC4hKpWi8ZKoETyOQ==", + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.14.0.tgz", + "integrity": "sha512-uofpVoPCEUjYIv454ZEZ3sLgMD17nIwlz2z7bsn7rl301Kt/01umFA7MscUovFfAK2IRGck6XB+uulMu6aFhKQ==", "cpu": [ "arm64" ], @@ -1284,9 +1284,9 @@ } }, "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.13.5", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.13.5.tgz", - "integrity": "sha512-WD530qvHrki8Ywt/PloKUjaRKgstQqNGvmZl54g06kA+hqtSE2FTG9gngXr3UJxYu/cNAjJYiBifm7+w4nbHbA==", + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.14.0.tgz", + "integrity": "sha512-quTTx1Olm05fBfv66DEBuOsOgqdypnZ/1Bh3yGXWY7ANLFeeRpCDZpljD9BSjdsNdPOlwJmEUZXMHtGm3v1TZQ==", "cpu": [ "x64" ], @@ -1301,9 +1301,9 @@ } }, "node_modules/@swc/core-linux-x64-musl": { - "version": "1.13.5", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.13.5.tgz", - "integrity": "sha512-Luj8y4OFYx4DHNQTWjdIuKTq2f5k6uSXICqx+FSabnXptaOBAbJHNbHT/06JZh6NRUouaf0mYXN0mcsqvkhd7Q==", + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.14.0.tgz", + "integrity": "sha512-caaNAu+aIqT8seLtCf08i8C3/UC5ttQujUjejhMcuS1/LoCKtNiUs4VekJd2UGt+pyuuSrQ6dKl8CbCfWvWeXw==", "cpu": [ "x64" ], @@ -1318,9 +1318,9 @@ } }, "node_modules/@swc/core-win32-arm64-msvc": { - "version": "1.13.5", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.13.5.tgz", - "integrity": "sha512-cZ6UpumhF9SDJvv4DA2fo9WIzlNFuKSkZpZmPG1c+4PFSEMy5DFOjBSllCvnqihCabzXzpn6ykCwBmHpy31vQw==", + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.14.0.tgz", + "integrity": "sha512-EeW3jFlT3YNckJ6V/JnTfGcX7UHGyh6/AiCPopZ1HNaGiXVCKHPpVQZicmtyr/UpqxCXLrTgjHOvyMke7YN26A==", "cpu": [ "arm64" ], @@ -1335,9 +1335,9 @@ } }, "node_modules/@swc/core-win32-ia32-msvc": { - "version": "1.13.5", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.13.5.tgz", - "integrity": "sha512-C5Yi/xIikrFUzZcyGj9L3RpKljFvKiDMtyDzPKzlsDrKIw2EYY+bF88gB6oGY5RGmv4DAX8dbnpRAqgFD0FMEw==", + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.14.0.tgz", + "integrity": "sha512-dPai3KUIcihV5hfoO4QNQF5HAaw8+2bT7dvi8E5zLtecW2SfL3mUZipzampXq5FHll0RSCLzlrXnSx+dBRZIIQ==", "cpu": [ "ia32" ], @@ -1352,9 +1352,9 @@ } }, "node_modules/@swc/core-win32-x64-msvc": { - "version": "1.13.5", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.13.5.tgz", - "integrity": "sha512-YrKdMVxbYmlfybCSbRtrilc6UA8GF5aPmGKBdPvjrarvsmf4i7ZHGCEnLtfOMd3Lwbs2WUZq3WdMbozYeLU93Q==", + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.14.0.tgz", + "integrity": "sha512-nm+JajGrTqUA6sEHdghDlHMNfH1WKSiuvljhdmBACW4ta4LC3gKurX2qZuiBARvPkephW9V/i5S8QPY1PzFEqg==", "cpu": [ "x64" ], @@ -1418,14 +1418,14 @@ "license": "MIT" }, "node_modules/@vitest/coverage-v8": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.0.3.tgz", - "integrity": "sha512-I+MlLwyJRBjmJr1kFYSxoseINbIdpxIAeK10jmXgB0FUtIfdYsvM3lGAvBu5yk8WPyhefzdmbCHCc1idFbNRcg==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.0.5.tgz", + "integrity": "sha512-Yn5Dx0UVvllE3uatQw+ftObWtM/TjAOdbd8WvygaR04iyFXdNmtvZ/nJ2/JndyzfPQtbAWw0F+GJY5+lgM/7qg==", "dev": true, "license": "MIT", "dependencies": { "@bcoe/v8-coverage": "^1.0.2", - "@vitest/utils": "4.0.3", + "@vitest/utils": "4.0.5", "ast-v8-to-istanbul": "^0.3.5", "debug": "^4.4.3", "istanbul-lib-coverage": "^3.2.2", @@ -1440,8 +1440,8 @@ "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "@vitest/browser": "4.0.3", - "vitest": "4.0.3" + "@vitest/browser": "4.0.5", + "vitest": "4.0.5" }, "peerDependenciesMeta": { "@vitest/browser": { @@ -1450,16 +1450,16 @@ } }, "node_modules/@vitest/expect": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.0.3.tgz", - "integrity": "sha512-v3eSDx/bF25pzar6aEJrrdTXJduEBU3uSGXHslIdGIpJVP8tQQHV6x1ZfzbFQ/bLIomLSbR/2ZCfnaEGkWkiVQ==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.0.5.tgz", + "integrity": "sha512-DJctLVlKoddvP/G389oGmKWNG6GD9frm2FPXARziU80Rjo7SIYxQzb2YFzmQ4fVD3Q5utUYY8nUmWrqsuIlIXQ==", "dev": true, "license": "MIT", "dependencies": { "@standard-schema/spec": "^1.0.0", "@types/chai": "^5.2.2", - "@vitest/spy": "4.0.3", - "@vitest/utils": "4.0.3", + "@vitest/spy": "4.0.5", + "@vitest/utils": "4.0.5", "chai": "^6.0.1", "tinyrainbow": "^3.0.3" }, @@ -1468,13 +1468,13 @@ } }, "node_modules/@vitest/mocker": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.0.3.tgz", - "integrity": "sha512-evZcRspIPbbiJEe748zI2BRu94ThCBE+RkjCpVF8yoVYuTV7hMe+4wLF/7K86r8GwJHSmAPnPbZhpXWWrg1qbA==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.0.5.tgz", + "integrity": "sha512-iYHIy72LfbK+mL5W8zXROp6oOcJKXWeKcNjcPPsqoa18qIEDrhB6/Z08o0wRajTd6SSSDNw8NCSIHVNOMpz0mw==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/spy": "4.0.3", + "@vitest/spy": "4.0.5", "estree-walker": "^3.0.3", "magic-string": "^0.30.19" }, @@ -1495,9 +1495,9 @@ } }, "node_modules/@vitest/pretty-format": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.0.3.tgz", - "integrity": "sha512-N7gly/DRXzxa9w9sbDXwD9QNFYP2hw90LLLGDobPNwiWgyW95GMxsCt29/COIKKh3P7XJICR38PSDePenMBtsw==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.0.5.tgz", + "integrity": "sha512-t1T/sSdsYyNc5AZl0EMeD0jW9cpJe2cODP0R++ZQe1kTkpgrwEfxGFR/yCG4w8ZybizbXRTHU7lE8sTDD/QsGw==", "dev": true, "license": "MIT", "dependencies": { @@ -1508,13 +1508,13 @@ } }, "node_modules/@vitest/runner": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.0.3.tgz", - "integrity": "sha512-1/aK6fPM0lYXWyGKwop2Gbvz1plyTps/HDbIIJXYtJtspHjpXIeB3If07eWpVH4HW7Rmd3Rl+IS/+zEAXrRtXA==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.0.5.tgz", + "integrity": "sha512-CQVVe+YEeKSiFBD5gBAmRDQglm4PnMBYzeTmt06t5iWtsUN9StQeeKhYCea/oaqBYilf8sARG6fSctUcEL/UmQ==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/utils": "4.0.3", + "@vitest/utils": "4.0.5", "pathe": "^2.0.3" }, "funding": { @@ -1522,13 +1522,13 @@ } }, "node_modules/@vitest/snapshot": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.0.3.tgz", - "integrity": "sha512-amnYmvZ5MTjNCP1HZmdeczAPLRD6iOm9+2nMRUGxbe/6sQ0Ymur0NnR9LIrWS8JA3wKE71X25D6ya/3LN9YytA==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.0.5.tgz", + "integrity": "sha512-jfmSAeR6xYNEvcD+/RxFGA1bzpqHtkVhgxo2cxXia+Q3xX7m6GpZij07rz+WyQcA/xEGn4eIS1OItkMyWsGBmQ==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.0.3", + "@vitest/pretty-format": "4.0.5", "magic-string": "^0.30.19", "pathe": "^2.0.3" }, @@ -1537,9 +1537,9 @@ } }, "node_modules/@vitest/spy": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.0.3.tgz", - "integrity": "sha512-82vVL8Cqz7rbXaNUl35V2G7xeNMAjBdNOVaHbrzznT9BmiCiPOzhf0FhU3eP41nP1bLDm/5wWKZqkG4nyU95DQ==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.0.5.tgz", + "integrity": "sha512-TUmVQpAQign7r8+EnZsgTF3vY9BdGofTUge1rGNbnHn2IN3FChiQoT9lrPz7A7AVUZJU2LAZXl4v66HhsNMhoA==", "dev": true, "license": "MIT", "funding": { @@ -1547,13 +1547,13 @@ } }, "node_modules/@vitest/utils": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.0.3.tgz", - "integrity": "sha512-qV6KJkq8W3piW6MDIbGOmn1xhvcW4DuA07alqaQ+vdx7YA49J85pnwnxigZVQFQw3tWnQNRKWwhz5wbP6iv/GQ==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.0.5.tgz", + "integrity": "sha512-V5RndUgCB5/AfNvK9zxGCrRs99IrPYtMTIdUzJMMFs9nrmE5JXExIEfjVtUteyTRiLfCm+dCRMHf/Uu7Mm8/dg==", "dev": true, "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.0.3", + "@vitest/pretty-format": "4.0.5", "tinyrainbow": "^3.0.3" }, "funding": { @@ -3978,20 +3978,20 @@ } }, "node_modules/vitest": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.0.3.tgz", - "integrity": "sha512-IUSop8jgaT7w0g1yOM/35qVtKjr/8Va4PrjzH1OUb0YH4c3OXB2lCZDkMAB6glA8T5w8S164oJGsbcmAecr4sA==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.0.5.tgz", + "integrity": "sha512-4H+J28MI5oeYgGg3h5BFSkQ1g/2GKK1IR8oorH3a6EQQbb7CwjbnyBjH4PGxw9/6vpwAPNzaeUMp4Js4WJmdXQ==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@vitest/expect": "4.0.3", - "@vitest/mocker": "4.0.3", - "@vitest/pretty-format": "4.0.3", - "@vitest/runner": "4.0.3", - "@vitest/snapshot": "4.0.3", - "@vitest/spy": "4.0.3", - "@vitest/utils": "4.0.3", + "@vitest/expect": "4.0.5", + "@vitest/mocker": "4.0.5", + "@vitest/pretty-format": "4.0.5", + "@vitest/runner": "4.0.5", + "@vitest/snapshot": "4.0.5", + "@vitest/spy": "4.0.5", + "@vitest/utils": "4.0.5", "debug": "^4.4.3", "es-module-lexer": "^1.7.0", "expect-type": "^1.2.2", @@ -4019,10 +4019,10 @@ "@edge-runtime/vm": "*", "@types/debug": "^4.1.12", "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", - "@vitest/browser-playwright": "4.0.3", - "@vitest/browser-preview": "4.0.3", - "@vitest/browser-webdriverio": "4.0.3", - "@vitest/ui": "4.0.3", + "@vitest/browser-playwright": "4.0.5", + "@vitest/browser-preview": "4.0.5", + "@vitest/browser-webdriverio": "4.0.5", + "@vitest/ui": "4.0.5", "happy-dom": "*", "jsdom": "*" }, diff --git a/package.json b/package.json index 493b8b9..6494679 100644 --- a/package.json +++ b/package.json @@ -76,9 +76,9 @@ "author": "Nicolas R. M. Dias ", "license": "Apache-2.0", "devDependencies": { - "@biomejs/biome": "^2.3.1", - "@swc/core": "^1.13.5", - "@vitest/coverage-v8": "^4.0.3", + "@biomejs/biome": "^2.3.2", + "@swc/core": "^1.14.0", + "@vitest/coverage-v8": "^4.0.5", "class-transformer": "^0.5.1", "class-validator": "^0.14.2", "concurrently": "^9.2.1", @@ -88,7 +88,7 @@ "tslib": "^2.8.1", "tsup": "^8.5.0", "typescript": "^5.9.3", - "vitest": "^4.0.3", + "vitest": "^4.0.5", "wait-on": "^9.0.1", "zod": "^4.1.12" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a58a337..a871a06 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,14 +9,14 @@ importers: .: devDependencies: '@biomejs/biome': - specifier: ^2.3.1 - version: 2.3.1 + specifier: ^2.3.2 + version: 2.3.2 '@swc/core': - specifier: ^1.13.5 - version: 1.13.5 + specifier: ^1.14.0 + version: 1.14.0 '@vitest/coverage-v8': - specifier: ^4.0.3 - version: 4.0.3(vitest@4.0.3(terser@5.44.0)) + specifier: ^4.0.5 + version: 4.0.5(vitest@4.0.5(terser@5.44.0)) class-transformer: specifier: ^0.5.1 version: 0.5.1 @@ -40,13 +40,13 @@ importers: version: 2.8.1 tsup: specifier: ^8.5.0 - version: 8.5.0(@swc/core@1.13.5)(postcss@8.5.6)(typescript@5.9.3) + version: 8.5.0(@swc/core@1.14.0)(postcss@8.5.6)(typescript@5.9.3) typescript: specifier: ^5.9.3 version: 5.9.3 vitest: - specifier: ^4.0.3 - version: 4.0.3(terser@5.44.0) + specifier: ^4.0.5 + version: 4.0.5(terser@5.44.0) wait-on: specifier: ^9.0.1 version: 9.0.1 @@ -77,55 +77,55 @@ packages: resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} engines: {node: '>=18'} - '@biomejs/biome@2.3.1': - resolution: {integrity: sha512-A29evf1R72V5bo4o2EPxYMm5mtyGvzp2g+biZvRFx29nWebGyyeOSsDWGx3tuNNMFRepGwxmA9ZQ15mzfabK2w==} + '@biomejs/biome@2.3.2': + resolution: {integrity: sha512-8e9tzamuDycx7fdrcJ/F/GDZ8SYukc5ud6tDicjjFqURKYFSWMl0H0iXNXZEGmcmNUmABgGuHThPykcM41INgg==} engines: {node: '>=14.21.3'} hasBin: true - '@biomejs/cli-darwin-arm64@2.3.1': - resolution: {integrity: sha512-ombSf3MnTUueiYGN1SeI9tBCsDUhpWzOwS63Dove42osNh0PfE1cUtHFx6eZ1+MYCCLwXzlFlYFdrJ+U7h6LcA==} + '@biomejs/cli-darwin-arm64@2.3.2': + resolution: {integrity: sha512-4LECm4kc3If0JISai4c3KWQzukoUdpxy4fRzlrPcrdMSRFksR9ZoXK7JBcPuLBmd2SoT4/d7CQS33VnZpgBjew==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [darwin] - '@biomejs/cli-darwin-x64@2.3.1': - resolution: {integrity: sha512-pcOfwyoQkrkbGvXxRvZNe5qgD797IowpJPovPX5biPk2FwMEV+INZqfCaz4G5bVq9hYnjwhRMamg11U4QsRXrQ==} + '@biomejs/cli-darwin-x64@2.3.2': + resolution: {integrity: sha512-jNMnfwHT4N3wi+ypRfMTjLGnDmKYGzxVr1EYAPBcauRcDnICFXN81wD6wxJcSUrLynoyyYCdfW6vJHS/IAoTDA==} engines: {node: '>=14.21.3'} cpu: [x64] os: [darwin] - '@biomejs/cli-linux-arm64-musl@2.3.1': - resolution: {integrity: sha512-+DZYv8l7FlUtTrWs1Tdt1KcNCAmRO87PyOnxKGunbWm5HKg1oZBSbIIPkjrCtDZaeqSG1DiGx7qF+CPsquQRcg==} + '@biomejs/cli-linux-arm64-musl@2.3.2': + resolution: {integrity: sha512-2Zz4usDG1GTTPQnliIeNx6eVGGP2ry5vE/v39nT73a3cKN6t5H5XxjcEoZZh62uVZvED7hXXikclvI64vZkYqw==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] - '@biomejs/cli-linux-arm64@2.3.1': - resolution: {integrity: sha512-td5O8pFIgLs8H1sAZsD6v+5quODihyEw4nv2R8z7swUfIK1FKk+15e4eiYVLcAE4jUqngvh4j3JCNgg0Y4o4IQ==} + '@biomejs/cli-linux-arm64@2.3.2': + resolution: {integrity: sha512-amnqvk+gWybbQleRRq8TMe0rIv7GHss8mFJEaGuEZYWg1Tw14YKOkeo8h6pf1c+d3qR+JU4iT9KXnBKGON4klw==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] - '@biomejs/cli-linux-x64-musl@2.3.1': - resolution: {integrity: sha512-Y3Ob4nqgv38Mh+6EGHltuN+Cq8aj/gyMTJYzkFZV2AEj+9XzoXB9VNljz9pjfFNHUxvLEV4b55VWyxozQTBaUQ==} + '@biomejs/cli-linux-x64-musl@2.3.2': + resolution: {integrity: sha512-gzB19MpRdTuOuLtPpFBGrV3Lq424gHyq2lFj8wfX9tvLMLdmA/R9C7k/mqBp/spcbWuHeIEKgEs3RviOPcWGBA==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] - '@biomejs/cli-linux-x64@2.3.1': - resolution: {integrity: sha512-PYWgEO7up7XYwSAArOpzsVCiqxBCXy53gsReAb1kKYIyXaoAlhBaBMvxR/k2Rm9aTuZ662locXUmPk/Aj+Xu+Q==} + '@biomejs/cli-linux-x64@2.3.2': + resolution: {integrity: sha512-8BG/vRAhFz1pmuyd24FQPhNeueLqPtwvZk6yblABY2gzL2H8fLQAF/Z2OPIc+BPIVPld+8cSiKY/KFh6k81xfA==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] - '@biomejs/cli-win32-arm64@2.3.1': - resolution: {integrity: sha512-RHIG/zgo+69idUqVvV3n8+j58dKYABRpMyDmfWu2TITC+jwGPiEaT0Q3RKD+kQHiS80mpBrST0iUGeEXT0bU9A==} + '@biomejs/cli-win32-arm64@2.3.2': + resolution: {integrity: sha512-lCruqQlfWjhMlOdyf5pDHOxoNm4WoyY2vZ4YN33/nuZBRstVDuqPPjS0yBkbUlLEte11FbpW+wWSlfnZfSIZvg==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [win32] - '@biomejs/cli-win32-x64@2.3.1': - resolution: {integrity: sha512-izl30JJ5Dp10mi90Eko47zhxE6pYyWPcnX1NQxKpL/yMhXxf95oLTzfpu4q+MDBh/gemNqyJEwjBpe0MT5iWPA==} + '@biomejs/cli-win32-x64@2.3.2': + resolution: {integrity: sha512-6Ee9P26DTb4D8sN9nXxgbi9Dw5vSOfH98M7UlmkjKB2vtUbrRqCbZiNfryGiwnPIpd6YUoTl7rLVD2/x1CyEHQ==} engines: {node: '>=14.21.3'} cpu: [x64] os: [win32] @@ -438,68 +438,68 @@ packages: '@standard-schema/spec@1.0.0': resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==} - '@swc/core-darwin-arm64@1.13.5': - resolution: {integrity: sha512-lKNv7SujeXvKn16gvQqUQI5DdyY8v7xcoO3k06/FJbHJS90zEwZdQiMNRiqpYw/orU543tPaWgz7cIYWhbopiQ==} + '@swc/core-darwin-arm64@1.14.0': + resolution: {integrity: sha512-uHPC8rlCt04nvYNczWzKVdgnRhxCa3ndKTBBbBpResOZsRmiwRAvByIGh599j+Oo6Z5eyTPrgY+XfJzVmXnN7Q==} engines: {node: '>=10'} cpu: [arm64] os: [darwin] - '@swc/core-darwin-x64@1.13.5': - resolution: {integrity: sha512-ILd38Fg/w23vHb0yVjlWvQBoE37ZJTdlLHa8LRCFDdX4WKfnVBiblsCU9ar4QTMNdeTBEX9iUF4IrbNWhaF1Ng==} + '@swc/core-darwin-x64@1.14.0': + resolution: {integrity: sha512-2SHrlpl68vtePRknv9shvM9YKKg7B9T13tcTg9aFCwR318QTYo+FzsKGmQSv9ox/Ua0Q2/5y2BNjieffJoo4nA==} engines: {node: '>=10'} cpu: [x64] os: [darwin] - '@swc/core-linux-arm-gnueabihf@1.13.5': - resolution: {integrity: sha512-Q6eS3Pt8GLkXxqz9TAw+AUk9HpVJt8Uzm54MvPsqp2yuGmY0/sNaPPNVqctCX9fu/Nu8eaWUen0si6iEiCsazQ==} + '@swc/core-linux-arm-gnueabihf@1.14.0': + resolution: {integrity: sha512-SMH8zn01dxt809svetnxpeg/jWdpi6dqHKO3Eb11u4OzU2PK7I5uKS6gf2hx5LlTbcJMFKULZiVwjlQLe8eqtg==} engines: {node: '>=10'} cpu: [arm] os: [linux] - '@swc/core-linux-arm64-gnu@1.13.5': - resolution: {integrity: sha512-aNDfeN+9af+y+M2MYfxCzCy/VDq7Z5YIbMqRI739o8Ganz6ST+27kjQFd8Y/57JN/hcnUEa9xqdS3XY7WaVtSw==} + '@swc/core-linux-arm64-gnu@1.14.0': + resolution: {integrity: sha512-q2JRu2D8LVqGeHkmpVCljVNltG0tB4o4eYg+dElFwCS8l2Mnt9qurMCxIeo9mgoqz0ax+k7jWtIRHktnVCbjvQ==} engines: {node: '>=10'} cpu: [arm64] os: [linux] - '@swc/core-linux-arm64-musl@1.13.5': - resolution: {integrity: sha512-9+ZxFN5GJag4CnYnq6apKTnnezpfJhCumyz0504/JbHLo+Ue+ZtJnf3RhyA9W9TINtLE0bC4hKpWi8ZKoETyOQ==} + '@swc/core-linux-arm64-musl@1.14.0': + resolution: {integrity: sha512-uofpVoPCEUjYIv454ZEZ3sLgMD17nIwlz2z7bsn7rl301Kt/01umFA7MscUovFfAK2IRGck6XB+uulMu6aFhKQ==} engines: {node: '>=10'} cpu: [arm64] os: [linux] - '@swc/core-linux-x64-gnu@1.13.5': - resolution: {integrity: sha512-WD530qvHrki8Ywt/PloKUjaRKgstQqNGvmZl54g06kA+hqtSE2FTG9gngXr3UJxYu/cNAjJYiBifm7+w4nbHbA==} + '@swc/core-linux-x64-gnu@1.14.0': + resolution: {integrity: sha512-quTTx1Olm05fBfv66DEBuOsOgqdypnZ/1Bh3yGXWY7ANLFeeRpCDZpljD9BSjdsNdPOlwJmEUZXMHtGm3v1TZQ==} engines: {node: '>=10'} cpu: [x64] os: [linux] - '@swc/core-linux-x64-musl@1.13.5': - resolution: {integrity: sha512-Luj8y4OFYx4DHNQTWjdIuKTq2f5k6uSXICqx+FSabnXptaOBAbJHNbHT/06JZh6NRUouaf0mYXN0mcsqvkhd7Q==} + '@swc/core-linux-x64-musl@1.14.0': + resolution: {integrity: sha512-caaNAu+aIqT8seLtCf08i8C3/UC5ttQujUjejhMcuS1/LoCKtNiUs4VekJd2UGt+pyuuSrQ6dKl8CbCfWvWeXw==} engines: {node: '>=10'} cpu: [x64] os: [linux] - '@swc/core-win32-arm64-msvc@1.13.5': - resolution: {integrity: sha512-cZ6UpumhF9SDJvv4DA2fo9WIzlNFuKSkZpZmPG1c+4PFSEMy5DFOjBSllCvnqihCabzXzpn6ykCwBmHpy31vQw==} + '@swc/core-win32-arm64-msvc@1.14.0': + resolution: {integrity: sha512-EeW3jFlT3YNckJ6V/JnTfGcX7UHGyh6/AiCPopZ1HNaGiXVCKHPpVQZicmtyr/UpqxCXLrTgjHOvyMke7YN26A==} engines: {node: '>=10'} cpu: [arm64] os: [win32] - '@swc/core-win32-ia32-msvc@1.13.5': - resolution: {integrity: sha512-C5Yi/xIikrFUzZcyGj9L3RpKljFvKiDMtyDzPKzlsDrKIw2EYY+bF88gB6oGY5RGmv4DAX8dbnpRAqgFD0FMEw==} + '@swc/core-win32-ia32-msvc@1.14.0': + resolution: {integrity: sha512-dPai3KUIcihV5hfoO4QNQF5HAaw8+2bT7dvi8E5zLtecW2SfL3mUZipzampXq5FHll0RSCLzlrXnSx+dBRZIIQ==} engines: {node: '>=10'} cpu: [ia32] os: [win32] - '@swc/core-win32-x64-msvc@1.13.5': - resolution: {integrity: sha512-YrKdMVxbYmlfybCSbRtrilc6UA8GF5aPmGKBdPvjrarvsmf4i7ZHGCEnLtfOMd3Lwbs2WUZq3WdMbozYeLU93Q==} + '@swc/core-win32-x64-msvc@1.14.0': + resolution: {integrity: sha512-nm+JajGrTqUA6sEHdghDlHMNfH1WKSiuvljhdmBACW4ta4LC3gKurX2qZuiBARvPkephW9V/i5S8QPY1PzFEqg==} engines: {node: '>=10'} cpu: [x64] os: [win32] - '@swc/core@1.13.5': - resolution: {integrity: sha512-WezcBo8a0Dg2rnR82zhwoR6aRNxeTGfK5QCD6TQ+kg3xx/zNT02s/0o+81h/3zhvFSB24NtqEr8FTw88O5W/JQ==} + '@swc/core@1.14.0': + resolution: {integrity: sha512-oExhY90bes5pDTVrei0xlMVosTxwd/NMafIpqsC4dMbRYZ5KB981l/CX8tMnGsagTplj/RcG9BeRYmV6/J5m3w==} engines: {node: '>=10'} peerDependencies: '@swc/helpers': '>=0.5.17' @@ -525,20 +525,20 @@ packages: '@types/validator@13.15.3': resolution: {integrity: sha512-7bcUmDyS6PN3EuD9SlGGOxM77F8WLVsrwkxyWxKnxzmXoequ6c7741QBrANq6htVRGOITJ7z72mTP6Z4XyuG+Q==} - '@vitest/coverage-v8@4.0.3': - resolution: {integrity: sha512-I+MlLwyJRBjmJr1kFYSxoseINbIdpxIAeK10jmXgB0FUtIfdYsvM3lGAvBu5yk8WPyhefzdmbCHCc1idFbNRcg==} + '@vitest/coverage-v8@4.0.5': + resolution: {integrity: sha512-Yn5Dx0UVvllE3uatQw+ftObWtM/TjAOdbd8WvygaR04iyFXdNmtvZ/nJ2/JndyzfPQtbAWw0F+GJY5+lgM/7qg==} peerDependencies: - '@vitest/browser': 4.0.3 - vitest: 4.0.3 + '@vitest/browser': 4.0.5 + vitest: 4.0.5 peerDependenciesMeta: '@vitest/browser': optional: true - '@vitest/expect@4.0.3': - resolution: {integrity: sha512-v3eSDx/bF25pzar6aEJrrdTXJduEBU3uSGXHslIdGIpJVP8tQQHV6x1ZfzbFQ/bLIomLSbR/2ZCfnaEGkWkiVQ==} + '@vitest/expect@4.0.5': + resolution: {integrity: sha512-DJctLVlKoddvP/G389oGmKWNG6GD9frm2FPXARziU80Rjo7SIYxQzb2YFzmQ4fVD3Q5utUYY8nUmWrqsuIlIXQ==} - '@vitest/mocker@4.0.3': - resolution: {integrity: sha512-evZcRspIPbbiJEe748zI2BRu94ThCBE+RkjCpVF8yoVYuTV7hMe+4wLF/7K86r8GwJHSmAPnPbZhpXWWrg1qbA==} + '@vitest/mocker@4.0.5': + resolution: {integrity: sha512-iYHIy72LfbK+mL5W8zXROp6oOcJKXWeKcNjcPPsqoa18qIEDrhB6/Z08o0wRajTd6SSSDNw8NCSIHVNOMpz0mw==} peerDependencies: msw: ^2.4.9 vite: ^6.0.0 || ^7.0.0-0 @@ -548,20 +548,20 @@ packages: vite: optional: true - '@vitest/pretty-format@4.0.3': - resolution: {integrity: sha512-N7gly/DRXzxa9w9sbDXwD9QNFYP2hw90LLLGDobPNwiWgyW95GMxsCt29/COIKKh3P7XJICR38PSDePenMBtsw==} + '@vitest/pretty-format@4.0.5': + resolution: {integrity: sha512-t1T/sSdsYyNc5AZl0EMeD0jW9cpJe2cODP0R++ZQe1kTkpgrwEfxGFR/yCG4w8ZybizbXRTHU7lE8sTDD/QsGw==} - '@vitest/runner@4.0.3': - resolution: {integrity: sha512-1/aK6fPM0lYXWyGKwop2Gbvz1plyTps/HDbIIJXYtJtspHjpXIeB3If07eWpVH4HW7Rmd3Rl+IS/+zEAXrRtXA==} + '@vitest/runner@4.0.5': + resolution: {integrity: sha512-CQVVe+YEeKSiFBD5gBAmRDQglm4PnMBYzeTmt06t5iWtsUN9StQeeKhYCea/oaqBYilf8sARG6fSctUcEL/UmQ==} - '@vitest/snapshot@4.0.3': - resolution: {integrity: sha512-amnYmvZ5MTjNCP1HZmdeczAPLRD6iOm9+2nMRUGxbe/6sQ0Ymur0NnR9LIrWS8JA3wKE71X25D6ya/3LN9YytA==} + '@vitest/snapshot@4.0.5': + resolution: {integrity: sha512-jfmSAeR6xYNEvcD+/RxFGA1bzpqHtkVhgxo2cxXia+Q3xX7m6GpZij07rz+WyQcA/xEGn4eIS1OItkMyWsGBmQ==} - '@vitest/spy@4.0.3': - resolution: {integrity: sha512-82vVL8Cqz7rbXaNUl35V2G7xeNMAjBdNOVaHbrzznT9BmiCiPOzhf0FhU3eP41nP1bLDm/5wWKZqkG4nyU95DQ==} + '@vitest/spy@4.0.5': + resolution: {integrity: sha512-TUmVQpAQign7r8+EnZsgTF3vY9BdGofTUge1rGNbnHn2IN3FChiQoT9lrPz7A7AVUZJU2LAZXl4v66HhsNMhoA==} - '@vitest/utils@4.0.3': - resolution: {integrity: sha512-qV6KJkq8W3piW6MDIbGOmn1xhvcW4DuA07alqaQ+vdx7YA49J85pnwnxigZVQFQw3tWnQNRKWwhz5wbP6iv/GQ==} + '@vitest/utils@4.0.5': + resolution: {integrity: sha512-V5RndUgCB5/AfNvK9zxGCrRs99IrPYtMTIdUzJMMFs9nrmE5JXExIEfjVtUteyTRiLfCm+dCRMHf/Uu7Mm8/dg==} acorn@8.15.0: resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} @@ -1301,18 +1301,18 @@ packages: yaml: optional: true - vitest@4.0.3: - resolution: {integrity: sha512-IUSop8jgaT7w0g1yOM/35qVtKjr/8Va4PrjzH1OUb0YH4c3OXB2lCZDkMAB6glA8T5w8S164oJGsbcmAecr4sA==} + vitest@4.0.5: + resolution: {integrity: sha512-4H+J28MI5oeYgGg3h5BFSkQ1g/2GKK1IR8oorH3a6EQQbb7CwjbnyBjH4PGxw9/6vpwAPNzaeUMp4Js4WJmdXQ==} engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@types/debug': ^4.1.12 '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 - '@vitest/browser-playwright': 4.0.3 - '@vitest/browser-preview': 4.0.3 - '@vitest/browser-webdriverio': 4.0.3 - '@vitest/ui': 4.0.3 + '@vitest/browser-playwright': 4.0.5 + '@vitest/browser-preview': 4.0.5 + '@vitest/browser-webdriverio': 4.0.5 + '@vitest/ui': 4.0.5 happy-dom: '*' jsdom: '*' peerDependenciesMeta: @@ -1396,39 +1396,39 @@ snapshots: '@bcoe/v8-coverage@1.0.2': {} - '@biomejs/biome@2.3.1': + '@biomejs/biome@2.3.2': optionalDependencies: - '@biomejs/cli-darwin-arm64': 2.3.1 - '@biomejs/cli-darwin-x64': 2.3.1 - '@biomejs/cli-linux-arm64': 2.3.1 - '@biomejs/cli-linux-arm64-musl': 2.3.1 - '@biomejs/cli-linux-x64': 2.3.1 - '@biomejs/cli-linux-x64-musl': 2.3.1 - '@biomejs/cli-win32-arm64': 2.3.1 - '@biomejs/cli-win32-x64': 2.3.1 + '@biomejs/cli-darwin-arm64': 2.3.2 + '@biomejs/cli-darwin-x64': 2.3.2 + '@biomejs/cli-linux-arm64': 2.3.2 + '@biomejs/cli-linux-arm64-musl': 2.3.2 + '@biomejs/cli-linux-x64': 2.3.2 + '@biomejs/cli-linux-x64-musl': 2.3.2 + '@biomejs/cli-win32-arm64': 2.3.2 + '@biomejs/cli-win32-x64': 2.3.2 - '@biomejs/cli-darwin-arm64@2.3.1': + '@biomejs/cli-darwin-arm64@2.3.2': optional: true - '@biomejs/cli-darwin-x64@2.3.1': + '@biomejs/cli-darwin-x64@2.3.2': optional: true - '@biomejs/cli-linux-arm64-musl@2.3.1': + '@biomejs/cli-linux-arm64-musl@2.3.2': optional: true - '@biomejs/cli-linux-arm64@2.3.1': + '@biomejs/cli-linux-arm64@2.3.2': optional: true - '@biomejs/cli-linux-x64-musl@2.3.1': + '@biomejs/cli-linux-x64-musl@2.3.2': optional: true - '@biomejs/cli-linux-x64@2.3.1': + '@biomejs/cli-linux-x64@2.3.2': optional: true - '@biomejs/cli-win32-arm64@2.3.1': + '@biomejs/cli-win32-arm64@2.3.2': optional: true - '@biomejs/cli-win32-x64@2.3.1': + '@biomejs/cli-win32-x64@2.3.2': optional: true '@esbuild/aix-ppc64@0.25.9': @@ -1621,51 +1621,51 @@ snapshots: '@standard-schema/spec@1.0.0': {} - '@swc/core-darwin-arm64@1.13.5': + '@swc/core-darwin-arm64@1.14.0': optional: true - '@swc/core-darwin-x64@1.13.5': + '@swc/core-darwin-x64@1.14.0': optional: true - '@swc/core-linux-arm-gnueabihf@1.13.5': + '@swc/core-linux-arm-gnueabihf@1.14.0': optional: true - '@swc/core-linux-arm64-gnu@1.13.5': + '@swc/core-linux-arm64-gnu@1.14.0': optional: true - '@swc/core-linux-arm64-musl@1.13.5': + '@swc/core-linux-arm64-musl@1.14.0': optional: true - '@swc/core-linux-x64-gnu@1.13.5': + '@swc/core-linux-x64-gnu@1.14.0': optional: true - '@swc/core-linux-x64-musl@1.13.5': + '@swc/core-linux-x64-musl@1.14.0': optional: true - '@swc/core-win32-arm64-msvc@1.13.5': + '@swc/core-win32-arm64-msvc@1.14.0': optional: true - '@swc/core-win32-ia32-msvc@1.13.5': + '@swc/core-win32-ia32-msvc@1.14.0': optional: true - '@swc/core-win32-x64-msvc@1.13.5': + '@swc/core-win32-x64-msvc@1.14.0': optional: true - '@swc/core@1.13.5': + '@swc/core@1.14.0': dependencies: '@swc/counter': 0.1.3 '@swc/types': 0.1.25 optionalDependencies: - '@swc/core-darwin-arm64': 1.13.5 - '@swc/core-darwin-x64': 1.13.5 - '@swc/core-linux-arm-gnueabihf': 1.13.5 - '@swc/core-linux-arm64-gnu': 1.13.5 - '@swc/core-linux-arm64-musl': 1.13.5 - '@swc/core-linux-x64-gnu': 1.13.5 - '@swc/core-linux-x64-musl': 1.13.5 - '@swc/core-win32-arm64-msvc': 1.13.5 - '@swc/core-win32-ia32-msvc': 1.13.5 - '@swc/core-win32-x64-msvc': 1.13.5 + '@swc/core-darwin-arm64': 1.14.0 + '@swc/core-darwin-x64': 1.14.0 + '@swc/core-linux-arm-gnueabihf': 1.14.0 + '@swc/core-linux-arm64-gnu': 1.14.0 + '@swc/core-linux-arm64-musl': 1.14.0 + '@swc/core-linux-x64-gnu': 1.14.0 + '@swc/core-linux-x64-musl': 1.14.0 + '@swc/core-win32-arm64-msvc': 1.14.0 + '@swc/core-win32-ia32-msvc': 1.14.0 + '@swc/core-win32-x64-msvc': 1.14.0 '@swc/counter@0.1.3': {} @@ -1683,10 +1683,10 @@ snapshots: '@types/validator@13.15.3': {} - '@vitest/coverage-v8@4.0.3(vitest@4.0.3(terser@5.44.0))': + '@vitest/coverage-v8@4.0.5(vitest@4.0.5(terser@5.44.0))': dependencies: '@bcoe/v8-coverage': 1.0.2 - '@vitest/utils': 4.0.3 + '@vitest/utils': 4.0.5 ast-v8-to-istanbul: 0.3.5 debug: 4.4.3 istanbul-lib-coverage: 3.2.2 @@ -1696,47 +1696,47 @@ snapshots: magicast: 0.3.5 std-env: 3.9.0 tinyrainbow: 3.0.3 - vitest: 4.0.3(terser@5.44.0) + vitest: 4.0.5(terser@5.44.0) transitivePeerDependencies: - supports-color - '@vitest/expect@4.0.3': + '@vitest/expect@4.0.5': dependencies: '@standard-schema/spec': 1.0.0 '@types/chai': 5.2.2 - '@vitest/spy': 4.0.3 - '@vitest/utils': 4.0.3 + '@vitest/spy': 4.0.5 + '@vitest/utils': 4.0.5 chai: 6.2.0 tinyrainbow: 3.0.3 - '@vitest/mocker@4.0.3(vite@7.1.6(terser@5.44.0))': + '@vitest/mocker@4.0.5(vite@7.1.6(terser@5.44.0))': dependencies: - '@vitest/spy': 4.0.3 + '@vitest/spy': 4.0.5 estree-walker: 3.0.3 magic-string: 0.30.19 optionalDependencies: vite: 7.1.6(terser@5.44.0) - '@vitest/pretty-format@4.0.3': + '@vitest/pretty-format@4.0.5': dependencies: tinyrainbow: 3.0.3 - '@vitest/runner@4.0.3': + '@vitest/runner@4.0.5': dependencies: - '@vitest/utils': 4.0.3 + '@vitest/utils': 4.0.5 pathe: 2.0.3 - '@vitest/snapshot@4.0.3': + '@vitest/snapshot@4.0.5': dependencies: - '@vitest/pretty-format': 4.0.3 + '@vitest/pretty-format': 4.0.5 magic-string: 0.30.19 pathe: 2.0.3 - '@vitest/spy@4.0.3': {} + '@vitest/spy@4.0.5': {} - '@vitest/utils@4.0.3': + '@vitest/utils@4.0.5': dependencies: - '@vitest/pretty-format': 4.0.3 + '@vitest/pretty-format': 4.0.5 tinyrainbow: 3.0.3 acorn@8.15.0: {} @@ -2393,7 +2393,7 @@ snapshots: tslib@2.8.1: {} - tsup@8.5.0(@swc/core@1.13.5)(postcss@8.5.6)(typescript@5.9.3): + tsup@8.5.0(@swc/core@1.14.0)(postcss@8.5.6)(typescript@5.9.3): dependencies: bundle-require: 5.1.0(esbuild@0.25.9) cac: 6.7.14 @@ -2413,7 +2413,7 @@ snapshots: tinyglobby: 0.2.15 tree-kill: 1.2.2 optionalDependencies: - '@swc/core': 1.13.5 + '@swc/core': 1.14.0 postcss: 8.5.6 typescript: 5.9.3 transitivePeerDependencies: @@ -2442,15 +2442,15 @@ snapshots: fsevents: 2.3.3 terser: 5.44.0 - vitest@4.0.3(terser@5.44.0): + vitest@4.0.5(terser@5.44.0): dependencies: - '@vitest/expect': 4.0.3 - '@vitest/mocker': 4.0.3(vite@7.1.6(terser@5.44.0)) - '@vitest/pretty-format': 4.0.3 - '@vitest/runner': 4.0.3 - '@vitest/snapshot': 4.0.3 - '@vitest/spy': 4.0.3 - '@vitest/utils': 4.0.3 + '@vitest/expect': 4.0.5 + '@vitest/mocker': 4.0.5(vite@7.1.6(terser@5.44.0)) + '@vitest/pretty-format': 4.0.5 + '@vitest/runner': 4.0.5 + '@vitest/snapshot': 4.0.5 + '@vitest/spy': 4.0.5 + '@vitest/utils': 4.0.5 debug: 4.4.3 es-module-lexer: 1.7.0 expect-type: 1.2.2 diff --git a/src/queryKinds/ddl/ddlQueryDefinition.test.ts b/src/queryKinds/ddl/ddlQueryDefinition.test.ts new file mode 100644 index 0000000..e72e756 --- /dev/null +++ b/src/queryKinds/ddl/ddlQueryDefinition.test.ts @@ -0,0 +1,208 @@ +import { describe, expect, it } from "vitest"; +import { Query } from "../../index.js" +import Column from "../../queryUtils/Column.js"; + +describe('DDL Query Definition', () => { + it('should create a basic DDL query using Query interface and test if it\'s done', () => { + const query = Query + .table.create + .table('users') + .setColumns([ + Column('id', 'INT').primaryKey().notNull(), + Column('username', 'VARCHAR(50)').notNull() + ]); + + let isDone = query.isDone(); + expect(isDone).toBe(false); + + expect(query.build()) + .toEqual('CREATE TABLE "users" (\n id INT PRIMARY KEY,\n username VARCHAR(50) NOT NULL\n);'); + + isDone = query.isDone(); + expect(isDone).toBe(true); + }); + + it('should be able to build explain query', () => { + const query = Query + .table.create + .table('products') + .setColumns([ + Column('product_id', 'INT').primaryKey().notNull(), + Column('product_name', 'VARCHAR(100)').notNull() + ]); + + expect(query.buildExplain()) + .toEqual('EXPLAIN CREATE TABLE "products" (\n product_id INT PRIMARY KEY,\n product_name VARCHAR(100) NOT NULL\n);'); + + // Explain Analyze + expect(query.buildExplainAnalyze()) + .toEqual('EXPLAIN ANALYZE CREATE TABLE "products" (\n product_id INT PRIMARY KEY,\n product_name VARCHAR(100) NOT NULL\n);'); + }); + + it('should be able to handle schemas in table names', () => { + const query = Query + .table.create + .schema('client_a') + .table('$schema.products') + .setColumns([ + Column('product_id', 'INT').primaryKey().notNull(), + Column('product_name', 'VARCHAR(100)').notNull() + ]); + + expect(query.build()) + .toEqual('CREATE TABLE client_a."products" (\n product_id INT PRIMARY KEY,\n product_name VARCHAR(100) NOT NULL\n);'); + + // add schema + const query2 = Query + .table.create + .schema('client_a') + .table('$schema1.products') + .setColumns([ + Column('product_id', 'INT').primaryKey().notNull(), + Column('product_name', 'VARCHAR(100)').notNull() + ]) + .addSchema('client_b'); + + expect(query2.build()) + .toEqual('CREATE TABLE client_b."products" (\n product_id INT PRIMARY KEY,\n product_name VARCHAR(100) NOT NULL\n);'); + }); + + + it('should be able to execute the built query', async () => { + const executeFunction = async (queryString: string) => { + // Mock execution function + expect(queryString).toSatisfy((value: string | string[]) => { + if (typeof value !== 'string' && !Array.isArray(value)) { + return false; + } + return true; + }); + }; + + const query = Query + .table.create + .table('orders') + .setColumns([ + Column('order_id', 'INT').primaryKey().notNull(), + Column('order_date', 'DATE').notNull() + ]); + + const result = await query.execute(executeFunction); + expect(result).toEqual(undefined); + + const query2 = Query + .table.alter + .table('employees') + .addColumnsToAdd([ + Column('employee_id', 'INT').primaryKey().notNull(), + Column('employee_name', 'VARCHAR(100)').notNull(), + ]); + + const result2 = await query2.execute(executeFunction); + expect(result2).toEqual(undefined); + + let executeObject: { + [key: string]: any, + manager?: { + execute?: (queryString: string) => Promise; + }; + } = { + execute: async (queryString: string) => { + // Mock execution function + expect(queryString).toSatisfy((value: string | string[]) => { + if (typeof value !== 'string' && !Array.isArray(value)) { + return false; + } + return true; + }); + } + }; + + const query3 = Query + .table.create + .table('customers') + .setColumns([ + Column('customer_id', 'INT').primaryKey().notNull(), + Column('customer_name', 'VARCHAR(100)').notNull() + ]); + + const result3 = await query3.execute(executeObject); + expect(result3).toEqual(undefined); + + executeObject.manager = { + execute: async (queryString: string) => { + // Mock execution function + expect(queryString).toSatisfy((value: string | string[]) => { + if (typeof value !== 'string' && !Array.isArray(value)) { + return false; + } + return true; + }); + } + } + + const query4 = Query + .table.create + .table('suppliers') + .setColumns([ + Column('supplier_id', 'INT').primaryKey().notNull(), + Column('supplier_name', 'VARCHAR(100)').notNull() + ]); + + const result4 = await query4.execute(executeObject); + expect(result4).toEqual(undefined); + + const query5 = Query + .table.drop + .table('old_table'); + + delete executeObject.manager.execute; + + await expect(query5.execute(executeObject)).rejects.toThrowError(); + + // Ignore manager + const query6 = Query + .table.drop + .table('another_old_table'); + + const result6 = await query6.execute(executeObject, true); + expect(result6).toEqual(undefined); + + const query7 = Query + .table.alter + .table('departments') + .addColumnsToAdd([ + Column('department_id', 'INT').primaryKey().notNull(), + Column('department_name', 'VARCHAR(100)').notNull(), + ]); + + executeObject.manager = { + execute: async (queryString: string) => { + // Mock execution function + expect(queryString).toSatisfy((value: string | string[]) => { + if (typeof value !== 'string' && !Array.isArray(value)) { + return false; + } + return true; + }); + } + }; + + const result7 = await query7.execute(executeObject); + expect(result7).toEqual(undefined); + + delete executeObject.manager; + + expect(await query7.execute(executeObject)).toEqual(undefined); + }); + + it('should test utility spaceLines', () => { + const query = Query + .table.create; + + const noSpaces = `CREATE TABLE "test" (\nid INT\n);`; + expect(query['spaceLines'](noSpaces, 1)).toEqual(" CREATE TABLE \"test\" (\n id INT\n );"); + + + }) +}); diff --git a/src/queryKinds/ddl/table/Alter.test.ts b/src/queryKinds/ddl/table/Alter.test.ts index 07e5284..b5f9b84 100644 --- a/src/queryKinds/ddl/table/Alter.test.ts +++ b/src/queryKinds/ddl/table/Alter.test.ts @@ -1,6 +1,7 @@ import { describe, expect, it } from "vitest"; import AlterTableQuery from "./Alter.js"; import Column from "../../../queryUtils/Column.js"; +import { Varchar } from "../../../types/ColumnTypes.js"; describe('Alter Table Query', () => { @@ -12,7 +13,22 @@ describe('Alter Table Query', () => { expect(query).toEqual([ 'ALTER TABLE "users" ADD COLUMN id INT;', 'ALTER TABLE "users" ALTER COLUMN id SET NOT NULL;', - 'ALTER TABLE "users" ADD CONSTRAINT id_pkey PRIMARY KEY (id);', + 'ALTER TABLE "users" ADD CONSTRAINT users_id_pkey PRIMARY KEY (id);', + ]); + + const query2 = new AlterTableQuery('employees') + .addColumnsToAdd([ + Column('employee_id', 'INT').primaryKey().notNull(), + Column('employee_name', Varchar(100)).notNull(), + ]) + .build(); + + expect(query2).toEqual([ + 'ALTER TABLE "employees" ADD COLUMN employee_id INT;', + 'ALTER TABLE "employees" ALTER COLUMN employee_id SET NOT NULL;', + 'ALTER TABLE "employees" ADD CONSTRAINT employees_employee_id_pkey PRIMARY KEY (employee_id);', + 'ALTER TABLE "employees" ADD COLUMN employee_name VARCHAR(100);', + 'ALTER TABLE "employees" ALTER COLUMN employee_name SET NOT NULL;', ]); }); @@ -27,7 +43,7 @@ describe('Alter Table Query', () => { expect(query).toEqual([ 'ALTER TABLE "products" ADD COLUMN product_id INT;', 'ALTER TABLE "products" ALTER COLUMN product_id SET NOT NULL;', - 'ALTER TABLE "products" ADD CONSTRAINT product_id_pkey PRIMARY KEY (product_id);', + 'ALTER TABLE "products" ADD CONSTRAINT products_product_id_pkey PRIMARY KEY (product_id);', ]); }); @@ -42,9 +58,151 @@ describe('Alter Table Query', () => { expect(query).toEqual([ 'ALTER TABLE "orders" ADD COLUMN order_id INT;', 'ALTER TABLE "orders" ALTER COLUMN order_id SET NOT NULL;', - 'ALTER TABLE "orders" ADD CONSTRAINT order_id_pkey PRIMARY KEY (order_id);', + 'ALTER TABLE "orders" ADD CONSTRAINT orders_order_id_pkey PRIMARY KEY (order_id);', 'ALTER TABLE "orders" ADD COLUMN order_date DATE;', 'ALTER TABLE "orders" ALTER COLUMN order_date SET NOT NULL;', ]); + + const query2 = new AlterTableQuery('orders') + .setColumnsToAdd(Column('customer_id', 'INT').notNull()) + .build(); + + expect(query2).toEqual([ + 'ALTER TABLE "orders" ADD COLUMN customer_id INT;', + 'ALTER TABLE "orders" ALTER COLUMN customer_id SET NOT NULL;', + ]); + }); + + it('should allow to set columns to alter', () => { + const query = new AlterTableQuery('customers') + .setColumnsToAlter([ + { name: 'customer_name', columns: Column('customer_name', Varchar(100)).notNull() }, + ]) + .build(); + + expect(query).toEqual([ + 'ALTER TABLE "customers" ALTER COLUMN customer_name TYPE VARCHAR(100);', + 'ALTER TABLE "customers" ALTER COLUMN customer_name SET NOT NULL;', + ]); + + const query2 = new AlterTableQuery('customers') + .setColumnsToAlter({ name: 'customer_email', columns: Column('customer_email', Varchar(150)).unique() }) + .build(); + + expect(query2).toEqual([ + 'ALTER TABLE "customers" ALTER COLUMN customer_email TYPE VARCHAR(150);', + 'ALTER TABLE "customers" ALTER COLUMN customer_email DROP NOT NULL;', + 'ALTER TABLE "customers" ADD CONSTRAINT customers_customer_email_unique UNIQUE (customer_email);' + ]); + }); + + it('should allow to drop columns', () => { + const query = new AlterTableQuery('inventory') + .dropColumnsByName(['old_column1', 'old_column2']) + .build(); + + expect(query).toEqual([ + 'ALTER TABLE "inventory" DROP COLUMN old_column1;', + 'ALTER TABLE "inventory" DROP COLUMN old_column2;', + ]); + + const query2 = new AlterTableQuery('inventory') + .dropColumnsByName('obsolete_column') + .build(); + + expect(query2).toEqual([ + 'ALTER TABLE "inventory" DROP COLUMN obsolete_column;', + ]); + + // set + const query3 = new AlterTableQuery('inventory') + .setColumnsToDrop('discontinued_column') + .build(); + + expect(query3).toEqual([ + 'ALTER TABLE "inventory" DROP COLUMN discontinued_column;', + ]); + + const query4 = new AlterTableQuery('inventory') + .setColumnsToDrop(['temp_column1', 'temp_column2']) + .build(); + + expect(query4).toEqual([ + 'ALTER TABLE "inventory" DROP COLUMN temp_column1;', + 'ALTER TABLE "inventory" DROP COLUMN temp_column2;', + ]); + }); + + it('should give kind as ALTER_TABLE', () => { + const query = new AlterTableQuery('test_table'); + expect(query.kind).toBe('ALTER_TABLE'); + }); + + it('should throw error if table name is not provided', () => { + const query = new AlterTableQuery(); + expect(() => query.build()).toThrowError( + 'Table name is required to build ALTER TABLE query.' + ); + }); + + it('should throw error if no alterations are specified', () => { + const query = new AlterTableQuery('test_table'); + expect(() => query.build()).toThrowError( + 'No alterations specified for ALTER TABLE query.' + ); + }); + + it('should be able to convert to sql using toSQL method', () => { + const query = new AlterTableQuery('employees') + .addColumnsToAdd(Column('employee_id', 'INT').primaryKey().notNull()); + + expect(query.toSQL()).toEqual([ + 'ALTER TABLE "employees" ADD COLUMN employee_id INT;', + 'ALTER TABLE "employees" ALTER COLUMN employee_id SET NOT NULL;', + 'ALTER TABLE "employees" ADD CONSTRAINT employees_employee_id_pkey PRIMARY KEY (employee_id);', + ]); + + const query2 = new AlterTableQuery('employees') + .dropColumnsByName('old_employee_column'); + + query2.toSQL(); + + expect(query2.toSQL()).toEqual([ + 'ALTER TABLE "employees" DROP COLUMN old_employee_column;', + ]); + }); + + it('should clone the AlterTableQuery instance', () => { + const originalQuery = new AlterTableQuery('departments') + .addColumnsToAdd(Column('department_id', 'INT').primaryKey().notNull()); + + const clonedQuery = originalQuery.clone(); + + expect(clonedQuery).toEqual(originalQuery); + expect(clonedQuery).not.toBe(originalQuery); + + // Modify the clone and ensure the original is unaffected + clonedQuery.table('new_departments'); + + expect((clonedQuery as any).tableName).toBe('"new_departments"'); + expect((originalQuery as any).tableName).toBe('"departments"'); + }); + + it('should be able to reset the AlterTableQuery instance', () => { + const query = new AlterTableQuery('projects') + .addColumnsToAdd(Column('project_id', 'INT').primaryKey().notNull()) + .dropColumnsByName('old_project_column'); + + query.reset(); + + expect(() => query.build()).toThrowError( + 'Table name is required to build ALTER TABLE query.' + ); + + query.table('new_projects'); + + expect(() => query.build()).toThrowError( + 'No alterations specified for ALTER TABLE query.' + ); }); }); diff --git a/src/queryKinds/ddl/table/Alter.ts b/src/queryKinds/ddl/table/Alter.ts index 442cc3f..aa40c54 100644 --- a/src/queryKinds/ddl/table/Alter.ts +++ b/src/queryKinds/ddl/table/Alter.ts @@ -153,7 +153,7 @@ export default class AlterTableQuery extends TableQueryDefinition { * Gets the kind of query. * @returns The kind of query, which is 'ALTER_TABLE' for this class. */ - public get kind() { + public get kind(): QueryKind { return QueryKind.ALTER_TABLE; } @@ -200,7 +200,7 @@ export default class AlterTableQuery extends TableQueryDefinition { * @throws Error if the query has not been built yet. */ public toSQL(): string[] { - if (this.builtQuery) this.build(); + if (!this.builtQuery) this.build(); return this.builtQuery as string[]; } @@ -209,7 +209,8 @@ export default class AlterTableQuery extends TableQueryDefinition { * @returns A new AlterTableQuery instance with the same properties as the current instance. */ public clone(): AlterTableQuery { - const cloned = new AlterTableQuery(this.tableName); + const cloned = new AlterTableQuery(); + cloned.tableName = this.tableName; cloned.flavor = this.flavor; cloned.columnsToAdd = [...this.columnsToAdd]; cloned.columnsToAlter = new Map(this.columnsToAlter); diff --git a/src/queryUtils/Column.test.ts b/src/queryUtils/Column.test.ts new file mode 100644 index 0000000..78580c9 --- /dev/null +++ b/src/queryUtils/Column.test.ts @@ -0,0 +1,319 @@ +import { describe, expect, it } from "vitest"; +import { ColumnDefinition, ColumnType } from "./Column.js"; +import { Varchar } from "../types/ColumnTypes.js"; + + +describe("Column Definition Class", () => { + + it('should create a column definition instance', () => { + const columnDef = new ColumnDefinition("id", new ColumnType("INTEGER")); + expect((columnDef as any).name).toBe("id"); + expect((columnDef as any).type).toBeInstanceOf(ColumnType); + expect(columnDef.build()).toBe('id INTEGER'); + }); + + it('type should be null if not set', () => { + const columnDef = new ColumnDefinition("name"); + expect((columnDef as any).name).toBe("name"); + expect((columnDef as any).type).toBeNull(); + expect(() => columnDef.build()).toThrow("Column type is not set."); + }); + + it('name should be null if not set', () => { + const columnDef = new ColumnDefinition(undefined, new ColumnType("TEXT")); + expect((columnDef as any).name).toBeNull(); + expect((columnDef as any).type).toBeInstanceOf(ColumnType); + expect(() => columnDef.build()).toThrow("Column name is not set."); + }); + + it('should be able to set name and type after creation', () => { + const columnDef = new ColumnDefinition(); + columnDef.setName("username"); + columnDef.setType(new ColumnType("VARCHAR", [50])); + expect((columnDef as any).name).toBe("username"); + expect((columnDef as any).type).toBeInstanceOf(ColumnType); + expect(columnDef.build()).toBe('username VARCHAR(50)'); + }); + + it('should be able to pass type as string', () => { + const columnDef = new ColumnDefinition("age", "INTEGER"); + expect((columnDef as any).name).toBe("age"); + expect((columnDef as any).type).toBeInstanceOf(ColumnType); + expect(columnDef.build()).toBe('age INTEGER'); + + const columnDef2 = new ColumnDefinition(); + columnDef2.setName("created_at"); + columnDef2.setType("TIMESTAMP"); + expect((columnDef2 as any).name).toBe("created_at"); + expect((columnDef2 as any).type).toBeInstanceOf(ColumnType); + expect(columnDef2.build()).toBe('created_at TIMESTAMP'); + }); + + it('should be able to set null or not null constraint', () => { + const columnDef = new ColumnDefinition("email", new ColumnType("VARCHAR", [100])); + columnDef.notNull(); + expect(columnDef.build()).toBe('email VARCHAR(100) NOT NULL'); + + const columnDef2 = new ColumnDefinition("bio", new ColumnType("TEXT")); + columnDef2.null(); + expect(columnDef2.build()).toBe('bio TEXT'); + }); + + it('should chain methods correctly', () => { + const columnDef = new ColumnDefinition() + .setName("status") + .setType(Varchar(20)) + .notNull(); + expect((columnDef as any).name).toBe("status"); + expect((columnDef as any).type).toBeInstanceOf(ColumnType); + expect(columnDef.build()).toBe('status VARCHAR(20) NOT NULL'); + }); + + it('should be able to set default value', () => { + const columnDef = new ColumnDefinition("is_active", new ColumnType("BOOLEAN")); + columnDef.default(true); + expect(columnDef.build()).toBe('is_active BOOLEAN DEFAULT true'); + + const columnDef2 = new ColumnDefinition("created_at", new ColumnType("TIMESTAMP")); + columnDef2.default('CURRENT_TIMESTAMP'); + expect(columnDef2.build()).toBe('created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP'); + }); + + it('should be able to add check constraint', () => { + const columnDef = new ColumnDefinition("age", new ColumnType("INTEGER")); + columnDef.check("age >= 0"); + expect(columnDef.build()).toBe('age INTEGER CHECK (age >= 0)'); + + const columnDef2 = new ColumnDefinition("score", new ColumnType("INTEGER")); + columnDef2.check("score BETWEEN 0 AND 100"); + expect(columnDef2.build()).toBe('score INTEGER CHECK (score BETWEEN 0 AND 100)'); + }); + + it('should be able to set unique constraint', () => { + const columnDef = new ColumnDefinition("email", new ColumnType("VARCHAR", [255])); + columnDef.unique(); + expect(columnDef.build()).toBe('email VARCHAR(255) UNIQUE'); + }); + + it('should be able to set primary key constraint', () => { + const columnDef = new ColumnDefinition("id", new ColumnType("SERIAL")); + columnDef.primaryKey(); + expect(columnDef.build()).toBe('id SERIAL PRIMARY KEY'); + }); + + it('should throw error if name, type or name and type are not set', () => { + const columnDef1 = new ColumnDefinition(); + expect(() => columnDef1.build()).toThrow("Column name and type are not set."); + + const columnDef2 = new ColumnDefinition("username"); + expect(() => columnDef2.build()).toThrow("Column type is not set."); + + const columnDef3 = new ColumnDefinition(undefined, new ColumnType("TEXT")); + expect(() => columnDef3.build()).toThrow("Column name is not set."); + }); + + it('should be able to set foreign key constraint', () => { + const columnDef = new ColumnDefinition("user_id", new ColumnType("INTEGER")); + columnDef.references("users", "id"); + expect(columnDef.build()).toBe('user_id INTEGER REFERENCES users(id)'); + + // With actions + const columnDef2 = new ColumnDefinition("profile_id", new ColumnType("INTEGER")); + columnDef2.references("profiles", "id", "CASCADE", "SET NULL"); + expect(columnDef2.build()).toBe('profile_id INTEGER REFERENCES profiles(id) ON DELETE CASCADE ON UPDATE SET NULL'); + }); + + it('should be able to build for adding in a table', () => { + const columnDef = new ColumnDefinition("email", new ColumnType("VARCHAR", [150])); + expect(columnDef.buildToAdd("users")).toEqual([ + 'ALTER TABLE users ADD COLUMN email VARCHAR(150)', + 'ALTER TABLE users ALTER COLUMN email DROP NOT NULL' + ]); + + // With not null constraint + const columnDef2 = new ColumnDefinition("id", new ColumnType("SERIAL")); + columnDef2.notNull(); + expect(columnDef2.buildToAdd("accounts")).toEqual([ + 'ALTER TABLE accounts ADD COLUMN id SERIAL', + 'ALTER TABLE accounts ALTER COLUMN id SET NOT NULL' + ]); + + // With default value + const columnDef3 = new ColumnDefinition("created_at", new ColumnType("TIMESTAMP")); + columnDef3.default('CURRENT_TIMESTAMP'); + expect(columnDef3.buildToAdd("logs")).toEqual([ + 'ALTER TABLE logs ADD COLUMN created_at TIMESTAMP', + 'ALTER TABLE logs ALTER COLUMN created_at DROP NOT NULL', + 'ALTER TABLE logs ALTER COLUMN created_at SET DEFAULT CURRENT_TIMESTAMP' + ]); + + // With check constraint + const columnDef4 = new ColumnDefinition("age", new ColumnType("INTEGER")); + columnDef4.check("age >= 0"); + expect(columnDef4.buildToAdd("persons")).toEqual([ + 'ALTER TABLE persons ADD COLUMN age INTEGER', + 'ALTER TABLE persons ALTER COLUMN age DROP NOT NULL', + 'ALTER TABLE persons ADD CONSTRAINT persons_age_check CHECK (age >= 0)' + ]); + + // With foreign key constraint + const columnDef5 = new ColumnDefinition("user_id", new ColumnType("INTEGER")); + columnDef5.references("users", "id", "CASCADE", "CASCADE"); + expect(columnDef5.buildToAdd("orders")).toEqual([ + 'ALTER TABLE orders ADD COLUMN user_id INTEGER', + 'ALTER TABLE orders ALTER COLUMN user_id DROP NOT NULL', + 'ALTER TABLE orders ADD CONSTRAINT orders_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE ON UPDATE CASCADE' + ]); + + // With unique constraint + const columnDef6 = new ColumnDefinition("email", new ColumnType("VARCHAR", [255])); + columnDef6.unique(); + expect(columnDef6.buildToAdd("subscribers")).toEqual([ + 'ALTER TABLE subscribers ADD COLUMN email VARCHAR(255)', + 'ALTER TABLE subscribers ALTER COLUMN email DROP NOT NULL', + 'ALTER TABLE subscribers ADD CONSTRAINT subscribers_email_unique UNIQUE (email)' + ]); + + // With foreign key with no actions + const columnDef7 = new ColumnDefinition("category_id", new ColumnType("INTEGER")); + columnDef7.references("categories", "id"); + expect(columnDef7.buildToAdd("products")).toEqual([ + 'ALTER TABLE products ADD COLUMN category_id INTEGER', + 'ALTER TABLE products ALTER COLUMN category_id DROP NOT NULL', + 'ALTER TABLE products ADD CONSTRAINT products_category_id_fkey FOREIGN KEY (category_id) REFERENCES categories(id)' + ]); + + // With primary key constraint + const columnDef8 = new ColumnDefinition("id", new ColumnType("INTEGER")); + columnDef8.primaryKey(); + expect(columnDef8.buildToAdd("employees")).toEqual([ + 'ALTER TABLE employees ADD COLUMN id INTEGER', + 'ALTER TABLE employees ALTER COLUMN id SET NOT NULL', + 'ALTER TABLE employees ADD CONSTRAINT employees_id_pkey PRIMARY KEY (id)' + ]); + }); + + it('should be able to build for altering in a table', () => { + + // Altering name + const columnDef = new ColumnDefinition("new_name", new ColumnType("VARCHAR", [100])); + expect(columnDef.buildToAlter("users", "old_name")).toEqual([ + 'ALTER TABLE users RENAME COLUMN old_name TO new_name', + 'ALTER TABLE users ALTER COLUMN new_name TYPE VARCHAR(100)', + 'ALTER TABLE users ALTER COLUMN new_name DROP NOT NULL', + ]); + + // Without constraints + const columnDef2 = new ColumnDefinition("email", new ColumnType("VARCHAR", [150])); + expect(columnDef2.buildToAlter("users")).toEqual([ + 'ALTER TABLE users ALTER COLUMN email TYPE VARCHAR(150)', + 'ALTER TABLE users ALTER COLUMN email DROP NOT NULL', + ]); + + // With not null constraint + const columnDef3 = new ColumnDefinition("id", new ColumnType("SERIAL")); + columnDef3.notNull(); + expect(columnDef3.buildToAlter("accounts")).toEqual([ + 'ALTER TABLE accounts ALTER COLUMN id TYPE SERIAL', + 'ALTER TABLE accounts ALTER COLUMN id SET NOT NULL', + ]); + + // With default value + const columnDef4 = new ColumnDefinition("created_at", new ColumnType("TIMESTAMP")); + columnDef4.default('CURRENT_TIMESTAMP'); + expect(columnDef4.buildToAlter("logs")).toEqual([ + 'ALTER TABLE logs ALTER COLUMN created_at TYPE TIMESTAMP', + 'ALTER TABLE logs ALTER COLUMN created_at DROP NOT NULL', + 'ALTER TABLE logs ALTER COLUMN created_at SET DEFAULT CURRENT_TIMESTAMP' + ]); + + // With check constraint + const columnDef5 = new ColumnDefinition("age", new ColumnType("INTEGER")); + columnDef5.check("age >= 0"); + expect(columnDef5.buildToAlter("persons")).toEqual([ + 'ALTER TABLE persons ALTER COLUMN age TYPE INTEGER', + 'ALTER TABLE persons ALTER COLUMN age DROP NOT NULL', + 'ALTER TABLE persons ADD CONSTRAINT persons_age_check CHECK (age >= 0)' + ]); + + // With unique constraint + const columnDef6 = new ColumnDefinition("email", new ColumnType("VARCHAR", [255])); + columnDef6.unique(); + expect(columnDef6.buildToAlter("subscribers")).toEqual([ + 'ALTER TABLE subscribers ALTER COLUMN email TYPE VARCHAR(255)', + 'ALTER TABLE subscribers ALTER COLUMN email DROP NOT NULL', + 'ALTER TABLE subscribers ADD CONSTRAINT subscribers_email_unique UNIQUE (email)' + ]); + + // With primary key constraint + const columnDef7 = new ColumnDefinition("id", new ColumnType("INTEGER")); + columnDef7.primaryKey(); + expect(columnDef7.buildToAlter("employees")).toEqual([ + 'ALTER TABLE employees ALTER COLUMN id TYPE INTEGER', + 'ALTER TABLE employees ALTER COLUMN id SET NOT NULL', + 'ALTER TABLE employees ADD CONSTRAINT employees_id_pkey PRIMARY KEY (id)' + ]); + + // With foreign key constraint + const columnDef8 = new ColumnDefinition("user_id", new ColumnType("INTEGER")); + columnDef8.references("users", "id", "CASCADE", "SET NULL"); + expect(columnDef8.buildToAlter("orders")).toEqual([ + 'ALTER TABLE orders ALTER COLUMN user_id TYPE INTEGER', + 'ALTER TABLE orders ALTER COLUMN user_id DROP NOT NULL', + 'ALTER TABLE orders ADD CONSTRAINT orders_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE ON UPDATE SET NULL' + ]); + + // With foreign key with no actions + const columnDef9 = new ColumnDefinition("category_id", new ColumnType("INTEGER")); + columnDef9.references("categories", "id"); + expect(columnDef9.buildToAlter("products")).toEqual([ + 'ALTER TABLE products ALTER COLUMN category_id TYPE INTEGER', + 'ALTER TABLE products ALTER COLUMN category_id DROP NOT NULL', + 'ALTER TABLE products ADD CONSTRAINT products_category_id_fkey FOREIGN KEY (category_id) REFERENCES categories(id)' + ]); + + // To drop default + const columnDef10 = new ColumnDefinition("is_active", new ColumnType("BOOLEAN")); + columnDef10.dropDefaultValue(); + expect(columnDef10.buildToAlter("members")).toEqual([ + 'ALTER TABLE members ALTER COLUMN is_active TYPE BOOLEAN', + 'ALTER TABLE members ALTER COLUMN is_active DROP NOT NULL', + 'ALTER TABLE members ALTER COLUMN is_active DROP DEFAULT' + ]); + }); + + it('should use toString method to build normally', () => { + const columnDef = new ColumnDefinition("username", new ColumnType("VARCHAR", [50])); + expect(columnDef.toString()).toBe('username VARCHAR(50)'); + }); + + +}); + +describe("Column Type Class", () => { + it('should create a column type instance', () => { + const columnType = new ColumnType("VARCHAR", [255]); + expect((columnType as any).typeName).toBe("VARCHAR"); + expect((columnType as any).properties).toEqual(['255']); + expect(columnType.build()).toBe("VARCHAR(255)"); + }); + + it('should be able to set type and properties after creation', () => { + const columnType = new ColumnType("INTEGER"); + columnType.setType("CHAR"); + columnType.addProperty(10); + expect((columnType as any).typeName).toBe("CHAR"); + expect((columnType as any).properties).toEqual(['10']); + expect(columnType.build()).toBe("CHAR(10)"); + }); + + it('should handle types without properties', () => { + const columnType = new ColumnType("TEXT"); + expect(columnType.build()).toBe("TEXT"); + }); + + it('should throw error if type is not set', () => { + const columnType = new ColumnType(); + expect(() => columnType.build()).toThrow("Type name is not set."); + }); +}) diff --git a/src/queryUtils/Column.ts b/src/queryUtils/Column.ts index a613689..d7e422c 100644 --- a/src/queryUtils/Column.ts +++ b/src/queryUtils/Column.ts @@ -37,8 +37,10 @@ export class ColumnType { * @param property - The property to add. * @returns The current instance for method chaining. */ - public addProperty(property: string): this { - this.properties.push(property); + public addProperty( + property: string | { toString(): string }, + ): this { + this.properties.push(property.toString()); return this; } @@ -90,6 +92,8 @@ export class ColumnDefinition { private checkCondition?: string; /** Foreign key constraint details, if any. */ private foreignKey: ForeignKey | null = null; + /** Drop default value flag */ + private dropDefault: boolean = false; constructor( name: string | null = null, @@ -107,6 +111,15 @@ export class ColumnDefinition { } } + /** + * Marks the column to drop its default value. + * @returns The current instance for method chaining. + */ + public dropDefaultValue(): this { + this.dropDefault = true; + return this; + } + /** * Sets the name of the column. * @param name - The name of the column. @@ -245,7 +258,7 @@ export class ColumnDefinition { } } - if (this.defaultValue !== undefined) { + if (this.defaultValue !== undefined && !forAdding) { parts.push(`DEFAULT ${this.defaultValue}`); } @@ -253,7 +266,7 @@ export class ColumnDefinition { parts.push(`CHECK (${this.checkCondition})`); } - if (this.foreignKey) { + if (this.foreignKey && !forAdding) { let fkPart = `REFERENCES ${this.foreignKey.table}(${this.foreignKey.column})`; if (this.foreignKey.onDelete) { fkPart += ` ON DELETE ${this.foreignKey.onDelete}`; @@ -267,27 +280,31 @@ export class ColumnDefinition { return parts.join(" "); } - public buildToAdd(tableName: string): string[] { - const addColumn = `ALTER TABLE ${tableName} ADD COLUMN ${this.build(true)}`; + public buildToAdd(tableNameEntry: string): string[] { + let tableName = tableNameEntry.trim(); + if (tableName.startsWith('"') && tableName.endsWith('"')) { + tableName = tableName.slice(1, -1); + } + const addColumn = `ALTER TABLE ${tableNameEntry} ADD COLUMN ${this.build(true)}`; const addColumnNullability = this.isNullable - ? `ALTER TABLE ${tableName} ALTER COLUMN ${this.name} DROP NOT NULL` - : `ALTER TABLE ${tableName} ALTER COLUMN ${this.name} SET NOT NULL`; + ? `ALTER TABLE ${tableNameEntry} ALTER COLUMN ${this.name} DROP NOT NULL` + : `ALTER TABLE ${tableNameEntry} ALTER COLUMN ${this.name} SET NOT NULL`; const addColumnDefault = this.defaultValue !== undefined - ? `ALTER TABLE ${tableName} ALTER COLUMN ${this.name} SET DEFAULT ${this.defaultValue}` + ? `ALTER TABLE ${tableNameEntry} ALTER COLUMN ${this.name} SET DEFAULT ${this.defaultValue}` : ""; const addColumnCheck = this.checkCondition !== undefined - ? `ALTER TABLE ${tableName} ADD CONSTRAINT ${this.name}_check CHECK (${this.checkCondition})` + ? `ALTER TABLE ${tableNameEntry} ADD CONSTRAINT ${tableName}_${this.name}_check CHECK (${this.checkCondition})` : ""; const addColumnPrimaryKey = this.isPrimaryKey - ? `ALTER TABLE ${tableName} ADD CONSTRAINT ${this.name}_pkey PRIMARY KEY (${this.name})` + ? `ALTER TABLE ${tableNameEntry} ADD CONSTRAINT ${tableName}_${this.name}_pkey PRIMARY KEY (${this.name})` : ""; const addColumnUnique = this.isUnique - ? `ALTER TABLE ${tableName} ADD CONSTRAINT ${this.name}_unique UNIQUE (${this.name})` + ? `ALTER TABLE ${tableNameEntry} ADD CONSTRAINT ${tableName}_${this.name}_unique UNIQUE (${this.name})` : ""; const addForeignKey = this.foreignKey - ? `ALTER TABLE ${tableName} ADD CONSTRAINT ${this.name}_fkey FOREIGN KEY (${this.name}) REFERENCES ${this.foreignKey.table}(${this.foreignKey.column})` + + ? `ALTER TABLE ${tableNameEntry} ADD CONSTRAINT ${tableName}_${this.name}_fkey FOREIGN KEY (${this.name}) REFERENCES ${this.foreignKey.table}(${this.foreignKey.column})` + (this.foreignKey.onDelete ? ` ON DELETE ${this.foreignKey.onDelete}` : "") + @@ -309,31 +326,40 @@ export class ColumnDefinition { return additions; } - public buildToAlter(tableName: string, previousName?: string): string[] { + public buildToAlter(tableNameEntry: string, previousName?: string): string[] { + + let tableName = tableNameEntry.trim(); + + if (tableName.startsWith('"') && tableName.endsWith('"')) { + tableName = tableName.slice(1, -1); + } + const alterColumnName = - previousName !== this.name - ? `ALTER TABLE ${tableName} RENAME COLUMN ${previousName} TO ${this.name}` + (previousName !== this.name && previousName) + ? `ALTER TABLE ${tableNameEntry} RENAME COLUMN ${previousName} TO ${this.name}` : ""; - const alterColumnType = `ALTER TABLE ${tableName} ALTER COLUMN ${this.name} TYPE ${this.type?.toString()}`; + const alterColumnType = `ALTER TABLE ${tableNameEntry} ALTER COLUMN ${this.name} TYPE ${this.type?.toString()}`; const alterColumnNullability = this.isNullable - ? `ALTER TABLE ${tableName} ALTER COLUMN ${this.name} DROP NOT NULL` - : `ALTER TABLE ${tableName} ALTER COLUMN ${this.name} SET NOT NULL`; + ? `ALTER TABLE ${tableNameEntry} ALTER COLUMN ${this.name} DROP NOT NULL` + : `ALTER TABLE ${tableNameEntry} ALTER COLUMN ${this.name} SET NOT NULL`; const alterColumnDefault = this.defaultValue !== undefined - ? `ALTER TABLE ${tableName} ALTER COLUMN ${this.name} SET DEFAULT ${this.defaultValue}` - : `ALTER TABLE ${tableName} ALTER COLUMN ${this.name} DROP DEFAULT`; + ? `ALTER TABLE ${tableNameEntry} ALTER COLUMN ${this.name} SET DEFAULT ${this.defaultValue}` + : this.dropDefault + ? `ALTER TABLE ${tableNameEntry} ALTER COLUMN ${this.name} DROP DEFAULT` + : ""; const alterColumnCheck = this.checkCondition !== undefined - ? `ALTER TABLE ${tableName} ADD CONSTRAINT ${this.name}_check CHECK (${this.checkCondition})` + ? `ALTER TABLE ${tableNameEntry} ADD CONSTRAINT ${tableName}_${this.name}_check CHECK (${this.checkCondition})` : ""; const alterColumnPrimaryKey = this.isPrimaryKey - ? `ALTER TABLE ${tableName} ADD CONSTRAINT ${this.name}_pkey PRIMARY KEY (${this.name})` + ? `ALTER TABLE ${tableNameEntry} ADD CONSTRAINT ${tableName}_${this.name}_pkey PRIMARY KEY (${this.name})` : ""; const alterColumnUnique = this.isUnique - ? `ALTER TABLE ${tableName} ADD CONSTRAINT ${this.name}_unique UNIQUE (${this.name})` + ? `ALTER TABLE ${tableNameEntry} ADD CONSTRAINT ${tableName}_${this.name}_unique UNIQUE (${this.name})` : ""; const alterForeignKey = this.foreignKey - ? `ALTER TABLE ${tableName} ADD CONSTRAINT ${this.name}_fkey FOREIGN KEY (${this.name}) REFERENCES ${this.foreignKey.table}(${this.foreignKey.column})` + + ? `ALTER TABLE ${tableNameEntry} ADD CONSTRAINT ${tableName}_${this.name}_fkey FOREIGN KEY (${this.name}) REFERENCES ${this.foreignKey.table}(${this.foreignKey.column})` + (this.foreignKey.onDelete ? ` ON DELETE ${this.foreignKey.onDelete}` : "") + diff --git a/src/types/ColumnTypes.test.ts b/src/types/ColumnTypes.test.ts new file mode 100644 index 0000000..65c8bad --- /dev/null +++ b/src/types/ColumnTypes.test.ts @@ -0,0 +1,40 @@ +import { describe, expect, it } from "vitest"; +import { Bit, Char, Decimal, Numeric, VarBit, Varchar } from "./ColumnTypes.js"; + +describe("Column Types", () => { + it("should create Numeric column type", () => { + const numericType = Numeric(10, 2); + expect(numericType.build()).toEqual("NUMERIC(10, 2)"); + + const numericTypeNoScale = Numeric(5); + expect(numericTypeNoScale.build()).toEqual("NUMERIC(5)"); + }); + + it('should create Decimal column type', () => { + const decimalType = Decimal(8, 3); + expect(decimalType.build()).toEqual("DECIMAL(8, 3)"); + + const decimalTypeNoScale = Decimal(4); + expect(decimalTypeNoScale.build()).toEqual("DECIMAL(4)"); + }); + + it('should create Char column type', () => { + const charType = Char(10); + expect(charType.build()).toEqual("CHAR(10)"); + }); + + it('should create Varchar column type', () => { + const varcharType = Varchar(255); + expect(varcharType.build()).toEqual("VARCHAR(255)"); + }); + + it('should create Bit column type', () => { + const bitType = Bit(1); + expect(bitType.build()).toEqual("BIT(1)"); + }); + + it('should create VarBit column type', () => { + const varBitType = VarBit(16); + expect(varBitType.build()).toEqual("VARBIT(16)"); + }); +});